From 3f26f9785ed9d08abe8b1234a4a54a96a0196cc7 Mon Sep 17 00:00:00 2001 From: Philipp Date: Fri, 22 Mar 2024 15:53:47 +0100 Subject: [PATCH 001/222] [Hotfix] Fix REPO_URL for woodpecker --- .woodpecker/.code_standards_check.yml | 2 +- .woodpecker/.continuous-deployment.yml | 2 +- .woodpecker/.messages.po_check.yml | 2 +- .woodpecker/.phpunit.yml | 2 +- .woodpecker/.releaser.yml | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/.woodpecker/.code_standards_check.yml b/.woodpecker/.code_standards_check.yml index 9d59dc08..8e0f7dc7 100644 --- a/.woodpecker/.code_standards_check.yml +++ b/.woodpecker/.code_standards_check.yml @@ -13,7 +13,7 @@ pipeline: commands: - git config --global user.email "no-reply@friendi.ca" - git config --global user.name "Friendica" - - git clone $CI_REPO_LINK addon + - git clone $CI_REPO_CLONE_URL addon - cd addon/ - git checkout $CI_COMMIT_BRANCH - git fetch origin $CI_COMMIT_REF diff --git a/.woodpecker/.continuous-deployment.yml b/.woodpecker/.continuous-deployment.yml index 3756a8bf..d1202978 100644 --- a/.woodpecker/.continuous-deployment.yml +++ b/.woodpecker/.continuous-deployment.yml @@ -20,7 +20,7 @@ pipeline: commands: - git config --global user.email "no-reply@friendi.ca" - git config --global user.name "Friendica" - - git clone $CI_REPO_LINK addon + - git clone $CI_REPO_CLONE_URL addon - cd addon/ - git checkout $CI_COMMIT_BRANCH - git fetch origin $CI_COMMIT_REF diff --git a/.woodpecker/.messages.po_check.yml b/.woodpecker/.messages.po_check.yml index f5691e00..ea9fa4d5 100644 --- a/.woodpecker/.messages.po_check.yml +++ b/.woodpecker/.messages.po_check.yml @@ -13,7 +13,7 @@ pipeline: commands: - git config --global user.email "no-reply@friendi.ca" - git config --global user.name "Friendica" - - git clone $CI_REPO_LINK addon + - git clone $CI_REPO_CLONE_URL addon - cd addon/ - git checkout $CI_COMMIT_BRANCH - git fetch origin $CI_COMMIT_REF diff --git a/.woodpecker/.phpunit.yml b/.woodpecker/.phpunit.yml index 1e6189d3..0c25a2bd 100644 --- a/.woodpecker/.phpunit.yml +++ b/.woodpecker/.phpunit.yml @@ -28,7 +28,7 @@ pipeline: commands: - git config --global user.email "no-reply@friendi.ca" - git config --global user.name "Friendica" - - git clone $CI_REPO_LINK addon + - git clone $CI_REPO_CLONE_URL addon - cd addon/ - git checkout $CI_COMMIT_BRANCH - git fetch origin $CI_COMMIT_REF diff --git a/.woodpecker/.releaser.yml b/.woodpecker/.releaser.yml index 5751f07f..68bdfb21 100644 --- a/.woodpecker/.releaser.yml +++ b/.woodpecker/.releaser.yml @@ -19,7 +19,7 @@ pipeline: commands: - git config --global user.email "no-reply@friendi.ca" - git config --global user.name "Friendica" - - git clone $CI_REPO_LINK addon + - git clone $CI_REPO_CLONE_URL addon - cd addon/ - git checkout $CI_COMMIT_BRANCH - git fetch origin $CI_COMMIT_REF From c7f4d183b18aa55129af46a88179d416f03e5118 Mon Sep 17 00:00:00 2001 From: Tobias Diekershoff Date: Mon, 3 Jun 2024 08:13:08 +0200 Subject: [PATCH 002/222] FR translation updates - nsfw, securemail, tumblr --- nsfw/lang/fr/messages.po | 6 +++--- nsfw/lang/fr/strings.php | 2 +- securemail/lang/fr/messages.po | 8 ++++---- securemail/lang/fr/strings.php | 4 ++-- tumblr/lang/fr/messages.po | 12 ++++++------ tumblr/lang/fr/strings.php | 8 ++++---- 6 files changed, 20 insertions(+), 20 deletions(-) diff --git a/nsfw/lang/fr/messages.po b/nsfw/lang/fr/messages.po index 36fd22cc..2af1c3d4 100644 --- a/nsfw/lang/fr/messages.po +++ b/nsfw/lang/fr/messages.po @@ -4,7 +4,7 @@ # # # Translators: -# Florent C., 2023 +# cracrayol, 2023-2024 # Nicolas Derive, 2022-2023 # StefOfficiel , 2015 # Vincent Vindarel , 2018 @@ -14,7 +14,7 @@ msgstr "" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2022-12-10 14:42-0500\n" "PO-Revision-Date: 2014-06-23 10:34+0000\n" -"Last-Translator: Florent C., 2023\n" +"Last-Translator: cracrayol, 2023-2024\n" "Language-Team: French (http://app.transifex.com/Friendica/friendica/language/fr/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -42,7 +42,7 @@ msgstr "Liste de mots-clés - séparés par des virgules - à cacher" msgid "" "Use /expression/ to provide regular expressions, #tag to specfically match " "hashtags (case-insensitive), or regular words (case-sensitive)" -msgstr "Utiliser /expression/ pour fournir des expressions régulières, #tag pour correspondre à un tag (insensible à la casse), ou des mots classiques (sensible à la casse)" +msgstr "Utiliser /expression/ pour fournir des expressions régulières, #etiquette pour correspondre à une étiquette (insensible à la casse), ou des mots classiques (sensible à la casse)" #: nsfw.php:72 msgid "Content Filter (NSFW and more)" diff --git a/nsfw/lang/fr/strings.php b/nsfw/lang/fr/strings.php index fc03d5ad..0f717797 100644 --- a/nsfw/lang/fr/strings.php +++ b/nsfw/lang/fr/strings.php @@ -8,7 +8,7 @@ function string_plural_select_fr($n){ $a->strings['This addon searches for specified words/text in posts and collapses them. It can be used to filter content tagged with for instance #NSFW that may be deemed inappropriate at certain times or places, such as being at work. It is also useful for hiding irrelevant or annoying content from direct view.'] = 'Cette extension recherche des mots/textes spécifiés dans les publications et les masque. Elle peut être utilisée pour filtrer le contenu étiqueté par exemple avec #NSFW qui peut être considéré comme inapproprié à certains moments ou endroits, comme par exemple au travail. Elle est aussi utile pour cacher du contenu non pertinent ou ennuyeux d\'une vue directe.'; $a->strings['Enable Content filter'] = 'Activer le filtrage de contenu'; $a->strings['Comma separated list of keywords to hide'] = 'Liste de mots-clés - séparés par des virgules - à cacher'; -$a->strings['Use /expression/ to provide regular expressions, #tag to specfically match hashtags (case-insensitive), or regular words (case-sensitive)'] = 'Utiliser /expression/ pour fournir des expressions régulières, #tag pour correspondre à un tag (insensible à la casse), ou des mots classiques (sensible à la casse)'; +$a->strings['Use /expression/ to provide regular expressions, #tag to specfically match hashtags (case-insensitive), or regular words (case-sensitive)'] = 'Utiliser /expression/ pour fournir des expressions régulières, #etiquette pour correspondre à une étiquette (insensible à la casse), ou des mots classiques (sensible à la casse)'; $a->strings['Content Filter (NSFW and more)'] = 'Filtre de contenu (NSFW et autres)'; $a->strings['Regular expression "%s" fails to compile'] = 'La compilation de l\'expression régulière "%s" a échoué'; $a->strings['Filtered tag: %s'] = 'Tag filtré : %s'; diff --git a/securemail/lang/fr/messages.po b/securemail/lang/fr/messages.po index 828d507b..6e6cc657 100644 --- a/securemail/lang/fr/messages.po +++ b/securemail/lang/fr/messages.po @@ -5,7 +5,7 @@ # # Translators: # Hypolite Petovan , 2022 -# Florent C., 2023 +# cracrayol, 2024 # #, fuzzy msgid "" @@ -14,7 +14,7 @@ msgstr "" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2021-11-21 19:16-0500\n" "PO-Revision-Date: 2018-03-20 07:26+0000\n" -"Last-Translator: Florent C., 2023\n" +"Last-Translator: cracrayol, 2024\n" "Language-Team: French (https://app.transifex.com/Friendica/teams/12172/fr/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -24,7 +24,7 @@ msgstr "" #: securemail.php:50 msgid "Enable Secure Mail" -msgstr "Activer l'extension des emails sécurisés" +msgstr "Activer l'extension des courriels sécurisés" #: securemail.php:51 msgid "Public key" @@ -36,7 +36,7 @@ msgstr "Votre clé publique PGP formatée compatible ASCII" #: securemail.php:56 msgid "\"Secure Mail\" Settings" -msgstr "Paramètres des emails sécurisés" +msgstr "Paramètres des courriels sécurisés" #: securemail.php:59 msgid "Save Settings" diff --git a/securemail/lang/fr/strings.php b/securemail/lang/fr/strings.php index 9d40a8e2..b13cc5ce 100644 --- a/securemail/lang/fr/strings.php +++ b/securemail/lang/fr/strings.php @@ -5,10 +5,10 @@ function string_plural_select_fr($n){ $n = intval($n); if (($n == 0 || $n == 1)) { return 0; } else if ($n != 0 && $n % 1000000 == 0) { return 1; } else { return 2; } }} -$a->strings['Enable Secure Mail'] = 'Activer l\'extension des emails sécurisés'; +$a->strings['Enable Secure Mail'] = 'Activer l\'extension des courriels sécurisés'; $a->strings['Public key'] = 'Clé publique'; $a->strings['Your public PGP key, ascii armored format'] = 'Votre clé publique PGP formatée compatible ASCII'; -$a->strings['"Secure Mail" Settings'] = 'Paramètres des emails sécurisés'; +$a->strings['"Secure Mail" Settings'] = 'Paramètres des courriels sécurisés'; $a->strings['Save Settings'] = 'Enregistrer les paramètres'; $a->strings['Save and send test'] = 'Enregistrer et envoyer un message de test'; $a->strings['Test email sent'] = 'Courriel de test envoyé avec succès'; diff --git a/tumblr/lang/fr/messages.po b/tumblr/lang/fr/messages.po index ef2f0e3c..43dba8e3 100644 --- a/tumblr/lang/fr/messages.po +++ b/tumblr/lang/fr/messages.po @@ -5,7 +5,7 @@ # # Translators: # bob lebonche , 2021 -# Florent C., 2023 +# cracrayol, 2023-2024 # StefOfficiel , 2015 msgid "" msgstr "" @@ -13,7 +13,7 @@ msgstr "" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2023-04-29 06:56+0000\n" "PO-Revision-Date: 2014-06-23 12:58+0000\n" -"Last-Translator: Florent C., 2023\n" +"Last-Translator: cracrayol, 2023-2024\n" "Language-Team: French (http://app.transifex.com/Friendica/friendica/language/fr/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -39,13 +39,13 @@ msgstr "Secret utilisateur" #: tumblr.php:299 msgid "Maximum tags" -msgstr "Tags maximum" +msgstr "Étiquettes maximum" #: tumblr.php:299 msgid "" "Maximum number of tags that a user can follow. Enter 0 to deactivate the " "feature." -msgstr "Nombre maximum de tags qu'un utilisateur peut suivre. Entrez 0 pour désactiver cette fonctionnalité." +msgstr "Nombre maximum d'étiquettes qu'un utilisateur peut suivre. Entrez 0 pour désactiver cette fonctionnalité." #: tumblr.php:336 msgid "Post to page:" @@ -73,14 +73,14 @@ msgstr "Importer le flux distant" #: tumblr.php:351 msgid "Subscribed tags" -msgstr "Tags suivis" +msgstr "Étiquettes suivies" #: tumblr.php:351 #, php-format msgid "" "Comma separated list of up to %d tags that will be imported additionally to " "the timeline" -msgstr "Liste séparée par des virgules contenant jusqu'à %d tags qui seront importés dans le flux" +msgstr "Liste contenant jusqu'à %d étiquettes, séparées par des virgules, qui seront importées dans le flux" #: tumblr.php:357 msgid "Tumblr Import/Export" diff --git a/tumblr/lang/fr/strings.php b/tumblr/lang/fr/strings.php index ece76c74..f23c9c44 100644 --- a/tumblr/lang/fr/strings.php +++ b/tumblr/lang/fr/strings.php @@ -9,15 +9,15 @@ $a->strings['Permission denied.'] = 'Permission refusée.'; $a->strings['Save Settings'] = 'Sauvegarder les paramètres'; $a->strings['Consumer Key'] = 'Clé utilisateur'; $a->strings['Consumer Secret'] = 'Secret utilisateur'; -$a->strings['Maximum tags'] = 'Tags maximum'; -$a->strings['Maximum number of tags that a user can follow. Enter 0 to deactivate the feature.'] = 'Nombre maximum de tags qu\'un utilisateur peut suivre. Entrez 0 pour désactiver cette fonctionnalité.'; +$a->strings['Maximum tags'] = 'Étiquettes maximum'; +$a->strings['Maximum number of tags that a user can follow. Enter 0 to deactivate the feature.'] = 'Nombre maximum d\'étiquettes qu\'un utilisateur peut suivre. Entrez 0 pour désactiver cette fonctionnalité.'; $a->strings['Post to page:'] = 'Publier sur la page :'; $a->strings['(Re-)Authenticate your tumblr page'] = '(re)Authentifiez votre page Tumblr'; $a->strings['You are not authenticated to tumblr'] = 'Vous n\'êtes pas identifié sur Tumblr'; $a->strings['Enable Tumblr Post Addon'] = 'Activez l\'extension de publication Tumblr'; $a->strings['Post to Tumblr by default'] = 'Publier sur Tumblr par défaut'; $a->strings['Import the remote timeline'] = 'Importer le flux distant'; -$a->strings['Subscribed tags'] = 'Tags suivis'; -$a->strings['Comma separated list of up to %d tags that will be imported additionally to the timeline'] = 'Liste séparée par des virgules contenant jusqu\'à %d tags qui seront importés dans le flux'; +$a->strings['Subscribed tags'] = 'Étiquettes suivies'; +$a->strings['Comma separated list of up to %d tags that will be imported additionally to the timeline'] = 'Liste contenant jusqu\'à %d étiquettes, séparées par des virgules, qui seront importées dans le flux'; $a->strings['Tumblr Import/Export'] = 'Import/Export Tumblr'; $a->strings['Post to Tumblr'] = 'Publier vers Tumblr'; From 77c471ab4df90e68f9557df4e2bc37ddccfa2d51 Mon Sep 17 00:00:00 2001 From: Michael Date: Wed, 5 Jun 2024 03:37:43 +0000 Subject: [PATCH 003/222] Bluesky: Fix error on restricted posts / improve performance --- bluesky/bluesky.php | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/bluesky/bluesky.php b/bluesky/bluesky.php index ba7c1d65..453c4ead 100644 --- a/bluesky/bluesky.php +++ b/bluesky/bluesky.php @@ -1217,7 +1217,11 @@ function bluesky_get_header(stdClass $post, string $uri, int $uid, int $fetch_ui 'source' => json_encode($post), ]; + $account = Contact::selectFirstAccountUser(['pid'], ['id' => $contact['id']]); + + $item['author-id'] = $account['pid']; $item['uri-id'] = ItemURI::getIdByURI($uri); + $item['owner-id'] = $item['author-id']; $item['owner-name'] = $item['author-name']; $item['owner-link'] = $item['author-link']; $item['owner-avatar'] = $item['author-avatar']; @@ -1592,7 +1596,7 @@ function bluesky_process_thread(stdClass $thread, int $uid, int $fetch_uid, int function bluesky_get_contact(stdClass $author, int $uid, int $fetch_uid): array { - $condition = ['network' => Protocol::BLUESKY, 'uid' => 0, 'url' => $author->did]; + $condition = ['network' => Protocol::BLUESKY, 'uid' => 0, 'nurl' => $author->did]; $contact = Contact::selectFirst(['id', 'updated'], $condition); $update = empty($contact) || $contact['updated'] < DateTimeFormat::utc('now -24 hours'); @@ -1610,7 +1614,7 @@ function bluesky_get_contact(stdClass $author, int $uid, int $fetch_uid): array } if ($uid != 0) { - $condition = ['network' => Protocol::BLUESKY, 'uid' => $uid, 'url' => $author->did]; + $condition = ['network' => Protocol::BLUESKY, 'uid' => $uid, 'nurl' => $author->did]; $contact = Contact::selectFirst(['id', 'rel', 'uid'], $condition); if (!isset($fields['rel']) && isset($contact['rel'])) { From 734d35d22b7a41c0f5bbe7cedea8e5eb9358b6ae Mon Sep 17 00:00:00 2001 From: Michael Date: Wed, 5 Jun 2024 03:35:00 +0000 Subject: [PATCH 004/222] Blockbot: Logging of AP actors --- blockbot/blockbot.php | 35 ++++++++++++++++++++++++++++++++++- 1 file changed, 34 insertions(+), 1 deletion(-) diff --git a/blockbot/blockbot.php b/blockbot/blockbot.php index e5de1ef3..eb634b1f 100644 --- a/blockbot/blockbot.php +++ b/blockbot/blockbot.php @@ -15,6 +15,7 @@ use Friendica\Core\Logger; use Friendica\Core\Renderer; use Friendica\Core\System; use Friendica\Network\HTTPException\ForbiddenException; +use Friendica\Util\HTTPSignature; use Friendica\Util\Network; require_once __DIR__ . DIRECTORY_SEPARATOR . 'vendor' . DIRECTORY_SEPARATOR . 'autoload.php'; @@ -76,6 +77,8 @@ function blockbot_init_1() return; } + blockbot_log_activitypub($_SERVER['REQUEST_URI'], $_SERVER['HTTP_USER_AGENT']); + if (blockbot_is_crawler($parts)) { Logger::debug('Crawler found - reject', $logdata); blockbot_reject(); @@ -169,7 +172,7 @@ function blockbot_init_1() function blockbot_save($database, $userAgent) { - if (!DI::config()->get('blockbot', 'training') || !function_exists('dba_open')) { + if (!DI::config()->get('blockbot', 'logging') || !function_exists('dba_open')) { return; } @@ -181,6 +184,36 @@ function blockbot_save($database, $userAgent) dba_close($resource); } +function blockbot_log_activitypub(string $url, string $agent) +{ + if (!DI::config()->get('blockbot', 'logging')) { + return; + } + + $bot = ['/.well-known/nodeinfo', '/nodeinfo/2.0', '/nodeinfo/1.0']; + if (in_array($url, $bot)) { + blockbot_save('activitypub-stats', $agent); + } + + $bot = ['/api/v1/instance', '/api/v2/instance', '/api/v1/instance/extended_description', + '/api/v1/instance/peers']; + if (in_array($url, $bot)) { + blockbot_save('activitypub-api-stats', $agent); + } + + if (substr($url, 0, 6) == '/api/v') { + blockbot_save('activitypub-api', $agent); + } + + if (($_SERVER['REQUEST_METHOD'] == 'POST') && in_array('inbox', explode('/', parse_url($url, PHP_URL_PATH)))) { + blockbot_save('activitypub-inbox-agents', $agent); + } + + if (!empty($_SERVER['HTTP_SIGNATURE']) && !empty(HTTPSignature::getSigner('', $_SERVER))) { + blockbot_save('activitypub-signature-agents', $agent); + } +} + function blockbot_check_login_attempt(string $url, array $logdata) { if (in_array(trim(parse_url($url, PHP_URL_PATH), '/'), ['login', 'lostpass', 'register'])) { From 231d830db0929fb0627e075b18da5c0b331e9c18 Mon Sep 17 00:00:00 2001 From: Michael Date: Sun, 9 Jun 2024 20:32:23 +0000 Subject: [PATCH 005/222] Bluesky: Fix overwritten handle when "friendica handles" is selected --- bluesky/bluesky.php | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/bluesky/bluesky.php b/bluesky/bluesky.php index 453c4ead..fa5ba232 100644 --- a/bluesky/bluesky.php +++ b/bluesky/bluesky.php @@ -355,8 +355,11 @@ function bluesky_settings(array &$data) if (DI::config()->get('bluesky', 'friendica_handles')) { $self = User::getById(DI::userSession()->getLocalUserId(), ['nickname']); - $handle = $self['nickname'] . '.' . DI::baseUrl()->getHost(); - $friendica_handle = ['bluesky_friendica_handle', DI::l10n()->t('Allow to use %s as your Bluesky handle.', $handle), $custom_handle, DI::l10n()->t('When enabled, you can use %s as your Bluesky handle. After you enabled this option, please go to https://bsky.app/settings and select to change your handle. Select that you have got your own domain. Then enter %s and select "No DNS Panel". Then select "Verify Text File".', $handle, $handle)]; + $host_handle = $self['nickname'] . '.' . DI::baseUrl()->getHost(); + $friendica_handle = ['bluesky_friendica_handle', DI::l10n()->t('Allow to use %s as your Bluesky handle.', $host_handle), $custom_handle, DI::l10n()->t('When enabled, you can use %s as your Bluesky handle. After you enabled this option, please go to https://bsky.app/settings and select to change your handle. Select that you have got your own domain. Then enter %s and select "No DNS Panel". Then select "Verify Text File".', $host_handle, $host_handle)]; + if ($custom_handle) { + $handle = $host_handle; + } } else { $friendica_handle = []; } @@ -369,7 +372,7 @@ function bluesky_settings(array &$data) '$import_feeds' => ['bluesky_import_feeds', DI::l10n()->t('Import the pinned feeds'), $import_feeds, DI::l10n()->t('When activated, Posts will be imported from all the feeds that you pinned in Bluesky.')], '$custom_handle' => $friendica_handle, '$pds' => ['bluesky_pds', DI::l10n()->t('Personal Data Server'), $pds, DI::l10n()->t('The personal data server (PDS) is the system that hosts your profile.'), '', 'readonly'], - '$handle' => ['bluesky_handle', DI::l10n()->t('Bluesky handle'), $handle], + '$handle' => ['bluesky_handle', DI::l10n()->t('Bluesky handle'), $handle, '', '', $custom_handle ? 'readonly' : ''], '$did' => ['bluesky_did', DI::l10n()->t('Bluesky DID'), $did, DI::l10n()->t('This is the unique identifier. It will be fetched automatically, when the handle is entered.'), '', 'readonly'], '$password' => ['bluesky_password', DI::l10n()->t('Bluesky app password'), '', DI::l10n()->t("Please don't add your real password here, but instead create a specific app password in the Bluesky settings.")], '$status' => bluesky_get_status($handle, $did, $pds, $token), @@ -440,7 +443,7 @@ function bluesky_settings_post(array &$b) DI::pConfig()->set(DI::userSession()->getLocalUserId(), 'bluesky', 'handle', $handle); DI::pConfig()->set(DI::userSession()->getLocalUserId(), 'bluesky', 'import', intval($_POST['bluesky_import'])); DI::pConfig()->set(DI::userSession()->getLocalUserId(), 'bluesky', 'import_feeds', intval($_POST['bluesky_import_feeds'])); - DI::pConfig()->set(DI::userSession()->getLocalUserId(), 'bluesky', 'friendica_handle', intval($_POST['bluesky_friendica_handle'])); + DI::pConfig()->set(DI::userSession()->getLocalUserId(), 'bluesky', 'friendica_handle', intval($_POST['bluesky_friendica_handle'] ?? false)); if (!empty($handle)) { $did = bluesky_get_user_did(DI::userSession()->getLocalUserId(), empty($old_did) || $old_handle != $handle); @@ -510,7 +513,7 @@ function bluesky_cron() $abandon_limit = date(DateTimeFormat::MYSQL, time() - $abandon_days * 86400); - $pconfigs = DBA::selectToArray('pconfig', [], ['cat' => 'bluesky', 'k' => 'import', 'v' => true]); + $pconfigs = DBA::selectToArray('pconfig', [], ["`cat` = ? AND `k` IN (?, ?) AND `v`", 'bluesky', 'import', 'import_feeds']); foreach ($pconfigs as $pconfig) { if (empty(bluesky_get_user_did($pconfig['uid']))) { continue; @@ -527,8 +530,9 @@ function bluesky_cron() bluesky_get_token($pconfig['uid']); Worker::add(['priority' => Worker::PRIORITY_MEDIUM, 'force_priority' => true], 'addon/bluesky/bluesky_notifications.php', $pconfig['uid'], $last); - Worker::add(['priority' => Worker::PRIORITY_MEDIUM, 'force_priority' => true], 'addon/bluesky/bluesky_timeline.php', $pconfig['uid'], $last); - + if (DI::pConfig()->get($pconfig['uid'], 'bluesky', 'import')) { + Worker::add(['priority' => Worker::PRIORITY_MEDIUM, 'force_priority' => true], 'addon/bluesky/bluesky_timeline.php', $pconfig['uid'], $last); + } if (DI::pConfig()->get($pconfig['uid'], 'bluesky', 'import_feeds')) { $feeds = bluesky_get_feeds($pconfig['uid']); foreach ($feeds as $feed) { From fa16adccaf47f94e7fe29e9e1a7e389e2f767039 Mon Sep 17 00:00:00 2001 From: Michael Date: Mon, 10 Jun 2024 05:39:58 +0000 Subject: [PATCH 006/222] Bluesky: more logging added --- bluesky/bluesky.php | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/bluesky/bluesky.php b/bluesky/bluesky.php index fa5ba232..e9648018 100644 --- a/bluesky/bluesky.php +++ b/bluesky/bluesky.php @@ -516,6 +516,7 @@ function bluesky_cron() $pconfigs = DBA::selectToArray('pconfig', [], ["`cat` = ? AND `k` IN (?, ?) AND `v`", 'bluesky', 'import', 'import_feeds']); foreach ($pconfigs as $pconfig) { if (empty(bluesky_get_user_did($pconfig['uid']))) { + Logger::debug('User has got no valid DID', ['uid' => $pconfig['uid']]); continue; } @@ -527,6 +528,7 @@ function bluesky_cron() } // Refresh the token now, so that it doesn't need to be refreshed in parallel by the following workers + Logger::debug('Refresh the token', ['uid' => $pconfig['uid']]); bluesky_get_token($pconfig['uid']); Worker::add(['priority' => Worker::PRIORITY_MEDIUM, 'force_priority' => true], 'addon/bluesky/bluesky_notifications.php', $pconfig['uid'], $last); @@ -534,13 +536,19 @@ function bluesky_cron() Worker::add(['priority' => Worker::PRIORITY_MEDIUM, 'force_priority' => true], 'addon/bluesky/bluesky_timeline.php', $pconfig['uid'], $last); } if (DI::pConfig()->get($pconfig['uid'], 'bluesky', 'import_feeds')) { + Logger::debug('Fetch feeds for user', ['uid' => $pconfig['uid']]); $feeds = bluesky_get_feeds($pconfig['uid']); foreach ($feeds as $feed) { Worker::add(['priority' => Worker::PRIORITY_MEDIUM, 'force_priority' => true], 'addon/bluesky/bluesky_feed.php', $pconfig['uid'], $feed, $last); } } + Logger::debug('Polling done for user', ['uid' => $pconfig['uid']]); } + Logger::notice('Polling done for all users'); + + DI::keyValue()->set('bluesky_last_poll', time()); + $last_clean = DI::keyValue()->get('bluesky_last_clean'); if (empty($last_clean) || ($last_clean + 86400 < time())) { Logger::notice('Start contact cleanup'); @@ -554,8 +562,6 @@ function bluesky_cron() } Logger::notice('cron_end'); - - DI::keyValue()->set('bluesky_last_poll', time()); } function bluesky_hook_fork(array &$b) From 6f56932f120fe0a57c8bd9383735c99d7d9b9c5a Mon Sep 17 00:00:00 2001 From: Michael Date: Thu, 13 Jun 2024 04:32:00 +0000 Subject: [PATCH 007/222] Bluesky: Handle API error when fetching feeds --- bluesky/bluesky.php | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/bluesky/bluesky.php b/bluesky/bluesky.php index e9648018..6994b3e3 100644 --- a/bluesky/bluesky.php +++ b/bluesky/bluesky.php @@ -68,6 +68,7 @@ const BLUEKSY_STATUS_TOKEN_FAIL = 13; const BLUESKY_DIRECTORY = 'https://plc.directory'; // Path to the directory server service to fetch the PDS of a given DID const BLUESKY_PDS = 'https://bsky.social'; // Path to the personal data server service (PDS) to fetch the DID for a given handle const BLUESKY_WEB = 'https://bsky.app'; // Path to the web interface with the user profile and posts +const BLUESKY_HOSTNAME = 'bsky.social'; // Host name to be added to the handle if incomplete function bluesky_install() { @@ -1719,6 +1720,9 @@ function bluesky_get_feeds(int $uid): array { $type = '$type'; $preferences = bluesky_get_preferences($uid); + if (empty($preferences) || empty($preferences->preferences)) { + return []; + } foreach ($preferences->preferences as $preference) { if ($preference->$type == 'app.bsky.actor.defs#savedFeedsPref') { return $preference->pinned ?? []; @@ -1727,7 +1731,7 @@ function bluesky_get_feeds(int $uid): array return []; } -function bluesky_get_preferences(int $uid): stdClass +function bluesky_get_preferences(int $uid): ?stdClass { $cachekey = 'bluesky:preferences:' . $uid; $data = DI::cache()->get($cachekey); @@ -1736,6 +1740,9 @@ function bluesky_get_preferences(int $uid): stdClass } $data = bluesky_xrpc_get($uid, 'app.bsky.actor.getPreferences'); + if (empty($data)) { + return null; + } DI::cache()->set($cachekey, $data, Duration::HOUR); return $data; @@ -1778,6 +1785,14 @@ function bluesky_get_did_by_dns(string $handle): string function bluesky_get_did(string $handle): string { + if ($handle == '') { + return ''; + } + + if (strpos($handle, '.') === false) { + $handle .= '.' . BLUESKY_HOSTNAME; + } + // Deactivated at the moment, since it isn't reliable by now //$did = bluesky_get_did_by_dns($handle); //if ($did != '') { From 9525259fc8c74b89f2c5d8ac2aaf66392060470d Mon Sep 17 00:00:00 2001 From: Michael Date: Sat, 15 Jun 2024 13:51:47 +0000 Subject: [PATCH 008/222] Tumblr: Add link for quoted post --- tumblr/tumblr.php | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/tumblr/tumblr.php b/tumblr/tumblr.php index 04f6a0a4..f0c68f33 100644 --- a/tumblr/tumblr.php +++ b/tumblr/tumblr.php @@ -608,6 +608,15 @@ function tumblr_send_legacy(array $b) $body = BBCode::removeShareInformation($b['body']); $body = Post\Media::removeFromEndOfBody($body); + if (!empty($b['quote-uri-id'])) { + $quote = Post::selectFirstPost(['uri', 'plink'], ['uri-id' => $b['quote-uri-id']]); + if (!empty($quote)) { + if ((strpos($body, $quote['plink'] ?: $quote['uri']) === false) && (strpos($body, $quote['uri']) === false)) { + $body .= "\n[url]" . ($quote['plink'] ?: $quote['uri']) . "[/url]\n"; + } + } + } + if ($photo !== false) { $params['type'] = 'photo'; $params['caption'] = BBCode::convertForUriId($b['uri-id'], $body, BBCode::CONNECTORS); @@ -648,7 +657,7 @@ function tumblr_send_legacy(array $b) } else { $params['type'] = 'text'; $params['title'] = $title; - $params['body'] = BBCode::convertForUriId($b['uri-id'], $b['body'], BBCode::CONNECTORS); + $params['body'] = BBCode::convertForUriId($b['uri-id'], $body, BBCode::CONNECTORS); } if (isset($params['caption']) && (trim($title) != '')) { From af868f45ab6095a222b2133c210d31c9c220087d Mon Sep 17 00:00:00 2001 From: Michael Date: Sun, 16 Jun 2024 14:35:19 +0000 Subject: [PATCH 009/222] JS Uploader: "jpg" added to the list of allowed file extensions --- js_upload/js_upload.php | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/js_upload/js_upload.php b/js_upload/js_upload.php index 786fc3c2..0d045dee 100644 --- a/js_upload/js_upload.php +++ b/js_upload/js_upload.php @@ -50,7 +50,11 @@ function js_upload_post_init(array &$b) // list of valid extensions $allowedExtensions = []; foreach (Images::IMAGETYPES as $type) { - $allowedExtensions[] = image_type_to_extension($type, false); + $extension = image_type_to_extension($type, false); + if ($extension == 'jpeg') { + $allowedExtensions[] = 'jpg'; + } + $allowedExtensions[] = $extension; } // max file size in bytes @@ -216,9 +220,9 @@ class qqFileUploader return ['error' => DI::l10n()->t('Uploaded file is empty')]; } -// if ($size > $this->sizeLimit) { -// return array('error' => DI::l10n()->t('Uploaded file is too large')); -// } + // if ($size > $this->sizeLimit) { + // return array('error' => DI::l10n()->t('Uploaded file is too large')); + // } $maximagesize = Strings::getBytesFromShorthand(DI::config()->get('system', 'maximagesize')); From 3e1b98d5d97a3c7a4c6e5fb28591293acfc0db89 Mon Sep 17 00:00:00 2001 From: Matthew Exon Date: Sun, 16 Jun 2024 17:10:28 +0200 Subject: [PATCH 010/222] Leave failed image URLs in place --- mailstream/mailstream.php | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/mailstream/mailstream.php b/mailstream/mailstream.php index b513cf36..4056aac6 100644 --- a/mailstream/mailstream.php +++ b/mailstream/mailstream.php @@ -220,6 +220,11 @@ function mailstream_do_images(array &$item, array &$attachments) $cookiejar = tempnam(System::getTempPath(), 'cookiejar-mailstream-'); try { $curlResult = DI::httpClient()->fetchFull($url, HttpClientAccept::DEFAULT, 0, $cookiejar); + if (!$curlResult->isSuccess()) { + Logger::debug('mailstream: fetch image url failed', [ + 'url' => $url, 'item_id' => $item['id'], 'return_code' => $curlResult->getReturnCode()]); + continue; + } } catch (InvalidArgumentException $e) { Logger::error('mailstream_do_images exception fetching url', ['url' => $url, 'item_id' => $item['id']]); continue; From 2789e880dc7f3a2614e9811a179dca291ae8a986 Mon Sep 17 00:00:00 2001 From: Tobias Diekershoff Date: Fri, 21 Jun 2024 20:38:42 +0200 Subject: [PATCH 011/222] translation updates AR, CS, DE, IT, PL, SV for various addons --- advancedcontentfilter/lang/it/messages.po | 6 +- advancedcontentfilter/lang/it/strings.php | 1 + catavatar/lang/it/messages.po | 50 ++++++------- catavatar/lang/it/strings.php | 10 +-- curweather/lang/it/messages.po | 56 +++++++-------- curweather/lang/it/strings.php | 6 +- dwpost/lang/it/messages.po | 46 ++++++------ dwpost/lang/it/strings.php | 11 ++- libertree/lang/it/messages.po | 38 +++++----- libertree/lang/it/strings.php | 7 +- mailstream/lang/de/messages.po | 50 +++++++------ mailstream/lang/de/strings.php | 3 +- tumblr/lang/ar/messages.po | 85 ++++++++++++++--------- tumblr/lang/ar/strings.php | 1 - tumblr/lang/cs/messages.po | 61 ++++++++++------ tumblr/lang/cs/strings.php | 4 +- tumblr/lang/de/messages.po | 67 +++++++++++------- tumblr/lang/de/strings.php | 11 +-- tumblr/lang/it/messages.po | 63 +++++++++++------ tumblr/lang/it/strings.php | 5 +- tumblr/lang/pl/messages.po | 65 ++++++++++------- tumblr/lang/pl/strings.php | 5 +- tumblr/lang/sv/messages.po | 63 +++++++++++------ tumblr/lang/sv/strings.php | 1 - 24 files changed, 405 insertions(+), 310 deletions(-) diff --git a/advancedcontentfilter/lang/it/messages.po b/advancedcontentfilter/lang/it/messages.po index f32c5b94..325be52c 100644 --- a/advancedcontentfilter/lang/it/messages.po +++ b/advancedcontentfilter/lang/it/messages.po @@ -5,7 +5,7 @@ # # Translators: # fabrixxm , 2018 -# Sylke Vicious , 2021 +# Sylke Vicious , 2023 # #, fuzzy msgid "" @@ -14,7 +14,7 @@ msgstr "" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2022-05-11 08:54-0400\n" "PO-Revision-Date: 2018-05-24 06:41+0000\n" -"Last-Translator: Sylke Vicious , 2021\n" +"Last-Translator: Sylke Vicious , 2023\n" "Language-Team: Italian (https://app.transifex.com/Friendica/teams/12172/it/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -125,7 +125,7 @@ msgstr "Annulla" #: advancedcontentfilter.php:295 msgid "This addon requires this node having at least one post" -msgstr "" +msgstr "Questo addon richiede che questo nodo abbia almeno un messaggio" #: advancedcontentfilter.php:325 advancedcontentfilter.php:336 #: advancedcontentfilter.php:347 advancedcontentfilter.php:383 diff --git a/advancedcontentfilter/lang/it/strings.php b/advancedcontentfilter/lang/it/strings.php index 5cc01739..d47d7a5a 100644 --- a/advancedcontentfilter/lang/it/strings.php +++ b/advancedcontentfilter/lang/it/strings.php @@ -27,6 +27,7 @@ $a->strings['Add new rule'] = 'Aggiungi nuova regola'; $a->strings['Rule Name'] = 'Nome Regola'; $a->strings['Rule Expression'] = 'Espressione Regola'; $a->strings['Cancel'] = 'Annulla'; +$a->strings['This addon requires this node having at least one post'] = 'Questo addon richiede che questo nodo abbia almeno un messaggio'; $a->strings['You must be logged in to use this method'] = 'Devi essere autenticato per usare questo metodo'; $a->strings['Invalid form security token, please refresh the page.'] = 'Token di sicurezza invalido, aggiorna la pagina.'; $a->strings['The rule name and expression are required.'] = 'Il nome e l\'espressione della regola sono richiesti.'; diff --git a/catavatar/lang/it/messages.po b/catavatar/lang/it/messages.po index e05bd277..9155bb48 100644 --- a/catavatar/lang/it/messages.po +++ b/catavatar/lang/it/messages.po @@ -6,55 +6,55 @@ # Translators: # fabrixxm , 2018 # Davide Pesenti , 2018 -# Sylke Vicious , 2021 +# Sylke Vicious , 2023 # #, fuzzy msgid "" msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2020-12-29 00:53+0000\n" +"POT-Creation-Date: 2021-11-21 19:14-0500\n" "PO-Revision-Date: 2018-04-07 05:23+0000\n" -"Last-Translator: Sylke Vicious , 2021\n" -"Language-Team: Italian (https://www.transifex.com/Friendica/teams/12172/it/)\n" +"Last-Translator: Sylke Vicious , 2023\n" +"Language-Team: Italian (https://app.transifex.com/Friendica/teams/12172/it/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Language: it\n" -"Plural-Forms: nplurals=2; plural=(n != 1);\n" +"Plural-Forms: nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;\n" #: catavatar.php:48 -msgid "Use Cat as Avatar" -msgstr "Usa il Gatto come avatar" - -#: catavatar.php:49 -msgid "More Random Cat!" -msgstr "Altro Gatto a caso!" - -#: catavatar.php:50 -msgid "Reset to email Cat" -msgstr "Reimposta Gatto" - -#: catavatar.php:52 -msgid "Cat Avatar Settings" -msgstr "Impostazioni Avatar Gatto" - -#: catavatar.php:53 msgid "Set default profile avatar or randomize the cat." msgstr "Imposta l'immagine di profilo predefinita o crea un gatto casuale." -#: catavatar.php:78 +#: catavatar.php:53 +msgid "Cat Avatar Settings" +msgstr "Impostazioni Avatar Gatto" + +#: catavatar.php:56 +msgid "Use Cat as Avatar" +msgstr "Usa il Gatto come avatar" + +#: catavatar.php:57 +msgid "Another random Cat!" +msgstr "Un altro Gatto casuale!" + +#: catavatar.php:58 +msgid "Reset to email Cat" +msgstr "Reimposta Gatto" + +#: catavatar.php:77 msgid "The cat hadn't found itself." msgstr "Il gatto non ha trovato sé stesso." -#: catavatar.php:87 +#: catavatar.php:86 msgid "There was an error, the cat ran away." msgstr "Si è verificato un errore, il gatto è scappato." -#: catavatar.php:93 +#: catavatar.php:92 msgid "Profile Photos" msgstr "Foto del profilo" -#: catavatar.php:108 +#: catavatar.php:102 msgid "Meow!" msgstr "Miao!" diff --git a/catavatar/lang/it/strings.php b/catavatar/lang/it/strings.php index 3a33374a..8f78b3fe 100644 --- a/catavatar/lang/it/strings.php +++ b/catavatar/lang/it/strings.php @@ -3,13 +3,13 @@ if(! function_exists("string_plural_select_it")) { function string_plural_select_it($n){ $n = intval($n); - return intval($n != 1); + if ($n == 1) { return 0; } else if ($n != 0 && $n % 1000000 == 0) { return 1; } else { return 2; } }} -$a->strings['Use Cat as Avatar'] = 'Usa il Gatto come avatar'; -$a->strings['More Random Cat!'] = 'Altro Gatto a caso!'; -$a->strings['Reset to email Cat'] = 'Reimposta Gatto'; -$a->strings['Cat Avatar Settings'] = 'Impostazioni Avatar Gatto'; $a->strings['Set default profile avatar or randomize the cat.'] = 'Imposta l\'immagine di profilo predefinita o crea un gatto casuale.'; +$a->strings['Cat Avatar Settings'] = 'Impostazioni Avatar Gatto'; +$a->strings['Use Cat as Avatar'] = 'Usa il Gatto come avatar'; +$a->strings['Another random Cat!'] = 'Un altro Gatto casuale!'; +$a->strings['Reset to email Cat'] = 'Reimposta Gatto'; $a->strings['The cat hadn\'t found itself.'] = 'Il gatto non ha trovato sé stesso.'; $a->strings['There was an error, the cat ran away.'] = 'Si è verificato un errore, il gatto è scappato.'; $a->strings['Profile Photos'] = 'Foto del profilo'; diff --git a/curweather/lang/it/messages.po b/curweather/lang/it/messages.po index 5a7e2cac..c53b3a6e 100644 --- a/curweather/lang/it/messages.po +++ b/curweather/lang/it/messages.po @@ -5,27 +5,27 @@ # # Translators: # fabrixxm , 2014-2015 -# Sylke Vicious , 2021 +# Sylke Vicious , 2021,2023 # Tobias Diekershoff , 2016 msgid "" msgstr "" "Project-Id-Version: friendica\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2021-02-01 18:15+0100\n" -"PO-Revision-Date: 2021-02-16 12:57+0000\n" -"Last-Translator: Sylke Vicious \n" -"Language-Team: Italian (http://www.transifex.com/Friendica/friendica/language/it/)\n" +"POT-Creation-Date: 2021-11-21 19:14-0500\n" +"PO-Revision-Date: 2014-06-22 11:34+0000\n" +"Last-Translator: Sylke Vicious , 2021,2023\n" +"Language-Team: Italian (http://app.transifex.com/Friendica/friendica/language/it/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Language: it\n" -"Plural-Forms: nplurals=2; plural=(n != 1);\n" +"Plural-Forms: nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;\n" #: curweather.php:47 msgid "Error fetching weather data. Error was: " msgstr "Errore durante il recupero dei dati meteo. L'errore è stato:" -#: curweather.php:130 curweather.php:192 +#: curweather.php:130 msgid "Current Weather" msgstr "Meteo" @@ -61,66 +61,66 @@ msgstr "C'è stato un problema accedendo ai dati meteo, ma dai un'occhiata" msgid "at OpenWeatherMap" msgstr "a OpenWeatherMap" -#: curweather.php:179 +#: curweather.php:178 msgid "No APPID found, please contact your admin to obtain one." msgstr "APPID non trovata, contatta il tuo amministratore per averne una." -#: curweather.php:191 curweather.php:229 -msgid "Save Settings" -msgstr "Salva Impostazioni" - -#: curweather.php:192 -msgid "Settings" -msgstr "Impostazioni" - -#: curweather.php:194 +#: curweather.php:188 msgid "Enter either the name of your location or the zip code." msgstr "Inserisci il nome della tua posizione o il CAP" -#: curweather.php:195 +#: curweather.php:189 msgid "Your Location" msgstr "La tua Posizione" -#: curweather.php:195 +#: curweather.php:189 msgid "" "Identifier of your location (name or zip code), e.g. Berlin,DE or " "14476,DE." msgstr "Identificatore della tua posizione (nome o CAP), p.e. Roma, IT or 00186,IT." -#: curweather.php:196 +#: curweather.php:190 msgid "Units" msgstr "Unità" -#: curweather.php:196 +#: curweather.php:190 msgid "select if the temperature should be displayed in °C or °F" msgstr "scegli se la temperatura deve essere mostrata in °C o in °F" -#: curweather.php:197 +#: curweather.php:191 msgid "Show weather data" msgstr "Mostra dati meteo" -#: curweather.php:232 +#: curweather.php:196 +msgid "Current Weather Settings" +msgstr "Impostazioni Meteo" + +#: curweather.php:227 +msgid "Save Settings" +msgstr "Salva Impostazioni" + +#: curweather.php:230 msgid "Caching Interval" msgstr "Intervallo di cache" -#: curweather.php:234 +#: curweather.php:232 msgid "" "For how long should the weather data be cached? Choose according your " "OpenWeatherMap account type." msgstr "Per quanto tempo i dati meteo devono essere memorizzati? Scegli a seconda del tuo tipo di account su OpenWeatherMap." -#: curweather.php:235 +#: curweather.php:233 msgid "no cache" msgstr "nessuna cache" -#: curweather.php:236 curweather.php:237 curweather.php:238 curweather.php:239 +#: curweather.php:234 curweather.php:235 curweather.php:236 curweather.php:237 msgid "minutes" msgstr "minuti" -#: curweather.php:242 +#: curweather.php:240 msgid "Your APPID" msgstr "Il tuo APPID" -#: curweather.php:242 +#: curweather.php:240 msgid "Your API key provided by OpenWeatherMap" msgstr "La tua chiave API da OpenWeatherMap" diff --git a/curweather/lang/it/strings.php b/curweather/lang/it/strings.php index a497dace..6c651e1b 100644 --- a/curweather/lang/it/strings.php +++ b/curweather/lang/it/strings.php @@ -3,7 +3,7 @@ if(! function_exists("string_plural_select_it")) { function string_plural_select_it($n){ $n = intval($n); - return intval($n != 1); + if ($n == 1) { return 0; } else if ($n != 0 && $n % 1000000 == 0) { return 1; } else { return 2; } }} $a->strings['Error fetching weather data. Error was: '] = 'Errore durante il recupero dei dati meteo. L\'errore è stato:'; $a->strings['Current Weather'] = 'Meteo'; @@ -16,14 +16,14 @@ $a->strings['Show on map'] = 'Mostra sulla mappa'; $a->strings['There was a problem accessing the weather data. But have a look'] = 'C\'è stato un problema accedendo ai dati meteo, ma dai un\'occhiata'; $a->strings['at OpenWeatherMap'] = 'a OpenWeatherMap'; $a->strings['No APPID found, please contact your admin to obtain one.'] = 'APPID non trovata, contatta il tuo amministratore per averne una.'; -$a->strings['Save Settings'] = 'Salva Impostazioni'; -$a->strings['Settings'] = 'Impostazioni'; $a->strings['Enter either the name of your location or the zip code.'] = 'Inserisci il nome della tua posizione o il CAP'; $a->strings['Your Location'] = 'La tua Posizione'; $a->strings['Identifier of your location (name or zip code), e.g. Berlin,DE or 14476,DE.'] = 'Identificatore della tua posizione (nome o CAP), p.e. Roma, IT or 00186,IT.'; $a->strings['Units'] = 'Unità'; $a->strings['select if the temperature should be displayed in °C or °F'] = 'scegli se la temperatura deve essere mostrata in °C o in °F'; $a->strings['Show weather data'] = 'Mostra dati meteo'; +$a->strings['Current Weather Settings'] = 'Impostazioni Meteo'; +$a->strings['Save Settings'] = 'Salva Impostazioni'; $a->strings['Caching Interval'] = 'Intervallo di cache'; $a->strings['For how long should the weather data be cached? Choose according your OpenWeatherMap account type.'] = 'Per quanto tempo i dati meteo devono essere memorizzati? Scegli a seconda del tuo tipo di account su OpenWeatherMap.'; $a->strings['no cache'] = 'nessuna cache'; diff --git a/dwpost/lang/it/messages.po b/dwpost/lang/it/messages.po index 5f7c2ee2..a5a79d47 100644 --- a/dwpost/lang/it/messages.po +++ b/dwpost/lang/it/messages.po @@ -5,45 +5,41 @@ # # Translators: # fabrixxm , 2014,2018 -# Sylke Vicious , 2020-2021 +# Sylke Vicious , 2020-2021,2023 msgid "" msgstr "" "Project-Id-Version: friendica\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2021-02-01 18:15+0100\n" -"PO-Revision-Date: 2021-02-16 12:55+0000\n" -"Last-Translator: Sylke Vicious \n" -"Language-Team: Italian (http://www.transifex.com/Friendica/friendica/language/it/)\n" +"POT-Creation-Date: 2021-11-21 19:17-0500\n" +"PO-Revision-Date: 2014-06-22 11:41+0000\n" +"Last-Translator: Sylke Vicious , 2020-2021,2023\n" +"Language-Team: Italian (http://app.transifex.com/Friendica/friendica/language/it/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Language: it\n" -"Plural-Forms: nplurals=2; plural=(n != 1);\n" +"Plural-Forms: nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;\n" -#: dwpost.php:41 +#: dwpost.php:43 msgid "Post to Dreamwidth" msgstr "Invia a Dreamwidth" -#: dwpost.php:72 dwpost.php:76 -msgid "Dreamwidth Export" -msgstr "Esporta Dreamwidth" +#: dwpost.php:63 +msgid "Enable Dreamwidth Post Addon" +msgstr "Abilita il componente aggiuntivo di pubblicazione Dreamwidth" -#: dwpost.php:80 -msgid "Enable dreamwidth Post Addon" -msgstr "Abilita il componente aggiuntivo di invio a Dreamwidth" - -#: dwpost.php:85 -msgid "dreamwidth username" +#: dwpost.php:64 +msgid "Dreamwidth username" msgstr "Nome utente Dreamwidth" -#: dwpost.php:90 -msgid "dreamwidth password" -msgstr "password Dreamwidth" +#: dwpost.php:65 +msgid "Dreamwidth password" +msgstr "Password Dreamwidth" -#: dwpost.php:95 -msgid "Post to dreamwidth by default" -msgstr "Invia sempre a Dreamwidth" +#: dwpost.php:66 +msgid "Post to Dreamwidth by default" +msgstr "Pubblica su dreamwidth per impostazione predefinita" -#: dwpost.php:100 -msgid "Save Settings" -msgstr "Salva Impostazioni" +#: dwpost.php:71 +msgid "Dreamwidth Export" +msgstr "Esporta Dreamwidth" diff --git a/dwpost/lang/it/strings.php b/dwpost/lang/it/strings.php index 0234c1f7..22ecc7b1 100644 --- a/dwpost/lang/it/strings.php +++ b/dwpost/lang/it/strings.php @@ -3,12 +3,11 @@ if(! function_exists("string_plural_select_it")) { function string_plural_select_it($n){ $n = intval($n); - return intval($n != 1); + if ($n == 1) { return 0; } else if ($n != 0 && $n % 1000000 == 0) { return 1; } else { return 2; } }} $a->strings['Post to Dreamwidth'] = 'Invia a Dreamwidth'; +$a->strings['Enable Dreamwidth Post Addon'] = 'Abilita il componente aggiuntivo di pubblicazione Dreamwidth'; +$a->strings['Dreamwidth username'] = 'Nome utente Dreamwidth'; +$a->strings['Dreamwidth password'] = 'Password Dreamwidth'; +$a->strings['Post to Dreamwidth by default'] = 'Pubblica su dreamwidth per impostazione predefinita'; $a->strings['Dreamwidth Export'] = 'Esporta Dreamwidth'; -$a->strings['Enable dreamwidth Post Addon'] = 'Abilita il componente aggiuntivo di invio a Dreamwidth'; -$a->strings['dreamwidth username'] = 'Nome utente Dreamwidth'; -$a->strings['dreamwidth password'] = 'password Dreamwidth'; -$a->strings['Post to dreamwidth by default'] = 'Invia sempre a Dreamwidth'; -$a->strings['Save Settings'] = 'Salva Impostazioni'; diff --git a/libertree/lang/it/messages.po b/libertree/lang/it/messages.po index 7c3bc1ec..cc890cc5 100644 --- a/libertree/lang/it/messages.po +++ b/libertree/lang/it/messages.po @@ -5,45 +5,41 @@ # # Translators: # fabrixxm , 2014-2015,2018 -# Sylke Vicious , 2021 +# Sylke Vicious , 2021,2023 msgid "" msgstr "" "Project-Id-Version: friendica\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2021-02-01 18:15+0100\n" -"PO-Revision-Date: 2021-02-16 12:47+0000\n" -"Last-Translator: Sylke Vicious \n" -"Language-Team: Italian (http://www.transifex.com/Friendica/friendica/language/it/)\n" +"POT-Creation-Date: 2023-06-03 15:49-0400\n" +"PO-Revision-Date: 2014-06-23 09:44+0000\n" +"Last-Translator: Sylke Vicious , 2021,2023\n" +"Language-Team: Italian (http://app.transifex.com/Friendica/friendica/language/it/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Language: it\n" -"Plural-Forms: nplurals=2; plural=(n != 1);\n" +"Plural-Forms: nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;\n" -#: libertree.php:37 +#: libertree.php:39 msgid "Post to libertree" msgstr "Invia a Libertree" -#: libertree.php:71 libertree.php:75 -msgid "libertree Export" -msgstr "Esporta libertree" - -#: libertree.php:79 +#: libertree.php:59 msgid "Enable Libertree Post Addon" msgstr "Abilita il componente aggiuntivo di invio a Libertree" -#: libertree.php:84 -msgid "Libertree API token" -msgstr "Token API Libertree" - -#: libertree.php:89 +#: libertree.php:60 msgid "Libertree site URL" msgstr "Indirizzo sito Libertree" -#: libertree.php:94 +#: libertree.php:61 +msgid "Libertree API token" +msgstr "Token API Libertree" + +#: libertree.php:62 msgid "Post to Libertree by default" msgstr "Invia sempre a Libertree" -#: libertree.php:100 -msgid "Save Settings" -msgstr "Salva Impostazioni" +#: libertree.php:67 +msgid "Libertree Export" +msgstr "Esporta Libertree" diff --git a/libertree/lang/it/strings.php b/libertree/lang/it/strings.php index 02d26542..8abcfa2d 100644 --- a/libertree/lang/it/strings.php +++ b/libertree/lang/it/strings.php @@ -3,12 +3,11 @@ if(! function_exists("string_plural_select_it")) { function string_plural_select_it($n){ $n = intval($n); - return intval($n != 1); + if ($n == 1) { return 0; } else if ($n != 0 && $n % 1000000 == 0) { return 1; } else { return 2; } }} $a->strings['Post to libertree'] = 'Invia a Libertree'; -$a->strings['libertree Export'] = 'Esporta libertree'; $a->strings['Enable Libertree Post Addon'] = 'Abilita il componente aggiuntivo di invio a Libertree'; -$a->strings['Libertree API token'] = 'Token API Libertree'; $a->strings['Libertree site URL'] = 'Indirizzo sito Libertree'; +$a->strings['Libertree API token'] = 'Token API Libertree'; $a->strings['Post to Libertree by default'] = 'Invia sempre a Libertree'; -$a->strings['Save Settings'] = 'Salva Impostazioni'; +$a->strings['Libertree Export'] = 'Esporta Libertree'; diff --git a/mailstream/lang/de/messages.po b/mailstream/lang/de/messages.po index 236e7d0e..cd55d952 100644 --- a/mailstream/lang/de/messages.po +++ b/mailstream/lang/de/messages.po @@ -5,16 +5,18 @@ # # Translators: # Andreas H., 2014 +# foss , 2022 +# Raroun, 2023 # Tobias Diekershoff , 2018 # Ulf Rompe , 2019 msgid "" msgstr "" "Project-Id-Version: friendica\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2018-03-11 19:13+0100\n" -"PO-Revision-Date: 2019-02-18 15:05+0000\n" -"Last-Translator: Ulf Rompe \n" -"Language-Team: German (http://www.transifex.com/Friendica/friendica/language/de/)\n" +"POT-Creation-Date: 2021-11-21 19:15-0500\n" +"PO-Revision-Date: 2014-06-23 09:54+0000\n" +"Last-Translator: Raroun, 2023\n" +"Language-Team: German (http://app.transifex.com/Friendica/friendica/language/de/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" @@ -29,72 +31,76 @@ msgstr "Absender" msgid "Email address that stream items will appear to be from." msgstr "E-Mail-Adresse, die in hochgeladenen Artikeln erscheint." -#: mailstream.php:82 mailstream.php:380 +#: mailstream.php:82 msgid "Save Settings" msgstr "Einstellungen speichern" -#: mailstream.php:223 +#: mailstream.php:311 msgid "Re:" msgstr "Re:" -#: mailstream.php:231 +#: mailstream.php:324 mailstream.php:327 msgid "Friendica post" msgstr "Friendica-Veröffentlichung" -#: mailstream.php:234 +#: mailstream.php:330 msgid "Diaspora post" msgstr "Diaspora-Veröffentlichung" -#: mailstream.php:244 +#: mailstream.php:340 msgid "Feed item" msgstr "Artikel-Feed" -#: mailstream.php:247 +#: mailstream.php:343 msgid "Email" msgstr "E-Mail" -#: mailstream.php:249 +#: mailstream.php:345 msgid "Friendica Item" msgstr "Friendica-Artikel" -#: mailstream.php:293 +#: mailstream.php:419 msgid "Upstream" msgstr "Upstream" -#: mailstream.php:294 +#: mailstream.php:420 +msgid "URI" +msgstr "URI" + +#: mailstream.php:421 msgid "Local" msgstr "Lokal" -#: mailstream.php:362 +#: mailstream.php:499 msgid "Enabled" -msgstr "eingeschaltet" +msgstr "Aktiv" -#: mailstream.php:366 +#: mailstream.php:504 msgid "Email Address" msgstr "E-Mail-Adresse" -#: mailstream.php:368 +#: mailstream.php:506 msgid "Leave blank to use your account email address" msgstr "Leer lassen für deine Konto-E-Mail-Addresse" -#: mailstream.php:371 +#: mailstream.php:510 msgid "Exclude Likes" msgstr "Likes ignorieren" -#: mailstream.php:373 +#: mailstream.php:512 msgid "Check this to omit mailing \"Like\" notifications" msgstr "Diese Option verhindert das Versenden von \"Like\"-Benachrichtigungen per E-Mail." -#: mailstream.php:376 +#: mailstream.php:516 msgid "Attach Images" msgstr "Bilder anhängen" -#: mailstream.php:378 +#: mailstream.php:518 msgid "" "Download images in posts and attach them to the email. Useful for reading " "email while offline." msgstr "Sollen Bilder, die im Beitrag eingebettet sind, als Dateianhang in den E-Mails verschickt werden?" -#: mailstream.php:379 +#: mailstream.php:525 msgid "Mail Stream Settings" msgstr "Mail-Nachrichten-Einstellungen" diff --git a/mailstream/lang/de/strings.php b/mailstream/lang/de/strings.php index 80f9a7a2..e107b7d0 100644 --- a/mailstream/lang/de/strings.php +++ b/mailstream/lang/de/strings.php @@ -15,8 +15,9 @@ $a->strings['Feed item'] = 'Artikel-Feed'; $a->strings['Email'] = 'E-Mail'; $a->strings['Friendica Item'] = 'Friendica-Artikel'; $a->strings['Upstream'] = 'Upstream'; +$a->strings['URI'] = 'URI'; $a->strings['Local'] = 'Lokal'; -$a->strings['Enabled'] = 'eingeschaltet'; +$a->strings['Enabled'] = 'Aktiv'; $a->strings['Email Address'] = 'E-Mail-Adresse'; $a->strings['Leave blank to use your account email address'] = 'Leer lassen für deine Konto-E-Mail-Addresse'; $a->strings['Exclude Likes'] = 'Likes ignorieren'; diff --git a/tumblr/lang/ar/messages.po b/tumblr/lang/ar/messages.po index 7879231d..48a9e8cb 100644 --- a/tumblr/lang/ar/messages.po +++ b/tumblr/lang/ar/messages.po @@ -8,64 +8,81 @@ msgid "" msgstr "" "Project-Id-Version: friendica\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2021-07-25 13:15+0000\n" -"PO-Revision-Date: 2021-02-20 00:23+0000\n" -"Last-Translator: Farida Khalaf \n" -"Language-Team: Arabic (http://www.transifex.com/Friendica/friendica/language/ar/)\n" +"POT-Creation-Date: 2023-04-29 06:56+0000\n" +"PO-Revision-Date: 2014-06-23 12:58+0000\n" +"Last-Translator: FULL NAME \n" +"Language-Team: Arabic (http://app.transifex.com/Friendica/friendica/language/ar/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Language: ar\n" "Plural-Forms: nplurals=6; plural=n==0 ? 0 : n==1 ? 1 : n==2 ? 2 : n%100>=3 && n%100<=10 ? 3 : n%100>=11 && n%100<=99 ? 4 : 5;\n" -#: tumblr.php:40 +#: tumblr.php:243 msgid "Permission denied." msgstr "الطلب مرفوض." -#: tumblr.php:70 tumblr.php:284 +#: tumblr.php:296 msgid "Save Settings" msgstr "Save Settings" -#: tumblr.php:72 +#: tumblr.php:297 msgid "Consumer Key" msgstr "" -#: tumblr.php:73 +#: tumblr.php:298 msgid "Consumer Secret" msgstr "" -#: tumblr.php:178 -msgid "You are now authenticated to tumblr." +#: tumblr.php:299 +msgid "Maximum tags" msgstr "" -#: tumblr.php:179 -msgid "return to the connector page" -msgstr "الرجوع إلى صفحة الموصل" - -#: tumblr.php:195 -msgid "Post to Tumblr" +#: tumblr.php:299 +msgid "" +"Maximum number of tags that a user can follow. Enter 0 to deactivate the " +"feature." msgstr "" -#: tumblr.php:225 tumblr.php:229 -msgid "Tumblr Export" -msgstr "" - -#: tumblr.php:233 -msgid "(Re-)Authenticate your tumblr page" -msgstr "" - -#: tumblr.php:237 -msgid "Enable Tumblr Post Addon" -msgstr "" - -#: tumblr.php:243 -msgid "Post to Tumblr by default" -msgstr "" - -#: tumblr.php:264 +#: tumblr.php:336 msgid "Post to page:" msgstr "" -#: tumblr.php:278 +#: tumblr.php:342 +msgid "(Re-)Authenticate your tumblr page" +msgstr "" + +#: tumblr.php:343 msgid "You are not authenticated to tumblr" msgstr "" + +#: tumblr.php:348 +msgid "Enable Tumblr Post Addon" +msgstr "" + +#: tumblr.php:349 +msgid "Post to Tumblr by default" +msgstr "" + +#: tumblr.php:350 +msgid "Import the remote timeline" +msgstr "" + +#: tumblr.php:351 +msgid "Subscribed tags" +msgstr "" + +#: tumblr.php:351 +#, php-format +msgid "" +"Comma separated list of up to %d tags that will be imported additionally to " +"the timeline" +msgstr "" + +#: tumblr.php:357 +msgid "Tumblr Import/Export" +msgstr "" + +#: tumblr.php:375 +msgid "Post to Tumblr" +msgstr "" diff --git a/tumblr/lang/ar/strings.php b/tumblr/lang/ar/strings.php index ffd3337c..3f7ca4e4 100644 --- a/tumblr/lang/ar/strings.php +++ b/tumblr/lang/ar/strings.php @@ -7,4 +7,3 @@ function string_plural_select_ar($n){ }} $a->strings['Permission denied.'] = 'الطلب مرفوض.'; $a->strings['Save Settings'] = 'Save Settings'; -$a->strings['return to the connector page'] = 'الرجوع إلى صفحة الموصل'; diff --git a/tumblr/lang/cs/messages.po b/tumblr/lang/cs/messages.po index 4e031be6..cb6f91e6 100644 --- a/tumblr/lang/cs/messages.po +++ b/tumblr/lang/cs/messages.po @@ -11,7 +11,7 @@ msgid "" msgstr "" "Project-Id-Version: friendica\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2021-11-21 19:17-0500\n" +"POT-Creation-Date: 2023-04-29 06:56+0000\n" "PO-Revision-Date: 2014-06-23 12:58+0000\n" "Last-Translator: Aditoo, 2018\n" "Language-Team: Czech (http://app.transifex.com/Friendica/friendica/language/cs/)\n" @@ -21,54 +21,71 @@ msgstr "" "Language: cs\n" "Plural-Forms: nplurals=4; plural=(n == 1 && n % 1 == 0) ? 0 : (n >= 2 && n <= 4 && n % 1 == 0) ? 1: (n % 1 != 0 ) ? 2 : 3;\n" -#: tumblr.php:39 +#: tumblr.php:243 msgid "Permission denied." msgstr "Přístup odmítnut." -#: tumblr.php:69 +#: tumblr.php:296 msgid "Save Settings" msgstr "" -#: tumblr.php:71 +#: tumblr.php:297 msgid "Consumer Key" msgstr "" -#: tumblr.php:72 +#: tumblr.php:298 msgid "Consumer Secret" msgstr "" -#: tumblr.php:177 -msgid "You are now authenticated to tumblr." -msgstr "Nyní jste přihlášen/a k Tumblr." +#: tumblr.php:299 +msgid "Maximum tags" +msgstr "" -#: tumblr.php:178 -msgid "return to the connector page" -msgstr "návrat ke stránce konektor" +#: tumblr.php:299 +msgid "" +"Maximum number of tags that a user can follow. Enter 0 to deactivate the " +"feature." +msgstr "" -#: tumblr.php:194 -msgid "Post to Tumblr" -msgstr "Posílat na Tumblr" - -#: tumblr.php:225 +#: tumblr.php:336 msgid "Post to page:" msgstr "Posílat na stránku:" -#: tumblr.php:231 +#: tumblr.php:342 msgid "(Re-)Authenticate your tumblr page" msgstr "(Znovu) přihlásit k Vaší stránce Tumblr" -#: tumblr.php:232 +#: tumblr.php:343 msgid "You are not authenticated to tumblr" msgstr "Nyní nejste přihlášen/a k Tumblr." -#: tumblr.php:237 +#: tumblr.php:348 msgid "Enable Tumblr Post Addon" msgstr "Povolit doplněk Tumblr Post" -#: tumblr.php:238 +#: tumblr.php:349 msgid "Post to Tumblr by default" msgstr "Ve výchozím stavu posílat příspěvky na Tumblr" -#: tumblr.php:244 -msgid "Tumblr Export" +#: tumblr.php:350 +msgid "Import the remote timeline" msgstr "" + +#: tumblr.php:351 +msgid "Subscribed tags" +msgstr "" + +#: tumblr.php:351 +#, php-format +msgid "" +"Comma separated list of up to %d tags that will be imported additionally to " +"the timeline" +msgstr "" + +#: tumblr.php:357 +msgid "Tumblr Import/Export" +msgstr "" + +#: tumblr.php:375 +msgid "Post to Tumblr" +msgstr "Posílat na Tumblr" diff --git a/tumblr/lang/cs/strings.php b/tumblr/lang/cs/strings.php index 2f5f8115..3135b0b8 100644 --- a/tumblr/lang/cs/strings.php +++ b/tumblr/lang/cs/strings.php @@ -6,11 +6,9 @@ function string_plural_select_cs($n){ if (($n == 1 && $n % 1 == 0)) { return 0; } else if (($n >= 2 && $n <= 4 && $n % 1 == 0)) { return 1; } else if (($n % 1 != 0 )) { return 2; } else { return 3; } }} $a->strings['Permission denied.'] = 'Přístup odmítnut.'; -$a->strings['You are now authenticated to tumblr.'] = 'Nyní jste přihlášen/a k Tumblr.'; -$a->strings['return to the connector page'] = 'návrat ke stránce konektor'; -$a->strings['Post to Tumblr'] = 'Posílat na Tumblr'; $a->strings['Post to page:'] = 'Posílat na stránku:'; $a->strings['(Re-)Authenticate your tumblr page'] = '(Znovu) přihlásit k Vaší stránce Tumblr'; $a->strings['You are not authenticated to tumblr'] = 'Nyní nejste přihlášen/a k Tumblr.'; $a->strings['Enable Tumblr Post Addon'] = 'Povolit doplněk Tumblr Post'; $a->strings['Post to Tumblr by default'] = 'Ve výchozím stavu posílat příspěvky na Tumblr'; +$a->strings['Post to Tumblr'] = 'Posílat na Tumblr'; diff --git a/tumblr/lang/de/messages.po b/tumblr/lang/de/messages.po index 8056174d..c41ba45f 100644 --- a/tumblr/lang/de/messages.po +++ b/tumblr/lang/de/messages.po @@ -4,6 +4,8 @@ # # # Translators: +# Raroun, 2023 +# Raroun, 2023 # Tobias Diekershoff , 2014-2015 # Tobias Diekershoff , 2018,2021 # Ulf Rompe , 2019 @@ -11,9 +13,9 @@ msgid "" msgstr "" "Project-Id-Version: friendica\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2021-11-21 19:17-0500\n" +"POT-Creation-Date: 2023-04-29 06:56+0000\n" "PO-Revision-Date: 2014-06-23 12:58+0000\n" -"Last-Translator: Tobias Diekershoff , 2018,2021\n" +"Last-Translator: Raroun, 2023\n" "Language-Team: German (http://app.transifex.com/Friendica/friendica/language/de/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -21,54 +23,71 @@ msgstr "" "Language: de\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" -#: tumblr.php:39 +#: tumblr.php:243 msgid "Permission denied." msgstr "Zugriff verweigert." -#: tumblr.php:69 +#: tumblr.php:296 msgid "Save Settings" msgstr "Einstellungen speichern" -#: tumblr.php:71 +#: tumblr.php:297 msgid "Consumer Key" msgstr "Consumer Key" -#: tumblr.php:72 +#: tumblr.php:298 msgid "Consumer Secret" msgstr "Consumer Secret" -#: tumblr.php:177 -msgid "You are now authenticated to tumblr." -msgstr "Du bist nun auf tumblr authentifiziert." +#: tumblr.php:299 +msgid "Maximum tags" +msgstr "Maximale Anzahl an Tags" -#: tumblr.php:178 -msgid "return to the connector page" -msgstr "zurück zur Connector-Seite" +#: tumblr.php:299 +msgid "" +"Maximum number of tags that a user can follow. Enter 0 to deactivate the " +"feature." +msgstr "Maximale Anzahl von Tags, die ein Benutzer verfolgen kann. Geben Sie 0 ein, um die Funktion zu deaktivieren." -#: tumblr.php:194 -msgid "Post to Tumblr" -msgstr "Auf Tumblr veröffentlichen" - -#: tumblr.php:225 +#: tumblr.php:336 msgid "Post to page:" msgstr "Auf tumblr veröffentlichen" -#: tumblr.php:231 +#: tumblr.php:342 msgid "(Re-)Authenticate your tumblr page" msgstr "(Re-)Authentifizierung deiner tumblr-Seite" -#: tumblr.php:232 +#: tumblr.php:343 msgid "You are not authenticated to tumblr" msgstr "Du bist gegenüber tumblr nicht authentifiziert" -#: tumblr.php:237 +#: tumblr.php:348 msgid "Enable Tumblr Post Addon" msgstr "Tumblr-Post-Addon aktivieren" -#: tumblr.php:238 +#: tumblr.php:349 msgid "Post to Tumblr by default" msgstr "Standardmäßig bei Tumblr veröffentlichen" -#: tumblr.php:244 -msgid "Tumblr Export" -msgstr "Tumblr Export" +#: tumblr.php:350 +msgid "Import the remote timeline" +msgstr "Importiere die entfernte Timeline" + +#: tumblr.php:351 +msgid "Subscribed tags" +msgstr "Abonnierte Tags" + +#: tumblr.php:351 +#, php-format +msgid "" +"Comma separated list of up to %d tags that will be imported additionally to " +"the timeline" +msgstr "Durch Kommata getrennte Liste von bis zu %d Tags, die zusätzlich in die Timeline importiert werden sollen" + +#: tumblr.php:357 +msgid "Tumblr Import/Export" +msgstr "Tumblr Import/Export" + +#: tumblr.php:375 +msgid "Post to Tumblr" +msgstr "Auf Tumblr veröffentlichen" diff --git a/tumblr/lang/de/strings.php b/tumblr/lang/de/strings.php index ce43615c..ed9af957 100644 --- a/tumblr/lang/de/strings.php +++ b/tumblr/lang/de/strings.php @@ -9,12 +9,15 @@ $a->strings['Permission denied.'] = 'Zugriff verweigert.'; $a->strings['Save Settings'] = 'Einstellungen speichern'; $a->strings['Consumer Key'] = 'Consumer Key'; $a->strings['Consumer Secret'] = 'Consumer Secret'; -$a->strings['You are now authenticated to tumblr.'] = 'Du bist nun auf tumblr authentifiziert.'; -$a->strings['return to the connector page'] = 'zurück zur Connector-Seite'; -$a->strings['Post to Tumblr'] = 'Auf Tumblr veröffentlichen'; +$a->strings['Maximum tags'] = 'Maximale Anzahl an Tags'; +$a->strings['Maximum number of tags that a user can follow. Enter 0 to deactivate the feature.'] = 'Maximale Anzahl von Tags, die ein Benutzer verfolgen kann. Geben Sie 0 ein, um die Funktion zu deaktivieren.'; $a->strings['Post to page:'] = 'Auf tumblr veröffentlichen'; $a->strings['(Re-)Authenticate your tumblr page'] = '(Re-)Authentifizierung deiner tumblr-Seite'; $a->strings['You are not authenticated to tumblr'] = 'Du bist gegenüber tumblr nicht authentifiziert'; $a->strings['Enable Tumblr Post Addon'] = 'Tumblr-Post-Addon aktivieren'; $a->strings['Post to Tumblr by default'] = 'Standardmäßig bei Tumblr veröffentlichen'; -$a->strings['Tumblr Export'] = 'Tumblr Export'; +$a->strings['Import the remote timeline'] = 'Importiere die entfernte Timeline'; +$a->strings['Subscribed tags'] = 'Abonnierte Tags'; +$a->strings['Comma separated list of up to %d tags that will be imported additionally to the timeline'] = 'Durch Kommata getrennte Liste von bis zu %d Tags, die zusätzlich in die Timeline importiert werden sollen'; +$a->strings['Tumblr Import/Export'] = 'Tumblr Import/Export'; +$a->strings['Post to Tumblr'] = 'Auf Tumblr veröffentlichen'; diff --git a/tumblr/lang/it/messages.po b/tumblr/lang/it/messages.po index f3d1df55..0f7e2237 100644 --- a/tumblr/lang/it/messages.po +++ b/tumblr/lang/it/messages.po @@ -10,7 +10,7 @@ msgid "" msgstr "" "Project-Id-Version: friendica\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2021-11-21 19:17-0500\n" +"POT-Creation-Date: 2023-04-29 06:56+0000\n" "PO-Revision-Date: 2014-06-23 12:58+0000\n" "Last-Translator: Sylke Vicious , 2021\n" "Language-Team: Italian (http://app.transifex.com/Friendica/friendica/language/it/)\n" @@ -20,54 +20,71 @@ msgstr "" "Language: it\n" "Plural-Forms: nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;\n" -#: tumblr.php:39 +#: tumblr.php:243 msgid "Permission denied." msgstr "Permesso negato." -#: tumblr.php:69 +#: tumblr.php:296 msgid "Save Settings" msgstr "Salva Impostazioni" -#: tumblr.php:71 +#: tumblr.php:297 msgid "Consumer Key" msgstr "Consumer Key" -#: tumblr.php:72 +#: tumblr.php:298 msgid "Consumer Secret" msgstr "Consumer Secret" -#: tumblr.php:177 -msgid "You are now authenticated to tumblr." -msgstr "Sei autenticato su Tumblr." +#: tumblr.php:299 +msgid "Maximum tags" +msgstr "" -#: tumblr.php:178 -msgid "return to the connector page" -msgstr "ritorna alla pagina del connettore" +#: tumblr.php:299 +msgid "" +"Maximum number of tags that a user can follow. Enter 0 to deactivate the " +"feature." +msgstr "" -#: tumblr.php:194 -msgid "Post to Tumblr" -msgstr "Invia a Tumblr" - -#: tumblr.php:225 +#: tumblr.php:336 msgid "Post to page:" msgstr "Invia alla pagina:" -#: tumblr.php:231 +#: tumblr.php:342 msgid "(Re-)Authenticate your tumblr page" msgstr "(Ri)Autenticati con la tua pagina Tumblr" -#: tumblr.php:232 +#: tumblr.php:343 msgid "You are not authenticated to tumblr" msgstr "Non sei autenticato su Tumblr" -#: tumblr.php:237 +#: tumblr.php:348 msgid "Enable Tumblr Post Addon" msgstr "Abilita componente aggiuntivo di invio a Tumblr" -#: tumblr.php:238 +#: tumblr.php:349 msgid "Post to Tumblr by default" msgstr "Invia sempre a Tumblr" -#: tumblr.php:244 -msgid "Tumblr Export" -msgstr "Esporta Tumblr" +#: tumblr.php:350 +msgid "Import the remote timeline" +msgstr "" + +#: tumblr.php:351 +msgid "Subscribed tags" +msgstr "" + +#: tumblr.php:351 +#, php-format +msgid "" +"Comma separated list of up to %d tags that will be imported additionally to " +"the timeline" +msgstr "" + +#: tumblr.php:357 +msgid "Tumblr Import/Export" +msgstr "" + +#: tumblr.php:375 +msgid "Post to Tumblr" +msgstr "Invia a Tumblr" diff --git a/tumblr/lang/it/strings.php b/tumblr/lang/it/strings.php index d4d4e257..e58ab31c 100644 --- a/tumblr/lang/it/strings.php +++ b/tumblr/lang/it/strings.php @@ -9,12 +9,9 @@ $a->strings['Permission denied.'] = 'Permesso negato.'; $a->strings['Save Settings'] = 'Salva Impostazioni'; $a->strings['Consumer Key'] = 'Consumer Key'; $a->strings['Consumer Secret'] = 'Consumer Secret'; -$a->strings['You are now authenticated to tumblr.'] = 'Sei autenticato su Tumblr.'; -$a->strings['return to the connector page'] = 'ritorna alla pagina del connettore'; -$a->strings['Post to Tumblr'] = 'Invia a Tumblr'; $a->strings['Post to page:'] = 'Invia alla pagina:'; $a->strings['(Re-)Authenticate your tumblr page'] = '(Ri)Autenticati con la tua pagina Tumblr'; $a->strings['You are not authenticated to tumblr'] = 'Non sei autenticato su Tumblr'; $a->strings['Enable Tumblr Post Addon'] = 'Abilita componente aggiuntivo di invio a Tumblr'; $a->strings['Post to Tumblr by default'] = 'Invia sempre a Tumblr'; -$a->strings['Tumblr Export'] = 'Esporta Tumblr'; +$a->strings['Post to Tumblr'] = 'Invia a Tumblr'; diff --git a/tumblr/lang/pl/messages.po b/tumblr/lang/pl/messages.po index 27a44e15..a8676455 100644 --- a/tumblr/lang/pl/messages.po +++ b/tumblr/lang/pl/messages.po @@ -10,64 +10,81 @@ msgid "" msgstr "" "Project-Id-Version: friendica\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2021-11-21 19:17-0500\n" +"POT-Creation-Date: 2023-04-29 06:56+0000\n" "PO-Revision-Date: 2014-06-23 12:58+0000\n" "Last-Translator: Piotr Strębski , 2022\n" -"Language-Team: Polish (http://www.transifex.com/Friendica/friendica/language/pl/)\n" +"Language-Team: Polish (http://app.transifex.com/Friendica/friendica/language/pl/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Language: pl\n" "Plural-Forms: nplurals=4; plural=(n==1 ? 0 : (n%10>=2 && n%10<=4) && (n%100<12 || n%100>14) ? 1 : n!=1 && (n%10>=0 && n%10<=1) || (n%10>=5 && n%10<=9) || (n%100>=12 && n%100<=14) ? 2 : 3);\n" -#: tumblr.php:39 +#: tumblr.php:243 msgid "Permission denied." msgstr "Odmowa dostępu." -#: tumblr.php:69 +#: tumblr.php:296 msgid "Save Settings" msgstr "Zapisz ustawienia" -#: tumblr.php:71 +#: tumblr.php:297 msgid "Consumer Key" msgstr "Klucz klienta" -#: tumblr.php:72 +#: tumblr.php:298 msgid "Consumer Secret" msgstr "Tajny klucz klienta" -#: tumblr.php:177 -msgid "You are now authenticated to tumblr." -msgstr "Jesteś teraz uwierzytelniony na tumblr." +#: tumblr.php:299 +msgid "Maximum tags" +msgstr "" -#: tumblr.php:178 -msgid "return to the connector page" -msgstr "powrót do strony łącza" +#: tumblr.php:299 +msgid "" +"Maximum number of tags that a user can follow. Enter 0 to deactivate the " +"feature." +msgstr "" -#: tumblr.php:194 -msgid "Post to Tumblr" -msgstr "Opublikuj w Tumblr" - -#: tumblr.php:225 +#: tumblr.php:336 msgid "Post to page:" msgstr "Opublikuj na stronie:" -#: tumblr.php:231 +#: tumblr.php:342 msgid "(Re-)Authenticate your tumblr page" msgstr "(Re-) Uwierzytelnij swoją stronę tumblr" -#: tumblr.php:232 +#: tumblr.php:343 msgid "You are not authenticated to tumblr" msgstr "Nie jesteś uwierzytelniony w tumblr" -#: tumblr.php:237 +#: tumblr.php:348 msgid "Enable Tumblr Post Addon" msgstr "Włącz dodatek Tumblr" -#: tumblr.php:238 +#: tumblr.php:349 msgid "Post to Tumblr by default" msgstr "Wyślij domyślnie do Tumblr" -#: tumblr.php:244 -msgid "Tumblr Export" -msgstr "Eksportuj do Tumblr" +#: tumblr.php:350 +msgid "Import the remote timeline" +msgstr "" + +#: tumblr.php:351 +msgid "Subscribed tags" +msgstr "" + +#: tumblr.php:351 +#, php-format +msgid "" +"Comma separated list of up to %d tags that will be imported additionally to " +"the timeline" +msgstr "" + +#: tumblr.php:357 +msgid "Tumblr Import/Export" +msgstr "" + +#: tumblr.php:375 +msgid "Post to Tumblr" +msgstr "Opublikuj w Tumblr" diff --git a/tumblr/lang/pl/strings.php b/tumblr/lang/pl/strings.php index a9f3bfb5..896b21ba 100644 --- a/tumblr/lang/pl/strings.php +++ b/tumblr/lang/pl/strings.php @@ -9,12 +9,9 @@ $a->strings['Permission denied.'] = 'Odmowa dostępu.'; $a->strings['Save Settings'] = 'Zapisz ustawienia'; $a->strings['Consumer Key'] = 'Klucz klienta'; $a->strings['Consumer Secret'] = 'Tajny klucz klienta'; -$a->strings['You are now authenticated to tumblr.'] = 'Jesteś teraz uwierzytelniony na tumblr.'; -$a->strings['return to the connector page'] = 'powrót do strony łącza'; -$a->strings['Post to Tumblr'] = 'Opublikuj w Tumblr'; $a->strings['Post to page:'] = 'Opublikuj na stronie:'; $a->strings['(Re-)Authenticate your tumblr page'] = '(Re-) Uwierzytelnij swoją stronę tumblr'; $a->strings['You are not authenticated to tumblr'] = 'Nie jesteś uwierzytelniony w tumblr'; $a->strings['Enable Tumblr Post Addon'] = 'Włącz dodatek Tumblr'; $a->strings['Post to Tumblr by default'] = 'Wyślij domyślnie do Tumblr'; -$a->strings['Tumblr Export'] = 'Eksportuj do Tumblr'; +$a->strings['Post to Tumblr'] = 'Opublikuj w Tumblr'; diff --git a/tumblr/lang/sv/messages.po b/tumblr/lang/sv/messages.po index fe631007..3ff328a8 100644 --- a/tumblr/lang/sv/messages.po +++ b/tumblr/lang/sv/messages.po @@ -10,64 +10,81 @@ msgid "" msgstr "" "Project-Id-Version: friendica\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2021-11-21 19:17-0500\n" -"PO-Revision-Date: 2022-01-16 00:55+0000\n" -"Last-Translator: Kristoffer Grundström \n" -"Language-Team: Swedish (http://www.transifex.com/Friendica/friendica/language/sv/)\n" +"POT-Creation-Date: 2023-04-29 06:56+0000\n" +"PO-Revision-Date: 2014-06-23 12:58+0000\n" +"Last-Translator: Kristoffer Grundström , 2022\n" +"Language-Team: Swedish (http://app.transifex.com/Friendica/friendica/language/sv/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Language: sv\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" -#: tumblr.php:39 +#: tumblr.php:243 msgid "Permission denied." msgstr "Åtkomst nekad." -#: tumblr.php:69 +#: tumblr.php:296 msgid "Save Settings" msgstr "" -#: tumblr.php:71 +#: tumblr.php:297 msgid "Consumer Key" msgstr "" -#: tumblr.php:72 +#: tumblr.php:298 msgid "Consumer Secret" msgstr "" -#: tumblr.php:177 -msgid "You are now authenticated to tumblr." -msgstr "Du är nu autentiserad till tumblr." - -#: tumblr.php:178 -msgid "return to the connector page" +#: tumblr.php:299 +msgid "Maximum tags" msgstr "" -#: tumblr.php:194 -msgid "Post to Tumblr" +#: tumblr.php:299 +msgid "" +"Maximum number of tags that a user can follow. Enter 0 to deactivate the " +"feature." msgstr "" -#: tumblr.php:225 +#: tumblr.php:336 msgid "Post to page:" msgstr "" -#: tumblr.php:231 +#: tumblr.php:342 msgid "(Re-)Authenticate your tumblr page" msgstr "" -#: tumblr.php:232 +#: tumblr.php:343 msgid "You are not authenticated to tumblr" msgstr "Du är inte autentiserad till tumblr" -#: tumblr.php:237 +#: tumblr.php:348 msgid "Enable Tumblr Post Addon" msgstr "" -#: tumblr.php:238 +#: tumblr.php:349 msgid "Post to Tumblr by default" msgstr "" -#: tumblr.php:244 -msgid "Tumblr Export" +#: tumblr.php:350 +msgid "Import the remote timeline" +msgstr "" + +#: tumblr.php:351 +msgid "Subscribed tags" +msgstr "" + +#: tumblr.php:351 +#, php-format +msgid "" +"Comma separated list of up to %d tags that will be imported additionally to " +"the timeline" +msgstr "" + +#: tumblr.php:357 +msgid "Tumblr Import/Export" +msgstr "" + +#: tumblr.php:375 +msgid "Post to Tumblr" msgstr "" diff --git a/tumblr/lang/sv/strings.php b/tumblr/lang/sv/strings.php index 4d39d3c2..84a0e774 100644 --- a/tumblr/lang/sv/strings.php +++ b/tumblr/lang/sv/strings.php @@ -6,5 +6,4 @@ function string_plural_select_sv($n){ return intval($n != 1); }} $a->strings['Permission denied.'] = 'Åtkomst nekad.'; -$a->strings['You are now authenticated to tumblr.'] = 'Du är nu autentiserad till tumblr.'; $a->strings['You are not authenticated to tumblr'] = 'Du är inte autentiserad till tumblr'; From 14e7413eb2f89effd151b4460c0a56cdb560c681 Mon Sep 17 00:00:00 2001 From: hankg Date: Mon, 24 Jun 2024 22:20:35 +0200 Subject: [PATCH 012/222] Add Relatica to blockbot fediverse client list --- blockbot/blockbot.php | 1 + 1 file changed, 1 insertion(+) diff --git a/blockbot/blockbot.php b/blockbot/blockbot.php index eb634b1f..adf0a7c2 100644 --- a/blockbot/blockbot.php +++ b/blockbot/blockbot.php @@ -499,6 +499,7 @@ function blockbot_is_fediverse_client(array $parts): bool 'megalodonandroid', 'fedilab', 'mastodonapp', 'toot!', 'intravnews', 'pixeldroid', 'greatnews', 'protopage', 'newsfox', 'vienna', 'wp-urldetails', 'husky', 'activitypub-go-http-client', 'mobilesafari', 'mastodon-ios', 'mastodonpy', 'techniverse', + 'relatica', ]; foreach ($parts as $part) { From b2108c7a4c7efe5c79f8c5e762e3cae207d9e0d2 Mon Sep 17 00:00:00 2001 From: Hannes Heute Date: Thu, 27 Jun 2024 11:44:15 +0200 Subject: [PATCH 013/222] fix for curweather --- curweather/curweather.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/curweather/curweather.php b/curweather/curweather.php index 5a14a9cf..9aa8584a 100644 --- a/curweather/curweather.php +++ b/curweather/curweather.php @@ -152,7 +152,7 @@ function curweather_network_mod_init(string &$body) function curweather_addon_settings_post($post) { - if (!DI::userSession()->getLocalUserId() || empty($_POST['curweather-settings-submit'])) { + if (!DI::userSession()->getLocalUserId() || empty($_POST['curweather-submit'])) { return; } From 5f27f72b0d18bbf3226f4850cb4aa6f2c36482fe Mon Sep 17 00:00:00 2001 From: Matthew Exon Date: Sat, 29 Jun 2024 15:23:24 +0200 Subject: [PATCH 014/222] Streamline log lines --- mailstream/mailstream.php | 70 +++++++++++++++++++-------------------- 1 file changed, 35 insertions(+), 35 deletions(-) diff --git a/mailstream/mailstream.php b/mailstream/mailstream.php index b513cf36..c5cf8f3f 100644 --- a/mailstream/mailstream.php +++ b/mailstream/mailstream.php @@ -34,7 +34,7 @@ function mailstream_install() Hook::register('post_remote_end', 'addon/mailstream/mailstream.php', 'mailstream_post_hook'); Hook::register('mailstream_send_hook', 'addon/mailstream/mailstream.php', 'mailstream_send_hook'); - Logger::info("mailstream: installed"); + Logger::info("installed mailstream"); } /** @@ -44,7 +44,7 @@ function mailstream_check_version() { if (!is_null(DI::config()->get('mailstream', 'dbversion'))) { DI::config()->delete('mailstream', 'dbversion'); - Logger::info("mailstream_check_version: old version detected, reinstalling"); + Logger::info("old version detected, reinstalling"); mailstream_install(); Hook::loadHooks(); Hook::add( @@ -105,7 +105,7 @@ function mailstream_generate_id(string $uri): string $host = DI::baseUrl()->getHost(); $resource = hash('md5', $uri); $message_id = "<" . $resource . "@" . $host . ">"; - Logger::debug('mailstream: Generated message ID ' . $message_id . ' for URI ' . $uri); + Logger::debug('generated message ID', ['id' => $message_id, 'uri' => $uri]); return $message_id; } @@ -114,20 +114,20 @@ function mailstream_send_hook(array $data) $criteria = array('uid' => $data['uid'], 'contact-id' => $data['contact-id'], 'uri' => $data['uri']); $item = Post::selectFirst([], $criteria); if (empty($item)) { - Logger::error('mailstream_send_hook could not find item'); + Logger::error('could not find item'); return; } $user = User::getById($item['uid']); if (empty($user)) { - Logger::error('mailstream_send_hook could not fund user', ['uid' => $item['uid']]); + Logger::error('could not find user', ['uid' => $item['uid']]); return; } if (!mailstream_send($data['message_id'], $item, $user)) { - Logger::debug('mailstream_send_hook send failed, will retry', $data); + Logger::debug('send failed, will retry', $data); if (!Worker::defer()) { - Logger::error('mailstream_send_hook failed and could not defer', $data); + Logger::error('failed and could not defer', $data); } } } @@ -145,32 +145,32 @@ function mailstream_post_hook(array &$item) mailstream_check_version(); if (!DI::pConfig()->get($item['uid'], 'mailstream', 'enabled')) { - Logger::debug('mailstream: not enabled.', ['item' => $item['id'], ' uid ' => $item['uid']]); + Logger::debug('mailstream not enabled.', ['item' => $item['id'], 'uid' => $item['uid']]); return; } if (!$item['uid']) { - Logger::debug('mailstream: no uid for item ' . $item['id']); + Logger::debug('no uid', ['item' => $item['id']]); return; } if (!$item['contact-id']) { - Logger::debug('mailstream: no contact-id for item ' . $item['id']); + Logger::debug('no contact-id', ['item' => $item['id']]); return; } if (!$item['uri']) { - Logger::debug('mailstream: no uri for item ' . $item['id']); + Logger::debug('no uri', ['item' => $item['id']]); return; } if ($item['verb'] == Activity::ANNOUNCE) { - Logger::debug('mailstream: announce item ', ['item' => $item['id']]); + Logger::debug('ignoring announce', ['item' => $item['id']]); return; } if (DI::pConfig()->get($item['uid'], 'mailstream', 'nolikes')) { if ($item['verb'] == Activity::LIKE) { - Logger::debug('mailstream: like item ' . $item['id']); + Logger::debug('ignoring like', ['item' => $item['id']]); return; } if ($item['verb'] == Activity::DISLIKE) { - Logger::debug('mailstream: dislike item ' . $item['id']); + Logger::debug('ignoring dislike', ['item' => $item['id']]); return; } } @@ -221,7 +221,7 @@ function mailstream_do_images(array &$item, array &$attachments) try { $curlResult = DI::httpClient()->fetchFull($url, HttpClientAccept::DEFAULT, 0, $cookiejar); } catch (InvalidArgumentException $e) { - Logger::error('mailstream_do_images exception fetching url', ['url' => $url, 'item_id' => $item['id']]); + Logger::error('exception fetching url', ['url' => $url, 'item_id' => $item['id']]); continue; } $attachments[$url] = [ @@ -322,13 +322,12 @@ function mailstream_subject(array $item): string } $contact = Contact::selectFirst([], ['id' => $item['contact-id'], 'uid' => $item['uid']]); if (!DBA::isResult($contact)) { - Logger::error( - 'mailstream_subject no contact for item', - ['id' => $item['id'], - 'plink' => $item['plink'], - 'contact id' => $item['contact-id'], - 'uid' => $item['uid']] - ); + Logger::error('no contact', [ + 'item' => $item['id'], + 'plink' => $item['plink'], + 'contact id' => $item['contact-id'], + 'uid' => $item['uid'] + ]); return DI::l10n()->t("Friendica post"); } if ($contact['network'] === 'dfrn') { @@ -365,17 +364,16 @@ function mailstream_subject(array $item): string function mailstream_send(string $message_id, array $item, array $user): bool { if (!is_array($item)) { - Logger::error('mailstream_send item is empty', ['message_id' => $message_id]); + Logger::error('item is empty', ['message_id' => $message_id]); return false; } if (!$item['visible']) { - Logger::debug('mailstream_send item not yet visible', ['item uri' => $item['uri']]); + Logger::debug('item not yet visible', ['item uri' => $item['uri']]); return false; } if (!$message_id) { - Logger::error('mailstream_send no message ID supplied', ['item uri' => $item['uri'], - 'user email' => $user['email']]); + Logger::error('no message ID supplied', ['item uri' => $item['uri'], 'user email' => $user['email']]); return true; } @@ -432,13 +430,15 @@ function mailstream_send(string $message_id, array $item, array $user): bool if (!$mail->Send()) { throw new Exception($mail->ErrorInfo); } - Logger::debug('mailstream_send sent message', ['message ID' => $mail->MessageID, - 'subject' => $mail->Subject, - 'address' => $address]); + Logger::debug('sent message', [ + 'message ID' => $mail->MessageID, + 'subject' => $mail->Subject, + 'address' => $address + ]); } catch (phpmailerException $e) { - Logger::debug('mailstream_send PHPMailer exception sending message ' . $message_id . ': ' . $e->errorMessage()); + Logger::debug('PHPMailer exception sending message', ['id' => $message_id, 'error' => $e->errorMessage()]); } catch (Exception $e) { - Logger::debug('mailstream_send exception sending message ' . $message_id . ': ' . $e->getMessage()); + Logger::debug('exception sending message', ['id' => $message_id, 'error' => $e->getMessage()]); } return true; @@ -468,7 +468,7 @@ function mailstream_html_wrap(string &$text) function mailstream_convert_table_entries() { $ms_item_ids = DBA::selectToArray('mailstream_item', [], ['message-id', 'uri', 'uid', 'contact-id'], ["`mailstream_item`.`completed` IS NULL"]); - Logger::debug('mailstream_convert_table_entries processing ' . count($ms_item_ids) . ' items'); + Logger::debug('processing items', ['count' => count($ms_item_ids)]); foreach ($ms_item_ids as $ms_item_id) { $send_hook_data = array('uid' => $ms_item_id['uid'], 'contact-id' => $ms_item_id['contact-id'], @@ -476,10 +476,10 @@ function mailstream_convert_table_entries() 'message_id' => $ms_item_id['message-id'], 'tries' => 0); if (!$ms_item_id['message-id'] || !strlen($ms_item_id['message-id'])) { - Logger::info('mailstream_convert_table_entries: item has no message-id.', ['item' => $ms_item_id['id'], 'uri' => $ms_item_id['uri']]); - continue; + Logger::info('item has no message-id', ['item' => $ms_item_id['id'], 'uri' => $ms_item_id['uri']]); + continue; } - Logger::info('mailstream_convert_table_entries: convert item to workerqueue', $send_hook_data); + Logger::info('convert item to workerqueue', $send_hook_data); Hook::fork(Worker::PRIORITY_LOW, 'mailstream_send_hook', $send_hook_data); } DBA::e('DROP TABLE `mailstream_item`'); From f3db763c599cfeb830fdf95a8de5738c183be30b Mon Sep 17 00:00:00 2001 From: Matthew Exon Date: Tue, 9 Jul 2024 20:13:00 +0100 Subject: [PATCH 015/222] More comprehensible check for root user contact --- mailstream/mailstream.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/mailstream/mailstream.php b/mailstream/mailstream.php index c5cf8f3f..b86c4e2a 100644 --- a/mailstream/mailstream.php +++ b/mailstream/mailstream.php @@ -144,12 +144,12 @@ function mailstream_post_hook(array &$item) { mailstream_check_version(); - if (!DI::pConfig()->get($item['uid'], 'mailstream', 'enabled')) { - Logger::debug('mailstream not enabled.', ['item' => $item['id'], 'uid' => $item['uid']]); + if ($item['uid'] === 0) { + Logger::debug('mailstream: root user, skipping item ' . $item['id']); return; } - if (!$item['uid']) { - Logger::debug('no uid', ['item' => $item['id']]); + if (!DI::pConfig()->get($item['uid'], 'mailstream', 'enabled')) { + Logger::debug('mailstream: not enabled.', ['item' => $item['id'], ' uid ' => $item['uid']]); return; } if (!$item['contact-id']) { From 589cf712cc92911d5288b1dfff06bd8c9d4cfb78 Mon Sep 17 00:00:00 2001 From: Matthew Exon Date: Sun, 14 Jul 2024 18:56:22 +0200 Subject: [PATCH 016/222] Remove old version conversion code --- mailstream/mailstream.php | 44 --------------------------------------- 1 file changed, 44 deletions(-) diff --git a/mailstream/mailstream.php b/mailstream/mailstream.php index b86c4e2a..8bce2529 100644 --- a/mailstream/mailstream.php +++ b/mailstream/mailstream.php @@ -37,25 +37,6 @@ function mailstream_install() Logger::info("installed mailstream"); } -/** - * Enforces that mailstream_install has set up the current version - */ -function mailstream_check_version() -{ - if (!is_null(DI::config()->get('mailstream', 'dbversion'))) { - DI::config()->delete('mailstream', 'dbversion'); - Logger::info("old version detected, reinstalling"); - mailstream_install(); - Hook::loadHooks(); - Hook::add( - 'mailstream_convert_table_entries', - 'addon/mailstream/mailstream.php', - 'mailstream_convert_table_entries' - ); - Hook::fork(Worker::PRIORITY_LOW, 'mailstream_convert_table_entries'); - } -} - /** * This is a statement rather than an actual function definition. The simple * existence of this method is checked to figure out if the addon offers a @@ -142,8 +123,6 @@ function mailstream_send_hook(array $data) */ function mailstream_post_hook(array &$item) { - mailstream_check_version(); - if ($item['uid'] === 0) { Logger::debug('mailstream: root user, skipping item ' . $item['id']); return; @@ -462,29 +441,6 @@ function mailstream_html_wrap(string &$text) return $text; } -/** - * Convert v1 mailstream table entries to v2 workerqueue items - */ -function mailstream_convert_table_entries() -{ - $ms_item_ids = DBA::selectToArray('mailstream_item', [], ['message-id', 'uri', 'uid', 'contact-id'], ["`mailstream_item`.`completed` IS NULL"]); - Logger::debug('processing items', ['count' => count($ms_item_ids)]); - foreach ($ms_item_ids as $ms_item_id) { - $send_hook_data = array('uid' => $ms_item_id['uid'], - 'contact-id' => $ms_item_id['contact-id'], - 'uri' => $ms_item_id['uri'], - 'message_id' => $ms_item_id['message-id'], - 'tries' => 0); - if (!$ms_item_id['message-id'] || !strlen($ms_item_id['message-id'])) { - Logger::info('item has no message-id', ['item' => $ms_item_id['id'], 'uri' => $ms_item_id['uri']]); - continue; - } - Logger::info('convert item to workerqueue', $send_hook_data); - Hook::fork(Worker::PRIORITY_LOW, 'mailstream_send_hook', $send_hook_data); - } - DBA::e('DROP TABLE `mailstream_item`'); -} - /** * Form for configuring mailstream features for a user * From c0535db74214eb0983c7bd145702d9600fc169f2 Mon Sep 17 00:00:00 2001 From: Michael Date: Mon, 5 Aug 2024 20:37:58 +0000 Subject: [PATCH 017/222] Statistics: inbound / outbound for Tumblr and Bluesky --- bluesky/bluesky.php | 2 ++ tumblr/tumblr.php | 2 ++ 2 files changed, 4 insertions(+) diff --git a/bluesky/bluesky.php b/bluesky/bluesky.php index 6994b3e3..9f21674f 100644 --- a/bluesky/bluesky.php +++ b/bluesky/bluesky.php @@ -1946,6 +1946,7 @@ function bluesky_post(int $uid, string $url, string $params, array $headers): ?s return null; } + Item::incrementOutbound(Protocol::BLUESKY); try { $curlResult = DI::httpClient()->post($pds . $url, $params, $headers); } catch (\Exception $e) { @@ -1982,6 +1983,7 @@ function bluesky_xrpc_get(int $uid, string $url, array $parameters = []): ?stdCl function bluesky_get(string $url, string $accept_content = HttpClientAccept::DEFAULT, array $opts = []): ?stdClass { + Item::incrementInbound(Protocol::BLUESKY); try { $curlResult = DI::httpClient()->get($url, $accept_content, $opts); } catch (\Exception $e) { diff --git a/tumblr/tumblr.php b/tumblr/tumblr.php index f0c68f33..945f8f35 100644 --- a/tumblr/tumblr.php +++ b/tumblr/tumblr.php @@ -1326,6 +1326,7 @@ function tumblr_get_contact_by_url(string $url, int $uid): ?array */ function tumblr_get(int $uid, string $url, array $parameters = []): stdClass { + Item::incrementInbound(Protocol::TUMBLR); $url = 'https://api.tumblr.com/v2/' . $url; if ($uid == 0) { @@ -1355,6 +1356,7 @@ function tumblr_get(int $uid, string $url, array $parameters = []): stdClass */ function tumblr_post(int $uid, string $url, array $parameters): stdClass { + Item::incrementOutbound(Protocol::TUMBLR); $url = 'https://api.tumblr.com/v2/' . $url; $curlResult = DI::httpClient()->post($url, $parameters, ['Authorization' => ['Bearer ' . tumblr_get_token($uid)]]); From 46a55f13f7bd2566e0ede5bdb5df6d78c42fdab4 Mon Sep 17 00:00:00 2001 From: Matthew Exon Date: Mon, 22 Jul 2024 18:23:23 +0200 Subject: [PATCH 018/222] Ratioed: add help text --- ratioed/RatioedPanel.php | 7 +++ ratioed/templates/help.tpl | 92 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 99 insertions(+) create mode 100644 ratioed/templates/help.tpl diff --git a/ratioed/RatioedPanel.php b/ratioed/RatioedPanel.php index 16f9df6f..e25c7f34 100644 --- a/ratioed/RatioedPanel.php +++ b/ratioed/RatioedPanel.php @@ -6,6 +6,7 @@ use Friendica\Content\Pager; use Friendica\Core\Logger; use Friendica\Core\Renderer; use Friendica\Database\DBA; +use Friendica\DI; use Friendica\Model\User; use Friendica\Module\Moderation\Users\Active; @@ -18,6 +19,11 @@ class RatioedPanel extends Active { Active::content(); + if (isset(DI::args()->getArgv()[1]) and DI::args()->getArgv()[1] === 'help') { + $template = Renderer::getMarkupTemplate('/help.tpl', 'addon/ratioed/'); + return Renderer::replaceMacros($template, array('$config' => DI::baseUrl() . '/settings/addon')); + } + $action = $this->parameters['action'] ?? ''; $uid = $this->parameters['uid'] ?? 0; @@ -111,6 +117,7 @@ class RatioedPanel extends Active return self::getTabsHTML('ratioed') . Renderer::replaceMacros($t, [ // strings // '$title' => $this->t('Moderation'), + '$help_url' => $this->baseUrl . '/ratioed/help', '$page' => $this->t('Behaviour'), '$select_all' => $this->t('select all'), '$delete' => $this->t('Delete'), diff --git a/ratioed/templates/help.tpl b/ratioed/templates/help.tpl new file mode 100644 index 00000000..fee47e34 --- /dev/null +++ b/ratioed/templates/help.tpl @@ -0,0 +1,92 @@ +
+
+

Ratioed Plugin Help

+

+ This plugin provides administrators with additional statistics about + the behaviour of users. These may be useful as early warning signs + that warrant more carefully watching the behaviour of a user. They + are not suitable as a trigger for instantly blocking, + muting, or reporting a user, since they lack context. +

+

+ The name of the plugin comes + from "The + Ratio", a well-known quick rule of thumb: +

+
+ If the Replies:RT ratio is greater than 2:1, you done messed up. +
+

+ To "get ratioed" is to receive a large number of comments in a short + space of time, with relatively few likes or boosts. If commenters + were enthusiastic about the posts, they would also have liked or + boosted them. Receiving many comments without such likes or boosts + indicates the comments were probably angry. This anger may or may + not be justified, but either way this is probably something + moderators should be aware of. +

+

+ This plugin allows viewing of an actual ratio, calculated over the + last 24 hours. This is a useful timeframe for sudden dogpiling + events that administrators might not otherwise notice. The plugin + also calculates other statistics. +

+

Explanation of Statistics

+

Blocked by

+

+ This summarises the number of users on remote servers that have + blocked this user. +

+

+ Note that the ActivityPub spec expressly says that + implementations "SHOULD NOT" forward such block messages to + remote servers. Nevertheless some implementations do this + anyway, notably Mastodon. This statistic can only count block + messages from servers that do this, as well as blocks from local + users. As such, it is usually an undercount. +

+

+ The reason the spec recommends against forwarding these messages + is that they can lead to retaliation. For this reason, this + plugin deliberately does not provide any way to investigate + exactly who blocked the user. +

+

Comments last 24h

+

+ This gives the number of comments made on the top-level posts that + this user made within the last 24 hours. +

+

Reactions last 24h

+

+ This collects the number of likes, boosts, or other "one-click" + interactions made on the user's top-level posts within the last 24 + hours. +

+

Ratio last 24h

+

+ This is the ratio between "Comments last 24h" and "Reactions last + 24h". It is intended to approximate the traditional ratio as + understood on Twitter. +

+

Performance

+

+ The statistics are computed from scratch each time the page loads. + It's possible that this might put a heavy load on the database. and + the page may take a long time to load. +

+

Extending

+

+ Suggestions for additional statistics are welcome, especially from + moderators. This plugin should be considered a sandbox for + experimentation, so it is not necessary to prove that any statistic + is correlated with unwanted behaviour. +

+

+ However, this plugin does deal with potentially sensitive + information. Even if moderators do in principle have access to all + information, it should not necessarily be highlighted. Statistics + should be kept anonymous and neutral. Also, they should be + presented only to moderators, not to the users themselves. +

+
+
From 4bfdb45e81c8550ab89381670c068455d780bcf5 Mon Sep 17 00:00:00 2001 From: Michael Date: Mon, 12 Aug 2024 20:20:32 +0000 Subject: [PATCH 019/222] Bluesky/Tumblr: Improved statistics --- bluesky/bluesky.php | 23 +++++++++++++---------- tumblr/tumblr.php | 22 +++++++++++++--------- 2 files changed, 26 insertions(+), 19 deletions(-) diff --git a/bluesky/bluesky.php b/bluesky/bluesky.php index 9f21674f..19466a42 100644 --- a/bluesky/bluesky.php +++ b/bluesky/bluesky.php @@ -294,9 +294,9 @@ function bluesky_block(array &$hook_data) $activity = bluesky_xrpc_post($hook_data['uid'], 'com.atproto.repo.createRecord', $post); if (!empty($activity->uri)) { - $cdata = Contact::getPublicAndUserContactID($hook_data['contact']['id'], $hook_data['uid']); - if (!empty($cdata['user'])) { - Contact::remove($cdata['user']); + $ucid = Contact::getUserContactId($hook_data['contact']['id'], $hook_data['uid']); + if ($ucid) { + Contact::remove($ucid); } Logger::debug('Successfully blocked contact', ['url' => $hook_data['contact']['url'], 'uri' => $activity->uri]); } @@ -975,6 +975,7 @@ function bluesky_upload_blob(int $uid, array $photo): ?stdClass return null; } + Item::incrementOutbound(Protocol::BLUESKY); Logger::debug('Uploaded blob', ['return' => $data, 'uid' => $uid, 'retrial' => $retrial, 'height' => $new_height, 'width' => $new_width, 'size' => $new_size, 'orig-height' => $height, 'orig-width' => $width, 'orig-size' => $size]); return $data->blob; } @@ -1048,8 +1049,8 @@ function bluesky_process_reason(stdClass $reason, string $uri, int $uid) $item['owner-link'] = $item['author-link']; $item['owner-avatar'] = $item['author-avatar']; if (Item::insert($item)) { - $cdata = Contact::getPublicAndUserContactID($contact['id'], $uid); - Item::update(['post-reason' => Item::PR_ANNOUNCEMENT, 'causer-id' => $cdata['public']], ['uri' => $uri, 'uid' => $uid]); + $pcid = Contact::getPublicContactId($contact['id'], $uid); + Item::update(['post-reason' => Item::PR_ANNOUNCEMENT, 'causer-id' => $pcid], ['uri' => $uri, 'uid' => $uid]); } } @@ -1537,8 +1538,7 @@ function bluesky_fetch_missing_post(string $uri, int $uid, int $fetch_uid, int $ Logger::debug('Reply count', ['level' => $level, 'uid' => $uid, 'uri' => $uri]); if ($causer != 0) { - $cdata = Contact::getPublicAndUserContactID($causer, $uid); - $causer = $cdata['public'] ?? 0; + $causer = Contact::getPublicContactId($causer, $uid); } return bluesky_process_thread($data->thread, $uid, $fetch_uid, $post_reason, $causer, $level, $last_poll); @@ -1936,7 +1936,11 @@ function bluesky_create_token(int $uid, string $password): string function bluesky_xrpc_post(int $uid, string $url, $parameters): ?stdClass { - return bluesky_post($uid, '/xrpc/' . $url, json_encode($parameters), ['Content-type' => 'application/json', 'Authorization' => ['Bearer ' . bluesky_get_token($uid)]]); + $data = bluesky_post($uid, '/xrpc/' . $url, json_encode($parameters), ['Content-type' => 'application/json', 'Authorization' => ['Bearer ' . bluesky_get_token($uid)]]); + if (!empty($data)) { + Item::incrementOutbound(Protocol::BLUESKY); + } + return $data; } function bluesky_post(int $uid, string $url, string $params, array $headers): ?stdClass @@ -1946,7 +1950,6 @@ function bluesky_post(int $uid, string $url, string $params, array $headers): ?s return null; } - Item::incrementOutbound(Protocol::BLUESKY); try { $curlResult = DI::httpClient()->post($pds . $url, $params, $headers); } catch (\Exception $e) { @@ -1983,7 +1986,6 @@ function bluesky_xrpc_get(int $uid, string $url, array $parameters = []): ?stdCl function bluesky_get(string $url, string $accept_content = HttpClientAccept::DEFAULT, array $opts = []): ?stdClass { - Item::incrementInbound(Protocol::BLUESKY); try { $curlResult = DI::httpClient()->get($url, $accept_content, $opts); } catch (\Exception $e) { @@ -1996,5 +1998,6 @@ function bluesky_get(string $url, string $accept_content = HttpClientAccept::DEF return null; } + Item::incrementInbound(Protocol::BLUESKY); return json_decode($curlResult->getBodyString()); } diff --git a/tumblr/tumblr.php b/tumblr/tumblr.php index 945f8f35..dd34bd41 100644 --- a/tumblr/tumblr.php +++ b/tumblr/tumblr.php @@ -133,6 +133,7 @@ function tumblr_item_by_link(array &$hookData) Logger::debug('Got post', ['blog' => $matches[1], 'id' => $matches[2], 'result' => $result->response->posts]); if (!empty($result->response->posts)) { $hookData['item_id'] = tumblr_process_post($result->response->posts[0], $hookData['uid'], Item::PR_FETCHED); + Item::incrementInbound(Protocol::TUMBLR); } } @@ -203,9 +204,9 @@ function tumblr_block(array &$hook_data) $hook_data['result'] = ($result->meta->status <= 399); if ($hook_data['result']) { - $cdata = Contact::getPublicAndUserContactID($hook_data['contact']['id'], $hook_data['uid']); - if (!empty($cdata['user'])) { - Contact::remove($cdata['user']); + $ucid = Contact::getUserContactId($hook_data['contact']['id'], $hook_data['uid']); + if ($ucid) { + Contact::remove($ucid); } } } @@ -238,9 +239,7 @@ function tumblr_get_contact_uuid(array $contact): string * existence of this method is checked to figure out if the addon offers a * module. */ -function tumblr_module() -{ -} +function tumblr_module() {} function tumblr_content() { @@ -756,6 +755,7 @@ function tumblr_fetch_tags(int $uid, int $last_poll) $post = Post::selectFirst(['uri-id'], ['id' => $id]); $stored = Post\Category::storeFileByURIId($post['uri-id'], $uid, Post\Category::SUBCRIPTION, $tag); Logger::debug('Stored tag subscription for user', ['uri-id' => $post['uri-id'], 'uid' => $uid, 'tag' => $tag, 'stored' => $stored]); + Item::incrementInbound(Protocol::TUMBLR); } } } @@ -795,6 +795,7 @@ function tumblr_fetch_dashboard(int $uid, int $last_poll) Logger::debug('Importing post', ['uid' => $uid, 'created' => date(DateTimeFormat::MYSQL, $post->timestamp), 'id' => $post->id_string]); tumblr_process_post($post, $uid, Item::PR_NONE, $last_poll); + Item::incrementInbound(Protocol::TUMBLR); DI::pConfig()->set($uid, 'tumblr', 'last_id', $last); } @@ -1167,6 +1168,7 @@ function tumblr_get_contact_fields(stdClass $blog, int $uid, bool $update): arra Logger::notice('Error fetching blog info', ['meta' => $info->meta, 'response' => $info->response, 'errors' => $info->errors]); return $fields; } + Item::incrementInbound(Protocol::TUMBLR); $avatar = $info->response->blog->avatar; if (!empty($avatar)) { @@ -1231,6 +1233,8 @@ function tumblr_get_blogs(int $uid): array return []; } + Item::incrementInbound(Protocol::TUMBLR); + $blogs = []; foreach ($userinfo->response->user->blogs as $blog) { $blogs[$blog->uuid] = $blog->name; @@ -1287,10 +1291,11 @@ function tumblr_get_contact_by_url(string $url, int $uid): ?array if ($info->meta->status > 399) { Logger::notice('Error fetching blog info', ['meta' => $info->meta, 'response' => $info->response, 'errors' => $info->errors, 'blog' => $blog, 'uid' => $uid]); return null; - } else { - Logger::debug('Got data', ['blog' => $blog, 'meta' => $info->meta]); } + Logger::debug('Got data', ['blog' => $blog, 'meta' => $info->meta]); + Item::incrementInbound(Protocol::TUMBLR); + $baseurl = 'https://tumblr.com'; $url = $baseurl . '/' . $info->response->blog->name; @@ -1326,7 +1331,6 @@ function tumblr_get_contact_by_url(string $url, int $uid): ?array */ function tumblr_get(int $uid, string $url, array $parameters = []): stdClass { - Item::incrementInbound(Protocol::TUMBLR); $url = 'https://api.tumblr.com/v2/' . $url; if ($uid == 0) { From a55f80cb39ea8737a56e265cb9edda6739cc2755 Mon Sep 17 00:00:00 2001 From: Tobias Diekershoff Date: Thu, 15 Aug 2024 06:44:57 +0200 Subject: [PATCH 020/222] updated translations --- curweather/lang/fr/messages.po | 7 ++++--- curweather/lang/fr/strings.php | 2 +- geonames/lang/fr/messages.po | 7 ++++--- geonames/lang/fr/strings.php | 2 +- gnot/lang/fr/messages.po | 7 ++++--- gnot/lang/fr/strings.php | 2 +- gravatar/lang/fr/messages.po | 7 ++++--- gravatar/lang/fr/strings.php | 2 +- ijpost/lang/fr/messages.po | 7 ++++--- ijpost/lang/fr/strings.php | 2 +- krynn/lang/fr/messages.po | 7 ++++--- krynn/lang/fr/strings.php | 2 +- 12 files changed, 30 insertions(+), 24 deletions(-) diff --git a/curweather/lang/fr/messages.po b/curweather/lang/fr/messages.po index 57ed6b8b..21e60c54 100644 --- a/curweather/lang/fr/messages.po +++ b/curweather/lang/fr/messages.po @@ -5,6 +5,7 @@ # # Translators: # bob lebonche , 2021 +# cracrayol, 2024 # Hypolite Petovan , 2022 # Hypolite Petovan , 2016 # ea1cd8241cb389ffb6f92bc6891eff5d_dc12308 <70dced5587d47e18d88f9298024d96f8_93383>, 2015 @@ -15,8 +16,8 @@ msgstr "" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2021-11-21 19:14-0500\n" "PO-Revision-Date: 2014-06-22 11:34+0000\n" -"Last-Translator: Hypolite Petovan , 2022\n" -"Language-Team: French (http://www.transifex.com/Friendica/friendica/language/fr/)\n" +"Last-Translator: cracrayol, 2024\n" +"Language-Team: French (http://app.transifex.com/Friendica/friendica/language/fr/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" @@ -45,7 +46,7 @@ msgstr "Vent" #: curweather.php:140 msgid "Last Updated" -msgstr "Dernière mise-à-jour" +msgstr "Dernière mise à jour" #: curweather.php:141 msgid "Data by" diff --git a/curweather/lang/fr/strings.php b/curweather/lang/fr/strings.php index be5c1ba5..268b3a42 100644 --- a/curweather/lang/fr/strings.php +++ b/curweather/lang/fr/strings.php @@ -10,7 +10,7 @@ $a->strings['Current Weather'] = 'Météo actuelle'; $a->strings['Relative Humidity'] = 'Humidité relative'; $a->strings['Pressure'] = 'Pression'; $a->strings['Wind'] = 'Vent'; -$a->strings['Last Updated'] = 'Dernière mise-à-jour'; +$a->strings['Last Updated'] = 'Dernière mise à jour'; $a->strings['Data by'] = 'Données de'; $a->strings['Show on map'] = 'Montrer sur la carte'; $a->strings['There was a problem accessing the weather data. But have a look'] = 'Une erreur est survenue lors de l\'accès aux données météo. Vous pouvez quand même jeter un oeil'; diff --git a/geonames/lang/fr/messages.po b/geonames/lang/fr/messages.po index b1cd8ce1..9fe03bdb 100644 --- a/geonames/lang/fr/messages.po +++ b/geonames/lang/fr/messages.po @@ -6,6 +6,7 @@ # Translators: # bob lebonche , 2021 # ButterflyOfFire, 2020 +# cracrayol, 2024 # Hypolite Petovan , 2016 msgid "" msgstr "" @@ -13,8 +14,8 @@ msgstr "" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2021-11-21 19:14-0500\n" "PO-Revision-Date: 2014-06-23 08:27+0000\n" -"Last-Translator: bob lebonche , 2021\n" -"Language-Team: French (http://www.transifex.com/Friendica/friendica/language/fr/)\n" +"Last-Translator: cracrayol, 2024\n" +"Language-Team: French (http://app.transifex.com/Friendica/friendica/language/fr/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" @@ -29,7 +30,7 @@ msgstr "Remplacer les coordonnées par le nom de la localité la plus proche dan #: geonames.php:136 msgid "Enable Geonames Addon" -msgstr "Activer l'application complémentaire Geonames" +msgstr "Activer l'extension Geonames" #: geonames.php:141 msgid "Geonames Settings" diff --git a/geonames/lang/fr/strings.php b/geonames/lang/fr/strings.php index 297e3b73..802dd118 100644 --- a/geonames/lang/fr/strings.php +++ b/geonames/lang/fr/strings.php @@ -6,5 +6,5 @@ function string_plural_select_fr($n){ if (($n == 0 || $n == 1)) { return 0; } else if ($n != 0 && $n % 1000000 == 0) { return 1; } else { return 2; } }} $a->strings['Replace numerical coordinates by the nearest populated location name in your posts.'] = 'Remplacer les coordonnées par le nom de la localité la plus proche dans votre publication.'; -$a->strings['Enable Geonames Addon'] = 'Activer l\'application complémentaire Geonames'; +$a->strings['Enable Geonames Addon'] = 'Activer l\'extension Geonames'; $a->strings['Geonames Settings'] = 'Paramètres Geonames'; diff --git a/gnot/lang/fr/messages.po b/gnot/lang/fr/messages.po index 3ce82e7f..8a928544 100644 --- a/gnot/lang/fr/messages.po +++ b/gnot/lang/fr/messages.po @@ -6,6 +6,7 @@ # Translators: # bob lebonche , 2021 # ButterflyOfFire, 2020 +# cracrayol, 2024 # Hypolite Petovan , 2016 msgid "" msgstr "" @@ -13,8 +14,8 @@ msgstr "" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2021-11-21 19:14-0500\n" "PO-Revision-Date: 2014-06-23 08:30+0000\n" -"Last-Translator: bob lebonche , 2021\n" -"Language-Team: French (http://www.transifex.com/Friendica/friendica/language/fr/)\n" +"Last-Translator: cracrayol, 2024\n" +"Language-Team: French (http://app.transifex.com/Friendica/friendica/language/fr/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" @@ -29,7 +30,7 @@ msgstr "Permettre le filtrage des notifications de commentaires par courriel sur #: gnot.php:64 msgid "Enable this addon?" -msgstr "Activer cette application complémentaire ?" +msgstr "Activer cette extension ?" #: gnot.php:69 msgid "Gnot Settings" diff --git a/gnot/lang/fr/strings.php b/gnot/lang/fr/strings.php index c498f7e8..53104349 100644 --- a/gnot/lang/fr/strings.php +++ b/gnot/lang/fr/strings.php @@ -6,6 +6,6 @@ function string_plural_select_fr($n){ if (($n == 0 || $n == 1)) { return 0; } else if ($n != 0 && $n % 1000000 == 0) { return 1; } else { return 2; } }} $a->strings['Allows threading of email comment notifications on Gmail and anonymising the subject line.'] = 'Permettre le filtrage des notifications de commentaires par courriel sur Gmail et l\'anonymisation de l\'objet.'; -$a->strings['Enable this addon?'] = 'Activer cette application complémentaire ?'; +$a->strings['Enable this addon?'] = 'Activer cette extension ?'; $a->strings['Gnot Settings'] = 'Paramètres Gnot'; $a->strings['[Friendica:Notify] Comment to conversation #%d'] = '[Friendica:Notify] Commentaire vers conversation #%d'; diff --git a/gravatar/lang/fr/messages.po b/gravatar/lang/fr/messages.po index f8a64a1b..6ffa6214 100644 --- a/gravatar/lang/fr/messages.po +++ b/gravatar/lang/fr/messages.po @@ -5,6 +5,7 @@ # # Translators: # bob lebonche , 2021 +# cracrayol, 2024 # Marie Olive , 2018 # ea1cd8241cb389ffb6f92bc6891eff5d_dc12308 <70dced5587d47e18d88f9298024d96f8_93383>, 2015 msgid "" @@ -13,8 +14,8 @@ msgstr "" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2021-02-01 18:15+0100\n" "PO-Revision-Date: 2014-06-23 08:33+0000\n" -"Last-Translator: bob lebonche , 2021\n" -"Language-Team: French (http://www.transifex.com/Friendica/friendica/language/fr/)\n" +"Last-Translator: cracrayol, 2024\n" +"Language-Team: French (http://app.transifex.com/Friendica/friendica/language/fr/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" @@ -50,7 +51,7 @@ msgid "" "Libravatar addon is installed, too. Please disable Libravatar addon or this " "Gravatar addon.
The Libravatar addon will fall back to Gravatar if " "nothing was found at Libravatar." -msgstr "L'application complémentaire Libravatar est aussi installée. Merci de désactiver l'application complémentaire Libravatar ou cette application complémentaire Gravatar. L'application complémentaire se repliera sur Gravatar si rien n'est trouvé dans Libravatar." +msgstr "L'extension Libravatar est aussi installée. Merci de désactiver l'extension Libravatar ou cette extension Gravatar. L'extension se repliera sur Gravatar si rien n'est trouvé dans Libravatar." #: gravatar.php:102 msgid "Save Settings" diff --git a/gravatar/lang/fr/strings.php b/gravatar/lang/fr/strings.php index b826ab65..930d7169 100644 --- a/gravatar/lang/fr/strings.php +++ b/gravatar/lang/fr/strings.php @@ -11,7 +11,7 @@ $a->strings['monster face'] = 'Face de monstre'; $a->strings['computer generated face'] = 'visage généré par ordinateur'; $a->strings['retro arcade style face'] = 'Face style retro arcade'; $a->strings['Information'] = 'Information'; -$a->strings['Libravatar addon is installed, too. Please disable Libravatar addon or this Gravatar addon.
The Libravatar addon will fall back to Gravatar if nothing was found at Libravatar.'] = 'L\'application complémentaire Libravatar est aussi installée. Merci de désactiver l\'application complémentaire Libravatar ou cette application complémentaire Gravatar. L\'application complémentaire se repliera sur Gravatar si rien n\'est trouvé dans Libravatar.'; +$a->strings['Libravatar addon is installed, too. Please disable Libravatar addon or this Gravatar addon.
The Libravatar addon will fall back to Gravatar if nothing was found at Libravatar.'] = 'L\'extension Libravatar est aussi installée. Merci de désactiver l\'extension Libravatar ou cette extension Gravatar. L\'extension se repliera sur Gravatar si rien n\'est trouvé dans Libravatar.'; $a->strings['Save Settings'] = 'Sauvegarder les paramètres.'; $a->strings['Default avatar image'] = 'Image par défaut d\'avatar'; $a->strings['Select default avatar image if none was found at Gravatar. See README'] = 'Sélectionner l\'avatar par défaut, si aucun n\'est trouvé sur Gravatar. Voir Lisezmoi.'; diff --git a/ijpost/lang/fr/messages.po b/ijpost/lang/fr/messages.po index bc322337..6f29cad7 100644 --- a/ijpost/lang/fr/messages.po +++ b/ijpost/lang/fr/messages.po @@ -5,6 +5,7 @@ # # Translators: # bob lebonche , 2021 +# cracrayol, 2024 # Hypolite Petovan , 2016 msgid "" msgstr "" @@ -12,8 +13,8 @@ msgstr "" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2021-11-21 19:17-0500\n" "PO-Revision-Date: 2014-06-23 08:37+0000\n" -"Last-Translator: bob lebonche , 2021\n" -"Language-Team: French (http://www.transifex.com/Friendica/friendica/language/fr/)\n" +"Last-Translator: cracrayol, 2024\n" +"Language-Team: French (http://app.transifex.com/Friendica/friendica/language/fr/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" @@ -26,7 +27,7 @@ msgstr "Publier sur Insanejournal" #: ijpost.php:61 msgid "Enable InsaneJournal Post Addon" -msgstr "Activer l'application complémentaire InsaneJournalPost" +msgstr "Activer l'extension InsaneJournal" #: ijpost.php:62 msgid "InsaneJournal username" diff --git a/ijpost/lang/fr/strings.php b/ijpost/lang/fr/strings.php index d8e3e95d..d2fafc92 100644 --- a/ijpost/lang/fr/strings.php +++ b/ijpost/lang/fr/strings.php @@ -6,7 +6,7 @@ function string_plural_select_fr($n){ if (($n == 0 || $n == 1)) { return 0; } else if ($n != 0 && $n % 1000000 == 0) { return 1; } else { return 2; } }} $a->strings['Post to Insanejournal'] = 'Publier sur Insanejournal'; -$a->strings['Enable InsaneJournal Post Addon'] = 'Activer l\'application complémentaire InsaneJournalPost'; +$a->strings['Enable InsaneJournal Post Addon'] = 'Activer l\'extension InsaneJournal'; $a->strings['InsaneJournal username'] = 'Identifiant du InsaneJournal'; $a->strings['InsaneJournal password'] = 'Mot de passe du InsaneJournal'; $a->strings['Post to InsaneJournal by default'] = 'Publier sur le InsaneJournal par défaut'; diff --git a/krynn/lang/fr/messages.po b/krynn/lang/fr/messages.po index a96af8de..8a306eb1 100644 --- a/krynn/lang/fr/messages.po +++ b/krynn/lang/fr/messages.po @@ -5,14 +5,15 @@ # # Translators: # bob lebonche , 2021 +# cracrayol, 2024 msgid "" msgstr "" "Project-Id-Version: friendica\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2021-11-21 19:14-0500\n" "PO-Revision-Date: 2015-07-07 15:14+0000\n" -"Last-Translator: bob lebonche , 2021\n" -"Language-Team: French (http://www.transifex.com/Friendica/friendica/language/fr/)\n" +"Last-Translator: cracrayol, 2024\n" +"Language-Team: French (http://app.transifex.com/Friendica/friendica/language/fr/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" @@ -21,7 +22,7 @@ msgstr "" #: krynn.php:127 msgid "Enable Krynn Addon" -msgstr "Activer l'application complémentaire Krynn" +msgstr "Activer l'extension Krynn" #: krynn.php:132 msgid "Krynn Settings" diff --git a/krynn/lang/fr/strings.php b/krynn/lang/fr/strings.php index 3c3574d0..84293f79 100644 --- a/krynn/lang/fr/strings.php +++ b/krynn/lang/fr/strings.php @@ -5,5 +5,5 @@ function string_plural_select_fr($n){ $n = intval($n); if (($n == 0 || $n == 1)) { return 0; } else if ($n != 0 && $n % 1000000 == 0) { return 1; } else { return 2; } }} -$a->strings['Enable Krynn Addon'] = 'Activer l\'application complémentaire Krynn'; +$a->strings['Enable Krynn Addon'] = 'Activer l\'extension Krynn'; $a->strings['Krynn Settings'] = 'Paramètres de Krynn'; From 276c27678feb7f2660efb7b199c40346abdb5bb3 Mon Sep 17 00:00:00 2001 From: Philipp Date: Tue, 20 Aug 2024 18:07:51 +0200 Subject: [PATCH 021/222] [CI] Add safe.directory config --- .woodpecker/.code_standards_check.yml | 3 +++ .woodpecker/.continuous-deployment.yml | 3 +++ .woodpecker/.messages.po_check.yml | 3 +++ .woodpecker/.phpunit.yml | 3 +++ .woodpecker/.releaser.yml | 3 +++ 5 files changed, 15 insertions(+) diff --git a/.woodpecker/.code_standards_check.yml b/.woodpecker/.code_standards_check.yml index 8e0f7dc7..fb5be33c 100644 --- a/.woodpecker/.code_standards_check.yml +++ b/.woodpecker/.code_standards_check.yml @@ -4,6 +4,9 @@ pipeline: clone_friendica_base: image: alpine/git commands: + - git config --global user.email "no-reply@friendi.ca" + - git config --global user.name "Friendica" + - git config --global --add safe.directory $CI_WORKSPACE - git clone https://github.com/friendica/friendica.git . - git checkout $CI_COMMIT_BRANCH when: diff --git a/.woodpecker/.continuous-deployment.yml b/.woodpecker/.continuous-deployment.yml index d1202978..4d3bc5b7 100644 --- a/.woodpecker/.continuous-deployment.yml +++ b/.woodpecker/.continuous-deployment.yml @@ -9,6 +9,9 @@ pipeline: clone_friendica_base: image: alpine/git commands: + - git config --global user.email "no-reply@friendi.ca" + - git config --global user.name "Friendica" + - git config --global --add safe.directory $CI_WORKSPACE - git clone https://github.com/friendica/friendica.git . - git checkout $CI_COMMIT_BRANCH when: diff --git a/.woodpecker/.messages.po_check.yml b/.woodpecker/.messages.po_check.yml index ea9fa4d5..aa40ab4e 100644 --- a/.woodpecker/.messages.po_check.yml +++ b/.woodpecker/.messages.po_check.yml @@ -4,6 +4,9 @@ pipeline: clone_friendica_base: image: alpine/git commands: + - git config --global user.email "no-reply@friendi.ca" + - git config --global user.name "Friendica" + - git config --global --add safe.directory $CI_WORKSPACE - git clone https://github.com/friendica/friendica.git . - git checkout $CI_COMMIT_BRANCH when: diff --git a/.woodpecker/.phpunit.yml b/.woodpecker/.phpunit.yml index 0c25a2bd..887e897e 100644 --- a/.woodpecker/.phpunit.yml +++ b/.woodpecker/.phpunit.yml @@ -21,6 +21,9 @@ pipeline: clone_friendica_base: image: alpine/git commands: + - git config --global user.email "no-reply@friendi.ca" + - git config --global user.name "Friendica" + - git config --global --add safe.directory $CI_WORKSPACE - git clone https://github.com/friendica/friendica.git . - git checkout $CI_COMMIT_BRANCH clone_friendica_addon: diff --git a/.woodpecker/.releaser.yml b/.woodpecker/.releaser.yml index 68bdfb21..f12697b9 100644 --- a/.woodpecker/.releaser.yml +++ b/.woodpecker/.releaser.yml @@ -9,6 +9,9 @@ pipeline: clone_friendica_base: image: alpine/git commands: + - git config --global user.email "no-reply@friendi.ca" + - git config --global user.name "Friendica" + - git config --global --add safe.directory $CI_WORKSPACE - git clone https://github.com/friendica/friendica.git . - git checkout $CI_COMMIT_BRANCH when: From 50930c301d3d736fb204a69d1cafd778af819ca8 Mon Sep 17 00:00:00 2001 From: Michael Date: Sun, 1 Sep 2024 11:39:59 +0000 Subject: [PATCH 022/222] Bluesky: Improve DID detection for custom PDS --- bluesky/bluesky.php | 26 +++++++++++--------------- 1 file changed, 11 insertions(+), 15 deletions(-) diff --git a/bluesky/bluesky.php b/bluesky/bluesky.php index 19466a42..101568c7 100644 --- a/bluesky/bluesky.php +++ b/bluesky/bluesky.php @@ -1793,23 +1793,19 @@ function bluesky_get_did(string $handle): string $handle .= '.' . BLUESKY_HOSTNAME; } - // Deactivated at the moment, since it isn't reliable by now - //$did = bluesky_get_did_by_dns($handle); - //if ($did != '') { - // return $did; - //} - - //$did = bluesky_get_did_by_wellknown($handle); - //if ($did != '') { - // return $did; - //} - $data = bluesky_get(BLUESKY_PDS . '/xrpc/com.atproto.identity.resolveHandle?handle=' . urlencode($handle)); - if (empty($data) || empty($data->did)) { - return ''; + if (!empty($data) && !empty($data->did)) { + Logger::debug('Got DID by PDS call', ['handle' => $handle, 'did' => $data->did]); + return $data->did; } - Logger::debug('Got DID by PDS call', ['handle' => $handle, 'did' => $data->did]); - return $data->did; + + // Possibly a custom PDS. + $did = bluesky_get_did_by_dns($handle); + if ($did != '') { + return $did; + } + + return bluesky_get_did_by_wellknown($handle); } function bluesky_get_user_did(int $uid, bool $refresh = false): ?string From 2f9076bffdede3add6feeae7e66e4ca095105a2c Mon Sep 17 00:00:00 2001 From: Michael Date: Tue, 3 Sep 2024 11:28:49 +0000 Subject: [PATCH 023/222] Bluesky: probing for bluesky handles --- bluesky/bluesky.php | 146 +++++++++++++++++++++++++++++++++----------- 1 file changed, 112 insertions(+), 34 deletions(-) diff --git a/bluesky/bluesky.php b/bluesky/bluesky.php index 101568c7..9145fc32 100644 --- a/bluesky/bluesky.php +++ b/bluesky/bluesky.php @@ -45,10 +45,12 @@ use Friendica\Model\Tag; use Friendica\Model\User; use Friendica\Network\HTTPClient\Client\HttpClientAccept; use Friendica\Network\HTTPClient\Client\HttpClientOptions; +use Friendica\Network\HTTPClient\Client\HttpClientRequest; use Friendica\Object\Image; use Friendica\Protocol\Activity; use Friendica\Protocol\Relay; use Friendica\Util\DateTimeFormat; +use Friendica\Util\Network; use Friendica\Util\Strings; const BLUESKY_DEFAULT_POLL_INTERVAL = 10; // given in minutes @@ -129,8 +131,13 @@ function bluesky_probe_detect(array &$hookData) if (parse_url($hookData['uri'], PHP_URL_SCHEME) == 'did') { $did = $hookData['uri']; - } elseif (preg_match('#^' . BLUESKY_WEB . '/profile/(.+)#', $hookData['uri'], $matches)) { - $did = bluesky_get_did($matches[1]); + } elseif (parse_url($hookData['uri'], PHP_URL_PATH) == $hookData['uri'] && strpos($hookData['uri'], '@') === false) { + $did = bluesky_get_did($hookData['uri'], $pconfig['uid']); + if (empty($did)) { + return; + } + } elseif (Network::isValidHttpUrl($hookData['uri'])) { + $did = bluesky_get_did_by_profile($hookData['uri']); if (empty($did)) { return; } @@ -148,19 +155,14 @@ function bluesky_probe_detect(array &$hookData) return; } - $hookData['result'] = bluesky_get_contact_fields($data, 0, $pconfig['uid'], false); - - $hookData['result']['baseurl'] = bluesky_get_pds($did); + $hookData['result'] = bluesky_get_contact_fields($data, 0, $pconfig['uid'], true); // Preparing probe data. This differs slightly from the contact array - $hookData['result']['about'] = HTML::toBBCode($data->description ?? ''); $hookData['result']['photo'] = $data->avatar ?? ''; - $hookData['result']['header'] = $data->banner ?? ''; $hookData['result']['batch'] = ''; $hookData['result']['notify'] = ''; $hookData['result']['poll'] = ''; $hookData['result']['poco'] = ''; - $hookData['result']['pubkey'] = ''; $hookData['result']['priority'] = 0; $hookData['result']['guid'] = ''; } @@ -177,21 +179,21 @@ function bluesky_item_by_link(array &$hookData) return; } - if (!preg_match('#^' . BLUESKY_WEB . '/profile/(.+)/post/(.+)#', $hookData['uri'], $matches)) { - return; - } - - $did = bluesky_get_did($matches[1]); + $did = bluesky_get_did_by_profile($hookData['uri']); if (empty($did)) { return; } - Logger::debug('Found bluesky post', ['url' => $hookData['uri'], 'handle' => $matches[1], 'did' => $did, 'cid' => $matches[2]]); + if (!preg_match('#/profile/.+/post/(.+)#', $hookData['uri'], $matches)) { + return; + } - $uri = 'at://' . $did . '/app.bsky.feed.post/' . $matches[2]; + Logger::debug('Found bluesky post', ['url' => $hookData['uri'], 'did' => $did, 'cid' => $matches[1]]); + + $uri = 'at://' . $did . '/app.bsky.feed.post/' . $matches[1]; $uri = bluesky_fetch_missing_post($uri, $hookData['uid'], $hookData['uid'], Item::PR_FETCHED, 0, 0, 0); - Logger::debug('Got post', ['profile' => $matches[1], 'cid' => $matches[2], 'result' => $uri]); + Logger::debug('Got post', ['did' => $did, 'cid' => $matches[1], 'result' => $uri]); if (!empty($uri)) { $item = Post::selectFirst(['id'], ['uri' => $uri, 'uid' => $hookData['uid']]); if (!empty($item['id'])) { @@ -1678,10 +1680,14 @@ function bluesky_get_contact_fields(stdClass $author, int $uid, int $fetch_uid, return $fields; } - $fields['baseurl'] = bluesky_get_pds($author->did); - if (!empty($fields['baseurl'])) { - GServer::check($fields['baseurl'], Protocol::BLUESKY); - $fields['gsid'] = GServer::getID($fields['baseurl'], true); + $data = bluesky_get(BLUESKY_DIRECTORY . '/' . $author->did); + if (!empty($data)) { + $fields['baseurl'] = bluesky_get_pds('', $data); + if (!empty($fields['baseurl'])) { + GServer::check($fields['baseurl'], Protocol::BLUESKY); + $fields['gsid'] = GServer::getID($fields['baseurl'], true); + } + $fields['pubkey'] = bluesky_get_public_key('', $data); } $data = bluesky_xrpc_get($fetch_uid, 'app.bsky.actor.getProfile', ['actor' => $author->did]); @@ -1748,6 +1754,42 @@ function bluesky_get_preferences(int $uid): ?stdClass return $data; } +function bluesky_get_did_by_profile(string $url): string +{ + try { + $curlResult = DI::httpClient()->get($url, HttpClientAccept::HTML, [HttpClientOptions::REQUEST => HttpClientRequest::CONTACTINFO]); + } catch (\Throwable $th) { + return ''; + } + if (!$curlResult->isSuccess()) { + return ''; + } + $profile = $curlResult->getBodyString(); + + $doc = new DOMDocument(); + @$doc->loadHTML($profile); + $xpath = new DOMXPath($doc); + $list = $xpath->query('//p[@id]'); + foreach ($list as $node) { + foreach ($node->attributes as $attribute) { + if ($attribute->name == 'id') { + $ids[$attribute->value] = $node->textContent; + } + } + } + + if (empty($ids['bsky_handle']) || empty($ids['bsky_did'])) { + return ''; + } + + if (!bluesky_valid_did($ids['bsky_did'], $ids['bsky_handle'])) { + Logger::notice('Invalid DID', ['handle' => $ids['bsky_handle'], 'did' => $ids['bsky_did']]); + return ''; + } + + return $ids['bsky_did']; +} + function bluesky_get_did_by_wellknown(string $handle): string { $curlResult = DI::httpClient()->get('http://' . $handle . '/.well-known/atproto-did'); @@ -1757,7 +1799,6 @@ function bluesky_get_did_by_wellknown(string $handle): string Logger::notice('Invalid DID', ['handle' => $handle, 'did' => $did]); return ''; } - Logger::debug('Got DID by wellknown', ['handle' => $handle, 'did' => $did]); return $did; } return ''; @@ -1776,14 +1817,13 @@ function bluesky_get_did_by_dns(string $handle): string Logger::notice('Invalid DID', ['handle' => $handle, 'did' => $did]); return ''; } - Logger::debug('Got DID by DNS', ['handle' => $handle, 'did' => $did]); return $did; } } return ''; } -function bluesky_get_did(string $handle): string +function bluesky_get_did(string $handle, int $uid): string { if ($handle == '') { return ''; @@ -1793,19 +1833,39 @@ function bluesky_get_did(string $handle): string $handle .= '.' . BLUESKY_HOSTNAME; } + // At first we use the user PDS. That should cover most cases. + $pds = DI::pConfig()->get($uid, 'bluesky', 'pds'); + if (!empty($pds)) { + $data = bluesky_get($pds . '/xrpc/com.atproto.identity.resolveHandle?handle=' . urlencode($handle)); + if (!empty($data) && !empty($data->did)) { + Logger::debug('Got DID by user PDS call', ['handle' => $handle, 'did' => $data->did]); + return $data->did; + } + } + + // Then we query the DNS, which is used for third party handles (DNS should be faster than wellknown) + $did = bluesky_get_did_by_dns($handle); + if ($did != '') { + Logger::debug('Got DID by DNS', ['handle' => $handle, 'did' => $did]); + return $did; + } + + // Then we query wellknown, which should mostly cover the rest. + $did = bluesky_get_did_by_wellknown($handle); + if ($did != '') { + Logger::debug('Got DID by wellknown', ['handle' => $handle, 'did' => $did]); + return $did; + } + + // And finally we use the default PDS from Bluesky. $data = bluesky_get(BLUESKY_PDS . '/xrpc/com.atproto.identity.resolveHandle?handle=' . urlencode($handle)); if (!empty($data) && !empty($data->did)) { - Logger::debug('Got DID by PDS call', ['handle' => $handle, 'did' => $data->did]); + Logger::debug('Got DID by system PDS call', ['handle' => $handle, 'did' => $data->did]); return $data->did; } - // Possibly a custom PDS. - $did = bluesky_get_did_by_dns($handle); - if ($did != '') { - return $did; - } - - return bluesky_get_did_by_wellknown($handle); + Logger::notice('No DID detected', ['handle' => $handle]); + return ''; } function bluesky_get_user_did(int $uid, bool $refresh = false): ?string @@ -1822,7 +1882,7 @@ function bluesky_get_user_did(int $uid, bool $refresh = false): ?string return null; } - $did = bluesky_get_did($handle); + $did = bluesky_get_did($handle, $uid); if (empty($did)) { return null; } @@ -1853,9 +1913,11 @@ function bluesky_get_user_pds(int $uid): ?string return $pds; } -function bluesky_get_pds(string $did): ?string +function bluesky_get_pds(string $did, stdClass $data = null): ?string { - $data = bluesky_get(BLUESKY_DIRECTORY . '/' . $did); + if (empty($data)) { + $data = bluesky_get(BLUESKY_DIRECTORY . '/' . $did); + } if (empty($data) || empty($data->service)) { return null; } @@ -1869,6 +1931,22 @@ function bluesky_get_pds(string $did): ?string return null; } +function bluesky_get_public_key(string $did, stdClass $data = null): ?string +{ + if (empty($data)) { + $data = bluesky_get(BLUESKY_DIRECTORY . '/' . $did); + } + if (empty($data) || empty($data->verificationMethod)) { + return null; + } + foreach ($data->verificationMethod as $method) { + if (!empty($method->publicKeyMultibase)) { + return $method->publicKeyMultibase; + } + } + return null; +} + function bluesky_valid_did(string $did, string $handle): bool { $data = bluesky_get(BLUESKY_DIRECTORY . '/' . $did); From 0dfb345f85d0b8016fd6b0c25be48e26a49e94fd Mon Sep 17 00:00:00 2001 From: Michael Date: Wed, 4 Sep 2024 11:46:33 +0000 Subject: [PATCH 024/222] "fetchFull" is replaced by "get" --- mailstream/mailstream.php | 30 +++++++++++-------- mastodoncustomemojis/mastodoncustomemojis.php | 4 +-- 2 files changed, 18 insertions(+), 16 deletions(-) diff --git a/mailstream/mailstream.php b/mailstream/mailstream.php index cc283789..ae57c4dd 100644 --- a/mailstream/mailstream.php +++ b/mailstream/mailstream.php @@ -6,7 +6,6 @@ * Author: Matthew Exon */ -use Friendica\App; use Friendica\Content\Text\BBCode; use Friendica\Core\Hook; use Friendica\Core\Logger; @@ -16,12 +15,11 @@ use Friendica\Core\Worker; use Friendica\Database\DBA; use Friendica\DI; use Friendica\Model\Contact; -use Friendica\Model\Item; use Friendica\Model\Post; use Friendica\Model\User; use Friendica\Network\HTTPClient\Client\HttpClientAccept; +use Friendica\Network\HTTPClient\Client\HttpClientOptions; use Friendica\Protocol\Activity; -use Friendica\Util\DateTimeFormat; /** * Sets up the addon hooks and the database table @@ -53,10 +51,12 @@ function mailstream_addon_admin(string &$o) { $frommail = DI::config()->get('mailstream', 'frommail'); $template = Renderer::getMarkupTemplate('admin.tpl', 'addon/mailstream/'); - $config = ['frommail', + $config = [ + 'frommail', DI::l10n()->t('From Address'), $frommail, - DI::l10n()->t('Email address that stream items will appear to be from.')]; + DI::l10n()->t('Email address that stream items will appear to be from.') + ]; $o .= Renderer::replaceMacros($template, [ '$frommail' => $config, '$submit' => DI::l10n()->t('Save Settings') @@ -101,7 +101,7 @@ function mailstream_send_hook(array $data) $user = User::getById($item['uid']); if (empty($user)) { - Logger::error('could not find user', ['uid' => $item['uid']]); + Logger::error('could not find user', ['uid' => $item['uid']]); return; } @@ -198,10 +198,13 @@ function mailstream_do_images(array &$item, array &$attachments) $cookiejar = tempnam(System::getTempPath(), 'cookiejar-mailstream-'); try { - $curlResult = DI::httpClient()->fetchFull($url, HttpClientAccept::DEFAULT, 0, $cookiejar); + $curlResult = DI::httpClient()->get($url, HttpClientAccept::DEFAULT, [HttpClientOptions::COOKIEJAR => $cookiejar]); if (!$curlResult->isSuccess()) { Logger::debug('mailstream: fetch image url failed', [ - 'url' => $url, 'item_id' => $item['id'], 'return_code' => $curlResult->getReturnCode()]); + 'url' => $url, + 'item_id' => $item['id'], + 'return_code' => $curlResult->getReturnCode() + ]); continue; } } catch (InvalidArgumentException $e) { @@ -361,7 +364,7 @@ function mailstream_send(string $message_id, array $item, array $user): bool return true; } - require_once (dirname(__file__) . '/phpmailer/class.phpmailer.php'); + require_once(dirname(__file__) . '/phpmailer/class.phpmailer.php'); $item['body'] = Post\Media::addAttachmentsToBody($item['uri-id'], $item['body']); @@ -406,10 +409,11 @@ function mailstream_send(string $message_id, array $item, array $user): bool $item['body'] = BBCode::convertForUriId($item['uri-id'], $item['body'], BBCode::CONNECTORS); $item['url'] = DI::baseUrl() . '/display/' . $item['guid']; $mail->Body = Renderer::replaceMacros($template, [ - '$upstream' => DI::l10n()->t('Upstream'), - '$uri' => DI::l10n()->t('URI'), - '$local' => DI::l10n()->t('Local'), - '$item' => $item]); + '$upstream' => DI::l10n()->t('Upstream'), + '$uri' => DI::l10n()->t('URI'), + '$local' => DI::l10n()->t('Local'), + '$item' => $item + ]); $mail->Body = mailstream_html_wrap($mail->Body); if (!$mail->Send()) { throw new Exception($mail->ErrorInfo); diff --git a/mastodoncustomemojis/mastodoncustomemojis.php b/mastodoncustomemojis/mastodoncustomemojis.php index 561262f1..fcb8feea 100644 --- a/mastodoncustomemojis/mastodoncustomemojis.php +++ b/mastodoncustomemojis/mastodoncustomemojis.php @@ -1,5 +1,4 @@ fetchFull($api_url); + $fetchResult = DI::httpClient()->get($api_url); if ($fetchResult->isSuccess()) { $emojis_array = json_decode($fetchResult->getBodyString(), true); From 3dc77b21023c1258d2a7a23033f6ff6d0300b215 Mon Sep 17 00:00:00 2001 From: loma-one Date: Sat, 7 Sep 2024 21:04:43 +0200 Subject: [PATCH 025/222] unicode_smilies/unicode_smilies.php aktualisiert MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Addition of the unicode character ‘asterism’ & ‘outlines white star’ --- unicode_smilies/unicode_smilies.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/unicode_smilies/unicode_smilies.php b/unicode_smilies/unicode_smilies.php index 3bd30644..22ee3439 100644 --- a/unicode_smilies/unicode_smilies.php +++ b/unicode_smilies/unicode_smilies.php @@ -1293,6 +1293,8 @@ function unicode_smilies_smilies(array &$b) Smilies::add($b, ':microscope:', '🔬'); Smilies::add($b, ':telescope:', '🔭'); Smilies::add($b, ':satellite antenna:', '📡'); + Smilies::add($b, ':asterism:', '⁂'); + Smilies::add($b, ':outlines white star:', '⚝'); // medical Smilies::add($b, ':syringe:', '💉'); From 712edf42366d0ad118116be0f23cc20ea2b6bbdd Mon Sep 17 00:00:00 2001 From: loma-one Date: Sat, 7 Sep 2024 21:10:02 +0200 Subject: [PATCH 026/222] invidious/invidious.php aktualisiert Further addresses have been added, which are now redirected. --- invidious/invidious.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/invidious/invidious.php b/invidious/invidious.php index 7153aab9..033ecce5 100644 --- a/invidious/invidious.php +++ b/invidious/invidious.php @@ -96,6 +96,8 @@ function invidious_render(array &$b) $b['html'] = preg_replace("~https?://(?:www\.)?youtube\.com/watch\?v=(.*?)~ism", $server . '/watch?v=$1', $b['html']); $b['html'] = preg_replace("~https?://(?:www\.)?youtube\.com/embed/(.*?)~ism", $server . '/embed/$1', $b['html']); $b['html'] = preg_replace("~https?://(?:www\.)?youtube\.com/shorts/(.*?)~ism", $server . '/shorts/$1', $b['html']); + $b['html'] = preg_replace ("/https?:\/\/music.youtube.com\/(.*?)/ism", $server . '/watch?v=$1', $b['html']); + $b['html'] = preg_replace ("/https?:\/\/m.youtube.com\/(.*?)/ism", $server . '/watch?v=$1', $b['html']); $b['html'] = preg_replace("/https?:\/\/youtu.be\/(.*?)/ism", $server . '/watch?v=$1', $b['html']); if ($original != $b['html']) { From 14e1c9677527118c73e999a221c006dd698a2b79 Mon Sep 17 00:00:00 2001 From: Michael Date: Tue, 10 Sep 2024 10:26:05 +0000 Subject: [PATCH 027/222] Bluesky: Fix for the handling of invalid profiles --- bluesky/bluesky.php | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/bluesky/bluesky.php b/bluesky/bluesky.php index 9145fc32..181e8d2d 100644 --- a/bluesky/bluesky.php +++ b/bluesky/bluesky.php @@ -1765,9 +1765,16 @@ function bluesky_get_did_by_profile(string $url): string return ''; } $profile = $curlResult->getBodyString(); + if (empty($profile)) { + return ''; + } $doc = new DOMDocument(); - @$doc->loadHTML($profile); + try { + @$doc->loadHTML($profile); + } catch (\Throwable $th) { + return ''; + } $xpath = new DOMXPath($doc); $list = $xpath->query('//p[@id]'); foreach ($list as $node) { From 10521115c4f51b4e773e94f3a8149711c125701e Mon Sep 17 00:00:00 2001 From: loma-one Date: Sun, 8 Sep 2024 18:12:13 +0200 Subject: [PATCH 028/222] More and updated icons for the smiley pack --- smiley_pack/icons/commercial/facebook.gif | Bin 0 -> 269 bytes smiley_pack/icons/commercial/github.png | Bin 0 -> 4720 bytes smiley_pack/icons/commercial/google.gif | Bin 0 -> 270 bytes smiley_pack/icons/commercial/instagram.gif | Bin 0 -> 1302 bytes smiley_pack/icons/commercial/signal.gif | Bin 0 -> 339 bytes smiley_pack/icons/commercial/telegram.gif | Bin 0 -> 627 bytes smiley_pack/icons/commercial/threads.png | Bin 0 -> 1025 bytes smiley_pack/icons/commercial/threema.png | Bin 0 -> 4777 bytes smiley_pack/icons/commercial/tiktok.gif | Bin 0 -> 257 bytes smiley_pack/icons/commercial/whatsapp.gif | Bin 0 -> 1353 bytes smiley_pack/icons/commercial/windows.png | Bin 0 -> 3584 bytes smiley_pack/icons/fediverse/diaspora.gif | Bin 79 -> 1147 bytes smiley_pack/icons/fediverse/diaspora.png | Bin 0 -> 4656 bytes smiley_pack/icons/fediverse/fediverse.gif | Bin 0 -> 444 bytes smiley_pack/icons/fediverse/friendica.png | Bin 0 -> 4719 bytes smiley_pack/icons/fediverse/funkwhale.gif | Bin 0 -> 471 bytes smiley_pack/icons/fediverse/gnusocial.gif | Bin 0 -> 135 bytes smiley_pack/icons/fediverse/hubzilla.png | Bin 0 -> 4563 bytes smiley_pack/icons/fediverse/lemmy.gif | Bin 0 -> 418 bytes smiley_pack/icons/fediverse/misskey.gif | Bin 405 -> 1177 bytes smiley_pack/icons/fediverse/peertube.gif | Bin 0 -> 137 bytes smiley_pack/icons/fediverse/pixelfed.gif | Bin 1064 -> 1262 bytes smiley_pack/icons/fediverse/pleroma.gif | Bin 100 -> 180 bytes smiley_pack/icons/fediverse/plume.gif | Bin 0 -> 410 bytes smiley_pack/icons/fediverse/writefreely.gif | Bin 0 -> 112 bytes smiley_pack/icons/noncommercial/bluesky.png | Bin 0 -> 4766 bytes smiley_pack/icons/noncommercial/invidious.gif | Bin 0 -> 908 bytes smiley_pack/icons/noncommercial/vivaldi.png | Bin 0 -> 4945 bytes smiley_pack/icons/opensource/archlinux.png | Bin 0 -> 4598 bytes smiley_pack/icons/opensource/debian.png | Bin 0 -> 5357 bytes smiley_pack/icons/opensource/fdroid.png | Bin 0 -> 7919 bytes smiley_pack/icons/opensource/fedora.png | Bin 0 -> 1408 bytes smiley_pack/icons/opensource/firefox.png | Bin 0 -> 12229 bytes .../icons/opensource/firefoxnightly.png | Bin 0 -> 4987 bytes smiley_pack/icons/opensource/foss.png | Bin 0 -> 4981 bytes smiley_pack/icons/opensource/jabber.png | Bin 0 -> 4301 bytes smiley_pack/icons/opensource/kde.png | Bin 0 -> 4678 bytes smiley_pack/icons/opensource/linux.png | Bin 0 -> 5149 bytes smiley_pack/icons/opensource/matrix.png | Bin 0 -> 4347 bytes smiley_pack/icons/opensource/mint.png | Bin 0 -> 8663 bytes smiley_pack/icons/opensource/opensuse.png | Bin 0 -> 12271 bytes smiley_pack/icons/opensource/raspi.png | Bin 0 -> 4534 bytes smiley_pack/icons/opensource/thunderbird.png | Bin 0 -> 4661 bytes smiley_pack/icons/opensource/tutanota.png | Bin 0 -> 5011 bytes smiley_pack/icons/opensource/ubuntu.png | Bin 0 -> 5067 bytes smiley_pack/icons/opensource/xmpp.png | Bin 0 -> 4985 bytes smiley_pack/icons/respect/cc.png | Bin 0 -> 4461 bytes smiley_pack/icons/respect/cc0.png | Bin 0 -> 4669 bytes smiley_pack/icons/respect/ccby.png | Bin 0 -> 4407 bytes smiley_pack/icons/respect/ccsa.png | Bin 0 -> 4848 bytes smiley_pack/smiley_pack.php | 242 +++++++++++++----- 51 files changed, 175 insertions(+), 67 deletions(-) create mode 100644 smiley_pack/icons/commercial/facebook.gif create mode 100644 smiley_pack/icons/commercial/github.png create mode 100644 smiley_pack/icons/commercial/google.gif create mode 100644 smiley_pack/icons/commercial/instagram.gif create mode 100644 smiley_pack/icons/commercial/signal.gif create mode 100644 smiley_pack/icons/commercial/telegram.gif create mode 100644 smiley_pack/icons/commercial/threads.png create mode 100644 smiley_pack/icons/commercial/threema.png create mode 100644 smiley_pack/icons/commercial/tiktok.gif create mode 100644 smiley_pack/icons/commercial/whatsapp.gif create mode 100644 smiley_pack/icons/commercial/windows.png create mode 100644 smiley_pack/icons/fediverse/diaspora.png create mode 100644 smiley_pack/icons/fediverse/fediverse.gif create mode 100644 smiley_pack/icons/fediverse/friendica.png create mode 100644 smiley_pack/icons/fediverse/funkwhale.gif create mode 100644 smiley_pack/icons/fediverse/gnusocial.gif create mode 100644 smiley_pack/icons/fediverse/hubzilla.png create mode 100644 smiley_pack/icons/fediverse/lemmy.gif create mode 100644 smiley_pack/icons/fediverse/peertube.gif create mode 100644 smiley_pack/icons/fediverse/plume.gif create mode 100644 smiley_pack/icons/fediverse/writefreely.gif create mode 100644 smiley_pack/icons/noncommercial/bluesky.png create mode 100644 smiley_pack/icons/noncommercial/invidious.gif create mode 100644 smiley_pack/icons/noncommercial/vivaldi.png create mode 100644 smiley_pack/icons/opensource/archlinux.png create mode 100644 smiley_pack/icons/opensource/debian.png create mode 100644 smiley_pack/icons/opensource/fdroid.png create mode 100644 smiley_pack/icons/opensource/fedora.png create mode 100644 smiley_pack/icons/opensource/firefox.png create mode 100644 smiley_pack/icons/opensource/firefoxnightly.png create mode 100644 smiley_pack/icons/opensource/foss.png create mode 100644 smiley_pack/icons/opensource/jabber.png create mode 100644 smiley_pack/icons/opensource/kde.png create mode 100644 smiley_pack/icons/opensource/linux.png create mode 100644 smiley_pack/icons/opensource/matrix.png create mode 100644 smiley_pack/icons/opensource/mint.png create mode 100644 smiley_pack/icons/opensource/opensuse.png create mode 100644 smiley_pack/icons/opensource/raspi.png create mode 100644 smiley_pack/icons/opensource/thunderbird.png create mode 100644 smiley_pack/icons/opensource/tutanota.png create mode 100644 smiley_pack/icons/opensource/ubuntu.png create mode 100644 smiley_pack/icons/opensource/xmpp.png create mode 100644 smiley_pack/icons/respect/cc.png create mode 100644 smiley_pack/icons/respect/cc0.png create mode 100644 smiley_pack/icons/respect/ccby.png create mode 100644 smiley_pack/icons/respect/ccsa.png diff --git a/smiley_pack/icons/commercial/facebook.gif b/smiley_pack/icons/commercial/facebook.gif new file mode 100644 index 0000000000000000000000000000000000000000..45488a5b5147f33b9237402acee364ec90062e08 GIT binary patch literal 269 zcmZ?wbhEHblwgoxXc1?yikx8`Iit2~L+gai^Oqmou>H)I-52&8ymau`^>Y{RK6>){ z@zdAOUc7tp^8Jff?_Yw@hj$;oeEa_E$IstCfBpIM=kNdj|0SiBa3RHig3d*$i6yBi z3gww484B*6z5xu1KUo;L7~~mr7=Qre5C+!L2kLz(ne$Q?tb4I@UxD@^lkRIQ$&nXc zUuwC#PEh$OQ}6G{@6j#vIbr5d>brml}1xFoc_Dev7nyK2dYUe*vl|J70-tWEld+&Rd zFNHDD;V#bZ&JYB-$RlL2;6B3gb+iXpV+_9@+-fqFGpSfK9X1&C1euJ(RE7bEaWhFk zkokr-<}26Ju;Yh^BPZwC_uVsYi{lZI~87Ce!H|^iCGyd7% zzYIK<=IJ;|v8=@O?-C9DtGe`(i#8!Ig~olCa~{3rt#1reGQ&EToieg0mz?+Pr3E$K zD%&Kt4rKV|e40I$J+VRe>|H)SCH@37?ELD>YxXl`522QDxxLLm z&4fEkvU2ARYhG_V=uEbfeLZdj?Fjkyv3m5Vl>Ko&!TB*0k33E=wvOhJ5wUYSz9HzTci zH7n-K5dU(v;_2a&-0cK&@>JURFX|TTf6d;v-o2fdGN*w$Kl-J|bdf&g>U@{0$GvmV z-MfF7WGW#Blao|V!(~2+TbH^gdnGo=%UACFu(lxQr;aK2W6#CejjOeJdl23=0TH&Wx?|FoxV1#M?0L3_ok zsguy#j-8;xq*_9s;io_ph7dfFjL0!J2sM*w9JFLaLE>myRu-GDzh=p)i91a6$FiaUb3NSh7(!7`%;7MqE%v|3hg3lkNZ20*$4`a=to66{h|EN;@L z8ZkUH4cAfQdPAtO9(zNoG1;1q8e`$fxE83IfLC@Om*H|nOpk?y0u8A(SgioreKaYO z_(WEp*eom7bb1E@%zJSAXn)MzstmLg3b9O&rCP$1%OrG*f3aGRk!rE^5kUwwiU@HA zn^374JWPl&gj@lKArkOKLbaOUarwMnP;#A#LUkB!fdb%665#MuC@x^51cOfy0tQcj zh!`S1!DSF^p@3lX*|>_!=>;*>NP@0JlY2*Hfl>n~g6l`{__%H(PEw0%aF#)*u`XB$7YD`2C3FrG`6P)+MkxXqNa#_d zF4g>LK}l-yX%uQA2AZI?;m3Mwr|#LM&wwgJb})sHIN< zfYk!zA`UU)D5WXBJTW2^v;CADwwNOnb2$?c zju`2suUC^q#{bf`Y#!LZtK<=+3HZ;jin?~xG(4s2t?Mn{M|Zn^l#_qZ3K(0Ba@c%6Lyd7U22aG}F+?0Ln}G{NTt1&8SG_}cO$_mq*fcOU#T`04~& zaH#)cOkbahWV#(PHRQw(YzrA1utH`bC0^R_}s5jpQSd^Ekn$k9ptOw zjFe`lg3~tiss&yd{+6f|_`@~|IIsmj-vBo&9v#<0}Rv%agnoS5Gy zO{{;GcJpn^^NUsbYVq{T$Y8hSVYAVr2X9tr(i^Kzm{{82D@OCH2?fdY+){d|VLr-V6BIO*Hf~jPna856w#CPnyZU?=Y1;g-eBKXO*_D)& zhc_&9*{k$@rHPMR_n^A*m8t&WtLT~hB3kXXQlF_=rnr}?@^dZ)r=R;qHFi8VR@7_P fcCP;IdePZ{i!aO>NYRW;;1`mIM#~NcC*=JX_GaJF literal 0 HcmV?d00001 diff --git a/smiley_pack/icons/commercial/google.gif b/smiley_pack/icons/commercial/google.gif new file mode 100644 index 0000000000000000000000000000000000000000..5855c74d745237a6fa3c8d17f4c630c9350b38d8 GIT binary patch literal 270 zcmZ?wbhEHblwgoxXc1$0?IkyGmz$Ie&weYb6<9k5t1*ye-JXvMldYAp1Ex)gjyuV%J=T^RtyTpI*VU?6t!h;n52|5?0CYGe8D3oWG zWGJ|M`UWs4{$yd~VvuLhVE_V)!r)_wNk} zM+F(!5~q5(I9PK{7H<1IbIk#^8*9X(edD%2SXau*SHA!0o8?}WKK2hvT`xK8*}jO& yrSXOTN2S`PGRMNk<~l77c9y8FjtRBgtPutiCvvheJ5HbIH@7KYd7gnHgEas)?q!Yu literal 0 HcmV?d00001 diff --git a/smiley_pack/icons/commercial/instagram.gif b/smiley_pack/icons/commercial/instagram.gif new file mode 100644 index 0000000000000000000000000000000000000000..f15e6ee8a2df5f527707ba988a3026bd3087283b GIT binary patch literal 1302 zcmdVZ|1;Zn0LSsq`y(NIlqBc~vxL}u7oCOp5|J+=p}s`#w(DWsO1tC6b#|szO^7eU zG-!Hmxcas+#gJL++Y&=WJEj|*J8nf?u^-y#%;%k*)#A_C>mK*~4_;zPY#1lY8F5B- ze?lOE013n+OZy{B@{yJOkrmm9y=lbUU)s7GZQT!S-Cx+fwMX{dKjrr)*=LvH|AI{4 zqxkJp{BR1`aC+}0g#jtZGY2-L0Gx{8RPfv}V9P0V`&8KW*)Zq`Hk~=^G~qf;v_TVY z&_wI5q77H!ihIfm-AuMhPg$kQp3r404B10w`ih5a)gyJ0nX$yoSoAXcaLFs<8mI3% zr~f)ph^GYLzAQO~Eepebf zR2n%v=l_W|ut*zNERWJCqBQ!zTy0RXHt3ozs94U`D7YgEu0|VNTpm4I&NKUAETm#A zq;f2zYCNQ}BIZFw%-92V#b{{N7`svv)-c4mJtJYf{ALuM5XZl zP`G*|yrEh+{)K3=Ml@9;`mvAOb&uPAkK57DZ6Arc)6eawi`DfH=@brrE9k73%-oX9bczO5(m9n>-(YUMnZ6-@ zu1zx0m|$p?PPR&?niA%l5)4fV3wO@X-%gx|5(G*BlmeIrOlIi-<^xl{xkOk1Oat@~6yr5Ta5X!tF#8g{=;OjGbg|@oGQuzsfDLkj_#@_>9t9!2Moz4c zd!8qH#J2^CWV1bqEv&S5|NY>COw~IXYdbN@g5SDh6?>5z)Cy~RH;bY*vdrsDYYppU z>M=EYL84$@{Fz17^zi)R3XjW|vxGK^)N|XMHHiaL_2~|2wu~uOT6z$k7=ypYTA~s{ zqy80KUX1=qYQy~8n6Ip*@f%Ce`0d}l8;*{pS+jWURjnbVnJXV%rtp(aY>8Cw9E^yd zE{@qLo;lwrlZb=X7RoZ7gsse6!B(sf}`nr1n+_`>{f!V%CPn zZ#|CC?5cQ)>WdxJIPWPQ<{&TNUq#giYF=C3w$u+*$l|E3B&D1nnlmOjq?Sxu=C>JM z)$qFH9tJYwFr=L9Y+bk wCC~D7lf{qx2ZtITsyuTFE}?dEd6{jnsS~Tc(RohlEx%H{gSuUCBqI_30Z9t(Y5)KL literal 0 HcmV?d00001 diff --git a/smiley_pack/icons/commercial/signal.gif b/smiley_pack/icons/commercial/signal.gif new file mode 100644 index 0000000000000000000000000000000000000000..db5aea12ec33b315e405aa7871c8403e2dc420b3 GIT binary patch literal 339 zcmZ?wbhEHblwgoxSZcxm1k&M$tja!EmVE${#@TQ5vR}cumZcwbvL9HLf}~9I-u*iFh(swWhSOHKk2)zgDGAVj# zSpsCdHwPK`-U4JeNTZ~*5<#T+Ptdt2HL)Z$MWH;iBtya7(>H)Y@h1x-7lS>64#;~T zk20`DADCa@AtJ$gWXY%U5VPqQl!a!^@mhavsc5yR-`torm!+RooquX1JlCv#X0D;N zp4p+7vDW+g?mTa=D{CmP&dzSEO=&4iZ*PsN=q>J!ZEK$15;8L=A%8}we}E%{H2|4w Bj4}WK literal 0 HcmV?d00001 diff --git a/smiley_pack/icons/commercial/telegram.gif b/smiley_pack/icons/commercial/telegram.gif new file mode 100644 index 0000000000000000000000000000000000000000..6ab4851ad4169b691ed355562ba2172e84516493 GIT binary patch literal 627 zcmZ?wbhEHblwgoxIOf2>JnISbtf$PgpD@n`lFwLxO8P~jL-1D9Z zEqpGr=(*UU=Tb|a%Po5$zwCw5@)yc0UZ}2kp|R?v)~c7r>t30ze`UVmmBZ%Oj$2;4 zZF>{F?_J#fcgY9eXB>W?b>u_YiH}X^K25y*Wy;krb8dW{d*kc8n_m~){JQ+kw{4HU z?|l4Y*OMQ6p8PoQ?8ng;KaaimdHm(i6EA;WefRtN``=H${(1iG?~8AL-~IUe<@dku zfByac`~UC1|Ns7jfTXn2kVcCC1f7dg6H8K46v{J8G8EiBeFGR2f3h%gF*q>jFaQB4 zq8QkBH#jskH#4&`w=uVL_b_$zPhe*0>7F>Pe@fHz*=E ze8$(UIVUon?dO$K;u12wZf`X0#WW7H5B4h4CeP-xx3XJTy5R~}P^*lj#T^Z|MuiE! x{5lFv9}cnYWn|#$w0dwLW<}5hjm9HWI8z#Yn)TdHbrel(Ok-6`EX>4Tx04R}tkv&MmKpe$iQ^g{cqIOVm$WWc^q9Ts93Pq?8YK2xEOfLO`CJjl7 zi=*ILaPVWX>fqw6tAnc`2!4P#J2)x2NQwVT3N2ziIPS;0dyl(!fKV?p&FYE)nr@q^ zL|n{dSH+%J1Q5ai`Y|js%b1g-Bsz|-d-(Wz7v))<&;2?2)SSftpGX{IhG`RT5YKGd z2Iqa^Fe}O`@j3B?Nf#u3C`-Nm{=^dvC_t@XllgM#1U1~DPPEV zta9Gstd*;*c~AbrU`}6I<~q$$B(R7jND!f*iW17O5v5fp#X^eq;~o4Xu3sXTLaq`R zITlcX2HEw4|H1EWt^CxamlTWx-7k*wF$VPP0*#vEd>=bb;{@U#SDLpQP7X zTI2`_Z37qAElt@2E_Z;TCqp)6SMt*o@_FF>jJ_!g4Bi60YhG{7eVjf3Y3eF@0~{Oz z;|0oI@9^$GdvE`qY4-O6Z8mbG3y)5n00006VoOIv02lyr0HVfz8O8tr010qNS#tmY z3ljhU3ljkVnw%H_000McNliru=m-xI5hy1flq>)M0scuuK~y-)t&}lqB2f^>=PKbi z?gOMrlRi~o7sMi;KuEDjDtlYI1PftBQl?53@KW3@+~JZ!k-(OLEDPDnMjJ)8G00oV z5_V&L*TlV(i)+F;@Zilb{N6C{KO-XYSwy~x2>*G0h{#vj5^Q;XeR{pTX}MfZYPFi| z?d^$(NDu_#IF7X2ZOO7XU$bqSD2f1hd3oXa`5A!4V!{3WJ({MitMcEV>$=2oOt06Y zR4S!$P19(#S}3JZN^y92xEXkHaRGp7nrnM?e0+>j3g7oP1A`#I^E^ZZUDt6OhcFCD zl7zuvK)GB-L@-SgAobq_9vvO6RCj)UP8`Q{yIm~HA_xMe(`lOD?RKeDD(ivGW)ol~ zVcC4cFesHu05lqnEb07lEX!H}YMO@UdBkzd-`4N<(RKafK*w>2qKK=jD^5;MsMqVM zbd*x$^Z9Jx+1c3&a6BI4x^C)Mt5pC_PfwZ8=Qxg&4P5qU`6<`e*XgI&wvAGX;c$qE zaCdjdWHNc5Y;JFFQ~&1XhKGj-!Z5`5eF}vFB7*PxDLfN+d3m`}*yVDWBuTJs`(vYL z+cw2wF^%u<@28_T8jUzOICvj$DcYx}CjcHFADPW&scc-=UAr7I*O#vAVi<<(?Cgk$ v$ZR%~PN%bReSP2Jg8eBX^5yli4cP8)Z#s&ArhdKc00000NkvXXu0mjfzromS literal 0 HcmV?d00001 diff --git a/smiley_pack/icons/commercial/threema.png b/smiley_pack/icons/commercial/threema.png new file mode 100644 index 0000000000000000000000000000000000000000..897230aa06fedcc0189c81925c89430f8ff703f9 GIT binary patch literal 4777 zcmeHKeNYo;8eh-~Mxb~oLQiFlAE!W)O|p<=A$%nWDFg#Vii)S3%?2XmgCvlEf`~#9 zN2y<@P^uh?EjnsB^{NL*Eg&Ldv7i+3TLH!P7-2lBV!by35vHBFapw9Tnc3{V&-;6R z@ALeg=Y3~)t0W@Cp7Id|f*^ZQs4xoL9nF{R6!7mh@CFCB+H`5GAqqFbTAfCrOd?@J znwEq~lTraerkg5Br+qDKH#9h7&V`d%uAidiZT48E{r<&LejWa*1-I+zd7T|HX?M1| zBT6)N&dSr;=ih2eQWv#d-FeUMZ&;l5deP9Hoh$QSor*ZijeMR^>Ds~Gk})$sx8}7= zz2FB-_Tdi19be!(nX(x>pHm)tek1OmoU`42`vPNM(<4s%Ppv-Q49dWg1&=*T4_PT! z1s=8O4&OCIeQ}ho?djP1;iJ37i|$RknYrRmkxQFfA;@a8QXr6s1cJBefFz1DcJf1O z17_E+i7s32PEj}}Uy^+BQ)$%f#F_b$d2N*A*#3gdz}>kE>gyx5H101Iu_@Z*8`m!^ zcbx1WP&}u2#_Gd$Zx-e_Gw048e0aOM;kHj!V$96uUJ+EJ{=85cb*bxs3Y z$*wC1-^b4+;&g>XVO3%C6{mr^pz>{9^q9*>mih{2FZcSQ|6Fl{`$O8rm1jzqU~Q?e4v!USDsQiAS^6^CPlMn%Wv8W~A9skET&AjsF>q{WFu(g4fI zc%_<8?W?Sz!b&-x`iYkq5o-lxf-*E+M@FYdNQv}Bf+wf?`%!#N7$8uQ1{^l2lGJ+4 z#HU(#G4O0QGpMiyVo2muW5p6!pwW>qN=NAkE!d1b7G#cqfHeI8OXE1p@9s^-9SS%Vq(DZ3)18$!CLUrvj3ZfPU9QF9n;F5k=}X zDLR4-P9@cb`C}>M#HhbEMVDkrM@}%vBvJ*Sdax>U+>#+8v1HW4EJ3_drL}kgvBx0| zO2s>|#>Hlyv7|FL5a2$_I}ZIecMBMx#9~aSAyUlYiG+Nrd3{W-A(V2=@`w=L1XJ#< zpfPbaLPL2x8BIoV<;W<9Z`Z z8ZP5-WvBwhIWnGwN={%)H98dz%BfW0@gzg5j<-yh1;+v;1#sX~ z!thCsUo8dxLHjmhsEY12optFD4WaVz5~UOIz8w_Gba>w9Rpd)dEMkm#1lK50}0I=C}bXp9ylN>kTLfk+CQiO$K2p3~|OPNfJ#ll#q z2g1UTF?fw!sYv@@X!GWQeTPdPs?>w^(=4Xp9TiO`508e2NlMFBf?><1z;I$X1wEch z$}MpMuHh*n0awS9;Pe=2*SB`%@3aEJVtXS552YzMD4T}Ly}W2Vj+{foy_qZ)o9)HJ zx%hZ?y+&a$;yN-g9_R?P0_|zh3SMj})ROUNV*+We0uYRbaB064j4_fh!+d7E&DfXm z8%=yIfH8**@Ef*)!wZ~+jM2kzL^JcT^9TM$YVilI0H`Mxc`tn@g*Czz;lBjYpF;WDCIWo-CYy5Dso1Hf6twLvqC=$ z-O>`Wxax6f80t_i$O&M5@Tr4U<=&(nIoZT4pRF4=MJG3vMo-xpb8}(TR~2x!L%x-Y zn6`BB3p}&R;iZ~bk~8a?{k`e}D}cUhiq!c{rz(Lh>U`v)a4$0F(bI&R;dlbci2 z-0e|#@ZcM}D=#~`x=3ed=U?5=ojO%}`SNA$x;2$2Di=_9}!{v9ZasrS^*(SHo2KsTG0@gQ4!q6}xh2er>H__xD}8)19h=0iM&D z^%WINy}yqSK@gL&44Bw`uQfckptW!CNowVf|J?~hpG!#*~x4cJ=nU&xc-Y$ZSh4p4HRSvkdxq^M=HY=pa$? k&~lI{I6`VF3L{|w6i8PxtUX#Zg_{>Py6kHO#{gUNpe z!~YCM{}?>}Gx+^y@Mn1UnBn6yhL6t~K0Raj1SDTDe16676^Pz4e0#_6?LEWycaqXd zaHRN8(77lzu_QG`p**uBL&4qCH-JI$CkrDNgFJ%{0}y~5!oZsOK)r9tjMS*Gb!%4i zx@zw(_PxEi>-4X4`}V~LNKDDlnt1zoV0Vm1yMMnXSAhFuFHc3;*vM(3<;GPfG?pH0 yu%2q`&J%P#XL0{C=gH>(8SA8Kgq0bb1te;8%W7DdI+O}KxY;ThI5{j78LR<73t)o) literal 0 HcmV?d00001 diff --git a/smiley_pack/icons/commercial/whatsapp.gif b/smiley_pack/icons/commercial/whatsapp.gif new file mode 100644 index 0000000000000000000000000000000000000000..59898b09bffb5b83fd36b4a9bc1753bf93f725c8 GIT binary patch literal 1353 zcmWlYX;70_6o%sxYY{C8E~vD!s2~OjvY3Pb+4qfXBqW4<9|>EkLxt*8>Qqt00*cnL zP^PvPYpuYv2B%c{Q&C)o!P-t~OIt(;kU&CKl8}}39<{^^U>7)ri$y?ChngXk2CAUo#7SK4 zJPQozSWY=~m@tXMnYjlIB!*MQbjp$^@tAoI6a!7FO_F6~uw3#;Btmx-L${C`+f~9_ zQgW9RN9Ng(g3wczV`B2%r6qnXBulkR4jbuE7SSq%{1kaqd1fBXE`>Z~&e23(wJKPZ zW+3KU_)t+rpkn`20mD(8F-tu(OTjE~IIa@OG9XOJfu5s@y@1%OF7}nMJ;sndi4ivTmvM$b|4W?t%aVd87t-ql(R)C^f2s)pFrp_RB8`81dXcCLxF=QUR5D+j_grGZMiL&|i@u?yU?U{%6v9NQ)5tagT#ZDatU8me8I zV`6calzg|c$WunPi4=Y<(JB&o%l1tb~S6 zW0sOWLrIw`z*~7Kkg>@;xlbeTsDSY53!-PKfk@C3@d|yaJrmfK$cn;WQM?Q~R-ESW z;#}A?8Jd0^croZ78V~*Vd+^V4|FMzaE7fw%SDri9+&7w+uH6pw=^Up{J6r1Qja`B6 z9&i7>;6RnX?!IsE&ve8P98&@PbrL6!YzxvdUw=aQU4 zsjX6O)@j_eIcBEVug*6K`6e*OLeDT!Dl;)CFES$((ppq>TyiL(&`y$OqXS%A;|4`%sO-Vp2 z3xEP2DDgH3eU*tT2=Z|)P_NY_oUE>|N}w~j0$8Gd{hBCP1crh^WA&rJHm<-TZ--7M z!J|@9C*p~Ql-QU|eE&pIcI{LWayKs?*I5fZX-3#X*sLprvvG0MPNK7IT;DM=Kxt%r z|10Bc(cT-wUOpFPkngM`|B-%`K+3<66)Y zj_Iu(Y2Zg`an+jZO&wZ2_@Nf5f7z)Ypt(us$c(1OqrYHUb1d+f!PtM%SHA1nzFB?0 z-VcAj<>?M>a?8%`S~W+?lz>2c5S#WxNLWHf4b$WY~cKFD#UXbwe4hY{4FB9GrdlN%*WqsMd4(w;q?vi zw?_E!pIxD+_ukW<+ZGe(?$~lzIer0M5!P(lHQv{~NlldLY47|ze0=i^osw03xCEAPCp6*VwQYQyN6)$OPr2Z;b1 zJeqJ8sSJD@mHtED@zz5>O(9#wLrTQcuGDbsTVFnK_j8ed$N$lVx<6)MBjU~vJ^LEI zaqRg`<%TtMWEi+}?u-p^Y}n1)Tz?lC{{k_b8WT7&d?$9@h($ literal 0 HcmV?d00001 diff --git a/smiley_pack/icons/commercial/windows.png b/smiley_pack/icons/commercial/windows.png new file mode 100644 index 0000000000000000000000000000000000000000..33109cfa72a07cb5637e72dbe3e3b26ba976d7ed GIT binary patch literal 3584 zcmY*c2{=@J7r$dSizV6jElW+7s3c1Er6F5nX^?&2mB?O}6jI4DlBEbU25&0aDndvY zvh|X&3}X#%w(s7l?|r`SKL7i_=bq(ve&?M3JkOnEGmJh8E&vAr0A*;PV-7y~pqqsr z+(|D!cLD%Q%MDAL5Ob$+v49|dH%}i|v5@Nlu41kco^AjT@omZ0Axsj@7Uj-OWJmy7 zg0{b^5#w$5?X^Y%7p3wsx7a7O-(c)r3(t>5N^=BKZXH-{iQbe*oO901^zISC*|?xk z>>qHw4O#bgc6MJ4e%T2MuV#^T9{Xpvo8mQTRxsgsKO%c;YXv!xh1y-ke2PL^#c0L)?BpfjqsiR8ctmRQ-aebVRDDx3Dtu(JML>C4 zZSfF!BL(+HdkYq`RVK5$`&l_UemW#1*E+g&UcPL@vS-VwRXtU9OrLG}Sc>D`^epV$ zpsgh-$02nDR(12@!pZEtgd|~&)oAqepVps+;@>ymbYDSOj91bo*eDjGQ2BF%|g#kkNG~;@T*%@v}x(c>Qm-8 z^X&6t+e`r>`bHzgVDK8|N0;!?VQ!PFifxaH{w+nS3IzIHr)P#@R%vZ4xduU_W)(!br_f{zd6Swf4NA zo=h}G)hRhsD%BuEzA_+LI@`YZfw^(TQ{`5hAl1t+N`}4(F!>UmRwr$u7&StugtCG+ z8~xt?^lSWq#TmELlovcsm=v(U{K#^|?lYrBjB=H)`a6xSZ9`QPhaRYU^}j6At*BS` z=B-$^jdY`W56wBFeTrV@za=C&XV~#x`&)|N9eYfNZrT}nzOUurvZ$55Bocr=}R_(KmEf_t7vVyW4GvD@VO-nN@y$l;~4 z&@o8bdD8RGP1hX+rsJs*X0B=Jca zVdO&zUXESf%imIyCNAKTLpc>gU7Na73SM$uy09KsVA^PfGa4u`Li!Ho$9BI|<`pjv zyBvXbNY%F^3B9W&gh=;^U2no+Ef$BbUyIf4vYTTcZ0A|uGK zykNBQRN52iR+bOH3bUMxR8q2d7L|^SvhS`Glrrnpbo8<$UrLwHJX$8=Tov0X%i;ah ziQIAXK_IF)se9^;A!Z-1 zM0H_Lsh~n91Uf@J4VDF7U-oCbLLc}#H-`Zxk>_ljqlK67I6KT9&aS6w^RQ-u#g0`w zL8FfQ#FlTs*T?m||1@;3v90q+pwH%jpSJz9PBa99hw`>Myx z*TZAJ>FgFabLlPD+|HT)Wybedi}YRE$5H6P!WUJikXOPsw%!+fZBQ)TqosJ4 zJ$akaA&;{fK8ynN8Bf!!-E0WQvtFxXq)XB}$d(Pv{z^Qn{<4p_0@kY~Vs=mV{=jEzCoo8yb4+=lQGWhX+Nqk*=D+xS^F#H#Z66d@2 zGc9$R8*g2=*_d}267hadHgX9C*h{SO<{l?DUo)(xS@W-)Bz;d_&t=*E&5SVRDkKINRY3!JDpB36$9v=@EkkHnNW){mhQi(>KXWLMW8c|bKzIFRpfV)?$XVH9u zU~ENZ2Eu?T^L~0yg3!_U`VvNsfsEcT(UGj~eP_=6yb#GS<1_2%`C1}}n44E)x#l;m<^6#^E3;i!TE{UbO8>53nFfZ<9x^#Hr?rMK0@~Gdj7aj>b zo^?gElQ?{H>iglp*Htovjd3i^^qjr-1N76$miHy&*xyH}XwR1p&URK_!@qXbA$_W> z@by-`I{TW(%m?5im*wA7iHj6E@Qp!Rl<%03JkDy_`*W_O+!__!h=`92zTNBmBT#k3 zy>0))?kF8~NK~{sFR^V8JF|Ur>7Z>Uuw8!33ja&*WoDS}(Qx6Ho$fHoo7K)edF(1_ zb<^+J2}%8L6DMw1uQiC@>>Vk>=iiI;pPjamkTOfGV9t5WQ7_Jl8GKPT_DncV{j9=* z7|EV{--SXR;J?SKaBOT7$Lv$Q&(7n0`_qE0$TI+dC3tFUn;B|riKU5of}b#X zQ5hNrZRdqPT(u~XK(kqMgm#$aAG?!s+KW5IOnd-ddFHYGFL4!519N*JMp9h7XsQ)6 zue*b=J)_nN{rfMU48Q0a?Orwa;GAv=JU1~OIo3#@a3jalx}C3ZzCH(Y8PRHc6xOr!}bl{S=;^DeIZU&ezaWNvae-t z=S2(@BMzMla#-EI8~nvJ)?M$j$&K{WM#p$YZ9HA9l~tz;qFLp0mtK=EH?2n_QavFp@%su{eo|PmO#jmTBZ? z{6WjIUuEn2SC0;3fP97YbtPm%SghXXz<2kA%L3^baIr@lXQ~Hc=S};)(daOS4Ig@5 z68ho@{qgXaeHrbOu9xBchvAIh_tM_UF>g%JjaNAOe~!x21o#)^L+OQt=p=PJ9oMgi zUyk%YDDd3eq8E`1N*puMQvm?F4KoucbEqB)gknK| z0;B{1kp#+b<-a@7G>IavvDB<^R4;>W?6oVbcp6CU5^Mbuyk-%iL0m$D#6V;s#0O3z z29lv+(ilQk2p@taF2RY5K+^%p6ZC=8Oi&1s3gm!Fnh(tlXqW?E!4%x(3%_Y235$mb z6o@Cyfz}N$3z%XNl0iVIK!^achKdBiYyYntFfV9jsa*kk1quL>jKG7n|H%kikzi>w z+F&}M{s3wzi1V9FIYgMYz%Km}pjtpHVTq+090$~1DD{6w0P&>B5W@c~Am-rDAZWEi zOvX+SpRJ=7)XnyC546#n!rXuu>`OQP*?u|(z=Z# zQV@0E_?Fm+5D4T+q_Ps1P_zQUsUd4=!y+!C2vkWX&?F7L+L{$O;}6DtLGxACMJc8G)xANLomHv#Ta}=3yb` z7z^M$c^LdN1;Ct*^>u(djKT)s3u}OZZ7={FmxOLuM9H}@P{|x(cu|*`%uL5ED7|>@ z^c1L)HPq3vlwd?CRj+=IG|`6uv>**V#{dAS9Jg(am$KvY^< zT3%6JSyfqGQ&j^*wbiwCHFfo!UEN(hJw1K>lcr3WJZ0*%88c?io;_#oyv0kFE?K&C z>9S?3Ro;uNxN+0wO`Cye%jPXxwr<Wan3za+_z#y zrh~UMvqrazSkonjIrW+jrx-+j_H$3rWnuf-!PuW*n$2>1<9?~25SILmaK^Y literal 79 zcmZ?wbhEHb6krfwXkcUj0!e8l#h)yUTnvm1Iv_qshJi_~hrjal#0!tQb5DI;5SaJu eeyx&uUxa7tw3JPYR;TvtS<4Zgtr^O|U=0A+vKN~G diff --git a/smiley_pack/icons/fediverse/diaspora.png b/smiley_pack/icons/fediverse/diaspora.png new file mode 100644 index 0000000000000000000000000000000000000000..06c32f6bfa29412330007d7c1f429f18816cbe37 GIT binary patch literal 4656 zcmeHLdsGuw8Xwv!h@w~!A7yn;q!z>^lVL)bG2s~=aSet?QK=OslL<`CYm)&IJYq$u z0xhnJZAGbXd8jC$i1gU7RO5LlER5i;~8Is~h;bI}HcF`VWV*;L?;CKaY(iGhl;JuVyqf z%vuaIOq&@s1evdD71vxE5vSi$@(PkC*E|Y{UN`H;mbUSZp6|!-9uJ$+G3vxG&$3#C z!QSxUPnexv%Q5B$?)P^(W>Ra5pPyXQxO=qs8hBkqjQc0KPs`fKmU>-G;KX|~-#st9 z)ar0~V~qIJ_Ni6LF55jKW`FbbU(%=euHW?^@yV*4zCVl^)mpcB%Cw#%@z-t^$yM9F z(8^C=Xm$Blz+2b33hItBCpD?v^IOkz9*+-{jCk_)-G9%An;p3h5ah6e2@6xm!opr9 z1k%{FWQ`=MG1#*y>7%CUxzJ32V;zu@~ESoNr-c1l;Lr1Pf3i-?>u^;}Pd@O;z&8Sj;Kr|!Yy_u98LW_>f!AH8R3MJg2!k`FJRe@>BGk~=l8Jmz@N{i>6e z{OZKA%6~|H9T{fP(i`q$k!wzIzJxTd)?u)&Fs0qd-?=7CwW6%Dcy2Bxx=I5Bh%tV58JvO&MM}Xz1Py> zI)NYiOWm0x%ZraaU%czetue!bjkl-#dcg%Wo|yp+HcvjAp!8ZEsnRQHo>^-Eod-eU zAhUs_7SSxMq*EB3gwu7To&z%~31_ZQj>rvRbSe{-X{6&aqvNT}MHH^$1O+;a%>*FO z(kuy^wHlp?FiSXgUIN_P%zO@Php>wzoOyBu9HuwYFvi1p2shl!q@$cbXIN}hsfk!= zL>~osl5kR4)9mfWI*>v|_4^yrj2e47DvD2QXf1%6z^sBnQ%1_|yO5lfyRLB4-na;$LI*PVY0dgJ#co2~Yr~Gk> z>nFm6T+Cmo2mI*ui6Y6?WCAIKfW{ZJeeV!bijy%T7o33Q^3Q-JXNFuS|0ECfgf z2us@f6cE_$AQvLcNRzDI7_ZlBBpe$BZ1e0NmV@P_B3V*OvNRw?P>etV2!VgRKtKq= zjh`=q6376&Ud5;_{|jwfJg~U8AV z(`l7GPQcYWM5U6t6dLRveeL?n&ip|u2n4taQ3_GeLp09CC>-Mkpr9X6l}aGOMQRkI zsln_fy_(G+jdVx~&=F__+S9HT>}@ZU&tP;$Ds8I*5R8iiaDOitzb|3FZO?d>v6%lm zO~iJF7%YorvK02!fer?V!W29^XXTjE<~K9`4xT*! zOHEx~CZf1@LB;ckyQ^w1S*_NI)z;4wc86D6kH)x;UYXmZtX;sne6PFn=E8c*q4ob9 z2_0R?Uq7p9RCGz)3fI!|yo&o1K3mp!8)>s@zFfGkr{|`sa^|j!?G#a5q(5?_pu8L^ zEw2mPai3Tg+;Xe<$UoW#B9M}m@$EvY{^q1rL& zWkl)O{JTGUCnWBvnTLgE>X!WG1=sYv%=@Y8^uEnO$7fAm-R@osEfjC5>^iYBC^dXb U{*8DK3n)7z3y+pogeGVI7lk^>ga7~l literal 0 HcmV?d00001 diff --git a/smiley_pack/icons/fediverse/fediverse.gif b/smiley_pack/icons/fediverse/fediverse.gif new file mode 100644 index 0000000000000000000000000000000000000000..498b57426b264f7d09e8e72465e00b2148ef9a3d GIT binary patch literal 444 zcmZ?wbhEHblwgoxSZc~JmEr#qwzvNo82&Rbc8UMGAkiOf_Hwzwj=kE;cj>R%YC3DX z>9ljUQWwG{r$(Rt706Ind2@EfB!iaH*sel~~e#zNuh{UQ_himcx$ba0zc`w8LOn*{Ff$ZF?z#n>=Ht%j`K^^PP&EMD>@IS=<{Cs}z>Cn*os+4JXa zmtG@v%>6|2T2YbJM|~MN1-BpBTy)-t;jzGxO$9O+JRUQ!u(7%D2?~-D_Tbl`3it_JYO-VF*cjXd>kW*CPNQHp zOHaX+nbts%`MOs1+0a_p@pZeKY-zCA>~ndS=ww(yqT?vn8|7`BeHGjTCljNONgeHW z@~>y7*1_|!!A{=~sJ{?Lwns|*i|^|>NwmsUy^4qK@jd4*GkZBBS;r}Qdx^N2Wo`1b7v_0`jL@pB#K zhB?26(lhlj?7E?EH@VF_W7hvtV0!*{(<5j}#ktsuWOtSS`LjC;pMp`xr-$AhX4_3>5lKdV;k{%Xg{(wV11+Yi-bt*V$;R`E>s zyHl;5mMXe0ZdhBx-3U+4$;ZZ*)J)Ewv)awo^Lljli--|bk^G{BVTfVkHv3_PZ4Phq zZr$8cr}#z5@yl)TxY0G-VQJ;0z4(n=4M%QbHnxq`8=9UpZ>j#t@80S)?lN2Zqq(c@ zuNm{mW>Zl0*{}JYg}!zvFIR=%ev^M{+>k-HY~Q5nn1_ptL!kJM@ryt4@v(IseQv>X zv#F%==#s|oU%j$&!Iht~lj%j9|2UoMhA#->lVxwu7MHP_rHm^?Gh&JCR6K>3J3s}=N(FtXv9fTSm(KaDWPf<-Ebp^Qw1 zfuO=ODIM$Emx3gE>yoVwi{Mz8DoVx`@{#uzRT|D}K!A)poz`WT z-#cPyEj5e9Eo!2HLXiYPr6Lp+1xf=%??H1YgAsJ1g%d^iBC*wDnHCHb1BAsbeF_My zc2El@H&8gs7-AVFO~$pP1Y06|-Ab^WNSwtLI7M+gPu-7cv~?-Luys*jIMH2#5znMZYo36s z+eM_{x?~FM9zE^)&QAYHE2slCh$K)$@d5}5$`d1~kS9^25*~@8LXA)=6;Wijti9|; zM#GwL0~MAGbOc&~_OxmRkF`$JxDRtNrBIex0D|!l3Ga`B33>_^SoVx}6$cCcph>V5 z&}WkYaosksd4au9(7PG-Xa@5AD?dGR@mCH3!~KJNl)n9P^~?293Val}zq|V7`X~iH z3f$ja|2Mff?~hZI4!i}Kz+owO_%Q=GXxXc$MJS-*kOA6W|Al8gung2k#v38X3H%x0 zP4#2d-N> zMLA$JIz{D0;M)T-y$JPg_h(HZ-mdq`nwQV<8i%;EoE1a%A?a-s?AJP9qrN=p^t`3W zIPuvEZ}BK`*N;CI{oYtC5PeNR^$iV-2Fr7pKO$Rk#yws|Er-d*g74O^mfe)J zr?<3izm)L9f^6`T-+ASZ;kdWotD1|y=H^tJRSqW>Ur?S|6sq_1Tj_CH8Z8Z#cRqZ> ztDLjB($ulYFRYVsmNan&{x+W~9($oVM-~xZwDpJ7ymQT6$UR-aOr|{V$bWWRU4MM~ zGLO0y;?6@iOxMc!)8$u&jMf%>+Koi@Pg!|X*Z4GxRn=*20{)QKR3UqVMuJzMQ zSkd**Pt@%>w`^lt^to?`&Q5D9dC3cZh$%83bAx79^B2y=Gb?LqCxnZGF5him;5|lE z8qT;hU5s5xhkNww(?R5uX(0(?H*a|3Sw7;y;ZZYw&fl;)E~_g*ez0|R2QmzyI$WtV&ho*xI>j_UQ!YotQnMB+Sw}K7}GfE>Ex%$hs$kdyTos8 gJiouLq52xLcS6CCT$hWwc6x=<10~i#4vM_Qn z*fZ#Wya)0q1Ka%r^9w9^B>Imm`E(*jYw}r*Pd_I|F`s|@^igM(-ki*jD`xuGi9ddt z{LbL`@t&Q!GyToZWfePboUK_=877u0ER-2k6(*jR7~an)EHS}dQISzmlTlk!UQ|sPD_RMTZt)tRkfV4$&3N0m`mEl^WKQD5(nqL$WlRXu%0 zjahD8dl}U7G8zLe85kqoiVRU6=Aa`kWXdp*PO;7+K`2+z9 z0096j000007yuXm00K#jfvKD34516Lw!`Sso8Rmqm~u?O_;r)nNh_L?=+mmT42BVW pjx25y(SSE0$n|pVR!fVsr+W&A(&_8!!D?q)?WLQvg2$@@06T;qHFf|1 literal 0 HcmV?d00001 diff --git a/smiley_pack/icons/fediverse/hubzilla.png b/smiley_pack/icons/fediverse/hubzilla.png new file mode 100644 index 0000000000000000000000000000000000000000..c5fc6278e937629bba214062056c09fe2a4c6d7c GIT binary patch literal 4563 zcmeHKdsGzH8DD%N2!bM7fjCTJ4Cw6c%mmVEv?|Wd%q|o5#qKODRC%Zv z1Zy6|C`21+ebje}^#O{gV7G=EHJBn&Z7L+RJ+&(_N*<-=&MpF;=A0hRY5rr+nVp$? zf8X!>zTfxVd**IUO<5G+H_J~T5CmwF6Vt$bI=F&;$AJIFZfiTZT`SDU2pd zbQV@Q&du)t(DSu-rf_Lpr0k5mc<^G9;g*fvDf~!sX1_yyq(iY&bFj(5eR%X zvk3{QnuLUBiGg%>Z+Kgs+#DBvB`baZ{)~`+LigXQB|4IlS`IC*^_?Dn?8f0uSNCV# z*cZv>=7y~H4=kF$JYw~3hr>F3+@&c&hKX~NW<>QCYig6WO?34;^WC|9fk8FX53E$@ z#iRz$}^~=zQ70`sBG2(f6>#nMOAu3n9dj0yw%HH{Id-3)dsRg|_cdDzJ{8PES z{GdE%LeGZ#zVog|_bPkOYG%At)ZK9Z%dnnbHIKQzZCCYIs@%<)^YiLHxpI_#y(PWn zwPkHlS$}9aYP)y;=(2wt-LUjOm#u5FR(?TT3x27td`@yu?cVKJ^lu^;9!aSvlRTKK z`gim8EO=-9acrhCG_`C(NAISmm)z!Km%BH=ACe+y6rJuz{l?{$E^j{F^rq>YW6akd zl+J7HIw32qUiwK`1X4KeE6dm!?Gf6JvBLb4+PMibX3>{zA%5dO>)&=EYU1R3V``;m z&OC`pnO!p3v7^B!FtD@^W={P4{HwR`b~YLA^!E!kW!a8>oppTzXh0_m8ZA@1grF=Y zAxT?wjL>Paf({f2RIyGgN#!scq+<-MSq;0-HNg-|tKk(=typVKV6xfdLK~A_n36#i z=1@u+j*anCISD{uVmK0Vnv7;U;Z(yOUIIMx!y*{+K)4(=oT*KP5-c_bk_aV2F_PqD z^DsEZ4^r7^J&~5UaDW25so`vnvl1dvety0%9~W9|1`(=MDn(*UgkcCkAoc-L+ z{Y9R_%aO>~DI06$Sc@6rIZ2(x!Kq;w%tO!OGg-CTL3*=&Kn0+O$Vpm7s8B32nMA`a z>|9bFAQ=eg2QBOwV7-dc7`w$`qnM;T#>~AqoPwqX?X3=*(UT5Mi5Mee0#G~fiazIZ zkw%+3Xu(ThU`+h0+A@?G@_G{N<>e~X$7i~C{P(Qj7np+bEKJKcq%|H zWC4#Jrzois*CRSyjv^8{g(FHFXAoLOGq_YQSKxZdFp8x%7IY@FCE0#%2ed$aA7%A@0qF zFAD*Z0m71ep8^7p1;~X+urVZOv1M2+Mm5Zb1o4)G(^{~cXp$onNsa-ez$YPA5U4Bz z#RxG<;OIOtco>Ga(5$}Tf1&xs1F5_vPiF1Fe}QMnyQ0#WT<@Fr)yR655(Ie`1wm5Y z6zpUk<5d`Nd8eps(rjSB?lI7=&&JswXaxmMQgRxTAqqJtqJ-4Zh(a%=5fsNs95e!n z>b%`F$ZogjxqQ;bEHD5afmWbBJz7DpcnTHe(QFW%pUv=90D>W61u`TUJ|LKAAYl=| zXFSVTCHgN-R35;vO$OL`$H3+V_CnF%W;mc3h~UTk4bhqJ-aB1ajaCR=!BreEMwEm*1uHtfB(3YnyN5=d2P7k@1R(>ikX5*fU zbzNbZ<(cFCvo3!0`{=SzpSJSy+Z|iWd>5yU+c^h@Z$7S2+dk}Y_N~BQeT1Gohx<{J zgW=78?6GUx(hg;01nydLrt_M38%G4hE&KFlHdnuTUp4%6eay~QrhawkN8pIr`r*I& zzMETgrt{P)B=JbvA)_p8lDom&^cUCDTjn!wy1J$mH?DPc<*HuTdEn)#TRV&kqaLd) zb(!6dzJVm+fl>PvA6!3e>O8$>erWS~W~KY?@%EgekAvGC#qQZfxZsyPjgKz4{hJPK zsV;21XOz|VgImHz|IdE_ zlq1|g?0LCLQ#!REK3SYxbD;MdT#Fw*e7pEWdyZsQU8WJM=73}biiwJfii(hske!{KpP!$gprE0lp`xLpqobpyrlzN-r>Ll? zsi~=|s;aH6t*)-Fva+(ZwY9dkw!Xf;zrVl4#KgtL#m2_Q$;rvf%gfBn%+Aiv&(F`% z(b3-C-r?cl=H}+-=jZ6?=<4d~>+9?6?CkCB?eFjJ@bK{W_xJkx`u+X={{H^|{{R2~ z{}~%1A^s6Va%Ew3Wn>_CX>@2HM@dak03rDV0SW*=04x9i000;O7ytkUs=%LcNGuwU z$fR<~Y&xG%CBj5fFc+i}VhFhTzMOzzVoI4ki2#T9y#a)d@3%A3$?vGo{UHR{zAGkd zcXur(Up8+-2Q)qsgM@btJ~LZH01z6HksJ{LNF1Al97+{FJt{JHH7sltN(DMF026l^ z05LfPN&y%?EsZrbJ~%Bt6`x3op*|oYAs{|G8$!uR0Sqq|Ul%S5icHB0Iywv0Q9l9$ M=~O8@`> literal 0 HcmV?d00001 diff --git a/smiley_pack/icons/fediverse/misskey.gif b/smiley_pack/icons/fediverse/misskey.gif index 84982750c6ffcc159c88b23e461aee4596f8f555..a4d6bb340edc3d19574a397ed51940eeffb6824e 100644 GIT binary patch delta 979 zcmXxiZA=?=90%~b_GquAv`BHQ(DATgDU3}9LlDSHXMi>_5tt@(0mIP55R+|jD1|c0 zRvua&T6*_C1_ig4r!K^8Y#<8Q_BuscdiOu-T-=N@GZSY_Os2*JLeg1Y_{%5Xd|!ND z{wV&K$W*PbDtYa!0#P7Oy~sruYM4X}lW6M{^6@nC$u!a$%b6I|FoU%3L5(wrVK#(mr0oXM9y7-`ekSOMxh3elozOX-V7eo0y_?;&AiumIzp^ATf01Hd zmYJ6mJHO2DT+TOjugH2gh@s>HG?>|M#|`%2R1m07*G)hq7z;{85+z$dW! z`GY>p>W{a0vj_bGv#-$XJ8q#9EWYd^8tbQ%Y&6#GFS64-dw@3_;0*+hTD~r|uk&r+ zD(yj@J%|mh9Ul(K93lDeM*K(!9b7*#Xj<2dY@j0>{Gnh4!JxLFmS8X3X&BQObQWJk!(C*UL@HBl9iIIjAUOR*(8#c zlWg)R%X4hRmitCojAZwdtb$}yNH&#Z^2Q)WhD}-kl>i=~SQUV2fXxLk9l#6#GXXp_ z#>D}c1>nnoJ?7*v096E237{Il8~}4krV7A30FMB86u?5jY5*)I*=hhw04xQ2rJUkk zp}1odS1=xlqqst6L^K`|P+Sqky-IP#6j!37xKfHMqqx}g1jT76u7cvU6sL23C#N|5 z#C^fYrvB3h!fOvi&hN9X{~&Tb6uTaYuRlt3{}?~{lVs}Wq^T|G^p@1&D0jGy{7>Lu zQ%%p2JS28|zlGpY9NpCNoshDg`^j$C`A* zFD~I3Ix|yQr&y$oGW?lcklJ!1psBqO=#k^v#)Eu*LsuY9`uXoq2J(H1M5OFLs?xj$ delta 331 zcmbQqIhDEI-P6s&GEss-f?=sP14G9uhRziXohuo-fM^v%*J`G&mCRi$7`j(7bgyFQ zUd_wlM9*bC-X8( z*V{AbFaQC_VGL|@56my{(2?ptv83o^j+7)9D_dqqSsN$o!{eQ9%x*2=3xB%q5jY+3 zQPJw!@^~|;oohr@A3oOmRk=s4tXxyEoU7JJ%c-fYtwTXv#J;CDyH+_)Wy;jJ+GK&* zbK32bOBYRB61QwB>x!jQqLb|flIN|O!ldUUoommsb!EvE2DjosjkHz5aooIa%*pJN a<0Oj$g*+m8MV$i${O&(^_~@Y{gEau$?t9<> diff --git a/smiley_pack/icons/fediverse/peertube.gif b/smiley_pack/icons/fediverse/peertube.gif new file mode 100644 index 0000000000000000000000000000000000000000..0cfeee9c3e965236fad3af30caf570285a0f4de8 GIT binary patch literal 137 zcmZ?wbhEHblwgoxSjfzvD6ddlT>LSES5jI@@t>e`QEFmIYKlU6W=V#EyQgmegW^vX zMlJ?s1|0?<0BK@ia-Gw^^7PpUix>mUyxty)RPL)3w%|~Twx9U{bJMM1Hy;T)w oSsXWY|EM#bm;AzbkI9LYbC-O&W|=W>%2G{YzqR&zGy{V*0P)i<(EtDd literal 0 HcmV?d00001 diff --git a/smiley_pack/icons/fediverse/pixelfed.gif b/smiley_pack/icons/fediverse/pixelfed.gif index da5c1e97bed58f41233e32428537f70cd9c1b665..b42d26b5ce5d3e5fcf32a8e476c6cc98cba7fd3b 100644 GIT binary patch delta 1241 zcmV;~1Sb2a2<{1gM@dFFIbj$87y#$~07r04i+p|ZRxQ|N7XO45|AiF)h7&P%n3-+Bt6wT zGfucU3g=W0-AVO{4&M?=?h#P$6i@IMP30$1?Fv%v4pH$NO!6U0@g7U_BuLaOIuO}K z>;_cyC`S-~+eQ)BL-j31)-*Tk8(r-ZPxdoH?GI4@YYr39Jn>^&} zb$k5u?f?J(_}s=A$vGI!H}!M~+$mkqCuY1RgsvxlnW8AFnj)v6CAE$amAP=em?*!V zD7~2~!;&h>voX2CF{;Efvdb~7%P*wFEStS9q0BS0&@!*pFsrs4kI{Cy2;o%5HMz+& zw!}8P3ENS@H@*kcP`^0Ar{}&1$V7JCo4Gm1yg9@?%XbXcM&$VL2);fG%TTsD$}7uc zvpday!S3P%k@~Pa&>F;60F(Y7&L|JTd;*jGtv%BRy`lh;`2dvusy@~T$%Fuq{s6Al zs6N>b#$W)e`~ax@SjgEo%*s5xU<9r+0ITf)kNu`U+XBJ80L#lB$;1Go{Q#x>0Mpd~ zyXFAd-Uskr7|<;Ntl|LP=K#(34%0&bp#1=U*7g9~^#GFo4b?XQo$!v+-vFJv0OIce z;PU{|_W+&!)Ox}Lr_KPG{Q$`L0G0j#!}tKb`2e^20JHl5uKTV!#yEr00FnQ$Jjq&K z&UaSCzdFLIL9qah|F=5Eusq1KJI#$sy%u)q0Eqtpkn`RyqyU8V0Cf7%GOp?>o6Rx} zu^evVdQQaRES~iyl9LAmD1R6L7ytkW{s8|895}E60t5*ZEFj3Rp#%vLAUrULK!L@E z4JQZ?AYuRn2nQG(RJa18z#>(MXeq)(K*R?j4;C1K@yL-ONRm8}!i2^{i6IlLXu{CQ zO(IH`NU_po%7hFMfo^D$V&D-YLXa+bV#Ugr8#F?MfEwX}1*!wF5`W3LGtHd0Z`rsR z`+!1|7Fh(|WGkgh965jk$C*231r)shgbYEN1W%$ofg{VAGseOQC@8XsS*!$4pFo86 zNEUpCLk-Me#H`H&S`s5fqXEb1@!~X!)JWb0+Egi0KG?BKQK}6kN@^vEPKmlSX;Gor zpGL7@aoV`8C52j%;(s(r(sRJ2O1ELs1Ok!|>OYLT`bQ`hDc+I3=Q?(5RWlbST(F3d zew9E&wJ3KtMnoeA-}XD3U`LgcMUYpVABmSvNQw6D!^pJ z%0RWa$D1U|JOd3j%ya`zIO5zwj5FN8!cZ&%MuN^a9)2_9I6}7!lZ`j#U}Pb8fAk_F zjpN{gBP{Hg^v`>hNRkdN;Sfp8k>*rs6O84v(F DFu+Gr literal 1064 zcmZ?wbhEHb6krfwc)pflfkx9i(SVs+lirK^zZdiWAnvzHv+k{=&j(4r4^qAhb!UB) z_Wda1^Ip#9BM`}Zzfy9)sha#r!TXbf&nHE%XR09&)T1tGXYSUU_gTgBv#RGC4cE_V z9=G+a@95iXHr{YXckUNW_b*!RpS4|gnC;zTw&%3*#+wF9uNkhqY_#Tr@%jruH71+S znruF4y6u4Zfn#Pn&zo#GX143F`QCk&hhO7VvkE*~nS zMYo4DZ1^Rz)AK{6G{eSU^QR~Na z`SU#r;CmdPa3^)urdWo%4;k)!;dvI!^E`y%-WQ%1p~BB%xn4zby@_IY`nl`qvCrE| zCfr#4Xy5g_hpxWZfAjH?+gt7&J%07pzQ>R5etG)$*SCLv|NQ^^_y7O@lF~{e6Dj@^ zbS_FwEJ;mKD9CR@Sj140SG`Dg@NM(!+%bZ6VH4ljpKLl#Qf0b zo~TjyY>TGxGOok*(tIWj4;FIDT4bKmNHj5UU}O`q=y{=V?A&qHW;US+1;^$N8LJsD z4koLgoa_9bO{HRjqRWiXH4#gHO*!ta?DSv2VnqT&!-^%Ip_wxuaRe%`39=+G2y$g# z@|-3oDP-c<*eRm!Hq&+K%S(%0YIJG}7BaDFhAsDMoV4X-kcw-b-js%mO0AmyQ~rJV za9C4V#U%RQ#2F8hSOtvc8hkZWV(FT!%^ZIqA<)@(scXZlIWL`_o^X(wQ}{t+i#wl$ gPEc3Ol!K4hCYi>qv5_n)OyH5Wu474*5MZzd0RKgqy#N3J diff --git a/smiley_pack/icons/fediverse/pleroma.gif b/smiley_pack/icons/fediverse/pleroma.gif index 7be5eca482992d966a37bd6cc8f7662fdcb48547..88b362395249c8b9aa41da0089e69a8ced223aeb 100644 GIT binary patch literal 180 zcmZ?wbhEHblwgoxc+AbfAfPNHrLr>5enYY2;Rg3}?VgXP1U#7<@O44x&&6TCmxN17 zDc5k^=nu8oXg+l)NhJq8DB}0h@IOn#C8d>sNbx5NBNqcZgAM}_fYdTD zYgTCK+}4`+Ol`_E+uoP!CQWagsL^&ka+&z4#8~e2@BiG)TY679=hU8HCI)K&0KXPh_z{vYttjwr$=r` zkKC9ZxhW%Rb4JwG%&2Xd(c814cVH)Y@h1x-7lS>6 z4g(N?Jj%ef=)n8}4;?8+kHwQDI!ZirP86Nw*qL@iI3bFqB<042R%@56Ll3Vt{0Vm8 zGcYkb9JfJE=I0v`1^EzTW$hvjw&-96wJKvnc_#K0=_+kG4iQz(7#_na6{T?D7zUN@ zM2Qr^r4h>)sV>!Dn8LSIlRL*=vC2@kHit#ONNL-4d$B})1>Pf04C;n*LfNOCM2v(k ZyRc}B-f)p!bJw0#y#3+RhxU#P)&Ml;m(&0N literal 0 HcmV?d00001 diff --git a/smiley_pack/icons/fediverse/writefreely.gif b/smiley_pack/icons/fediverse/writefreely.gif new file mode 100644 index 0000000000000000000000000000000000000000..baeb03b0ff7dc3b862c1d0492f49552a1ab2d3ba GIT binary patch literal 112 zcmZ?wbhEHblwgoxXkcWxcI}#^w36aKLFb~>#FEq$h4Rdj31pDc`A42%pq z3_t)<&cI~U)4%fcTmHp!w%j`1U}yb>tzzND*2SMIPjJrDoV`*-re4s<1XYv?#f-bCMl2!Fzk=-UY6Y6 zUiLQ0B|s4@Euey^u@%z}C>BPY&~!qPajZ!Z6seWzh|yNSA{A`4NNpem2K(K;BqXCV zPG;&~&CTtP@B6;@dGCF`@B8Myw=G&(G0mE9MG$0KC>W@M&m4GVXHA6nyRO7vgpb~~ zniYB#*McTBRg&WX)mxJQ1!-AAko2FGXkGTi?_}M)mgk*7tSZ^@Y2vZ7dtM{%{rL;Z z{Kh#w5BWW355|sovYri|>F$502VKQZ%e8K5q&9bSSi)Tw?wnJLF6lZmXYX&<`##Tl zFgLrppWnCh-uL?!{p{a;MB(-aUoPxhm)}qG+b8_0cWc+4rZb&|?_Zpho4=pg)~S5) z>Qjn(@apv3f`_Ia|HF)Fzn)uE5E2_t%O@`{&ADl5Y))3`yJlQoV#WFOpQYzsd^z>v<<Cir?&muWGYzNNhQ1RUXWK3npIo`$yFG7a*Q6;}-rGMY{kH48{`Y+=UO%b_RfOJNL%Qy^G@A3&&(D4=WM6eGJm|*^CKMBZ!P+`WarEA4y6{-KDX^B;9L?%qG$|3q8+?=0Ebo36|N2XEZG@9i^(H=gUhac$z%DcT0Fh`j=fE-l02 zS`i7ef~wd!QRRUxtt4U9AxMcYo#ccDprbs9$q6rZ`K4DdR2IG1a%Y5$B+Ed(9Bk7- zbz5bP(AFS$M9jC)T9RfVfC6+5O)K$4icNbl6PJbWhM2%mQ$=s^Vk;t1v`p0iO511~ ziI=D4W(r$qMN2eMVygm+2O;3di`DCTk|l_imKIx!!=`F6!tU{S2$CWw3Wpkasx_f= zX*`iCG$1k<0gw_jIjPHP0yQu>UTxC77zXFjq4<^|0Ckp1{4Ih$q+|y zIRw&0x^bt&?Z9c^;c*Y+rf|_EcwC}~k!Z?20%EBq!>Z)sBcn2)Lt->KqM0}bHX5;Esch}7-h=@Zc3tY zPM4s87YoaYru1#q8d(9=I%lwHcT)~GO*0fpQ63kSab#LA16m4JqJe2AZ4TNrH$Hu{gO+5LJSeB2|5j6!*-_P?F*C{xPW;UH&5+xZ4RgKO~(dVtX5PR7LVI9=m(jfsIVDUVmzI9+36U`)#6 z)%8E4%X<4b1rqRAPzyXP?RAvyg=gYh(Qr+9JGrbP87^9Vb^QB($iVS6?>-8T+!np6 zvKsM!^e+5s2eI%=DgwyXI|_nuFeMqRO(DpgxyEHdc6ZE%!pV9lQa<@o*7O-jUfqF{ zFF_F#3Y6Al^(i~+tO%KP^!xwZc**|Rp-SJYlOA8-|KY6JKgpwix`(;rIZN@0|2RLq i{>B&IYWQU^?$docXIk+7{;I_g0|}K^209n5+5BJDr0P5X literal 0 HcmV?d00001 diff --git a/smiley_pack/icons/noncommercial/invidious.gif b/smiley_pack/icons/noncommercial/invidious.gif new file mode 100644 index 0000000000000000000000000000000000000000..deb471fe9c741ce4e47fd93f20fa8aa4fb4dc9cb GIT binary patch literal 908 zcmdUu*-z2|9Ke5OhpUIuTIsZ-?u2<2Y8DI zc!45FJ3^ zqeDVMqNAgelaq6Eb4yE0Yierh>+74Fn_F61T3cHi8yjnDYbz@&i;9XeGcywt6NyA( zKtO*`s{QdnWCnpsOMR0KN^z`)n z{Jcmcij9rsa=9BD8xn~mK0cn!W|x8F;o*si2^x(?rBW*@DspmihK7bVH#fJp zw+jmkDHKXsSs9&9UszbEuCCVW^=9VJ{}-+P7~2!EXcE@nG6qk=Svoj5|3Iv+ZW`Q0 z^oT8T&A(9)qhE-jk%i+x6F1%H;cL%%f?_KBfw^6V<0YDxXR3cAs(FtVe6}zqTHp!R v!ZfSzCe~&q?ZTqBKQXpf#8=LgNB1{GHbj-6`pNIxN*e}!rPaak2J-1IzTnMy literal 0 HcmV?d00001 diff --git a/smiley_pack/icons/noncommercial/vivaldi.png b/smiley_pack/icons/noncommercial/vivaldi.png new file mode 100644 index 0000000000000000000000000000000000000000..17d09db33a04906c325e1c0c92390d3421698a81 GIT binary patch literal 4945 zcmeHLX;2f{77n0@5k^$p5H$wJaUpw$ByB=O!lp)}pt88oNjjk+n@Iyf1$ihBkimk{ zQDhl?D#$2`$S9(WinyR4sJIQdAmfNWm*9>I@@@hmzL~05R=xRWSEZM8zw_O5zI)EC zbf-#Y`#KPvi39?{!QW3b4_t?se|EOute3dgg3GbxfkF5@B!;BZYZaIZCE>9;l!O{F z1%Y5}R7;v1s_1s_m2209jae4vveQ3bbKz;4O=?SlpT}4iSQhrKVrkob&xxdlqAL-U zF;eN}-0;-!snX2Ru6Hi$imE1MY=Y|-MZOvv#dm0ls4Gaz^au#@sT|+&@=Qugi^ts7 zNatW@Mp6QHp(QjwyY3pzEp(*U@6-BST=po`EyhX#6DVy2QxJ$}OjMtxhZ5`_0}&QoBvdqvjp= z$=}}E

tUz4@6(-HKM-?YM+v!RW5v))NBHGnqf{$fzkMRxVsaU*oYW>*TDs*-i~@ zix0fdgT4- z^1J)CD1E+HDSqNkciV6{=!tZJdteLJQn)Q*gQ>o}NO!BHXu-pxo8PTM4sG4zX2^@M zpX4U(PwrD)xIJ;Q+ez%2A0zW$&vzuRy8JZl?hj|@Te+UGj*yJw#kUFD1)-%}_JavY z>!+F0)T_R?sa(AE%D%@YS(7G@@DFA4jEC)!;;>iiU-wYbo^A5@A}sXHKW7s z`fsv7n`s^RK|07N+^#)mQ&l#tGka>;E8gs}32x^n$Jw~JSP%L3+>+PEn8FpB&RbZ$ zsb74Qem6@|xCE4(5d)vO> znS{v&_FM_NEuH~7J3l*Mi>yNQ5+!|)hdkvHVViVUKre) z%``H}0>L8%dL@m)2OS|A(=T5sWu81kjY@2 z^f5lQPAu-B*BH800D91jh>pgf(rIcnt+$5(_l^c6-2wfjhanJjC~Y2U&_?NHsCP7~ z!CiY($YnkLx+uNMl8#(PLsh66Kn-A4#%ELd`imt!9%c!Ym|AD?0%CuL#4*Juu|A8< zJYq?wcObyMhxaq|$J{MofD(&gkyaLE4$ogCAe-lh1-~9GFd!S%I!tvuQA|=MuwWH067%{JRBK=DMc6@3QJ0dD3C&dP^2tW zLE*?yh{0kaY)DG)MKMQ@fvQAQy`wTy$pIB4=g=VrB&RTCY$gSwgA>A`a{)8tjwo0> zCYvRLbh5wn^M4wJ><@)&Felg$OkC(r^^Zvd5O=48;REXXoqUKSW61B6A)bqWY9c909~ zrAHB5s}Iy_RRXd(0Fv3WXIKo{Nsi!%2*FW6N@qeaoeMME1I=e1%wSBRGhuo!yjG4W zV*eM~+&mr>;j8W@#l7$-W*~yU^XOiSzjF!_>FXq4r0-X`zRLAQ3VadxYju5<>x&flBJkJh z`oGCV{Pa47YQVps81S<6s&DfR@S?%O%q4jHh+xu%>zuBk3&w?@^`*&{i&g4r-^+%Ar02uIq^q)-Rl+gyx||JGV;Gsl&MUEG8d;f zIa;x*9#w1}ZF+yN<{YK+!;K1c{_`hWxn;f;zPY3XtAc+fU65SixIxK>Pp4hmxTa&t zA&%)<@l@A^fT+n%ArE1nVcs_M&;}tRkpYG*SPjs zt^Hiz$nR3_KN00NSDZolb-a_j8_hOuo$Vva(vOziDZV*y)r-ZZf*WFbb69~=Jcjh- z@hM@+C{g3HVpGReir){-`-7cxh)FZTJ<9ABJa}wklnT;Q&py1DbiXn$sD5$Q@1>AwZX$9C8;95*|9 z3a8m#8aCa*VaDU64!2Pwju$UUnmKr*gFqZtwY&&QH{G7K-;l9X=#oFTVp_7N%5h}O z!LY3CNm&W062aREdG#La8y8;`zj}HmBx1PY+^k=pO-}XfBe$1kz42xL5m~!$Yq;Iz z+p$|3+uOyXHRIYEs*fCcrWGkfM24g5?SlitqV2=8@)xlC+#Bd}!a3c0pK!v2Lo4so zN3zLm^6C+rqv%%?_Z-DbtX;$nJBc|XXu!Z(n>EFFAY& zo1dI;_TYEh-(IrH{*hS7eEC3GyQO{22tVCPyFvP4rFT~4ov(Rw^gv2(pSK}AQPz>p zG4W&Gcp?8<&7o*FyDH(rgV#8=AC&#$}RFRb7n*z0qAXjYc7& zqQNmD8aGs2Mu`Z~W5xxSh!Kn%P7-HOQBX7yCz*gdZZWSKL_Enkb3AAAk3Ofi`@Z|V zd%t_%JN*{vlgGX0^A{h1K=7J2F>WGw`tnyFFK{1r=NSneM`or@;UG+WKE2i z%e66L#>E;10@p>ee)<5>@IFs&1gM35DqKN(GfSGvj>FRPJItfAg5G@Hul4gAB8zB| zr(w*R%=#HiLuE4mkC!;Hjio^z$-Ay!O-cNeI&eXA=9{QH^NRdsDUG#>Z4=Hn#I9&> zfHz+s^2wqFkw?oH_>G43f%vn*KWzX0(fmW#eC~+~;u?14wNQ;?<+BP?{*$!0?sSW& zT`9bjRE}otsr&5I>TSsG`A-_Z^E~MB@3yG}g5=W|2m~JUSdB)n)o7mQ0x~F_U93+0 zN*^%)o$3FG5A|{SW__(+cQHObDD%%B>xZB7sU%h%ygP6WJ|aZAWNv0n&4$|T1x357 z22{-zcZgbky0WEJGO}r9z_eo>S8hkv&$?l2o}K^YRA&2y5<%)24Et=$(o>)N)Vwvtb)d%E9i`P>tN4bi1()uf-*_pE6eabtE%pD}Oy z+)`zoF7sM6Y`^rtle+!acWy{eSZp$`SH^}dub%QVHCdk8!nTxe%2?iZcK;4rQ_GIY zKkm3ZI*;5}RvG44m(f2YjOr`#{JMPe+|aONY(pYiyz$PK!n||0imop^G07wNxG+OM zTs5aXszW_}w^DX<)clg@wjy)hVo}X|W&hgw-!{6@vQF?(`jzoNc4X?(?w8z67+3VB zM?vF}+U#*95AsjFk#=3Xvj2%`drvQBaW3 zf8@#cAGmVLXIY*#v1i-7=VaR}!j0wcgPwD-ptq*zk_g&rmXZc5#YkOd8)!O#AR@|T zBk4?r6H`n&Yf($u4tyyQvj(-~U6~Hi*)+@yHgTq%Ntv0PO3%!sRR&2^q)&v400d@+ zBgHPW$>JbfYKfbd0PnmRmWbUDE>kU;qSK2tRy!lcrMMJ<;$5s0lSKN6BkTqvF)=Qo zivoP9B{MkAM!;}RPL4DuTxzwa!>CH7f)NbHFbE(ZN3Mk zC_IsIShMXk6Ypd!TyRec1KsU!%eI@`=@@93F)?NUb%0sXm!=%2)#meE1k`Ur;Srf`1uKgm1Ye@=c`;s z$`zCWGT^iV!Wo4MqUdlXBtt1uj-d!;kTE@|v=#?PT4;u+0_0K_@Gx?Pks?teq(T@R z!es^&B2i2MVJIV~Ns=P5a6=D@ckC?aO48IbDxS&!s4!ek8xdLt;aE5W;YK44DKR4j z0VASN8I2T*Dcw{Cnn)p zNJ}~cc8{)heQsxerxg&R0;g0o1{n||3gHNaKooAkAtQ}axJqWgDU5Qf(9Q0!8o36P~-*Oi!z-C5%6y`iEsmYY%;*F z(*`y#uouGJn_-t`Al^Un*Hw!@atg7ycam4qw^y!Sxn4Jq`)hId%NrZ zCYR5P;}l~7|AKPBVQIL~eiR(Eyr{Rw#R&ohcEP5)Ij`3NOJ7^!REI#&&!4|M1ZzqI zfzg}O>f*gy`}lhKc{m?Nj|8Xb&Dyw_ROP94C5K=Q8CaY5;84Tg;}h>`{QD0gCTXq( z$Cf89tWA@x%DDN)h*8f9xHPgjnerQ25ED!J7GuR}zRM&beMjzHUeowPwb?g4BDdag z_VFc0fTv_OWt2}lsccTUfNfbR@G3rH8g1bHtkQ%0b2(> zRs_Abg}tksTGUb5&l&J==qH64Cl@;RO^w(`x81BfSJPVYEmD1ON6_Wn_g2*J`Ebz6 z@yyjBVcQn}llx_1IJQ2ow(6W%U_cX?33Hy>4|_LX>}V$Pgy_l-FWxu>4+9kxXycRP Js$$dT{t8o%qb&dc literal 0 HcmV?d00001 diff --git a/smiley_pack/icons/opensource/debian.png b/smiley_pack/icons/opensource/debian.png new file mode 100644 index 0000000000000000000000000000000000000000..b9b8a16b300e65fea37a1e065c2a1f2278083a4d GIT binary patch literal 5357 zcmV zaB^>EX>4U6ba`-PAZ2)IW&i+q+O3*va^yG;g#Ystdj!5g9*56}y}=%TKaeWh?Y7;$ z6KhXfRVo!l0*OQ>HD>+i-`o6)pICi1F-gfaXUk8loNBx%_WsX+_EpWa6y7&9?m@W!v;f<1rzy(s8E9~wtFf4#qFTS(`O3+eax8GSd? z*8zNc^(lUKJmEn!?f4j5)I3u5(w;z8##Bc9e_Fi{& zErO#O^RuYeQqC(b?1VF%uVsFPe~H&}ek;GlHap1LWU1ZQ&YS8y5#KJl>6+Vao#SwW zDMr7%aP)roaL$z=zWPDn4yrBLFNLd{o7pJxo_3`akIjmr{hZR7|fl_ ze)u(?PyEy0Uk2J+VeXtQH%`EUd3g;u)6mT6U#=n{Za*L6;7UmO@>ROz4hW`J_8UU?wy#73uM4%!0fWK;=MRW91Hnr%-o0QI~j1v zBtMy@k0E4|Q@q}r?}$6s`sD9v=!Hb2kSUTvf*Q$+F~v;16(H113Mrl-J!@1e(@ zdhXIoue}Z6GvY`i4;f|D(WakaLIGyxDYMKv+j0vit+>+4OIBHRwGGyG*m0+wx9qa( zZf{w0Puc#Gwa=ORIcx68nm>us>*PIaoECWv;gn92=8TN_=*YNe1^~3zoY~@H^qM)% znXNvU5Rzw>Ns}|3W{eER<$T)iEqCvk`!;We=>D&H^Iv7oXzKnSnKPQY51IQtZ(n3> zwnMk!BuJ}}n8J{O^5dfBOIuM!3d`5Nrrjx&HQQ{yi^NjVO(rc0L)c zN7Ji!y-rCkjj~JXj3i8rwfWi87%8t(x~WWoP_ot-0dY+%<~ZOKM|k)2@as!21U-rWw7-5nn(sciM^aU!?-ll)g+_6c@Ktj!gM2cdk#q0^9JRy;%%`0B zl-8$yg`$|e7#sBMwJU!@94oXPy@Wa;pA@D`%j?zK8Zwg3%ev_T!gpq@43MTY5J=*I z&y+qOENL}OA7c%1_AQ>uE6EiW?}}k=(nxiiF7&!>C&9h-g`8;u>*Wr@+6@vRV+xsm zYSD#_A=1v=9MnoX9G`>gCQ=8LQklX|^5OM-xq=wv2l-$Zyk7-)j zK2X8QjiEuc+jHOS!X=vePlAp89vXjlOlx-*ZT6fXw*a~`buUAx{aovE zw!0oG%-A!`1;#zx7|ViX!kh%84+7ShG)OZM^}tBVqmeE(Ll|=mu|2My_-3V^r>kqY zgRbsHg96N`sYSW$e87?n`AidH6BGo2U!xKBEJQ5c2eNDHm|0S7)N{(LNqN7xqJ_P6hO;gZwCxTMC&_`Li()K_k(&VM|Mw%H zCJ3++lc@kQRcJQ)xqV#_=-#do;9X#*X{aG-ryv34AraMKfO=`;$fATUObsfjdE3Q{ zy;kdbrR;prwY)Fp!pzSHX7j>qDIX0D9h5y-_1r`oN)psu_-bhL``AAZ?KB&kVXVLo zb5PfCz|2Mm_B$VJhnbamc1w4OOL_`D#qMYH32GXhzBtGNE2qQmnVS}11uACHfO?F) zIY7|j~4P@DvVusa+8+9Qv6Vqxdr%s1lt)h|!+o1u zg4;>_>CSzSt`;h-W~(vT9W0H-UtLEhvPM^*XhfT+-2Rz~`h=KU=fM(Gj9ZXO(@@k2-dGLEGO1V=nN|IC@Tif?jb1B^R!J0ulaX}H+73PzCdj%c z>LY^e07!eIyCD>Bv6dd~g~gbJ^C^8`0k4pwK=*`5T~U3xs0n2kGr3_YGA@l&*V`ng zeYo=;&06p9%TaNiBn8M4Vw(GMwPK@`?F=dnrG&a<-GfDl5T5FN#C-B!q6Tcx6rSK9 z;{g9cHU#pibx?VQK7@~E9IRm>#Sn3TSt>#T5sqd^kXItn@yT3x@?k$5E5r>a4?|f) zMl3s_cbH3$rJSpp&41l=(`t}E1wFzfBdX3aTI6Ay41{f|hzcf87%$z>vC@LVtrlm5 z8po+MYs%&7(oxkzgg5{NKvFYi8sb5kO{eYP7iy4U}zYOBX9F9ax{zXPE-Ox4)~&A-il&T>wfE6ovNZ>GJ2swS)p^^ zTdsWRS(^R!ND}(8hrvd{fz(5_>gW%#5jPrQA`_>K(eikGN&g)&IgbQ$}d9t(|M~} zxqV=<7IMG*hY>n@AT$t$ZBwa0uLD=my6#2LjA%#H`k3@PLBPTn_|sko%!;>m1)y3A z2N7V=>Ci3AhVL9R8AZUs(YAr;D4^$F)s{}FW0C1gVOYN8YCZpzu6hB80ukA}U z1bS)FdtkNG1?eJ4L)|9J)1;#fk<@avVQ9*-R1NVTvT{JBBDVXBi-N;F`}4ZPqA5P- znGx*HSEI_Y>2>D~y#^H^rr<#QT139)m5GCGb->pnxSB2W$b3){goUXYQk$b%*g8q% zKqH2ZTHjO#GOaOI*LuMw_l-3p>GbG~oQ7EoMzEA?cMRms(EH8yd?P6^3DxvivdfUmOKT;;Nyj)jPy_x;k}5yNnB<_oIP_OSesF%wY#C z+?knIcWXh3WYFDD@An=Est6*^r}l)6u15LD;R zxxMa8p!Cl5xpO>sMjaR05^W2Uo8Eojt5aF?U5lZ;%hdf9D3$qP=_~Y3M5v8350c@F zPXn=x%RUqC#S>##W!C#JLNqKRUQwj801&~o{1s$5-9NG&}Rw@a_poxUi& zmg{0mIn|^ts;S(DU#>!;MMJfKoD6FWk$FhvYm?}E<6TTXN|FM%x^2^2RcF+7FE3=> zPMFD{3UdGtuw-1cH0UU7O4{ninWMZ1<`qA!+eq6xoFD_ubg~$cxd5$gI+v;unG%qj ze)dK{JY`orC10%Wp+H7amhPxw^kF`g5=gSF`&*1Y@SMcUSKVac%2ALZ>RK%w3$&?s zPHDmrw@Ipzi1e9(bq~!Yh%&1=26mM zQ*VWkF4#yT%=W28(1irHlwHZbRamol zV1L=%=w{weVo}A<@z3}Qbxqe{UdileZKxAM5$TeV z3Gg5l;W16fXI};!5W&FFKcJ{|b9GKR6_=o4^g`-r&LI}2&j5$Fc-9{2mI(e3cCMA? zpxbE}u%l5T(r*NcKi=%nNp*h>{z-cO;MMsT<4q$>&#Y9AHp*@9kcTS+`7322Z#n#F4M5X5v>aX)okX^k1-|T@6OahEV`lR-8 z&l<9aHu2Vek0YBCTDZ72fhb>KI$gVTlQ`7erGZA*O$6tN5g1oS2w4D+Q;|Z#M!WLR zhZa#N$c~_ol}gLdRKZ+=ZhN9bg$9k^gQKYFr9RHSD%9w(`LER%9Kze$H6hDkEQ&tK zq%*@KyQ|#31L2_ecq9ZKa_!?G_v0Z|3+|K=QVnB*&Ovm#P_mlE6B%4fGy$DRA=B!; z>al&dS!G_MiFBSh>!yOwAUh6+;8t4%Ym)$&P1DEMj_+r>`h-Qvy-kR>CXmseeWi-+ z`drKMg{C$iKUbIYYL_FQcBxFQ)TR%&k9WtzqU?0fY+J-`n3Lv9A2Apv-l7bHZmjG# z!FzdV&WkI8qt7~2!$8h%qX;YDfbiiV8&4BipY~mIhM(b{zpb+(8$vQR#>Km!v zohGI{ln%}1 zi-080hKqH-XL0*|VugMiU)b_L9nCK%!tnA9;2ylG!@*nmt=lCuk)wfibI7b%b1X3q z%kM~%^>Mdu*KOVDUuaZF67NZ5e4sa+#!eq1+-JYT>E3bK%}hEfhArav9j$>zMfcO~ z-%zgB#X`vEr7)q{)mW^4Ds@`?8Z&d6A#5Eb9?%YJs>!Gx%IlGgtFz9wX&Z*4c10&0 zlAVE~R333tANfF$%!B?*ztQXNs5p-1Jfp(>j4Iy8sCAN~J_WS}7A{X6(@dznQ?&P? zk3NOLrdSO#oJq&s$OEE0t*XE*AZ;x=tZIIXK(VxBiK>)x%=G?4{!!{bf3T5OoMyWt z5Hi@)87S9ItIvNhE@;oFjuC*>VZNM z3VhbAN)_I~W971;Z=3yMT||8(LkjDB2zq{71AZ|QK(XVBh`M!edFOezjA>^G_7%>f zFNz*tP8yKk)Nt)luyCFVu=wLqd#1BNv7;2S4S&?7TVYzph(;PDP-)BJ75#!8m4g*& zY7z(s!WGH7bqkq#*VF@LeC;6`e; zyVXSM*x{OY$WF$a0W^Q<6v?#iEU1cC)R$@}OTj`Z=vBKQj{$0=^i$U7uw;egq5)oe zq-nqQNQ1n3_t_%_A=LuqKxdrusaF@$q>K!+NzU zi|A%(aIKiAPlh{;uQcv#jSkn3;MI;rhyv2OX;}KmYtQPfoaaQ)l&SoEyszwg*eEZow* zt^fc5glR)VP)S2WAW%|IMoCOX004NLeUUv#!$2IxUsI(b6+t_QI7FyU7DPoHwF*V3 z5Nd^19ZW9$f+h_~ii@M*T5#}VvFhOBtgC~oAP9bdI665gx=4xtOA0MwJUH&hyL*qj zcYshYGtKH42Q=L_Q;E2k$*zi_SA-y-4>K5+nPtpLQWC!7>mC8V-o<#9|G7U$kD9X> z5D*{h@IUz7t(Bjg@RGuDp!3CXK1P7hF3_ks&iAq7G){ov zGjOH1{FOQ|^GSNGrA3c`-fiIGx}_<5z~v4w@MOrQ>`FnJLOu_?pV2pEf&N>dd(G>u zxsTHaAWdB*Z-9eCV6;Hl>pt)9YVYmeGtK^f0Fcdcv-G10CIA2cHc(7dMF0Q*|NsBT z05<#Y^3_0S%Me5ApR@GO+3~;4*-&*~ERlHt z0004WQchC zaB^>EX>4U6ba`-PAZ2)IW&i+q+O3;wcI3Eng#Tj|UIOt3mV@Ux-hr3zFF;nQ)UBE6 zJGL|jemWiKJ%2l&_!)it zJ$~jLx*r1g{_B_cUE_J*e}&^7=yhA^mpDD|+xT<*PLw`pWZnD9?sG;n+IoF{eZ+6? zS@vG{-L;Sm;Y!a8|F#eto0`g2<1JM(|!?|i;1-{oqT!aupyZm!OYY8?^ZHrQ#K z-FBVd!w#kx+;W-U&JE|!d&Os0-5?Ft2YuV^vhmeVU&zNGbDp=|doK1|x9WOatZ?ON zInr4MvnR73-{#jh{_Xd-f%X>6t-Z=SR?N!@Ura-p(@%~fA$C78jVHd=+`q10zm!-{ z2IC2H;Rf5)?;(1$U)b^|&;E*rL&J5~i_P;HfDm!*$YiW116Q&>+GMZnT(*`t7V^`W zx%0twGGL>LZZb<3yiX*jI9;1_vOUMT= zaeU*A?z-=x$DVrbrPtmD@EKvmkwzY6)X}D!enJ6erkQ7%b+%;}P+DQdl~!J5)zvmw z+kS@~ciMTEU3YtD?aAu*to@p~zt5U|vgS^rbX@+*8gJ+P8p4WBqH;#YT(D$3D+2)9 zDQ8!)Avk4DIlHR!#{1})WmIyeRmR9*Sk}dD-?{tB++XI+5Z(VYZ|yQ8I?|UFW z2TAcEX`*HObDM3I%uP4HyKPhNbRxf!-@`SK;bI4JcBD|Ru*}-Eb8{V0;!7Jb`Wk(A zzBX@DowE|Kyh#OFXr#DLq7DM7sl0Y3FsYS1yIFCs)$$5@s}Gcp0zRf11PKM=v;xwx z0JLV6M^hftX1;AO?&4abS_Awjn-cR%+~Jiw$pyb8tuK4&R3;7h#Qemb93u*ochAD=!D?4iKm9z;6c;l}SrQ@cNvHP)hgbw32i3NUN{Xo9hIL&@#gu zcfLARzP$hq9c*L6IhaGr!3wF4C#WKi`xqVa1e!zc1Nb;@66~ySma;W*Qu&n67`sm5 zW`oP6DS&5A>5kxZ`n_#${`(<1;CyU!0H1G|sBkHgSlZ%V*0qufO?TI(|n$4|LN*~Gq(A&iU0Gw&7V#D^Hg_| z8TLoM0kip*aAmZL{Lke3KLmY$&fUBxpFd}CaQl7wlo)V?X!e0)MklVE4wyS&Hg7cV zU(j5hlIWi$ac2G$#Q}VU7a6|~^Xmov>E!aB!}lqe?-j)bxSceY+kmvwnpID{-ov_0 zA1@FB4Rv=pJG$l`-HlquGE(N=@6_5s5u`IU7dSwbyZl`mmNbN2L=w{CoRdlUC^I`K zt1R15wQvgaRP#YkB-=;slm63s3uWPhppjaaYhu@68?$x#! zNeWFl=oUDuepORPt z%hB-=Ff08EGU-JzGgnQ$(~kYx1x=P+LLbokYH^v^x1Q2i#|DkH2{Z@NMQC%gLaUoT zwg-)`n27FJ1PSTAEoI^snx{poqa(dj9ep|yig)Um*O=_&Zs7kukn6df&uX6+f<4zU z=~j()i5015jOAMV=bORv3mE*MfK~v>ejO z9fa5DUZVpc1PP~jo$@-Q-xr2h3q@_td-Zk9GpXN4tXvn*1Y(E`dC^-fEhH@sCT7iu zm#^tYtRd_I{I~KEVw)U^z($guvG?cLoi>QfyIcaX!3-1`UuaxSES-tv9SfHq74U)S zbt?cd$c}?lt%C3r$DkixnKMdV%oPC==(QRC8=8F}3dzq}>1#XJS?wSK$f||2y{T}fphH9|2P$kI=Q&F(LjrYMJ(r(l){a0WSQ0(xrI`X#m_8k?k| zb*N6jGFLJ%0rchY#RPcHi^|rb0W!Os2G$M{ryM4St3bus(Bm!D#~~?X#xf^4qv1lx zf3%1?oD|ro7yRx$Qbt-DmUY+B)YuS5H983zAi|9YirEc=n<2G?12vl32za>(r8=~K z)-o7;=&iI2x12_*0q#dt`)MFXTlRin*UDaDhK~|UG+g%Fl{H?o%HcIkaNDoCTdsG76#F2 z@`VUW_jVc&-gOsR!mbH^qly9l&PM!zU}bh4pLxZThjQs2VTxzyiCmoYfqm;rEH1|* z-zEQPLG*?$o!w;|boByqX9jLK%F|)7iFDZHaZk08bf$wy#?OL8pMM-wJm8ilh&O035HAs%=)OQ%>b6Rh zyHE#YGytru74jIO8|iqxTsr1=941J#O^Dn^%3JB0LFXx~TwG z*QGZ~U627U>t1m+01jN@K0h3ywZ{h<3{aTO)BFrv!qtfx2(b7 zeUNBE@D=Qoqf26DsW!_bffg3L2Zphe$)(BlXf(yS?8e|?wiu)s(QiT?g0Qv9Tt%qZ zM^0O@EIL_~@XiTt8+0=y&GL{J_?y&9uf!}sY?$l1TBQ$lf&})$KrfBpbJF4qK9AN5 zpXVyv9-iUUDUl=AC41=A65*9rI=l@}oaCmL(P@bwTF5#Gr+tsjJIT#bn!TFKFcMP6hL!f$5|T`N8q%?sT` zE1r}Au!6z_K!R+oV$%25^s7whdfqbkd;Q`{uzttJBUju@ujA7T#-5f-xTn&cwVZ@_ zt`+aE#a3-;6xtEugM`wn7xRt@c@}oEC?Se)Vy7folvFf(UlYNiWhwH;$pOiXg_@UO zY{V&yx+G6qs9F~~(9#+(?}eoG1l{`M&*rtHNAjRC)kK4d5+h+7n)4lFhAx`I-Mgli z40J2tMaXt?)GjvB?Y)Wx`Hd_D4ldEqN8}5ZK*-Z(`sjiNb;Yq|$MC=LJQ$5{ZFT?G~Fy>b0J^^)ns+ z%*}jF?uWU3#NaCgquxuM?dYjj49ssqcwflV{2Aj}f=hRE{{5crTbkx|8>pR+tCjif zuH17itqGjdzRvQ`rOk8g{qwc#k0MyK9sWK%7FZ#)ZaMd7_ED5}#2B4W>a9K?VM zd5&;8!kj~>{j++JUfczQn&ON*hR*QO=~bijUuM*T`ulKgz7VgFqk@QLOVEvauy54Gqt z`lNPtwl*=OjTh|{t#U*Ah-NFjgbc2yEzsAPFz2+0B%rdH!WFcygT_6L9HVI0Dz~(} ztX6E~aX_)w6m$2-boXdDCa&Dqbz4vR(3F_d&l|QE6Gi(wjL(H>tXfaBqzf>d3$>7G zD8bx%?be@|MrXBsqRvL~uLbE%j&*QbiUrY&R?_y&v%XN%fEH{{w4)g-c;7M6VIpuG z*2*AZP}Rn$)t*Bc>7pGWyzy%=5OJ$aSA0U^wXGJ=N4;6ZA%( zjw6{`0?p~{>cs4{TmkfgU5S24FkSB08Z9!?ZoEPNT@HIv;e6fLYZX?~776N8Sm8v3-tyK7|l_1$tbRLs% zav-|#;!XWiaDhZ1ryDx8{AW-#e~s1u z465cYv3j=Cv}OHQV7{({@0)#H+GOfn?opOaYnyvwa= z&lyiMw19s0YY^f$mK=S#d!zu!O|L<;KEa)1EK$DOT7+ryEk;ABS$M9^T_?U!Ml#a+ zmZ*@nYB4jn4dXgmS?O9Ix+10+-#ainV@l;#V=J~W4YZ-n3In;hp`cA>tu=*YTZF;= zbOny~_yIky6`zKFiL3E~rrOJSPZf03v9`21sGa}958D?AcG*}*eXOd!^z3RdBS_Vs zm8GOsC%3)sy?m<`k20H--R+$5?Agk<6jaL!cV>vd%hO(8$U7bM19`vT4lvv#dBg4- z=*)N2Y5nT2aF=M~`31WhbPwdXr)7}iSCTrMw<`Ru4lmT9ML}}EOj1fRN#E)@fL}<` zSUoTBkYwqIspu`x=m{xBkdVfJ`Pnr$C#=mXhxu7G^A7^hHPLDxBzj46 zoJm8cEv?SE0$3~)wTHG6sumRu2}3mi!xuewFy#~{t<9gc%hck)_xEr=myypzPvbk! zt`z7_Xft|NrCcy^jiS!DWQFa$$B%xRB@?F)Ae4%kO+Fyf9@dY0k{^eXSwZ#|!I%||VMvD%x{ z#5rI1ye>3k{^G?B%CI!)An>eO(`~I*|E*->I*XRTaEG$BiLA9z)fgSuEY*(Hir-VL zK0;Ff0#r-ljBv9~#Da8H)KHqMN5G%D9HmvNa&lb#kVA2&!S9V)*33- zWf$fY0sAik{$(9tl;RfsHjm5SSgWrClv?T-TQ=$=c}EV8@i0-XB*Yk*F@s<(}fW@jM?qQwe>cbH>vu zD{#n1eQPH=o7aX|AoHJW2?^oG2nl`{ZfH=hwu*=}Z2J^wbfu9;yEBtV6_ z<~lod*p)ihfCod@Dhz{fM@vl0a7y8TFZ*JicWv%a}yn=D~@%fpW{a+ehQ;__S>8Cl@^oM=9agvWPFe zw(r3vkd4k;;E*Ss_7baME@uu=Pcu0%rhR!De~7)mH!+n%uZF``r+ zg>sfywBe0+Mrei}@HYx7*c(RC)4t=mAw7F~Zsfil5*Dy9L)BO0kcq(k6Pflt;SQIv zcZeb(&72d!2&FZZ*7}=i82z<7Ho`7iBm-9=XyMRIYMLA);Ub|#`8e;$sGcz#0#9CqL_6}lj%RzPJt{wiXL&4JX(O0Ui6 zrC|BARYy~a@{y<=!Y18zn)kRL+S67ZQ#{+zpP!kJ55W+Y>%HoEX07KcV2}IB!so%lpT@jLWIXc>_-!=k;VTAzG@kwi z%WsqXcXKqqPx9Z*(fmmu|74ElPXhTTb2NVv$Um8*`FF|weU9eeCHp@FWW68j^sgr` zH+rwZJ19Negr&ict4JMF8s-$v-bp)|dJLEg-+h#>nf0)s!;{ftYr`SIR#SVEHLDnD z?pgpEG8@&r*0P75R%vjH)U40?*9iLe1>+X4Gud=Ag5|IyzO;Seeb6&7E=Njabmw8n z;NX!sCFIU(1a|A9+zAmG`ClZE8Y?$y*R%it0fcEoLr_UWLm*I6Pew^hMF0SJoPCi! zNW(xJ#a~mUA{7TKND;|Uoh*ooIBFG&P$AR`tvZ-o`XMxFNK#xJ1=oUuAB$B77iV1^ zTm?b!1H{qENzp}0{9jUN5#zyeKi=JY+`R*YdYNff#~7gLwwX>Q#B6Rw480-*0sV+# zNM@EXD@iH%j<0(J_<9%TS^nq#96f5@Vn9G7o?(V*6R#6bZQ2Isec}i!$tv+V@u*1` zB!1+&;_(~jqRRr$jF_499C3tLEVi-I#;jy&#FNA^RnsY7$a<`D-r}s4tE_oX{=#rx zUtZ!m%|RrwfJI0Up`eNllwl)It4@lAH0>vR{8860kxL=h1{gW!QGo{8^@IPx?{2Na z#JHCfP5_-Rj`J}Lgm!^O&2heu9j9>u1fPK`z2&def$2}uYb`By1oUnL7uPLK*#j;QfrgDF^i30^O@#Z_Rz2J^&f&Ds=-K90DUn%3kw%cUOCF|DI{~ z_X9=ua+S@G43q!>00v@9M??S_02=@zQJ_Ql00009a7bBm001{#001{#0U3ZsT>t<8 z2XskIMF-{w0u>rL;U!h<000C2Nkl|H!JrRPJw`cb+`Zv!_jM=-?mgjdnhdx;NsR;o9Q>Tx098s|t>>S$J_RbOi{I=a~&l*;w zi-=NzZX}QfauB3M6#7KJU!J-C{nx98u3fx3Yq~Dn{_*~7_ZP{t1$}Khp@0Z0OB>Kp zA3Av%ZA1+OQUUcBcM-9O)A9!>LA2=p7uTP?bvQrkx}X96&QBtGK@}wn@#qlyI)CM@ z{?qiE-!!DBYVCZ+!M+O|?7d7YA64R!%Bie-A1D!&Q&LQe(49PhVJoEyc_-QQjRA?uX zFGa^Wxviey-UDwq9~xbaI}`!&ef(UOFu#ll=tKe|y&7d%)iu>kbR~2+418QygdjK92#!b*tEtFkz*+_2@*>{!6tPWPh(4boJog zy-R#xYfT+^)Ety#mafS25K*XDoN!?gtF4X1GlL|a9z>^7xDyj7Cx$2?^t^|HHz<%g z1yLA+WrBd+(N*1q0wetter|!t_feLOgdxiMFM@^|C~XjVJ_5MoqhMM%?VX4~kjsH- zpiGm{^RTt?cr~aSD9c7f2nz*_)-||eWBA!zQE3?B^!5?DE(j>wehh+|DwoOZjUBl6 z#){*RI7#r2z<+m+)t1 zu-n@)lBvfdAoL>97LCndq+5w4S_pDkys1nvmP``gJW!eBCJX(jiNKh;b|zRo@IHpq zR?DJFm%SEX>4Tx04R}tkv&MmKpe$iQ>7vmK|6>zWT>4ih>D1lR-p(LLaorMgUO{ILX(Ch z#l=x@EjakGSaoo5*44pP5ClI!9G#pLU8KbSC509-9vt`M-Mz=%J3y$HnPzp20-A1{ z>10C8=2pbeD?$*^hiSxQW*M`Rl!EX0x<`PocX6KOf9}uGqvkCJ1VrK)W|%hdI`QPD zZE)TvjTnMuzPM~KB@8!K(hN~T6UK^#>zo$`gO z$13M7&RV(3n)l={4CnRbC9cyPLJ|vDgai=^s@OmoHsZAEq*zGPe!|B;==vpcDdgG! zBgZ@{&>*{h@IUz7tyLHw^OC{|p!3CXK8AtNF3_ks&iAq7G){ovGjOH1{FOQ|^+|fI zrA3c`-fiIGx}_<5z~v4w@MOrQ>`FnJLZJY>pV2qvfc{&cd)4c$xsTHaAVXcHZh(VB zAXcR8HJ^8PwfFY#nPz`KqC9fCbNJtD00006VoOIv02u%q03uPKL-_yz010qNS#tmY z4c7nw4c7reD4Tcy000McNliru<_7{2I{-KE-hu!C1AR$EK~zY`rIt->R8auk624HBK-GiWfF597F_f1(8VT;*&E|%BDpqO46G^`A`Grt-52WHr zV5boYpD7^7W!?weSq%K${q2Ohp2XvE=lP?v3v7Dr8?1>4a$z;zg%3Eb8BxC8#x ziIeO-_~nw$zIqhjJvNE29&7AR9S8yM3y=N+3L*kDmLiz%KZ>S#8UK5l%^e2{_LYWh z2(=2#4CZhzz?6_8peTs@Zv~#UB%0<0AQrp2a*&ar9YGK7jm!oZP1FDnB8Xt;(3%ERlp50DsOMOAMwKdh$)>H$~(%eM< zNQUs>oDDuX1j*}p>MD8QfhMO(7e=p;$(kjliN>yTZgdVAk6~WwN6ydO9CBHxdhjQp z&9&tLaNEULSI3dDG03I?*y^w3*Y6Gk@Z0Z$v_0QlZhPKx1BmMN4!E43LQaq5MV*~U z+;0DWuqEaP=yMXRh#x*t6B|eE(yl%O!Z*82lKUAhjfcSbJANSR z&iC+Nm&yU}%UJObooOoLSCHux!n+D_$2y+d^$`Bmi%2Qi`DiO`t@hiKSWI%{v(uFE z!aZXRAIBj8kW<5mjrY;nRLkK59k`Tysj{ZYkq^FLXlAh#_$08$h=j+Sdz)iKCaz&! zK97}2A#WN!bJrF))E(yFCud55_X69ENcenSOI1DC4t%@Z8En^ixXm806O%FC{OA-` z@qsr0yi=*1{d{g9vhrVrss|qdUIP4OG%x{-0~dksvsE>Jn0@aR4gMEL{WirBuQU4q O0000X1^@s6D=Y3@001ZCdQ@0+Qek%> zaB^>EX>4U6ba`-PAZ2)IW&i+q+O3>vlH@oNo&Vz$IsyR4dK|1~x`B?b?}1T0J+0Ad zs_L%Hh-8o;-2E*MFx~lY|Mj~6!k->{aw*qVdMTbisiz(X-!%XI`Mw69-oM|AKR*lq z{=N(S_k+k=##j4Zmh(G)@P7W+2WtAgKmYxGSJ&@6?RTQz5B{9cbmho5`!~qni7bBa zhu>@0{xu!$o7vw1W;ZrtGT^E<`N;a|CBFV5z(4dI@#^PQVm#?aW|;5dmL< zr0yby?Ng|cY`Xb`NF zaw^nYBZY>`mQ&8TumsP28?Cb zORv54-pAmgBMr_qIDYWPjMHYCd6rpcn|+Q&`mD6_Dyy!x`WicK+dzQZW!K$y-{XWs zDxGxlDW{%x`Wcs8yLQvfx7>Q$?RWeYweTz3e~a2bBlo|KTKGjRzCh`?`md<*cCCL- z5dnT=M=jCACYqk-QObjKgR7pL~V};xAp?0Dr8PUNTd8X;It9j5HI~7f8BhP zvnFb5xRV)nUZdRBZ!IUU9{S>@cj8vYIrSdOYX`fhE;1lS{sA_39l6;WXO?*Uam;n; zF`Yd&Y0{2g%(JEGw`Jc)tuu3Hw^dtiv_X`TR>wtff(H(;iZ+>moMT^g-X zN8M@c5<2hf9abkjr@zEGbmtSqaNC$+Y$m3H7ANOOEPE`3DBbQ)=$lHc+-&M+9wJj} z_X>4jF7E9_Z7wc-#f5toA{)q=wYkAK>V@4eV8;=$5DsqjOzzc_T2-^i@D{UcHy*bS z7fXaRG18f{%C02%rG;BfmAW~hKxN<*X zFiCp`jdMeAyVjBe;RqRw?3{oZV&Zzg1Ur>|*PY3APTqSsx8!x8Eq`)qB#}QiA4or+ zCAmU|??ENheN(MuOr4vW=JJI~B?wNz8QqqDGX=Pi6@B*is?Bk!(s@%}^LK;S>Lfpb zigD|#+(jvOhU03^!*4>Fj=H`#p+Dpq!Tqg5DmpV!&b;rzvh=N}Z@<*ozFe(p^QLI}lpJFR!fjNDGH=ZFM?5*^q_cN6x0 z8xv;WBd8M^M@^R|Si>EZSSXah&8)qlMy7Ux6&)ftr1u)D)HvWJ3TxMF5Da|20W4E7 z26z1iSJ9tn+(9PXGfwThfvVgenK{}ytJjc;*6k@%24wdY_7^gArQLwj<&-F!p`{i0 zwvcsaG9&(jU{Hx{CoBi9f(g26vhaOn3L;3zM8uFmXD2#LyiZa-FpqvDJ~Klh03^Ac zt=kpU5CwqS101B|P|iRjAKc90_U*acJeyI*Z8pSwxCHy^LlayBph^hf7YzE!Q}4r> zzze|KbC~c@YA#S)G64 zq&c5$#$e&*3Gir8k)m2FVbbn}Ox9#52buxgkH|EW%4h_@wIN1#T_N6S8D)?;Ykvvf zp#GKHQF_5+T!7qa>*6-P%-yk%&u~N7f+Ka%FDDx$tT{ z?Jg#79uyn4nX*O2G|qjtP3q_X{<-wLVOOF~rIyO!z&)m7G9wn|P}xE$xyDMlCfB%j zVzN47p_muglKT+FN`*t$r(#Cx+Vc!?4V6H@Ub|j05}&kY^+3L z0tL!uC*cU_W(rg!Jf-J7q7QzR;OV&me6rTst zYL5Wx>D-8Ni;5sfuT001HlLiPfOk4kOnDFtxT-DG_N7qe6&U)9M_qh|3hqn}qc}`r zX$ud49Lf=GypGbipdq;}R6W`RLB?ecBPI!{tXYCU@JK5GLc|Z~nNP_Hn%-Bu!pJ(v zan!^N2v!36ApY|(sna>RHbsNz1SM}62&0CwfJ~UxEsQ^oEQc?X!54U!5jf$1*ajh_ ztSt;!Ei}OTAPR98C`?kclcb<6`HEAJgYfP#eXdj&Gx>(iK%7Ar##O&DPbo;3 zOUx>+q;fn!2c-lvJ{Jbpaa(bhL&3BSR|gVK_AI~l9eKnTbT!oxR36OZrSd1GdDg4* z4D81_I)t(;7t{?B$8XpWVFfPDi9c%IF@S)4f!o%kZoprn+D{Vp!_Sd|oU&F>4#&vK zAnh}WNqL5|OTqwBTg@TVD8XoOG2uD5L$n6>aFcZBSqEuR`)sH%wIU!5we=|79W|-3 zqlXVfO^FCQ37N>fdez^I#5NcwLWra2j({*J^PjOeI9PrTO$O#R=7}^Jjm+*vTD%5) z40ofFkCS+FK$TV#TVM1fVj8<5lDk#W351H7xJs9BJuK3DwJUtWd^{jQwl3eQl;38c z`o0P(aJN}NkI+MA4sI^tt*CX#w7VSEVAP1#BD8MQz^oWdbRXFu%R?C~nH&q{;en9@ zpynO#mB)}$VH1KJs6@nS?ob`tb(OXV7j!DfsCOBf`2=!zQjaR4C^m7) zjuYqAipP(GXI_{)5Jjo=#GnBQ83mBOGeirJFC6$PTr9DPQ}YXW>W&JgaF7x;N{-IN znAJgu=zHdnw3iX0bY!eBxs7~Vp@4^Ngw(;&saQ3asYC-k_kzu%7z4GHk#PqX04qf5 z0CY!#Vo@x}dvC5%^l>Rl3#$Dw9BB_gBMX+qr6}o+B|={}O+aY%^8-=TIr!ZwIu>1; zDCm>PqCm-V`)EkYRRLh)a1&Qv6ToYUU_XUMIxuQeA2MtDM-qJg0nb75^MAYUqV)(d z)Az`Wd>n9m$3+k9Y$oDJd@u{wP^^0Oaumx54KlmH92zO2Wbqoh(HR0xcPAgK!x&yri&<0Qq9z(5|gZ*He{w4^{hYf#KqnkAv!a*?pZ!RGZS7 z1VkF3fAEBGBO%?z3uP*o`Dz^J1O;(5YictMEecSL8@tn}m|PiICtFp#eXEdxk(aA7pY@WiBwI$m2?>eCiGV&}dU(dMgh=7cRLV3|r zaerd(^`&%?g_t}SJy!893s(#&9ubkOeacJ-C{rEhebsyMe^JHDVAX~iRHLDi&`AZT2k0s6jp+f@ zg|A6DLfV#jvWuN~hD81Frt~0saWJH;ezkNHcV1unwDg}yOiXTpo2G1BlJSFjQEZ*L z#3-n{L&x9A00>TyO=X$kW2u%~fp&7piZszYO@}`NIT_i{~_S(rBTXr#7k*1O<5Ugw;!m;BpW?6cR|CNDZ<_G7r>* z;7R3-*ix6G`qYuC@UlZKUMauN__W_k5(qB@0e~F{d7A@$W~y#aJyFqPkScp%EkeaQ zpX$(=YSNcTSw}8NlvL|SKhEcGZvvjG`bxRs?JMXDvUE;dUx7Q`&cEs&cq_G5K!QXJ z+J;RKFl0Qe_Lk;ekEY6mQIwr5sEO*rSXskmYpDZa296K-y-NV8;Tw_TYG0%RS zzaE5}y4{%~!Qc?E$;PuFB!)?0gOgK@mi2Cp;CHD_)CV)l*nw*`^+I9*1xho-kou;> zbKj`K1!>G-i^~J&@vsU@7es4)Mh!12$w9HMAt^9NwxFAW9Z_!u$wik&5lnJ%osz zAkOa$@`v+DE}NKvv8&Q7NW7y0+~=z&!c@u;VTC7TMv*nO9z#JsMMY?4=a~H5C}m5< zcIY#z19KP&LW_yROUb&!RUk92MSYa68>h%gj)L^L(j;VBU{2x=b_%Qob7_eRtq8CI zI5NMV>78=nV9441D*=Y>KWzdtU^FPRq9T_r$7mDdhGoutituxDf^j&T$ygcPQU2%- z|L-qRfEjs+eG3W&_6S1Ek_Ye_X`(89;DiBg99M?4%1?ZNFb|sk!+YFbVN4$~x&9Xz z$uX1mpALBdh7Cb=pizeY*Q%s>wdeMF4F|2GD4me+lRVP$B(*<3SP1p1&9g>nsbWWW zBj9qjvw}=qov?#tUYAf?NTeHl#2tyMxtAjx-xSqW>IsR|IpIV^MN3BC>YfK3g_!s) zh=Y2%+z|35p31sshAcvrOw>B-F74w2@a}I!GpADFQ8UURKK;4c*-L&5#f7M=Ng!BaHng zmZTKk1Y`!5W=?2IwF>|saBFCtM@9wZZUSa}KdCNT$6zEqiSI31)&)SSDtTp1$f-pj zv{2kAT4IU=$Zw%mODR;I6LkA`*I=qv!JxDl)CCz*U8r{8kQ&q^8k4y1dM=2uGK*jn ziUs_v4j|HE9#>i6C*I}o(7>j}RFtVFuMj}cKvT0_=Hmheg2!{kMYu6p2sN!{jmP(p zaJsM`hc)olCfv)Y2-36=0iL^K$k(4A?)4e-s6Bp2>=q!-9*N&UxS z#0)dnOneA)f2&fc8LC`nph`O7-=Z{&QM}?EFL#0ijh4b2G ztvdA3(h}p`6NjeWqn29GxF})0Dea5L$J(XinT}J}IHtwEAuEkE9UTZKkA~XeR2AF` zL-09d7Dc=iDY2-!LRAVI)>~~;^+0wM^`g<%ip(mqhw7h#Mi54Qr^H9P+>Px2Y}hA1 z=2Qa=b^j5BpzpL;W}J(umhUUNtix_5NtTANqbxCVV_9I@2Z}D92dGi&I8k)TWJ%*7 za4vddcWl*%Q29cmD*+KnWE%`@ha zqyq*sX`%2}NJgt%k(4=N$P*;OO}$iYe1YOp;w!gyFy+X$F!^ji`sDVjOCV_m{v0tW zgAH0e)vf~yJQ6R^o{Agw!0y>mron(!b?)n@_UnMU4iW|2kCiij*zxo}w~=M0kxoOt zpv@GBUN6q$og`G{;ES5Q=)DGltSUv(F^7TZwK1Dut$20a#q8R4@iw23!Qc9tx~oaP zxS9H(!15KyEZ_&i$K@m`ChTE*f*!{Pyixk(FW#mD6hH#tFGI|6$OV8hJlB5_lLc87 z!7kDc`-!PR;f1cQVK^%HOt_d3aNN`@HUxWaFX`k+QfxVC?Rsurr>aFes;y`V zl+uNVyS9pARG0>wFV(-M)1{$NUY2hK`+~fPO|3zbaaq2f*%(YA^2@X-NQ4Oup$E+W z&Jz|VqDaw{Ak|x(m$KaIKy=w?Z~#OcKes4ztu`8lM};t;UBunhHYlq9q<(^CrseL( zYNksZ<^l^!7)b&!_DHH7LN$8RCLe9?)Xb%<1t=}@LPt2s5newTNNg?1PBZfzldw#! z2FRbpp_;*5LM+~^uls=;Js?}0B}aTejEQ8xpz7ETaN-3b3Ok1B8Qxn3_C_`0iszZFr0J)OT~)iOYr~wJ9b>+_ zxqdO}8NMgId{C>1ve@~e-Ovc(or*kss}8ua7=uH#kV;Ku3u7rSgc)9Yjgdyk!6igT zPa%zlHVn?U2?uT%N3xc()8gfIPi{kY0-Hio*F~Wq4`nFr4Gj@Do@Cbg!}_g^j<-?D zm{e}n;Ar>Z1{zlcpM}}Tg%!1#OI<)<$j7QxMyac=1xUinOeY3zzzfbsItf#wt5VI{ zBd5)Hkk(*YsdJ$hp&611z=#CFUospn1y3=4+DsU!Ol_|C1UCXWgDxGv(0)=pQyAE5 zvA&7w<_;OEvg(<4Zcuw6m6pisTij>9ZINMGi)h?|X@wvDXP!E`K>@hcKHEbgjiP-9 zZwc17sjeCP(?8$8I_$8u+(R{B0)U|derWdfbE&LCrP}MCf@KYeo#2Z$o)K(R;dZ#9 ziCo3w7Yb-SC;%EB0BAvTqhntSigF$@?K;;-n%a6mI<#f0G{;?f%nF5#1}V*#9x8Gj z>m4Ju^lIN-rFy1yjNQ=- z1df~laBG5Qi-u3xi_cE!4-lOe5M`B)07ebkOvR8~9Ge)?O2mYesIh}}=q(Zsy<8D} zYfw7_KrRdJb_rX-nYbey6pGL*-G&zXL9AE6w&G`?L49rWG4=02hyzKIY6;FjnmDA| zo4oQgB|eHO=u;h&`J9iM!D_xDPWTkO2jBri_0`lxAQpJJ#OPq*l(ZX&GQ&wT$~>6P z8PJVinIQaL)3rCrlcA;PB%G^Fa^hLJ_#51eq)di=tVAcnQX1Zht-B9JyH zO`*=gd%_~E5=JV7!+zzyu-#?K>}miu6n?L zsYB^%D`;-s9J(LRsr6rN@rXD>`H=h4K5E-3x|neVXo#t#f&elk4|YS1W*j=1rzVoT z2)y*W5^Ck(q`|=r=f6#;Yk_7eX*aaCDILK&%3a-7?dcX0 z&qzLvO-x(o=8u+~F+Fo@F_y&A#xp8zQ9`2nR< zFB9Q$C`hf9D}g{GaDL;ZnG7D7?ToC&K3{=rbz6JDm42@kR2~Yez1p<> z23Ck0ftl8FX$?(07tcN5>JX2kfcw+ZOj>ZEoBFZ_0m7ofC{U(YB3 zwRqr`uyLp>ZNSm)=}IwDV+cD)K@Ftt017R;Y9}tVbR|1sv@;Q1iiS3!9waSw-?fe^ zBMm2+x8go>`JIRU=Kun-c;@ z(3l+TZHOk5^dWROd-Xc-Ft9k@9@IOdolL}M(xW98fBNkkZ^6BNG=-@jTZy8b&tP@f z^2>mNmdUj6fd!MidPrM>_7Q?H7(U>v20b~0@81iuf)cWld{av2Z6wgv9_pPsBAygb zYFJs)aRT3)!~l7;tJl_f>-kO;s}*Iuv-VQVm`g|VGVY>$)^5r0HWVIh3VY2Vxxs?O zQs*ZrdQ?wwAO*THlD_g$8QEeJcs<;3lg$f}yP4W}w31fCp+K^fOsa2lHUyv!Yt61` z>opFXh-x9P9GohL-0#{68)Ia=oCP{$zGqZ~bY0s>dX+emAT#y+i*_xLLyRg*lat3o zqBJoS-T@=9eK2xatN*0Ps!-%%~pdDiMQTFSJ?S__r0GY6#T#R^E9 zRk_tNpFBEx0EiicBD2=o7wW=Y>GQjw0Iluzvkd7&tpR9yTMF~FoU}zCq2x6!TJ&vr z-`ogdg0jHlZ!r^rs%ObiBic4B#>?-lV=)Xt!@gP_hPmKh0*jLixSfVgQY)07RQGM+ zG*rHtb{O?1M81ortBWdTT{|ws8w-6J&Trp+)QY86cb58)N{a~LG1q$PI^=xU`D=cv zhd#AVgBOkotmIwl5{iE(nOZ4947CFuF@Yu_?_>V3@V#|ksJpeMRktSCDC%JB$3^PT zZLNXXFCV)@wea7|1zw`U6??1_-r;pxyIS#Ytv*9eT4JHbbI0CsC#@-Ok`y^CvLBqG zD^dq(A!&(Hl%RjB+-he~#2Jai>6I8Mpf8aCAw<(oL5q3<%k`n{Bn=IOcFdt@eF=lr z`VVJ-nF1GwZ$;pPZyZy z?fE(v@)}nTX$KdvoJ?#Xpaca4k+k!B>gkM%kU|wF>~BCug5g8El(-W_CmIO{E%8o< zqZfonf1diFyueNjA#NV*^OGrI;tc^9;2Jmzy31A}2WunnG|6xyG@%>L~HpV}->LKf~oHZ{f7ik4!^Pu*#|*|$IoBXJuo znwp6otromYXUh2RmjL-X?FQHGve^;$+JT~WRX}8*lMfiW<8y}gmKH{O8?E*9-ZbeI z)TVaf0swA*sukJMMQZ0AU*CrI&6M`|_5ka6q*x-u=eVzVraAd8q~(0($XD$h1q?tu zDk4TCG6>1tZ;V<*b=7wzJZ4jWVX5yF-jP7Y=LfFa*^Hj?ONRGw)XdEFHDzGtB6>zj8q2*v{h2iD1{*j8VyY+nCUych<>hV76;Pr%D|% zw_RIARoPL`O~s)nA+*6Aocgw-SID5Z?|c1<2W`+@c*HK@;|*u2XPQfYg*i?2SogOR zp{qMcDT@)rgr*0~0D#XGuHwSm3a2M(wT)%t{8k|7c#x%F@+(3&xm?6VQ7-(&X5G-s&95g-EO@+IF z2^D?d51UwX@!16of^A1>pc*$l&t_2@%G5hi8LAzo=dj@`?R@vuJyr$RwRCFQo;kHo zlKfG>M1mpfA^)WXTdnx1Z3`~9juMo7K>m|j*@`0|SuF%STYP1|pOxqvxz)Y8JXp)$ zg=Unzkxk0$UkBm^*Pbrb^@GSLL6j=Wo@PVXnj3E0C{|82CC(QW=I}?s~b^QQsGZA!+EN zysMr;ep|W~FYV6Mvk`J5nT!bX@ZcEEiaVklqaH*j&6nc~&ZE4wdF-X0RY-bL=?O6S z{?|&8nK-5{7z$@SweT&)ppw1?-z7w8+P%vynmW)|%_MOf?$q?S1@;UhHP!f!Hqkf- z0v2Qm_Yi*C9Fd)#HTvH^tQ@p!7wkl)1Djgp0-(s-7^;4E4UpHIr?{T_2RtA@?UJHS zehUTa+9PxH03KPehdP|88rmJd3}bmp8o)U?c~mW0CTqiC(C=#?H$i;;=98=qtJran zL9y2I%K4tpD*xm2SvNU~?2-|NiH^vzowXd;wNo3ju#xj zgYk5WuIg#$eY$KA@|C-hfq-H^N`|Gi_f(5i`i(Bd;GR~vzoeQ@LeN;X>Bkv9gsO#R zzwIkhviOzNmwvqns^lW&wHgV-W&)@ksM;3f-ytEwPRm z(UK~_!RQw+XurkHT}?8m9-Bp7@o_3lJ5;=$u);@pv>+VspL|T(Fs#$U5;bBG#*ffa z`&YiXFX71fPMZIBS_M#xDsgmR0004mX+uL$Nkc;*P*P7uNlZlm0C=2zkv&MmKpe$i zQzar5K|6>zWT@g`K~%(1t5Adrp;l; zqmz@Oi-Ag$MzC7=@@X+nkf- z1boNWJpz2ai}Ec0bAOH=Eo(C%AQ8_p)2a|}5KnJbOwRknVOCHy;&b9Li!Mm~$aU4@ zH_myN1)dqUQptJZFtLLp{%j8%ypVW zh+`2;kRd@u6-AU#L6la56dOs}kNNlqUB65&m0U$Iax9<>9g6D*|AXJ%+PTRIFDVoQ zI$s>;V;B&3fkw@7zKVGd000McNliru z<_7{2C?IWdzt{i(1=2}GK~zY`rIuTaomCabfBW)X&iT$cGv`cahEjTwUZ!E7rG>VE zA}yfUCU}Vksxj6V9}pE135vyN&<7Lk3r|!q7#<2~d>}DR3R4lP)z}gvy=v*5c3_-N zd**U3-)-;h!#T7~X}rWQ+4=TPzVE-*f35XjYs3HXxQQiqyK(iBbdp_fN#Jza~AX*2jO?!ykQmc{y#CWw`ljI!*U(*#~36+ezz^;BNyYrugf&qjkCYB zLf*Kw_c({1qvm6iA0EP87{dg1%mz@n*W6PqiL~qJl~arI@p8f6BbRgCGik1J^Z{H#6b`E5-c! z;mZsb&L5#qHI~lt>qOxcVK_~>c$j&W?KlNL`EWg02Ub8XAXl8390Gfx18N;u3(kTJ zJ^Wjqb4T=*5RISv^piCe_XuS{TkyKeH;6c7o7>K-az9V2vyf^?G_Sn37Mq;`)98R( z3&w&mKzKjViu(Y>vA#{!N-*_)wQ#W%L`@iM!9WWJ+c40=X%zyZsE)EZ?YvALgjmn(v<@NIbGpiRRsrKc^FCvV|k8t3%nLccUq?=I1!tW)C3r-QHg?Lj+0<>pRzf|Bf|#}Wd|jPD@bNn_p~FyGDU?$v<`B4!*YQ;XwLqpY zC+4DV8Xvhla311WH)4LUc`EMN=d0ufEi>0Ah`c zLsWJ2XAXPdV>9_J@5yE5ps~AFyfDxkULx`vcz%K?bv-Xks|C;o}P;zpCi^&#-*?XM zobSx;=E|Z%N6{wIAP5>I2@^+y^EmK#w6g)n8vC0RIMt`g7aF25BVDW0D5)fpZdk4* z>7)`x(r?q-q_OMO+ zx6Tho!U{vKIZD@O!0y7I*e(+frOcwOI>7s+Y)-_3(v*JZzVDgM6WmU$J$x{*@a|>y zZc|aGnA>)$BFCX{q_fSnlUu?sq&;om|3G`VQc~9SlYj5B*4D}sr^KsO(x!7A)_3i# z?rg2#=#DgTKW{oWQCYPia|LRpY5OT=@~w+;AYQ9%Dkw-M2?~0V3`k)|`bJUMDVbBw z?AR}YJ!q+8lfRLbTn!F(Nqi?y=6aEK5G^|XV9a*j)ETVxS&8-arH%Vm=T{yYeJG3G zXWj8fd--pS_pfhrT6DUv{ZGH|R&;9H(pR30A@^M=gyi2M$Y z+$lAz+Ww}R8;48dLkg0VI|YGWn~yELqnOW^cTgP_Wy>~qx6~ZaUhgPwWy^%On`3C(}cYIW;ZjVYmp zy(^n1$K8-@vp=(OnEaW-!Q{VNbJqG)^{nUHXIA$Jqo%C%`qm@e+QntqxcAR4=`|TE zR;Zs}r&_vgGg5T>xyp(qpy^B$Xs(6QNEFwoSQw#EkSvo*3%U-1eEm&Y3{NBtbOjkt zsYQ(L+LH`AMTi&+yrr;I8$>2hVQD&YZd#NaPfNsw1jFBt=4(O$fQmF=bdxGctw&8F zh6NV|*Jd%BLARI~5=D%KQW-r+qa*1&7LNrpgH2Q_!tkTfeRYHqjTVOtLV!CFBf((M zqHMO&Xk;0=ER8On%@GQPY#3o92oqQ^^~==;%*0gd-OLaJ7-CY7>nN>((x~ZXOiZCk zF^Cuppr^lxPoPgDe0(*d|QN=CEM4O2r=Pp*IAl0+7Lg{?J~Odf}$U}8Qb!o*;uH;D*g4j)$xfs&~82272UW+(v8q5zHn=HNna1)m8M1i|EC z-Y^qWV0@+zmkYxjgh%i>f*}yIbrk4IENN&|W+(zc@e~}K;37DaL|`71$0K=60hg;_ z@(6@WAS9tA`AQ2EfukWBoeBfxq*Pcu$=0glEebQ?Xn;&2VjwK|l|+_=8I-_5#E7KS zDW+EnIi(`!8Za}P93O=1BM`#g0s)T$B7bExpVa9=Cz>%iFpJBxXv}3nK{9|?%-p8{ zz#<2^pg}qkGiY>jjV4LNFo#4pd%jdl!FD1r1181{BmjjG9tsOk4qt9Q`k-8aCyb!* z5PJjY zU=6771WX-Ig6T2Xt}o=&-?aj!(<5u(p&{V7!wvS|4JBpFk!ZNX1vJQm;Dz`d@Tk; zh79l7cTvjCY%WWP~;>Mh`(F!MA{s zg)*z7v+x})Z*2cm8!u^L)5M(_~A`XxXn!ngQJK=+QPEDD;b;h>z`~I2k zRCMA6_e-BLQszw9l+c(XJI2YH8BiZwAKX0rbl|lwKif5_E99`J!{X`D@opYlST0U; zXjwlVEvlE`sC)6b$gXpr_;9;VbTOh(+~L^0*pfzJ+fzZ?Bi7H>qg~G4uG!}I#D7iY zSDQG$UXiCg&>|&G&en%Lvit1%4jU@BF!>G^l6fxMIzEubqz_1@Q&BEhqcYkL&tq zi)s!1{6LywQG2^vN1fyu3w=RX)ewx~U{wkyJN0$}9JM7!X?kxZHTu<)tXxGvWP(u}q@t-+tVg+ga zyvjCX-5gF@RYYyt>c=-6j;e$g5Z2OtWck4?`S|23 zH(T~E)pvEa$ilIh@o7E7N5#|ho!70dPt3c}P#n?iP+YiY(n?MoDy5@hCv(zu+7VY`8XEy$;+{qFsJ_x|p3 z@?}kEaKH%qcsh+n8zBi4hk?7j={wX4Ty>$m8gTn}N<vr?jL-~vwN&Z%1C-Oy6AB9 z+O%zsZZ6T#mG7hQsz8C8^Ia{yeOE2_V&&lKNJbcYLUs*OHK(WTcILSgCe8KKW z%9Q69qb@n`94(*x`Uy37u|-?tSL4LJYrA_f0e)hV4r>hys81cCJ_u zzH9Dudg93V>d@@YHtQQv`$AXI^CFc^r`j9X%7*m?MghHOh_%<4eYULHqe3HnWt(++ zN$RHjwVR)wD5!^;Q*SOkR@!U)yYq;Y?dWA2?FGlI%1W+%=aehf;tc)V~>DpK;T zyCf+8=F_8T>;9EAXGhbsmYkg-=e`<#e@!{8*v5Nc^`NFurEPVwEy>?MD#w0Z7Ugpz zplHU#6Y(tL=l5%hGlI|Ar>&`&3TkCFT9X#2_tS|kwr@5u-j^+BoqK*8MrzUeEb31!%yKR5$ zebSwwSmu=p>3*y`elQDEoq+_^6(yZ5lxtKh4A;mAmO-TjWk;iVcp0>qd=Wu0WJD~f z7D3&mCm;rii=Z#vq#UW%mr#;{DLNuNB{)K!vPkZZLtdVA4}%Z@s0a#U7*ug;z0e?n z%(z1EY!b5}hFOJLB!Z%(p$uP*j$oiHl*M8C8OTHg@}x67bhttoCid@#0B<5lNl{uM zo1K)D#7g3_G`d(e?C$Q)<{)eYVFC@NK3Pp+2Bum+#RSoZAtv;49jT>AjhbP?#AKQT zN(4b*o$qCp7KisApH*gsf9iQG$}ib&}$NO za>6f>P*YO|Lg4bZ_SytpoH-m^&L-jr6;RcKUE%k(43J1e-&&X`h$U58vlSrwJxz*K zyd -%Km!a0WU8%-`a^r~M{&vog?*f!4afNi zlZ(44n5c}8GTphjyXnHm3BC-0d7J@I61ASf)N;ZE1;AM(z`+G50>c6T0n4~d6h%;` z3|7dPZV1ZZx^ekj1eXnf2+@(CDzUhMUYVe90EHkjn6JPPCeGpUfHyeC#1MpF$~X!X zhEX2DK?P3AR=pYhExBF7yeNh#-X3=eSuC8i!E|U?75Klj;P+ zJJkqMMTAqBiA|V~a0MKg&qratJA%URlp+b89#o2!qc7!wq#o>_Y!>x(R5%ge_ty6sN19uS!7w+45R>RXa4F?B2frbmCdzLArEQVJ-a$Abx2#^fM;4ilC01Wb1YE@vVFlm`n4M4)i{FLb>| zK_y{2!Y3B+2)F{}Y37PC&73IL_kBrH5~eHw!k8QZ^N)nF`vYd1X2zR{J=lNX#KWvG zV8{TwJ{cHZU>3694#R%VOk?LS{PgGIFWdn@f86AQ`29%NN4h?Ufe%vtSY03K`XB~A zNcm%R{om-KzdKG5YVa#42^^Lx2;w|AXj#d=2oTd8X*ybd<HwZYZp z2P|A8r}@l?+E(^BxUbc(wC&_X`(( zNp}6ihass>PFb2k1lP&pA1mfTFIiAiSy^k{lkR2Yy=xwlMzLk_!H4s@p4{`g#xHTt z?H$$>mtI{pGs$yF;^M{o$BC!TfAm{Z&Wr9}O1(7x=k1r;Z3uE8Cln0XnowJqtq)j! zI@mRAlH+Z!W14I2OK1SEXu*OzF)=YOT5Uw3O+N+g$~d#EM~Pu~()C^8xu5L$#MZOt zOnG^0;h=*@pI@~0nYL-oMwek0k<-sb9K1YxkO%FXq^_1%BRQvU-N;isx<1J}cxFP`r2VbKB4%P)EzNii+okJ;8IQ z(-e`l+b%mS|N4+~`IUP=+?-H?m(Aa?r0M6Jh<%5&x6O^9do56!iM0O-1!&OIlhr#g=`K=Z@xj&z=qUq9rVR(KcEowq3)k^XuLGWMZxeb}QXYW?apLV;< zTp4n#?UcV~&Q&JVv3Rjuc{@WOwZDA$?qx^g_3s2@s~)KB$fr+dWqy{w+<|VX_qKFw zZHZ%LTs~cEynW}ufw9rczy03xT3A!#@4vas`=NPb#t6&rX5}rj^|r{$%#5nLbz`vc z*0rK2@t7}mWoVB6@;S)QkTEL+Lo4D#5I46Y6U%7@Q6BZx9eQhV`>5iHe&d@BT17SO&=tojW#8uX)O=6m%B}Sw#glrYZK~N ziyat2osNJ?vDPXNMJ+=WoGF4*ZFz_|MSOvF6bmS*(*YlKw2tmw-|CFh8U3%Bxy$ai zzwfu-_uFrGvf1Ft&5F~`)FKEH=gM|?;di|9#9jm6-*o+bCrZr!kWi#_r68-;(Uzw4=`PoHm#TXtZ^na|dNX)hgk ztMk#`SfvD{4~SbhfN$sbbEQtbZ(tcAYu2bo2dt#+_c7u<^#OdAG+- zJ9Vo1$EM7gG1t7tt>Rv}HuJFS(?zWr4Hsp!S9A8&X@so@c&$-kVrDb)zTwLv0hiwYDmA^ZHxb+n0%$<(KBd za&h&?AGPMk$EIi0C)H26dq>+JbJtBHXD9Y_bsjp}xv09dVCu=sE@WHi={leH*oC{+ zbu4^)#^Rf!ZFAeHiw-jGi!0@|$jWa2?I-^D{8=^wE7ZovKb)|UIomd??TY)eqJvA{ zTL@fp({61rUV5mlHs>i@6}w8RW9tsqoqR9hhqlGLAGx3}cz4&5RC{8+>6xo7^+y+U zVMkW%-?Oj#_&qb`f3xsJ&I{J{Q>Hb?PLAO|T$VXC#lP?Jj>2OdRUaHpzx=CHI)478 zjO3#+_jRBxReRHa>1@icZ@9Wi=W6U}U!8VjZHK<&KFj+(&0YI)tG_geJ0rdO=MlfT zDz|TU)>gL$zx?XJ_T%>-zA%Zn%4P35e@EuFRm~F)K6}c1VePqG9~D zckdLcYwShOJI;KY);%fG^K*Ay#e?ZDek>i_@<|5?>n_T}`YLqi(5w*DGo0WD`e;yu zg@+)i=~0nkOM#5~K`|e)>AK%|ONa8DO?Q{cO}IrnDB-g!C6HH{>ticRSu3YYPt&GG zX-E(RGJ{5gWuY(~wdqt|8nzWPu0vIbTx!!5x;>~}kN|4b8}$U{jPezfE=`N3N?d^U zI+pZPz@AN4BFiF;>2A2H|!sTe1%Rx3_WI7ML)frZzEWG0G*!gCagJ`M*6vl1`L zybwYaPR1{k%Ql@3j-vzd1x2@ekUkXdR{`pQM;Q?(^#mRa;=?_{vas1n&I%Bc=M1Od*g=1>Tq;x3;aD7$fgps2;jH9{DYIN|&!C4QK`|c`RWB&^ z2&BvhhQt~Xn=+!NGdvLJKFB))J&?N!hA6k2b_i^_5}wOp(<$@QoWSxNtu`6I+3L6W zIn3e@0L*Ce2Vjc?n88XJf!~~BwipA$s9d42%!F8=P(gA%4|y2QVlo;{1ZK1nBxW=N zKV~tQ%oqus*?`4lph*8Pilq_{tCA@j9+g7HDO9Y%%$O+yMgoP8B&--?1SCcp{Z})1Q=P6 ze1cGB(b_oIw~SY}5{jyu0t(-kLYS!loEj(O>KkH9m{2i*r$>Le z4%qpBDg}}<2CR$~vjkGin31)ZFbe|!W+F`it2KqPkOA{Z_OK9;Ba8$xi=mECD_EYY zR_JZ&Ld_qEj+6jp6`)`kVSxqqSHbZ9gmLA}7|1vk|C=VMDqz?l1O57J@bH3XAwGB* z_G_jbJOAUSe=YvU86fr8B%{)IOs+AxMy0^0z+=@lCfBGG7!`P|y8bh{v_sb^5Q4vg zBJi?w?#Wlj!;2Q?$?-W6o+ zN!hS7QOsT*Mv&_glt+VXtDgal<7JoIIsTgo@e`*Tx^BBN8=6cmN2YJWCu~uX$LlRZ zH1o#A$B>O%*J|oo8>?%ci)D%A9YqHkuU&9BcI%WWMJrDIl(9;Kw4gE1Ju%&L1ri`G MXRc$<;-ZKC1S>)FzW@LL literal 0 HcmV?d00001 diff --git a/smiley_pack/icons/opensource/kde.png b/smiley_pack/icons/opensource/kde.png new file mode 100644 index 0000000000000000000000000000000000000000..6a6ff9ac7a5460d0ca7a7a791cc556e7ded3f434 GIT binary patch literal 4678 zcmeHKc~BEs8gEe%L1#f3Wfe6B1x1o{Cm~7q5R{uB!7OAH@uJh+freZr4MbTGqpYK_ z&N#3GQeNXRqJqO}%^)5th~PDfQ!?CXGtGgGx?)y{vU(#QLb-}}Db z``%am)~aG6Mmmpkh9GF9A~G}a>nLW-w@A+8 z9h~#IXaQ;5bXexI2U#m|Yx?l(zw3-eHQ7J+~US|Vx*p#(F9$Bk$ z&z-a2t1w^Zbl0V)Rhut|g?XmFzfLu|(YYKeKKl4iCE_X5`Ri?|H8or7_O8l1xc|NV zHcr>z*1Ih`Z*r$L6}cyz>}q)!cp>wKsW~g>_(2_t_`{b>_%3r(~Q~9574FG zY;#;YsfvH(d3{w|#nzjsmjDB1&_lc@+J;ib)~v4 zEu!FQ&bbMRZHl51XEr#fUuxW}Gj|xz4z8`7^{V89$|q>dq#VEVzFC7kJsn0*J-hg+ zHKR1s@T!S!=oprrX5J^#mM#WWXQe@P#VeyR!l>utq)|iht$GtEI|vGxX*Jav$Eb2x7C(3ulpCbd{>Xm~FK7|FTG z3}eCsf{cs|euju|G$#oV6h#HFP#_fYfCbO8%)sDQp26b9LiAvSQWnBYn;6TIuyg>@8_@51Skz#X3SudX zG0jX+Vd<2C@#+sj5`F%rG_%g04oL_o9i<1R7BDOF)|3$nrK-<^r67sco9teI?6)i# zTKk5qw_;;8_H_CO0^Iv>-?Dz4yWJRADV12Lkw|01Q-sR7?EDyMBxn+|zltSNRE8pA z9)Z9To>+nqJX|9a^H35DxR!x=4bkaMGHLz?xC zLQU(bI0k3gM5IEIREEM*R4NkrBj_8Wxs=%gDv`xRV7^Ff*Racifn)%&I9sOxz%B>5 zU?FA-XN+dG(WsMi*^oG_XP;ULwiAgncqq?2RO? zUG~4M+0DZV=vnee+5+ZZW*7DBs5okA&!}gpqwQOX!?AA)3@3V0u;A$wX^#_N^{9ws z+>k_p?$KMWujTablme+i5D_XB@<zx>QC*y(Y8ldZ)7x3~jH^{&PK$3^zs2w?L4~X!aTem2C0= z!eNX;88+;uldGfK2Nj(gi@<66fg&_WEjzcXK%VR#>xZ|FXs`RJu_i1JS3R|!5a)Rwa-YQMwv>U*)sv%qlzZlZ(7 zApXNw{?6`Eb#0?^@~esS_gCH%UfnHq!Xz&0Z;CZe-0&Q~>iUxhJ`oO`_t1MyMwDdN zklHNovFqz>-3QhMl}d|N`APY88(-dq=cnJg`L|HirI`||sX{NW^Y zq4Va|aY99x92t7Km{H0F=}_rAj=717(KT(>oO zA-Ypvh<~nVTK!0lU0ai2?J8?pSl#72{>am)|I8^V+&v+I`SDoDsm^V&X^~Th+|z&h zymQGuoqNitj-heIKXHSP{IX>Iql4{nhlt!uvPzExG{M)qJ1uP*l$oPzymO{<jE) literal 0 HcmV?d00001 diff --git a/smiley_pack/icons/opensource/linux.png b/smiley_pack/icons/opensource/linux.png new file mode 100644 index 0000000000000000000000000000000000000000..0340301df931cfba0f78c5c8119d0dfe051a7e79 GIT binary patch literal 5149 zcmeHLc~Dd57QZaA3AiDmMGV0Ok*ox=NB|*`r33>+#iEs)o11VU8%cl&1p%QJ!BPsi zP$(FeiUrhK*|Z`msHh+pyr&iN)^ zGPyy%7G_J#006M?_hW^i_XX(J+QbOGVvE1niQXhnj8W~7!x&hN z2mwIdA>npfTqc@47w!2t!Y<|sEhsObyY#^#{mT1QtNy%b%Yb^-%w=-rT(fImMM=(D z@1h{>xVHI^S3$XX4=$DcxYf9P^(O`ASHI)hPy1z*^wDixIDUP?2Jo|tl|P@{zTPS| z3EMhCi9)Ve=^tB{BP-}oeUl8XZ8qO)5TtqfgXhSds%pYB%LPlt(PZI1o0M@Ac{OWq z?w76~cO6t8xa&PJfB-!Y-M1`WnpXB10O+M7K0aK3AD@@Gpcxb;BMx869=vYCIwl2 z_hjq#ktf6B_?9#0hsJA-^3$#ZC0<1lb>KYN+*a{>jJ~A%CTrd`8>YwHEH%npR*OIP zys7r#sS?rpY_afjnzwU)UDzOhlN;|oa{ss{Du1Z8wp`wGzkE}FdH1TFU`=U-v$8nK ze6=&*6l-|x_~A4s=PStfex%$(Pmk>0**={0@YCxX^&GD1M{(`x$xl2-nc-(>u0OBL z$nzS?lI+YjXxLVI=hVOu)F~|nQboN1{iD&Gh-Z1fulLQe)7#Z~u`$*+ZzSc$(ujxt z`^~TC>hmV}^VFV)Wz7bctG!+nuC0DX4_cPue9I}xz}8lO!HVYhN7V7h6QwVDkk%pN zF5m$kC<)0C!Kd9E74_6^0Ls5GfNobgmwY zK?F?fW>*f8Blm$L5x)cl9GVcsgA$@4x&Z6xVdk!8pa2qB1!B|^u~f-WGqE~c2KuZO z6R;Sai7J|j4dZYzJ~9Q2q2MWaB95&_;>cJJGmN`JAY_EF)=xp8Z%k~YN+o9y2=Vdp z_;?q*Od%qW=yW=PNG6cUIMf2C+#ywgYMfN*poN&kV8KdAfyh;eOp4KBf_z!5iiyRd zdd$oCBytXC8eXcLVgcoYpa$gx5}rtqNC-1Mlqz-{3NjVYKYA#6=!gYnCcR_=>F8 zV$*7L>C6lSb)Uw4&H82TI%Cv|!(p&wP^>mQe-;y~U7sP4L5P4c`RGEX3MoVw2fEQg z9EA)*I6ldZj&mbY1+Fe`FvXPy&VcflDpjBqg0)a6I37W9K$r@G5Cr2$APL4%V7eO) z6i|dXDxV?{!XSw#aC4afu|a{LT?vY3Mx})kpimG+Ky?++VVn@Ay5cA_AqfY`;fCjnp1v)4J#8@v=NIRYKH(i48=g zvFcX}9wLE5RiKtl5|!*irO`=5qAStGg-&^8vYBALP<(ikK+p7u&(kcn%E zWCn4Dy-a`zcl!DADzI=tPqf6$-~pzD>T05#1DLbR0+*qOCx6)z*$C1mVeU znnqX3gsON@0k0FGJfd8o?WyAmHGB zZ;KKDW}|-v%wC`e6c*W_LSvObhi&}WWUkSCE28O$1ppW{`?J>ZXg3P-w+DuAw7pv2 z*P{$~9CtZ4TW-8*A(DaHgprb~uA-nn)y#X)X+yLYk~# zO_O=HiPS+@lTo_#2UT=H$Jw*hx4%_%cJ?H;4mV^6&RW^`$6sqpo+sB2jo8l1p@oKq zDndi^G>&_4Hs*u2o7UK_Y`J;UysmrjmYnv%8e2aItRU~WKSLP7%mWJSf|9NW;1cZM%q@L=zQ z=XzsqkSQDkdqbsC`4J1dswk+>7r@&Ujt&pU?1+qXT$I&V1KMh5Eg@y?i4G19pV!qfxB>Pi`mEseZmIE6tBQ(>#{&aw{Qk>> zgM(L%FCF{hi-q4&2u^$SgP$iBXOjTH-Y`GJ=0iPpaPQMUKM6RRfBN+4r+-~i)OO8c z2YZ?5_1P9F56sEPCw&-FX4pcXpJ`ZCRfX~Y_Fxj&ZBh7vc*KLZF{83SBD>+Ma%N;1 z&-)P9%cErXjYnzU_h&fndFMq;=$s38S@D(IZeNNYp6D~Q+-=}dBAauppFuuozU13_ z4g8mJd1a-hZN-mA#=0|&&H3Fnac6!j**@QQf&xZch8Rg(XV-k)mebZ2OrcVJK3#5Q zHj9Ow_ceU-QvZa}=AB&`orZN?RXm1$bvHj#y1+e*TME6L32^qJR>{PWdRs zQSW52P%WCEcFAeI!|Ku#PW$%llTYCEU0N^xW_^XcyNo1$)O>UBXns`L*PClLxBRgD zTDiV_UT;w8vzm-U9b#b=*l@VNj<;=F#kuamM`MM>XSyDyGz15QH{MJ--(Mdx3WOQ& zICXxlY;I%l-cXGN!EB?ASEkjFWRC&!-V)F82PNm)PX$E=`!`+xDJ~%4=YuEPI}?q5 z9XV22RK{ou`xfg zeCA%Tvx}{>H9c|h{k;vQU1Zz4UNhX4q}W>Aq&aK9DrM`^wY# zIk(Op522)`=Gcs0QzrfB6<2ysVPm>#N35}9+U54v&OH1Gre*2|s z>%yHC4$dRIQc-vMmE%`Zealy8HFg~R>Avl{r33YYuXR7zJM*)oHL0P6b1p$p%x2MK zvRO=~k%B-OEj2G1^G-aO5-u+aFaB}v(ngA_c>V8hBHNCra^FpQ_PN!mtJHTJ9#6D1 zZEd^yl;!NxzccJX*}Mz&WxvN&+OR#RvNwS;KtjxL-TsqyngXqwRpfVu-P&%t@irS$UyRqhBL9}XYKs5Cv!t%*%R*{{`gdT#j_{7PckLl z>E(Y6w0l2|wEuR0d$8c%@%8!TYd)vX5ow1SAInR6V^7oUu0s#KU9vEo({$@v>R{V} za^%&V1GDEF9=6pdT>5s?{g3+HzZ>j%>(#l*5H&iX92rgEKh zuBK%fB=#*1#-*ghUYpjnuK%l>Pi~a%w~Dv^85cb4-P`#x)ddlmti~a5Zy+k|5zsii<}WD)md??$HZ5Nc_A-f6v{7VLzS$7 zL$a2sG6OUqaPcw&2V73Kj}91-C@&4}6*GpwQHWe=M9Qo-*d%#*m{gN$9L)`g)f!}( z3eNO$0$pfcK1>0gj7WtnduR;v`~7OaRxNoQ7-29NFkFLaG$=rzzMxxX0;t=!K%p4o zF!MgvD|%#6a>EKIW0$IABZ2@wJd&TwW3`UbyM4nd06nk(-3=b~N5o<#k5O;aH4!@-6`NfmMkKORlh3ZKDy2 z1P;;ViADjjCm>}}7!zwkZi**b&iF(?_$coL^hoVdFhE(Yv{_=Sl=LiSBciNNa}q0Z zbo5rBhz!QS5vWe5*Q2DJ_Wp$&8!j6)Hfk76Fe=M;YvT zA_E0j9ZDJm14@w`jtW{qL$Cx#aRfV#qQEPHu4J6!vr?!yg$k!gEyoC`U8mttQqO8p zN-GE`WgzurhM?840u`m=SbDkSbunN&MHl1XF^}63btr<<**1$2(Wvn;i_OW%0thf7 zt3-EIV9Zf0y7(fQQPd>#8ZCtrxGqDh*AP1G7-%)`^?^=QI0;;>C8Hi?TWC-W5SCH; z6c9x1pcdNX7E6-Th$tz+O5~{93XT)U$c&khc|eM5NE)YTBBPifXsw>sW-P%q zG(HY5aiS3XUufm_P|yrJRDzGG=DBE| zfNRLbRxoY{52nX(yN=k!?`Z`)C$JnP=ushq;ZagUk|?FaNt7q-6vG&JyFmUIyH65i zKjY=I9Y9B*6==_>R`8ePo+^dY~YAdr9-B$DckFGCwZa zXSe;r{F^V}>_`Ec=qh@nr1q2k&+l~@Zv533cd}LWa`%GdeU`t?yU1ydl=Lj3lGksU z6DngG)pvHVn@tz~5NRo2zv-FCI~4Ns!4DRd$2a{sC)u&~LbkTPKWmz`uy$)z*ZG%z zuiaC6qN8{4?X%x>K6A9QuAwKqC!z{x{Tn$_AKB-+_|%2eMGq3YpKpCH4x|fNa`Vjx Ia@IHe2RrI31ONa4 literal 0 HcmV?d00001 diff --git a/smiley_pack/icons/opensource/mint.png b/smiley_pack/icons/opensource/mint.png new file mode 100644 index 0000000000000000000000000000000000000000..83617fcd313b54a3ec540664f04895ea11de933b GIT binary patch literal 8663 zcmV;|At>I7P) zaB^>EX>4U6ba`-PAZ2)IW&i+q+O3;ulH{tAh5xgPUV@lmIgDn#gI<1r2Pq<_n)+E+ z-J4k%k`UnTX8_Wy|M~B2{)<03mt;cZYfb6mPpF}~#y`q+|GB^0E1a+Q53g(X>*wZu z!SRvjyT5-->$$)2dHi@Fhv)PD^>dTQ(@uFBdM>;g^m?=7AM@$t(~x)f=l1#8RCoWQ zrBB0o{x9{sQxDyjzWp3BlQARhd1u`6)?eqVyKnOP-}%P(%va|FH(tK*@94w%8h_58 zc~9LhCh+~QZ}WGJ=X3ut9d|>oVWn^L^n7mPujlW~(&rvo_kOec+@t91ygvW=G=F=~ zviG`2*8+J|LwW}F8p`<>H+H7epT`n^Gyg~aozLIO-*UBU5VgrrySX|)RO^`WZG)Y* z*=^VPKJ1{2!7Z2h?%Z(xd{%sR)eQn*nSB1*?XvOJPa@*{Aab6M-McULytnFoysYr% zX}Qx`8nY*|pZ=QfAN;3(zcjSB(%jmsyyuF3Ipr7KP~`NLy9kKg&z#0Hzt-H}uJ3;o zSWg7wndZU(+tu$TdbA(8#i4@=hFaF#JeM%v7QKA$@*xMy|Q!JTIR73 zpGMD>_MHgWXri0+(gp7m!6{Df=9z5Iy)L@@W8j5AM4u>|LVy~<3L%C>y%kcZ844%F z7*ou##2Q=jDWsTE%1JoYvdtVxCQv-I=p_)qwa0#zn?j+IeR%I$jMmW8y=LomuNC61RuB2zQ(JlWYV!(tk5r(PRDN-@n$qp&AMgKb&%Wp3L5JI;x!#E^j!7k24|jDpNA0?pPx0~AJ#=5iB4Tm;;4XuD*QSPBd&=!rB+H{w z*GBH1;L#LIi=P;d0Y zjj*T#l|+xJ&XnhwBjEgWJcHYnS+8sM2yRaZ&V|w)WSQo!;kwbO$5(yvO3I6`G;6Ht zYwS5_rrRA`n{;b21K(=K=TizlDq)lc2f0%s%TEYo!aJkzOzinR)Sj;uaTOu?He)6r zeO@tHbQ7XzjDnVhJ`q}>uUTDg8OF2 zmMnMKoa!}E0iEl6&OqO$CrE*e?yUmf&7X$jnhsq63;LnUubYjd7b^nx?L`BdF`(X4 z0l!cRu}-MfB6-2G?G7##2E%0BZ@5EX;*S046^^3vqH8q-rT=JJLm>FPjEKCMW%V3} zpDlzbWnv;#I8h`dW%6%u$IXP52&SCN-HWa#%Nbc}%r4Uvy}CuLd7(LjS(Dil&F%N_ zh!w-D=;Fjn?j%-3%9hNW>_OmS4yMsKu z%gD9TQeA_oxF>e4P7&m-=7jVvC{Mf4pQ{6|v!~WlhUO2a5tPD|#5$m?=$CD3s6v3u zV4U}?keMVtVLoF(hb;xk8S;>{YMyEFu{*iyy!KTqwn%uhcs>X~8-pEj(r-yXW*?BD zwrdQ|CW;pM26%y4c`h^xG6R{YDx{`AmtYDp^#yjE!IIQeJTZ3Va;dj7w0K6=T8&Aw zG2?-Y+**s-PDVRM${p)l#a z+Gy$vcYG08|LS2VS1|!^tsY*Jn|eUg4hrOb4>t5mD^2d4O0b2{F*Rs7(zw@TDz)AN zLYe8*^3km8Iv2-nk9{7#3$~WE|JGbGbeY^buSKcFfW_v#-{YSX+x^Vo$pI^4s!sWMckkJ zDTEFVUNa?BUD~hQ`2MQ6^Ac#j2tJ zF}@h1(6MDWu}-dbVnc#2x}QL%j~pP7PAc3Wk79Fh^3=O5=!{=2C6@usv9@} z_*9D>`G$zqynuw1m5W(k5yBZ*O`O`8M71_ELDu|2st=s1qc=Orz5$kYjeni_z(&`a z7j>NdI1`3=b4Wdt5CIpamn1lI+yq)b@Q(t8@xw(g%YXp=Oebk(k#1trmPt;lx4xHhRc}iiy@z9eCx%d!s^J$G*r%GK(n-06?5I zi2d;5RqF=XnO2Hcmf)BQeny)S413xH6}TASY{-^5E6_EFj^b!9#Q_LRWL5%ryHDnx z5n}2G&?t68NI7&7Imkod$$^tIFGzSNRUbPc} zW}hW5NbF9rZJxzdAuGtkfigJ^agm;bY$g1#D5_u{ze_$zJK&7#1ET)NC!`A;E852A{R;y@^oY42KfGtKnKEv3K%SB4z9D>a--^-;?tNROR6iNv6p-F=W7qxm5w z_N!zYf~3G>2Ji-13POdfXVwVf#7%(?m%A#^owC+@u}I>Nu?7T;fKigci^v{4n5>sk zMcI8DwC1K2>g?0;g+b|YIfN=vM=@-6xfS|9HbF|5s77U)%IE7 zFp`W3w{XAi1f(;dgnK}IWvJUqzNoAn7chi?|H~1QoHLP$-XbPaP@-?@_*T>i4`I`{2Uc?O-dH_dMiIJ+-_KVca01mRB)J)?koN}iR2$>5L!jL5{ zoi7ctbwIym-e(8Zj)Dv~r!ne?MN3+{oG59(gFV$3ta-6~^*76hlXh7WsiLk#A}A#O z381zjuhk0huXdfmaX{{3I9)Uz@>e+rn&=89) zOQs?yGlAMTCs?z~7sHzRO0C&5mlrChO<1*HX6BvQ&!v9zrdyS-fnp;`tU9#?Wuyqj zcb%bqu0~LAw#E}tiS$V2uJ?XI0H5e0CV)%@$YeZ**-x0NEnzQb$J94QLgi8)$K6sS ziR_>tBC1*$abB++?%;MrJ3&WwmVwPZm;>%2i>5Ga@TyIULdqRyrlsK~FM9!gT2@JY z^bwI6XduxDd33zUNr8E?wFwFknQEd|CRJI;9A8Js$NM6B5Fn=zQHq!N$>0?o>KxmH zFkqf$=Kc&J^SIWseaKlmrFLf!F)s>@w%d~ba=BCDS{fbMR3!zur$i;?qoTmL91IJx zWm0$^p0NyId(b#T8ySsH3aqIXNi&R`k@`vEo%J&ORL-o|sABqJt7^)srq&YeduxM?Z-PMuzsG$iH2Z)$F<)I4$_=zugL{UcNxCo2xgYA6Y<$TB!S&^sHXSpE}x_~ z|K^H{Knvry443hJ#9|i?w{WX(DnC$wr}C-L@)XZgo>(|$lmw<|>%orCG66|}Af}SM z$g&@@q#}BAXL9M)3$_vxe<#fHOk{wPxBv_;9p+cey^ z=Q6kkVBsd|npT$klP4uy9?iM$zFx8mTCaLKAi54;uF<1(`ckAM6r+h3LxU{UCi&l} zA*7Ye!(F}*6q#Sw$WTl2HO)aab|_mKyMDG!Eo0qfNsnTTH{_x(LM#jOJj?s%M>DBC1h?2;RifKfpyXUUKD{61D?iutD+ARhiXkd zJevpmmYaDz39wcq^M+h8f)slym}s9+A~~tKjY^^mUVU7}+}-1ygvOKK!ZNV1_Tl@J z&B}Q#r>O@5JUGDD@7IhjqUfdBJX38g9-ViG$4-#|{cuWj_reEg-YUrlynUfg^Ly_6 zzfq_8%AEsqriv;)`5SG<8T-P|G5|~Uq3W%wE#08%aH>>QHD8MpJ#^hw2XfUfG)XRN zvPF&9f&N8uK*Od}6>+LIy1h;D+rU40GMe^=`>S*x9fG0mnZ(obWrs-(2wc4Qs0bVt z$b+0Km&{DtS`0wz!Bx1e-A~d*EaaO{+W~$*3#GfX zGOoo3?L?n-ucrin5t0^t6I=hd9CpKsSgCOAQAJ=j`%NH0fOvV>^^~#MoB}QS>D1ZjZWgx~p z^>ecgd6ea04)XYi63Z_N6c|ww!TLYg(f;;I`oWtD|L>^tH_WM;Uk|%|W>1sTtGAT$von%qgsy4O%n7c}+9*2oh2p>iP-8JJl1uDw^s858GfUUo4;6qug z#AIXJMUCU}ZV#~G2R{@p()F%E^rCqeVbn!e&U5o?{PqG=!l{6Hxagg%McnEvrF}(n; zF75bD?K=#n8@xq+W6vEf$6o`r6#(Bz(H;krsurFnad29!(*k@eQ3?$G=n6j1EzrHy zmS)g$1fvgHeWSK2W-le}F!)p$c0#04qN5x1WpY=umcrB8ci!+6K5Crz+*@5tI9#O- z-?_DcgS_Fd5upZczEIjJOW4YA4 z0S5wLRGVWQ_-~KeXBvXn9=0FltS!=XO=tc4EPv-hh3JsaS~%P4u|3*5>VYmZ=kPx$nJpcW*cr4Y$I}C~bgOop5`|v3B)g->!e)c1A z3Z))des8UcEzM1rGfLTizxZ6E#+8M;yB8;`g1h(mEGXbUQ9)W^zb}-_mDh{Dk}}w* z^>#}h46Dte4RaB>2Jztz#;Cx%(Rmzf)STM);S;wro};(Kq@2mUr{z6iI))-gMX_#D zsORAz6ehc+P%uH#twjrWJ^F%*7C?aZPD{QZz!&HY+Id?ZtrcFIS+kheS}UQM*I7=7 z`6vs2ugIzm^qp41-wU^`MQEm@Xk7t)vZ`ep7qrBhi*Zd!F5>I9b{x{< zqE`=j)~a0yP_a0#vtwI=NE>1ie;!_(WMP>e6RoZ*QY(=6ET!UGF=(QLVba0_q0QDY^ zpfpm_I+PGUPCig~Qwn;_{aQWNx>(jminmNxf3J$|W9|BJkm;**3H*Q;x>7G%oCrD_ zh=}uN#t7v(NF^5~byl=fcAs4^=kP)-F*M)_=qzNnPq|`V58G)ih8ph|v|2*7+~BNB z(ajG=Bt<6RFD48Ajh|(n?V`JgnGoRCQz%y5>^gntwW546?~p}dEOtp=Ahh}sLyMnp zGk$_qZ#xK3@3b)GP*6^oPYW}E8_!Dbr)6G4Mr>`Su2e7TODBpiIn{gC9l^uv*aSF- zb=4|oI?nE~HX748ZdKk#V)muj-Me{TqKE#{$qA~2!ipAv+0x2i&LEXWjN39g1{Rmo zLBn%YNGwN;ZkmR<-VS4ESKRv>8N~}k1qv_ZPK-;xV?a8a470$}v z^NS5er7zQ$w%2034jM_Mq1$g`HNF@tnNc$5T+1uI&SUsQk6>AJR;Kn*dwGt_gVHDg zJbBg524M?s6dh`{n8*O)(z)BHC#|~Dk5s3*7F4I5rjD-lgvfyu!h1}B@B?&v)>4@R z&=N;g)6)8JoY<;@Ma>PZZR*)KzfsbEItmFv0g9?Ql&t-9z7{vBgEu~&lQ(1zls8&6 z+X78Tj`sZNSd2SoDzy`Jj?A?AY|NjRFoPt7XG+2>3=G9HjJC>)4u;lGM?CMdGcv6} z9H8RfXJdP9^0A3wp~{imI+cPz$wnpk?OZM9+w9)>pY7T1zNa{J+A_akUx&+YIS?*eLBa+NAWz@(LD%VZJbSQ0>4={ zA+*uJ$f$@(L!Q$xRur`LBm=m>k0wh;i(Jwnsx|F}K+T6|K_uy0?7A!fA{B8Q+&OHU$J9nQ8hK7xN$vZEq|ICCx@r9YNn7PAw0(zy%z&lw z7Ac!&pX*-mS@zmz#W?FY7L1|8lw@$us4-Wow$rd{0aXq5=DXt3gbvCjq)_B{6?7bmQBzj6{Dp&b4 z*t=MvppJc2JCEA})sMauzf&PPOD6N-i#bFgJY&KGI=Zaz&_LBYofCK0rOk?|wZHRw z5Urn+C%d16UWX^lO%wt~&rEAu7}C%}@p(d~PNx9o=VP=7_Crda59402$oj>-4>5he z``0(0Tg|`S`}c;;-@5#-4V%Ap`Cl70zr5ScuN#+XqHa(Uwp@{l6xgGd5dvNZO@#Ez zlqDu=`t{Y{eD4;lpU!DDgNlo)0l2RabL!e^4SomY@vYo1gt|`5>ulXonjh!ouLIza zo3h_DdxIq^re&o9B@*C%( z!+xF_HZtjX;xMsL>|nWrS;$1Xmi?dp(vDQ8L3qyHrWtrjn z`(qRc?gGuaZGRuzcJl-XJOfu++h1(}GoPf_+gkJp7}y3buG^Zt2VCv|ktba;Bu5I+ z^cM=i`x$*x4j8-z`qtduTKhPC05a57>IOJC1jdS#z3%bu-p=0sJ=5y%2d9E^ytkJT z7XSbN24YJ`L;x888vr6vphNip000SaNLh0L01FZT01FZU(%pXi00007bV*G`2j&MD z1~xYyXt|dF00c`(L_t(Y$F-GBY*bYg$A9 z#)TUb+4>P&z}m#EiE9#IX=I}-*@3|@F-B{ov{3~4n3mR-DNH*s(&>D@d+%{Eo#_-? z62ES8l6!M+&hPxsdG8!0BK)5#I5svm+0@ijJ*)alrIZhpwblSRYb{!9lu|hW5h0(? zXMiN|^}xWu*wE0>dO{+Rkbk?1#iAsWNf{p>|M}9TOD~HERa1#XLZZY7=pKO3yo7|}$-hk3U3Rr>q;@jUNzJRZ-Dj*gyn9xsZB#aNANn`OJ&N3#srdcb<~ zYy01_=QwxwV=|@tL?RLT`ufhqGhxIyYwmLivhqGOQ~E|B8ES7;f7`S6A1Y!AvGonwpvdP+eVJ z4J}(bl(8i-rUDQvXzjDr9b{koQ58@@1rTZ6L8Ng3A!K0CrM5KuvGXRgTS)9;ch%nHEl@^v|V z>n-N8H)sfioZ+U|WW~=^(jE>gXQRK*7{lWVJZDSgYb(wBCBML8e%1#_r4=BfAQ)R#xvGI|~@=Q*Akw|Ai+5w9!;kBqC_7E1p(?zShVpz=~k3 zX0w*IDWIyLlA<*S)qb?5K+smRS%8_oB3zhv_MMV5*QR~w(p_r7v( zKN#nsop!7>EEaBaGd;#)KB4Nvt_S$l!ZxaI%DNl?XmLASZ8WLeHAD;+qpWDs{tdO5 zzlJEQyhaCCHLy~CK*?rtoY01VU(4mP0RoZmF0LeNXM=K+ka!nQ=hK>J%lD ztu;TCus!@V-QgjuSeDASBochC*7j9>?yg?FdVXYNXic;lJ(2{>zU zOh23?Q%r7{@5J&I`Mvn98f9%oG+65)K-k^F?!H$DI>C(r02eM?ptZI2gWlfWPrAFi+g;cFM+1LTK%JUK;7BAA pIoRCXJOX%s2awHXpA7gf)}JI)8i+{yE`|UA002ovPDHLkV1lq$-hBW7 literal 0 HcmV?d00001 diff --git a/smiley_pack/icons/opensource/opensuse.png b/smiley_pack/icons/opensource/opensuse.png new file mode 100644 index 0000000000000000000000000000000000000000..0be8f1bdb9160105fc71eb47dd09c21ee9308251 GIT binary patch literal 12271 zcmVX1^@s6D=Y3@001bRdQ@0+Qek%> zaB^>EX>4U6ba`-PAZ2)IW&i+q+O3>va$L!gg#YI$<_Nhj$H~=fZlL4O=a~f(B)es; zF^Ot`s4BcA77zD`cr^Q8|9i~;@V}N~G%=N$Th5mM#TJ|I{H5CWzxUnQc)z|MzTR`c zzHVImyy1B%@IAaA^ZtCk^LqOE3nhMDAHTkC%KRLseh&0`3p25a^~guq<0+5UC(~|V}5_(|NG~c1D&HVch1(2ost~v6<=J2Jg2XG3KzKZv1z*Y zb>@AuzyD8;4R|nJGgoe~+wl%DlKUB3;rcn)WcX;b&&jT=&jBzI=T2OV3wXe07m~}) z7VnF5*s0<~P=TxtA^E<`e&-&!w%fJhcNFkFX6$f>k6=RB- ze5-^|Hz}l;Qp%~Mnp)~P=xn$u~FQLSeN-m|;(n_zP#+qubrPkVNZ@vX!ESZ*D zX|=W1J16b2bF9wiJ1-1B!iXb{Jj$q}jXnvV8E2Y#mRV<;efbp@5MWkbW!2SI-)<91 zJMOgeF1zlw`ytj&IPs*DPdW9p(|>r)ebV+9ul?@1fA2N-@tVJm(&x%gukmszUx#pl zlO&(vF&`ZsFY*8Z?d3CDU5s9ylh17P!Gw@JSDECT<>WCu7`OB3xF5dz>AAo4o58yO zso(rxdCtgn{|(O>x$c|i{`A{lcy09yx8XWSS%^(R$Uyq>fnB?=U3KZV?|r6r_)Op7 z?7d1ETh1T5p1yKTVa?s0$z_)~hb&$5327A!p5i9q>fUi-xVCk&6?5^UQ#iRmuF#ir zT;keSnX@-i1PA05M%VjXUvP~oKGSM#=hj_07=n+K!~M^6ug%qd^6nG&fpMI8Br_@g z&aS#w!^w8nwM%GInQo6?X|yE6VFic1xYA{J=_|Rodak;EerVHEY4=%sw3z|qRRCr_ z=r{4fhek|!rhy|yzz}`89o^)X+=+dxvs%da8pAY!m+{CEUD&;Dn>zuqLQI59E}%H^ z#jn)Si#|0EnSyH4CTxAfu>_a1{URfV9R0Li{uubF`Igwn`G0Uy^fE^O-Ej&*LVtXD~l z;*)E=g_H8V3)YmclDD_~2NC*zsaA9dal6qLitwQi_ z(%L3vLJ9!LFnv^lD*;Hs_M2b!&+mh}k_W*|o{-_8?0EvQR!7Mpj6z5QY?X)vcL<%s z72#GcJ_o>~4iKTPwIirOct8?Db+gFg2ehlHlNUrtTRxiB@eWiYtr+K=3x8Y^oMQ{M z&rAYfaeu%X4u|Ej4yLRr^EJ78gS2Igy@`FyI6W!ZF=Jl5Pqfx^-Ot-&;59Ck3p|bJ zimq0^9H1PJ*g22mK!o0=K1`CMVnxEb)vZTl9z>7k6 z?Q1E}mHQ4gO{idT1+yGH;{l>QfSi=fIMrj!>afFx+>HVB6o|n~hC^VFc(|NaZaQqA zU7LdMbUk)B$g-&t*|;89>i{Y&w?KK^nj~tij^C){(F(m(OAX3%QQ;1lurolPfnW;l ziHUk@j_*lM$IXOjyEnpJ3?+NLR|VVPH{;FzJ#Y?buzaU{U}kJhxa|th2IUB?#r=SJ z#E)!ohP}Ur`ETORuY-)GB%VF2N^!*dkUR?TEX(x5Ve371G)SPoHnO!)V1l_n0O>D^xuuP1{l<43JQLm?}jcBV=AG2!cHI13uqIQ9fg$l-$NI^}7D4M#O-%*AQRtxh3dJ(Rp=af4b2W>2oV zHVtpaV?o&I8y9KxiR!2+}2J z5gh~84w_{HTBIq~+%vl7Ey#jxFg+k^+_wT%qKT^78%N-R}50>Hwyz@3wTi+6ML0@L8DAx? zaRbo^z~QquZ!+uwuW`3-U820~P{~`OWCIn=DQej8JEeM`Tb%^&p2qK_zYB|P(ogfw@!;_8>Pb#fnBNEKS zwiVCAX>;#^Dy9&@zEB|umnF#o5CLxo1-*9qy+ zI&Z);52{G@AYYaVu6U7%WuYKkP~+X9cLA~Sc~>|1-Y#nhNFX)KQPBzUc#WEJg;!CL z4C>@mOR5uXplu%1nF&wZID@NPlThI$S4-v#@VSYA`Vij2q7U~5`esvZXzU}ndsJP5PK5-WvS74hN8+Bxf z#_UWqt}8UGE!gOh7=qMGAyjV-B8egkOi@X4Q|0FuGWZIrH!iT}G5WCA;?(Yy@MUYz zK8x~kyMi^a&=ZUrA~4g2Zu4`H85AP#fRPKkY}1@7ttgPcj!^o8b3){*@Yah-rNrxO>G0g&^X9 z3Ro?`>?_$61e?&B$HEYYFz>no%(xWtm{^9aP>4S7k9PS#ej`vQ7QTdgLR1P_L3GI2 zOUk7ks)@vIDus8sDFLiFjK7jFU5->^MY>YD+YIm4n)Ds2*GPsVnkgLoUntI%LIh!= zU@wO#q};4JROvVxvn>&V1p|i!;!*VzN+{+~VI-<_QVF_-bc6R)MFF)|AnpLQ%bzHh zqGe@XFW+By{>M9pkmlDRAKb}v|Ar(7s8v$01jC>(2#^54bEnloA5*6QLxLzqB}Aki zM=%o4UlBBF+kl$FFGXk9gaQ*cnEFbWln@qtCC89MsrP1yLg-?m>=)}Cx zpHSdVs7L@(#2^ZAEXvYM9J zYPTrSAeDp!g$G~O068S{l0pHR85UIpz(&afUuf3=HGwH{rW7J+AJl##8Zr7Be6p#X znWbkjG{KWR7?2iuQ4GQ`>q;$F!>T&J&X7SxOxKm5d;&H|z~Njg!KUbp#8S4Gre#Ps zY-DUCDGpqX-~e%{1S+W>kifOjMOc{Istns71Qp5epv->6K3$F~g|ql#)M!L94@q=R zY?Ub`;H@mci;es&@Sw)uT6J))Nsgce$dUmy76K$l-7v!gjbTz2$grtl2*p8xPhB5s zjN$JHNy6!KM48eNV=!hYZ^45Qa}3`oM+51Fmq4o84`=8x3&K#MVn^9=8LyrG{%LbqFN6n1J+LJLAWuP+D6o`jiFc_sfXjh_5HCRhAGnPJq>LCXIZD9FvG+KHKV<{zcMl55`%XWI zQO<%yX}OUkh!*e^L`hjXBZC?lxu^-5MBacFFT}C>Q{reK%$$-O1?7)~LA$E~${i7h zF*jfZ@nA)iK=2hk!07}5$1i9N>=eq;)D6C53x!dgzyh-1B`*pz2Ph)CH=+o_k2>_! zX-rJeBIu^#YnchTfR>Q|(zTxaLEUcWxO#^If|3vQz6y@K6(7t3kp|+AYew!sJG}I! zQLhw~h+zBxViPDo;(7>3a1$**?uZK-U~)%&Kr=iL#c!dteD1LuPrQ=M{x%}``~tXQ zo{%!lC0&CI0plS0s#^*RW^fC_I51A+(rchKYbbhRZt&enz)7!hE~sJxt3|*Pb*ee) zYHxz|j6rST3+xVruSh{Pi^ej!3-E}B?G;ThO_ls0(gCF71yaf(@Xl@dil22LD1-zH zt%9}C!MTx4Z%`p}8BI{&-{oCuw2%sK=rLAy9pH|rBbTyev;H*vm z?7PbW*yVQMcO8~mA~8;-i;XxcF#S=c7?m$`iqr?^)>k($e_9E*GvIFmpR^H}>fWeL z<;iZ!5sBZ5h>ZF~KzvgvgbXBX4(^Lzq&$>ePJFj)Y6S3ZGi(cMOw}bK%ozw1a@7&O zzFkHZo%ent2O)SWn-Q`FUq0Cnw5$Lf!n+B6@Mo#TE9nu7fv26&BL}74)J2@4$x*6J zRI2xs3Pl}n+ z#&NUd^nr{C*d*wnYi|GoW&$EW#4wnFz~?yCCD?q7IVe5>ddte%=0pgqjSt6CAdbz}xPlw zGxA5MZrsKII8fExa>(l0G-^Z19u4dpG0laMm74iDLu_fRB5?2yE4%?1hM$7!<|S^p z697Gs#*)M^T-EpSMm?HoDG7~cEienU;v7ud=CES`mO+oDh7mkoH7+w7vooaF;Y}cqaNHJ8B_B;wH;x3eQyQoM}l^n@i z7&osp4Hk<=8Rh$j!h(Kfn-|w8MlAyFx~kFxAJoKM#TYv^87>l= zQ+3c7C#b2+m5$VQVIZ~Di~}LHA8~a(qz_Q1>Zq%z22X6bl1^PRoCGg6N9AGYPjLE9?ZlUf1*e!4HJX9PHRj7@?} zN?fAEzGzp|@$ZK=Kfbr)e9elb<1HydmI5Ro&v|iiBZ`zxS?e`rYBph$JdpZhWih^S!F>n&fogeJje|!tSPo!- zi)SAYJpj=bYNOjpaF_+<#>1GozojAXQr8zxo}3V}iCg2AI;G8M>e)1)bLpNBDp;SQ zZep(03p|_}q3Xn7anPS~TIw@=1Z-ZeJ#bL#0e9vnf{!jEA-T|}%3%m0;>(7j9f`Au z)+K2gBIY1N7ZrFKPNLGdytXmMg7K=44%ObU*BC20_a+Xu&}PCLO@%w{C+3%Q05Ig7 zdTcdP`*=BO3W4mugNFB6!S1(DpRW(=_4o1P2uHBQ43e3E*wiafL*fcp3YI#9Pk@J> z0LAq;m5Gxe3t)Do8!d7{h=IP$fpsl0TwdfATvSeM0Y+CvxCSr?7(Nw8C8)f14+;Ve z;4!YMT*Hr`m`j5JYDevioAx0Yf03>2Ov-oE}&nM zEhSByNNEjuWZFB0h|(cw8whtrE?DBqLD*$#kzcBB*nN!?a5`{pO(}}+ znD|7E^F;gu)y0>OO$}K_eZ5>cPL0coR%;NpP&YIY7x<($`S+{PCIYZW7|37_5Dn33 zn{3AU2onBAwvhBEA=>%9D0SvB{{$m;20~XN*D@LB)WCzlBZjIon2`_%P17AHRO+o} zIuO*lZviCea`0f()XK;7YR)31!CXYB7z6;oMH}dg3wMKwdua9Euf}yKHr2CycX{NZ zJ3^M)K)8ANAHA9aM+!Xd<9cO_JCZ+7Xe! z17=>IrX5eCIU<0B0EX{R2tZ=l0_HdllTy7jP*Sg@QesFDH7d1FMC`3>05F#uN)>vZ zDb(Z{#Cd429&TG{4_qzY*08Pyu++wcHh?r|NqZ+)PK{h6;FHZ;(%kMV%xj&H%>}(H zUDH0{JZLI55U(iyK%et(>;Z6RZ6F|)!|!uSjV&k(3+4xcuAt7dSfo{*xdcS)W2<|6 z5Bhqwf^#(?xavjl0O~=Sctl7{xbp_wbb%2m8Sd%~F(Y-0072z&&8Td+X|PZt5DRWd z#8Z@mn0UIh26!FX=USw1(&QZPEd@isX_`+?Sq7-B>P~;K5salcfZ1yjanxMWSUt*B z{1I{vZR|+;mzK4wQMAjFNn45I106%7gZ|jN_9$Kh63wjXJlcR1Rowedo;fX&u6v>W zccx?P&#n}gvbzXQk!3-8nKek6w`S)AOJUtoxq!u-5I~q>>)afW*v*bvRKI4QgeZAI zHMCd<$&jqStO;^<9qu#{8ii|axw0}68VpPdMF+U;d? z%n+*wk_Ql7D`Jq^1}drPuL9|WHjfLz4apWQctG)C0jNO@b7~(XzZe*K4f9G(`!bu{ zwm_^xO{&m@d@03xBCabW>%9Z})OotmyEoYp5vD-F-ALikQ?tKZM3ZZ8hOiqeK&7er zB2Bs;_jA$*u&8M$R3O6&hys~8OP}P@(Hj@YZL~&PA!lef21|Brd8pIVl2xgEku}{G zrV2s5?;ygEz+>#&_(k;eQp{a5gErhuBEaA{yTO+nK2(b%^hdtz=PK1oR+k^dX`Xuk z0E)V7rVA9Q71Su=->W&9x{H{I_|fpAYm0)M50AcRQYJ@K*q{F1)Gix}Y+)ai19Elg zlej>HIHAzD8W?0CfeD!s)q`x26XZ!b@E276_6qwB+8C{e6_Fe%x(b!Rp+qQF0F?8f zQlMhg=GWvrxxIr%ZV^Rq$Ma~jJuMA0i{|)n!lf{HBPDn%ghJYjSC;mJhzD4*jo2I) zz!ABYi!7~$yU%4vv3OZGnY}<0YEY@_KkWj6)xcH*W&D`BS_)O!+rbByRr)B;G8X1A z)OGmA?PqI}`Br1>9m7fy-Z0QMADZ(FjTXdcHq{KCkF7YBDuWhKBw(w01d;Shkf!b2 zKqx_wtGe1)xdVAF62L*t5SU8)Q!SZaUqJ3niZ&SwlaQuu+8%JQ04Ze=jCu3&GdpT^ zOepfPGa7;rYF44wy=z%gdp9X>btD`7!ne3J5fu8Ks(D{(a0RQy2ob!`ye}dAf@Vn^ z8ETY)U)`#eTsayW6t5>GQdU0@`9#fzZov~?hU`H=(Flm zd&@+hVO+S4C~a_2y7fGPXz!FXI|E0Wmr3bru}2Ejj1sRo^X=B%H`KT~+6dMus8@Rl z`!l}dz94Z>KQ0*b)KYNqDA`6FDbCL`5w z2Cq3`g;m1hvbKVeAEJ=sHlMTzbpe(PB?0fWLQ9RB**T5fJQ8Xo_z@7Tp2!3+RfJX< zcUt{QqvoqO*1HDw8UcD05$$Aa)&#rjU6Z?QKxHHpCe~Jg)-UI64}0XgY1Cg&5|Fr(82~HYI%uc;&o}1hWqObRlw9n)moBP!=sQ296^eJ_#&z(L@9bg z5(A?NWSM1t0+H43-A^C_hWtP~$j>rO32?7=8%!uB3@?I#ME7q&+??@RbwGay6ZmjO zsW(MO(}v7afGrK1(1zMc=KN}0Lo6}(v2CHm)~1RiJsSm2>Ig z1Ks)X7~xJUq>hFPOsZC3AX!E4AbiOrdIupArzf5dprUevcM9 z95{;#@=4ql+ckZ(T^|)y3gS&$OK;KIphKZj1Wy-t;#Fv*Xd_DT(^`333;vQO5@^XP zS|7N3A=Egq)gvKJ$e-O=4CzBHdU_%>iKBiwE?Eh)jf-$ZtYHIGMS~y$S?Ib)ET}JB zk(2TG-2#XM%i4`_g46pE$63|1bU&Ur2tyqZwGg9QuY*Pjpwbed+WgTfZpK@@j9^>Z z*h$)aLtAiId^@#MUewf>RNQmY7CLq!w1^9sM;e@Vn&)i}H!UvuyJbA@b)@}P8M*_p zGN|I>?LL3NcBvbOD4a=UY5mo8wWBn!ph>Zi-q0BatmUtZ0{AFeqh9ST=%afj>$Ky&v?aE+_8rItZ%9;>+R>u@ ztq>rAHiXrQZtA>DZcj|H#PW2b!agP z2W*EJvqU|NA)@t8DO^R}k;nvRCvhYN;F4L&W3`gGT{PW}Qw>31lm-@GYcL~P>K8{< z4b`>pscpFGVE(yi%-YF*O2+Pz>TUGO(PXknnni>bbR^wXje5tEFwdhMc&_x0eq7c_ zJqZkhxetB-l~@H@2-|s$FA;?CR;l$ASJi+}R@2h&kU)XHtX7j2^{5maXlYXx{)#;6 zTD2ZmjEZle#I$~MmuG{XS(G2eORign=7g%kuTxm5w09Wg1|<(+}1LF1uw18KOlY2$`} z*U4 zA;m!6K(Am5U={Z&p4)`rUmLdOGy3!Ou0uqwc3NbD2i&`s#Zt*`HLJB#twh5^iCUPn zFV?rJtrao>QekHN5Ks+uA8op4fTnBXa0*8e)oYTT&_aTiiXR~tt>lh-AR*eKJ%&5Y zTCIUpY_b%7nNeeK@JfWB?iM-yu@>c@jB#RV8)?OFYaQe6nNruXl;$9D2lA4@hH3%u zD(&})ESN+T=qSOp>IRsn81Y2oc30Lu9$7RxafBJPZ?(Ew7}}MSEJ8sYJza2Wg`kt9 zW!=TDqiv~DT9Px?xn%+Zgd&3<;VZ8EPQLqlhyw|xCxKHztWPQ>_}>~5PCH6d4I4c~ zz4RF2Jop!BSfDjnutK%TcPH8AHOTfTQ8=`>Nos=1Va1TOc~sT>O(1Y2 zX{*%}n!!t<0D`?PPPXR*J0P1Y5Y*|jKq}E$Gz`}oxU(QP2{p9=l?+7uvmiUu&&D_K z;Gp>2HDd<|Ng87pYx&b}dF;UK+ee7=A9g_T1kytt%e$dq(#w2sGOd%i`tUZ z*0|>lrE3$K6dVyvq+N#!B4ifPtxbM~mS6zp#ErPup3zQ(3^<+= z1by$L8&-39G-%ZJz0-3tp%O~42f?wnc+h@MJBw3~vj%GTHbe7gEiO=^z9}^A>)dT^ zp~HJThL7zmx`(BXJ=&}$#s?HPQBw_ymG5{GRvtB5b>r;vlA)4zRA_ssh+({gYrkVhD;f4YD?LL4r1nl=^jc-EFDVK8A(MH?f# z2r1QUmaIegW<7j71qqYeC03zs+**;osp`>Zmnmxq$2|4elID9rtR`+#f{2O*xOj2) zzI53o=7x_Wm3BrVTb)y6~Y^qC)ETW^c**E9l@GZw-yYV z(e7UmXUf|7KwU+xyAgs~xZ>ktgWBrC>nf#Z-wrX{HtUg~tJb=RnemHk!)jJ*r5Zn= zGra!g2~K*cphnNJ?Uu^io?2%+_}UG zB=Qh~!G(o_>|ETl9>SWUZ`x(&{=C_c1?@oIJ?gCIGzcfnTE@wU6Frj{n!RmMlaS!^X60c z;m)yNTCP$c=6d8oISY_=O$61)EU(!EUYw=&wzS4ufmo);_nafY?gYOres(mDI{2>z zHM4en5O3FgO--q#r$@OQjz~c&V;KL&`P#bD^P3a(SJK@FA(YSx)j>mDahl9Q0z%Mk z%0YkZ`|n~1`}es|ufpC!sg+-CfUDY&dWcZeC8)C>bUKHw1SYZn8S`<+(cW-jYXb$n zjLf1S6#a7qL<*^fqPKE;y5$)R>6)%?xMy>ZAWrREVQaMo@b%DcG+JbGBQERtQ9p8~ z`YzlKFm?ViLiGfSp0f#Kezo!_IM6sfAG$XhfLakltVZkIQ%l!(@N88|_qOmwNm=zB z^}te6y4M_PQsCxoHF3MtNLf14eJnp}3Mc%B0yV5s^*k0r`s?v0JPOynz%8D6I_7@s za(=?u?qX}6!SI$Upzgk?(}zHVQ)uB0B9vZdG<c%kb|_;8QImD%#z^7u;)NmpeHpJVxF{fPSs7KW%>|s7EaOI=ij$8M^zvxLMb);}=RJ$;# z3+bGm_2f2!GwLaGa&Sj&xH#^U*XpN}FnY|q`LDeV$dmT|p?y)cN@J+4CZl%goHG<1 zPC(pH;kTXz(MqTgl%ODs1+RJ-0;tquuW>u~o-LX8pAq2-Kl;;LR@5{>&-;X;7;E zm4K}oC)_^}LHGeaW`foZ8&&dXm{t6n>FKc-wbTgvrKe&S92SzIhi96e{09IAsdnf1 z3*oMohUE%W!_g0fs(jM5W}?Slj+z%*gGP_GUjOaxr-^ExamnWY0K*)`ho$PaCjbBe zgK0xUP)S2WAW%|IMoCOX004NLeUUv#!$2IxUsI(b6+t_QIAo|!7DYuIwF*V35Nd^1 z9ZW9$f+h_~ii@M*T5#}VvFhOBtgC~oAP9bdI665gx=4xtOA0MwJUH&hyL*qjcYshY zGtKH42Q=L_Q;E2k$*zi_SA-y-4`T?(%rfRADGA^4b&mjF?_xa5|JTxwGo6|zju4B5Hdfl06-|wJ zia4rjI^_!)k5$fFoV9Y5HSft^7|!V{%Uq{9gaj6`1PLM(R8c}1He$5uq*zGNe%!}D z==vpcDdZ}Fkz)ZBXpmh$_#gc4*2+&#cuC2C8-O`jj;Bp5Tcrs*DcBLRqA)g1{&*+=7K>sb!z2^1S+{fty zkfyGZH^9LmFjAoGb)R>4wfFY#nPz`KDz!T58{|8HV7U9l1p8_E&+=OVSqW&)%~_q$D{dqrkOD zK;M35opHurqX8?T%D?W5Io$x5t|yf($zBL-d?5RERW<2#c_r8`qk06ZX2m46TM}5c zBzbSngCZ2N=^gz?=4ry#c(kUsVdxF2>%IBF*<@3}n3tw(B0JS3HXeVEbA4M8NL*uP z<8e-<(0Ld6P7e-S#;`<6>Bif>MMikQ0k-IljnUNF75p&%dF`0sgy^vlH62(}ZF zJDhWnnAp?$1-`yciqh`JqFJxYCCn;IZ|bYRchc;PO>(gFQ4KTId>Bke!=O)7%4ji3 zkvWn`>;G8B<3+D9+q;k%?gjkmJ4)TzHFSm!AdmL3vA;pC-5bPrtSo}Bv$ z#|BhWV7sOg#t|*p6|c*1S*vg7ps3!(zV`Ro*AA)X35-vzKnTgD{?l|tej_t!3M<@S z0r2PLW6D66!LE3nKww$1)3aZ*%IW+MWLPKjNa0fM%b$V8WF-<0sZV~bqPPF-(RB-2 zAJ#C4^>jp6kMr2}A~1U$l}vD!5m#aU8far6-b+X505QFX6tjoiu@9jmp-HGSLqg>9>VftwZ% z5IMfpe{j-#hy8Nm=#-PbV@8^}&`3|t5>lFmB}(XVqw%j3>YG!mXzbf22Kz`{| z3H01*>8DkFo;N>xf^C(_EJ~70IjVH*^Aw~O8#eP8`OlTnuXhBS#fhu6BBJ}G9yc1U zw1n5xzIJIh(0kjz3czBrl2^4h|IxHO%M<1#Std;)_onTo8@_l%{pR<@ey)9^bDtij z6K)Lkb_7F2Ksu08RBlO~G&ju!aB7dg{o=7$5V$tjacrale*=fqQD6Gmv>*Tg002ov JPDHLkV1hSIF`57X literal 0 HcmV?d00001 diff --git a/smiley_pack/icons/opensource/raspi.png b/smiley_pack/icons/opensource/raspi.png new file mode 100644 index 0000000000000000000000000000000000000000..c07eff2e7caed932cf7c078e395f8a204d07ef08 GIT binary patch literal 4534 zcmeHKYfuzd7H)iip!mQL5D|KZ7?jx4^XPFNGQc>)W5Ce~paGRYPd|p%c{$U-fF>x4 zfz>F+Yz1AdauZp6fUB;QSwSO$NYRYUzAM5QE-~~aDw>D0b2<{WPYm7Vi5B~854sNINl2h13JO{Sftu$kz zU^drA!IYDsA;{Tg)?f9m6O8FL{&CaEv*Ux#Fo}DovfXp%?fbk_8!`UidH*Zv7d*Zl zG0$u9>-#Ggv6;;c*9vb$MV9I(oFBD7c=<+i23j0DW$)#h{I5MjL+>8==jq1#ttoe6 znjarULxNO>Pn(tmRAD|r-tlWAP83$P+Mk~~c5B>JkAjxlhw>ktK6=zQKejaI4=UrN zX(QtTM|beQ+P1qsdh<1TSoGrU&*t`Yc8scVyD~l1Z*g9`6@uK>GHSJ6t5)}C19I5$ z-WFwCT~y%d^rW)ruxV|o-RkvsNk88e6$@v~E!4kt^uC_qgyg-zZnDI-c-gR+l4x6JC`mIvMH{np$_TNLpl^UFm-3y_+-k zH-Q@eRKVah0Qb58>=hq z?KdkfZ?9Onpy!nS?ex^!igW&#QtEx)DAG4+d?hJyP5ZVQcnLqxobY1Ltxp=uO7?rj zY#QD27gcum_526bOa6{YI^HZyJb8VCIe(+unzUWbhdaB7tM_+6J;v+tUC-{BGoEaH zylBCOV7D9Q>o<>;&s=%(`|*NDEhXNqTe`8rL{DerXVx%i%aV-DbDfpdo0~o0*fh$r zdaXL6W?t*Ppsw*xo<8Z?X33ANd0?;4{_)KZK+`!H&|E3Hc?!a6=HsN*K=GYs8|XR+ z3XgQ!aAG;d!UoF7Sd_f3>MwXOLn?XiNOS_7O-*Goad~zsDQ|u2w417Dt~7Ko8W3+fX52fSS$dP!9(ioefC(0{T@C zM>1HWXd>mXX4wfUI-9bvAwwxhV!+>)WjDFfAqkW+QDy*jfLVnvO&P1z=?6SG35<-{ z=JEn!zl3BNdQhyFV&g_!=?o17xDW8YgznGX1qLXcPNA_9SzLHpjgrUBuOO`iLn>U4 zG785jjKUDHK_oyhg2WKHL4qTsftJZ=Aw}b}@gY=Ni-W~21jSJSay|oiWJ0-NHX)*r z*)ow7!6;ge7~~iY80AvRAQt0NOg@BSft>+eiJOK-#Zi%fijoQ?Qn7$W3}P9DU=lHn z;4-NU!Q>K5h6`jOOoF+nNJ0@~wVQEJPR5KIDb!{$x&}DG6)L?}$rJGfgBHCBXKCP| z7xI92E3bmcWS*tzSYBec&Tu3nIIWVjP%ZbEUT!XU|AQgx(g+QhdN|HrFg-E85 z$lnr(6oMgmE6LEgzlG)&4;mJ$rR7KH*QdQ))V z*%axD6L9qo5t+EfNP*p>uU-4?%&)WpArT8fL*WQ5C&dURl;Mb+qA>&))1(-qMS|J# z-mC`L9afsn!R?gF2y_Hmf%bH11O+Mv~_l4WNLKROgYQZ;e?7w2|*dLCug zt#%u$4b84?*p)WUFnz{P6C(=BCfo=~8C5aM5T9E8aaf11rXa(oM7+J~O7%HQP5qjg z*>q3qvpd0Si0bmJ&J$e+@(ihgFk4$S+4J4KZeMRI`*7W9XwSVP+Vk|Nnuu}5VbTBX zbo+i;@uSxp_D=_oZw7uqA_0h#S?O&2faU<5RcPszw&oM~}!pi@k7lpo6nH%R6k@XFq6XnnTMGCei zxEGf{a?g8s;`aU8PcAfW%ZeK7_XGcOT3gNY5&Jfl*1Zs=`G5jI+UWV319LM9{s)I9 BizNU6 literal 0 HcmV?d00001 diff --git a/smiley_pack/icons/opensource/thunderbird.png b/smiley_pack/icons/opensource/thunderbird.png new file mode 100644 index 0000000000000000000000000000000000000000..2d849e5d30e1f1440869d78dfdbb18a521059ce1 GIT binary patch literal 4661 zcmeHKeNYo;8c&EK=1@`L@B`a5R<9tNY`!E}38Dl6B^V(pSkP>CH*qD&#$m8-Q=t1VFUP)7x+p5h^T?*>GicIL*J>wjcszn=Gb ze(&%3Jd+P|JXcf1bBRvsY_(yu?)y&r;U`E zgqYPf5+a?Hk;8FbvuG_N&q7{3je+SyhU!8;NU>B*yw`O$M`M}WdV|~6$?fS@w#dDw z@IDn(wFO+Mw4ZaSbCPC?J;T2Bc)T?Eq0LX5Q1Wr`_Ioc(Vaq()c2+QBw;lIC_J#H| zw?5+h#BU3|3hoJYDVzSucYI|`-I)BzPfM<5CTi~0WaCXGg=^}PA7!q&9F}`EFkbtP zVPbY2UhGo)P9b{~Ps3eR`G&kB z2S*;vfx39D_gYGB3#K;h@LgKl)$(iDr8T!~&1L3CYh%~O`F{5xdHItEojt-!M^1J0RC#XCxxm>IzFU6+8%_H(nwO%t*0y?0pU>}9 zuDV$4x%urX;mK!pRW}dsG0oj#Hh!#_6TJOIV!L7S3|%YLTDouL_KwD?1Gc8t1B>q- z`1vncSY`3&!H%Mp-hsh};esLOOZVpl1=mtPM2olXeOU6htSg;)H@96_#GUfB$4c#F z<+=y6x>WBSQONI1+n68Tk!Q);!mCLs{{Ha&4*a^ch_l|*GVg9zsz(1f|Iys2ytlX; zu2-K+i^_kJ-7raiGiHbPg{>aC=Z4YFS^MdF-r3{fFLus6{#Y6Jc6RVLL2G#d0Ul$g z)-QYF%qU%BebGcUb_`pWX8%lTEL{e=&PjppO4P)nIBgMP1Z^ONPKyn+9fuP-%W1># zRFZ)Vq=~Ys1RW>O2q21336{t;h{hH{uArhb?PNk`oDR=S#g&9$Rv16ji2?u%$zYJv zVzxR^r%K?)MZr6376~A?3zMo6BxthM&tlVP`r)mPJ{5o-A}3}OiG_&BVi66Da4?bS0Hlx5??yOuV3CUA zNe7)~$H~Za(#lL32tnZe@wPO(*_{r7i%2tR0j>@(tN67kqhd7L{s>kA6J@cvqk!12 zc`}sol~}KFV@KTS3?u@=`*C0Mewn-58F*RtJMwagv1s;6e)E$Rrp+7^N7DOT=yn^8>13Pgvcw4){HSm5TFvoQr0x* zs{tKlArlykRZ|=yk%lOgVu>7)i)A4*UO6o$?GDh1ET$L{N_#1=WkEqQKv<0JQvl$O z0J)$Mb`oP~yN;&KDgjFgVk7&9HDEar7=x)Xh6JF9M1~>?R6Ik+-W8}!J{^&u$N+zu zpp2{kmp8k3pwQluM^g?k|7y3XcSR+Tt9rkBKh2bTDM65XQJ@&!n}P#NCkZ!CfYm#M zufVJ(66_v*?fTMA{Z1<=rMM(Sstkc;I6=ZPg+dA|jTiyTafQq%F~|*aq*tVVbO&u@ zGB7(i+XQq3T7mX-YX!aQE>z&_TryUWY!!fDFrt8eE10M+VG+A$yv#UM^czh=-3|jb z84%ZN1DhAv3q}2#VV`Dz?;rW=tHmEV1q2OF@<#d&$~7q08!7Nc&V$`GDAyY)@J7yq z-SvNyi~s64MOwkXpbT(WD)!gk1_v!q!~7^UXB@}Q*;lu2d>yb1w?!v8!0GG<_TtWY zcb5|whcPjl$YHm=d_2d%w0G7}aGGw3QP0*X8cuINovK^tb1sVx@$#G<-~;DoFCC)Z z;M_1SGO_jA@bsLGP}d??ez$+@)SQ%~M~_A0zWc6L7SFt18697m3k?|}TKIr>qy5^& z`iD;|cKK%h(pmV+r7EeZ&HGv7SVOs{PF7J+Xy#n?wvFg&ds1GF>Z^B`U8MO)?NMIk z&}429ZyUw+kNwyE_p>Lv#4Uk`v-158auZw?UHNvj!C4Of7ab}iYUdv3Yy~0`N5!G|X8gyt*YO#8u|^;p_OpyAzO|HTzxjp6sEYF3)H!9kZ7o RR|U$?iHVF;ADpAl`7c%W%y|F+ literal 0 HcmV?d00001 diff --git a/smiley_pack/icons/opensource/tutanota.png b/smiley_pack/icons/opensource/tutanota.png new file mode 100644 index 0000000000000000000000000000000000000000..9008c6845c386fdb021f665f7a73cdd1bb24964e GIT binary patch literal 5011 zcmV;E6Kw2>P) zaB^>EX>4U6ba`-PAZ2)IW&i+q+Qpe?k{i7dhX3OfJ_1rB90#$=H}LWOG-h^1a+9Rb zRbEOA!x;?F;SHc!|M~Ye|KcxJn@p5kQccP77i+A(@ut}8?|OAMp6Bbs+js8yxOxA= zb13i{u8(Qm=QobauM2X#kN4-}CXaiZau4L*2R?s6@2v0VJ;{5Z;IHHE{%q=fK}!$I zx&Qld4|@;(`Z;ETF@^DhH+}^d?0NRror3=Nq4Ao}v)23%jenYv^Y3@|PpS6K+sD6$`0YK*-s@Uji_}q# z>0Z>^QqDV0?1VF%%My>wf8l*TkIJLiW(QfDEVUck`B1rcu-ip9U31&5^E%vMiqS8h zdG&tyaE_Ibef5JhxDfT>w$CQiFv*1vgUkgE`}euHbKk1><7S0BPsf?wF_=4Qli9O%A>9=r6^b1%L2 zHYlGFhm17xD5H)x{R|TbFf+|O%dE34wnfl{F6M{5FJBI1$Ym8S~MR@vIr3puOhI78j$}%xTVS^}&Q7 zo>__}XFAOo8H~$$+3r1ezcTk_-VD+G)4ci5GG{b(|BK8SP2EH0KIZL{tj%`dHk<@$ z7ZOttGSGgUu==W;Q%Bw_)|J4eot)IL`JPxv%zK1Tb~#5@@zPe_bMKP*Z>Hp2mu=fh zs(sl2q^0S1>~*b`IK7v|ztmeMaCQ*RY(r|T4DG(Oh54;&d};hsg8XN%zdaB&&VptO z{aQI;;4^D4`nsbLGP1#wJbPY2?iGfipv?*;>Iz-)z84lLsZ%8s-5`39K=z<;a$_g6 zV_Q(hazuH!Yjo#l4tvoN#C4=rh+O$$%EtbWg7jwtwLUiGNe4+}Nr4DhD}2#|iU@I) zb4T#4xxflNOD&YeUbFVH*NU<$t9DHwv?x8KRoaM8-gx0TStrwgNKeN{t~=wRIp;!K(oT;+u*dOOXgil27_s_y?G`Q&sl$)zxKE z+s(BVx7I}f>N+AR(whuY(yDVV=ade7tF)Yy3=1rf1rXidZD4e>8W6GrPPzIEtU#AK zR-C>Ax!Xd;a03?%3bfB%08!7n@@{^Cd>JUn6;yVcV6O(m0mOSc!jxwgD!Xq5iXq$s zbkJ6A<-Bq&D;UHlWuer=90VkzMzSM*e8Wkvqd|seJid{6kim8UJnFl;Wk!XF*|L5% zE(=SEkQ)Gd7Dy{WJA1A_8s2<9{@d_w&4$*bIb#@n9cH4JU4mlHP+@fq%-r2D4jiOa zB2W#rqsvzY$!h{@r4#BzgmuDpuQ8j0J1CQ`WOA>Rd6D5kLCwb!YTnKK!_p$I--$hD3>Ds&uXk0qG>9NRC;z&$PGX&on==7)GbO@fj= z;rwhB=3yD%MfIBsxB^xsH3TJK9}h zA2~PKrj#HEBqWZveZ;Dru9k%h@i7A!2wYa3%$kustS{{WE%^>AFsm|irU}I?f3>6= zM1OLAz{V|cy{npHxrO$hqdNptJn+*6IQzhQ=6*98QW)*i54y-~M>6C>JXgtHau0lh z)#dab!g5W%>O(I5g!DrOw22&DZ7C;GEfXDpHKWszcX|3E2O;6qZ(hw$C-CZKr%>lL zld3X}nQ-jPB(^PsY?wec`vJ>q(u!odoK$7?N*TnwTv$0{=Lq$v4$E+6J8drOMst+^ z+nf6}A?)5l@f?U4h{B{k5f2pjm9TW?CCgW%Z%7&JB54=9(Fy0vTx6B8Y&zM%?yefY z6DsCUq|ln$ga=Z}P%U<5lTP$ZQ?a56L%5uXKF9MdnoALdHVeJhjGkOkRrodA5=LgA z&nYjcsCo&8hGOp%heg+|;J^^tG^XC=iqUqbuOZ}!L+E+f+(_BM$ARWfDC?7r?C7xO zUNXc}GNdI%Er7ga515{yPe5lmOV5h!G1nxlRz#f)-fc9Sg6?_bJXf1^d4MAccFRt^ z53-P8d3A<(BGm>I!SM*`IKHXC;jMN$0FwKux~}!12vJSTYc%GLZ2@CcLl8xo^I|j? z+La})WVq|PqDUP#&|bIe$wr`TV*Ez;N5#7Uj)e;1^cia%Gt~p44r6o@J(xsr(y3We zj{d>Xbq_#Re4&Y2#{*?PKnvm}sP?(>MC1e&jE96H@Jd~9l}uH^>BN}Tw}-Hs>rGA< zE~~}D2-Pc>AzisdoJLH%2j+Cp&2}PM>vh?F!( zI1^+}-%CO0P(Vz?=YE~D;CUaV-mIGwZuL}u%*2Fh?%glh%(AvN9810fS= zP^reDJp=Tqr&7s5ICu>s8HJv$jSjA|n%xV!K`^AS9A(gS$8h>|8%TmNJ|v`Tr<-qp zUk%q|jb0V{UY{TuQ_2HVPsU8%)dytlDS<{T$5%l6$e|p)3hceS%nONr!W_THpXRah zG2*!GLxeVw5rojyGF;MTDpFQ=*->^n5P~Ck z6j6&2m{6mEjsjddH9>!ANuiIZ+K4`iCRk~Kyv|-ISRWk13cp4fmZK;aSE>w4_F(_OU?Y z$)wR>Dj_sMX&x9_eHW%p!F&9N0gV0oQP8(N9Jpm|Vqei$fcT;@~ zi%8%;YhWv7taLAA>&}u4)GZaKvQ|N`95Fg}tSo&ua{yJ>G+{qC0Mm7n^vy|)==P|_$$E{EuL16->tKGnu?iM>N75*9 z%t`c(21HmbZBB59N^2@7NIqg@!beD_0W7C<;gMMHU9V^r=)|{5@dv%S?ODLkwS8XX zR0CjB1)#!Z{jf%I`?sQYT{TZXnumg?<(3^YCI>sh%@sjbQD8_@>yhRtGaxL*(5ahxt zjt)=j-l-4oP&h!J5TlbS051`Xtw~(zSG~1L)4bud`A(|*iBd7&NtN%F%6aV-Wa|gm zTuOe}l2Gpim%2>?jRT7kl<9~WrN${;u#hS0hJ8(7n1d$BOafhKX=~QPhayY0Q-EO{ z>#m#hJOc|!Y%ob{uuDs!;hRB)!H~U!>G5o73>J_y66JLMp%1MS1&327ON&sI$_2au z+;8MaSKvVNw2?;VhdLdcN>7B*v?@i4XzOC)JgK+jsmjaIRvTkFa ztmTW*0p-&f=nM3UuP4=0s{W7^V?X7w^+yLS4|kWxzRM$-fjrxGkW&oT` zFtjpO2gTtq?EnPgI?w?V+FS6Dr5Y9dDKNsyWOaLl-eu*kwFRu#ShLedip0^@h)m0H zPf)=E4>4&vDdIVte@BvXE1#@}YqUh(;K%qlXB4NsEV|kkDNQsg6GC*S6Eh zm&^u~O3xe(`ddC9wC=GfAhrWpDDfQ^y$L?dIS1C$8{uHVhUSbVrN2pN@@JpXi9J7^ z(SHb|YkqXW^|O#epVAm;8P3Jd2F!7S%yBqgv1B>&KvH78EDOVu;d|e&_*Cs(8?i)QA!9mPcR@6N)ZY*~t|}ukah2wrO;5%a?8gCT^{} zAU|K&ix>GPum8`1976Hb)pT>&YhTr3MU{L(I|_D%E{LN-spt1M>WXH7?PE%~q8psY=VXB|~ z2i=sKFou4s$favPq0rSE6}w<76VPAPhz;t_{1Q z#B6Rw480-*0sV+#NM@EXD@iH%j<0(J_<9%TS^nq#96f5@Vn9G7o?(V*6R#6bZQ2Is zec}i!$tv+V@u*1`B!1+&;_(~jqRRr$jF_499C3tLEVi-I#;jy&#FNA^RnsY7$a<`D z-r}s4tE_oX{=#rxUtZ!m%_x#sz#=4wP*BAN%CHfqRVT$ln)VYu{z2C-kxL=h1{gW! zQGo{8^@IPx?{2Na#JHCfP5_-Rj`J}Lgm!^O&2heu9j9>u1fPK`z2&def$2}uYb`By z1oUnL7uPLK*#j;QfrgDF^i30^O@#Z_Rz2J^&f&Ds=-K90DUn z%3kw%cUOCF|DI{~_XARFa+(E2jSm0-00v@9M??S_02=@zQJ_Ql00009a7bBm001r{ z001r{0eGc9b^rhX2XskIMF-{w0u>xMz<9#^0005HNklVCxQtGFqh(rLCtHxKH(MLr@lE8pNfRrL4 zf`f8hH;TC&N12SRWQ{%_PlG{=XIa77@iAXMggM{+WqZbv#1_qMZI!-SJ$O;Q3UHXNG~hq2d0CG&Ma8 z&>5ScHyoxt6hhTB+b7vlMdgD7_I@M?>aX#(wAAIQaQwkhfs}*!Q;LX;0ILoGB2;}_ deme1OxdhkEJ(O&(b`}5t002ovPDHLkV1gG2g*pHL literal 0 HcmV?d00001 diff --git a/smiley_pack/icons/opensource/ubuntu.png b/smiley_pack/icons/opensource/ubuntu.png new file mode 100644 index 0000000000000000000000000000000000000000..1e68494c797857105972c72386c36f02d60b5d8a GIT binary patch literal 5067 zcmZu#by$<{_a5CPrHIlSNF$QcBgQrwK@bE)8tGO_kdPLnC8Q+-zokyRK)?-gBOF?sK2}JntV{gqDUX1t}9L2n3>lsX=vs@0-{UF&?l_6%Y1< zK$Kd(dWP;g=3cDMu1;3A4$oQLeVm`OKKHh@0)f0|%2I7zZ&xLRTrJbNg>+Lg6WMn* zwJ`^@-V=pIFgVKfsIkR6dW?yVG4WvySX4 zvag22dc00B9!G!MUHXnThkI&v52CjYJd`L;k1sD8`<6cx&e2Y)a)*^xQJtj7s=M-8lJx_mbd_!Z#w=^o`YW{V z(P+=p9qSJTn6|)SFQ=2HyV6I3ZW$4Gd(@pg8!Kl2c+SfuyP!NR=iQ#4dZ^0IPAx2K z*PZhDRk$@WB(y#GB|E;%eI65Z$IZ8e{~-PBZS(NC@fp8C6QOB3b8Y&kqa35Kt~v_O z8LK*zbE$2!w{85%J{~V5DyAZb%Nv6h`PbH`UL;3X_@4(G5Pmp%;yK)6Xj0ej%lF98 z$4Eu$yX7Mp%<5G0(?3%vC)yo;^O&ITV~@7K!(LWV9Ax~prlYLFe6iKT7`d62pR%}= z_Po{}d?I1ibe@{4iizZ}@INsSC8wC`V@zL{!2w(B^jekn;2C_Dow2OgW~K?cLw0Gq zJ$Htdx?4F46`#&0TYzNfW|R)fOm7-8&Nq-Zqr*37ZFQZsIv%ri#`V@I5_pZU$3v}%?-HR3}wa?V)!EqmcKl^rXFbUlJTeD)#3(pE=@HBL=roqUws%KP{ zH~(pEdjnpxy8*Ag$!tw32aapi^0%k+`I@pKZ3Bl!cE%0IKaAFTKS~d8H(5l{1Xp}7 zcwsQp);XuR&~Yqt)*(V^TsqIuyL;o0sl`I{*DBQ~BFA&EN3AL;JbU%wlmk|zZ_7rf zPM%p5OdN%qdG11!s9rl3PFn~{78((!X%S|)B&}FCNOY2xiL3tT7Ezk+oV19rOz!O8 zZJjX9r5NodG}@AGzY?!l)5P=lM{fInZ(T>&8+~!KM5Stl@wuaxjiLrF4nOtiESIdD zF{C@s`<2EQ_C$6qwwrKTxO9{k#FxMwv=TaIe7SR3ZZ8LAN(S8MiIr5*v`_Mx5E00& z8&^1_+40m@oI&uWm35D+*yk9$lz=CgJh2R}pj7sV(zmb67cf}imOUXkh?9tD;-}?e zdrX8;n(G^~@am++503VG@OQfosU7p)da5^=SVHi7*oI0}&hsVC&9zW71C%k}I-+?|PkmJg33aflOX9H}dxutTE2 zU4I_%Z2IYdU{4d+G2#JfPLvnO&+dmj&(<20%rcB_IXw>4iFPQjRBU)?!6+DG$aKPi zA5OksJD3(8-P=z?7YTZD`xoU|(k7*5Q_9!RoE4fx+uy9*yss{gp!hG3I#*}VQOpIN z)Gsycb@$l^n;ARY5?q1|z>)+BixUnnbKb0T;uzX7ITDA7x|WpXR59&6^x@!WZ!({i*LvoOO z{2nK>8&M8PFKf>IM3XEp)MmifQ~`M}!Zy z`o190b%znLX32WV4CwIF&}y!N2211590q;z64(CPB^*s6sTB-MN|Dp#40^k}1GmPu zRxTL(zidfPjBM!`^=}Z`I zPQ`(G3-QSbJBJM*DIAsf+ZYpj^@D67Q9H9tSBO7;QI?P9lZ8>eUf9q=#bSTJmB3n#Q;~agG%39a7Lw_cz)nJXJWV-o`EZ*y0^nki@P$mP-rKwn&PY=_}2TY zc7n-vf;I5#a8DU(;l7)k(n*2)e5y4iE8l3}-xz(yXv|`*!v^O>R7?mJkL2fXR%R-; z>L}eU4cLd*-~FrjtwX@%XTDpbhOVw$5k*Y;)<_hI$VzER&3iWB6z>T<4%(vK#Czh_0r00s6~ZtP70I_gO%DcncoI zR;J-Z(hgtN6@2%5bq7NlCNrU}L&vE-1Potu!-B&s14)kR;wET(<=@kehT~Eb5llpx z&g()&jKYM3+D+aPbH!`fK*Pa0lTbyzpRB%gGBVw=4-uQ$6ahRz1G5B0D^X8DkjT@E zH_Ag&L!x=bc~u%Y>=jm~+HMGgbC+IwC}T+Teja-6gG8nF^F^@?JIc2toIxd@?lOGD zUGzSU)8u$ahYXdmdoS7Mu$SMeEkI)E@VD3!+J`D+j5Dcg7|6086tp5s89c{(oU!+5 zae%R!`QuBG8BAS|*;I$++MpGLW}G#F*e=2A-GxMZ^Yk_gaGCY0%3^DWm8ni>q=lqdH*9cn7T+{8xY)y9G*vLAdYXnXSaeil#If3aM zS5CYf-Q5=7ky4E?i-?|8<}CCVIE4IMtDmLKdhw|C!~{egXPj=WZ5#9&;nN>4o;#$C zVBHk!C1h3g6BQJ`Bdu1FRyX>{dwUJC396qxDAg2VF)4wIv%DhNBGtP z!mWXqPh5<@p(d}zzKUlTpz@33@GdHyg=j#XJG=4`lwz-T=EG==r$J1$`qp3FMb(xV zF)miN_KZ&GYYS2)1j)tC4E2E0>}LO>MPuu4FP$hdNcT^r^6cktn<|Es)PaSJ)x(j* zFvyDbX)a3fEWgy_xVq&2y{$`D3^><_ESUWZcBC27|%dx^)1ajklKN;dts*{No(E#Y|D-5%(Uc`no7 zagk3a^!Ty7p5k1K0VVWXJiN|ui7W|Tza&D{uYIRr=shHUaXOw?BPP|N#ChUGs7=pt+` z8&Yj+lWk8QW+L3`M3N}W8cm6XdD*~Ro$eop>m;+dn#67h3(%U+xVnCa-T#;|*SPsj zT)Zbc!YQWM%)v07eaf7&(#l>MnZ|cHDL>1R6@X4fB?YrX_x1(@p7LHkxtGRb*G&=_ zvQbc-wXqXsaAYuebFu3w`jTu$`ZFrRDifn$9KysB8u`%B*qQUOp_fDZblB{&E%6Xh z-Be0+4ZgCC+?L#c{^i`p*N)X92noYc6ho5c4-PuKo!`Wfw$B2TLuJF*{HU}_`9gFE z_({~*RJrJ`HfVIj*2Icn!Y`Sf(1M!z9s8W$ zjlGLvp9V0~Ld8-Ys_tQ(AYWu6EhN z&XNn+W7o=cnnb1q;jg{FCuz{{<D~A#kbeX*J<{SC_MiQ-RC~pX!X|Pz^ywZJOt+t4qJ}Sb6goD;l)WKi`py}sYi5h z(nT`ahvO76^Pxf()1hB|y=^WpikCe;@O_9e5;>(U7}J%eO3~0no^L8(Hkn$285APq z(YUJiW0t&n#9`_8lml?tYquz$oq0%E{~(UpsmO0S%gFP1>nW#y3~xmZGmwaiw~cA< zs@>;WF?{>pxlHD+t^TXLi5e-6yU-7e`Gzi0iNaAM&VDkcqQm4IBM=;?ORABPMpaY7 zvV9N;C)8F+NeiZ=#HyvEsRBbN1HULUUd79(b;vV!J=M);rzheKmw*;6nJMUXYJbuS zAk%hVD*{TVuPNIc%zG$@VV8k>V(9Qy+4hrffZiDA65f)hez|* z_z3Z#OSi02#15nm#tR&s7a%c}xurLL)fLhdWvQC8M#Y~8eK5{; zo7gI=iX9_jMVfFq1-@1?tCyd)m)+a7+1WwekG}K=Ih(l_>}t0qfwA{;W0WM9^2 z#-;!sI2Z*a!XX3q@Bh?*EFvI)XG29`4ao%f|CIxr6Z*W12+r$ZY}T>{2fzn_1ro7N zfB=wqjRu&@2*A$`m~$j63vwy+4`U}3Kp z0>H%T0GKEk=XH-j?tiEMhJsB2l)(xMET9&4|A+7|5nzi=2inIfiJjwhv)Hf&4K}O^ zARxhO*8-x{uloW@TuX!{d_6}%Mj&z?$`0(n0xB*6;$xxyyBL60*EGOrKz}TM2wIhA zQ=bm>HqbM_562jfYYUGO3Uipb1EDt>{zik@H!D&8Y>hW zg1vP>*7dyt_62pG>rSy@*W>$7z3b6{(J(BrB{&bz`}IV?(qgL|z&n8BuA`v~l3)7? z{Lux%v4E>WLE!{<)BuCTS?#eK2qXYR32@+e=gWBlP9k?0QkiIt2$!B)!cRw-3~(91 zpbC22!$}Ekq##yeC7I@{t2NeprO10!@y3*e%FRUdl!Un~+%Zd?FQd4d5)zX-hnT%S zH%pk;IF;>oA~$FBPZs-!&D+v)`7GPLakGug24DKWp`jq;!Hq_5T^Rr+Krm$uXt|(ROkN|^@3l$L% z23J7Af{ciQ%V-ruYh@_{YKvHxp^n=WIz?Kst`zzupyFxInd3Rr|I9fr@4fro`}^+w z-R0!V=Fnh&OX4gd1VNUf0O2xlCxOd~Fd2MXL~Tq2x0ZBCgl-w4C#y9onLG(6>(bOX z88^sf5M;Qi2=$(NflN5_GRMQ)j8rBq#;QDf2OEfOb9XCSNYiB-Huk@~aUqdhXx6qo zaN)d(-&F3;_o~R}My~X+kJLC`oZ*<6ft;REeCnJ> z?vTIx{3V1HoYl&vHsbxsJ$p%kUFn%$9&2{H8f@2;l3q6da_SBhit9wHbWtHH(f$26=3;qCwDvjdEY#P?4|itB61xrJ03- zfD2ys&2cN6ok`|y+1X~*!Kq7aTBEWk62b|envdr1T;pBz>D=b#rD`ho+0lp;b@H|D z^UJNxJiSW)QfeDh*)%dQYdY*;|MXr@V{4Dw7jbk}_m9~V4$5X$3!}fn!n10_&A#5M z%teK0mB%MJB13*%#h7Wu76@)v10A)TdDWV2=0@@quS%DCmk=V{5C4;KB4#4 zWLoXY;xkjCA3_^K>al=)+w#84->-YhdQr8Ap|*H@=yapY)8rRWWp&McOSPJiJHsiX z=U&hGC*KVVx_%s(Qedq)<`&i~0+nZwg9?if2l1sU1r5PeC{8md)S&br$lcSRMx=?j zj*Q~*a;1PW&~T1ImSX}+xQmz}R{P=!@_=*=9+n;~k)|g~c^JjhgXnJH0{{iCL&ye2 zl2Xez2q-38K6o~Y=@ha_MVBa`M2JJlzA6n)X4BX-2G!3XPi0a(h-7ySCgU#?E*^sb zZvsk!PN(M6>3Y4Mrf1Pqns_?Q0&f~rz<0tyAJlVAC#P>aQ{;g#Ak762b~1EQwGGzMLvppUoE>ikjx$e2TaXrYyW zMx`&qwW<`26!%NTl{&}q5Sa9}y*fpcWC{n9((xo*0aUeMSNN?h{YB!?*A_+!;^hjp z$qJDDmZnZFdqdV+z8P0c;f!|#n7_t-OZ!#qCS{-{7W0KFX^PQ3kx)P}?$5_mQaQ#q zJ#slx1_NWusBDzUqOx5$D3!}YI8-L;%EftHgeS$(aZnh!Bk&R3(x$-YX*%2A~ieXQ3`E8Pyf# zVN^DkiBJ&)0m!f`2SqV9j}5z+pfD+au}Y&rKsx0LBp#=$mGPzpBjJ4SP?3Pbq%qz| zLX!}k3>XL~L2_k^;mv|XuE4`|h>=a0!(?$83?2-_92VPUob?J^qXm^{#Dp0%7TaWQ zObZ_b1BgY8bqWAXau5sOSA!!ul}4gcB?%}-m&iuT*UMtiP8gy?goq9YpbRFP&*1W5 zR|yRBSuT7SUdUkb8RPU-m|T|jzqF0bLv|lcd4OCC_D?g3Mms7DPab_6eNB>^T8T_H zH3c7$j)tH`QgO`WC%_tAk|rR^cpOZRv2uMSm;XU2uwW?{W8w@@O$f*zlY>!F9CM{| z*ceYHgE2OSB5$K>RWh9((cs?kfJeX;C{GhtWG7Ri7QC&kPr!{?0EAH)TiWOYMSOFd!j<4xkRBYCtd^$i0SB$gXrR9kvV%0xXDw@H zwgAZo>VQZs_!nTB@tOb?m)Zg06rD)yH>H^f5D!20If`~~ESP_7ZZX!O_)iB<`y|$5o0m`3-8HfQ{hV|AW?;ul&lsP+ zr^1Y~!*1#Os?QdzeK0KDF_I>0NJK9bDMJSis;KikyzkzN0Pm;0(-5oH%C!;in4kU*?8>X!A(vg4j(ocs0UJOZFA+vbzEq zY7=%lpUaChD<_n)ovW^h)q7H3jU3zTTWlF-r?HD_L=o1q`XYxi|$p!D}McC zC*{<1@0rg1`vYulu48^2b?oHc;T%iiUl0F${e$|btI(;3Ezq63nI(1(gR_qm-IytX z$!_VF27(uvYgPDEvRi1-E=z9Q@y?HS-6s{$G8FUy$6KD`D`*AiTr|vwLYuX{|28EVWt28 literal 0 HcmV?d00001 diff --git a/smiley_pack/icons/respect/cc.png b/smiley_pack/icons/respect/cc.png new file mode 100644 index 0000000000000000000000000000000000000000..b28ef687f359018c136149b631ae3f0bfb38bbc4 GIT binary patch literal 4461 zcmeHKdr(tn7QYA6`?@m09F_a-+_i4>CnK>{g63ftW-H@P=(A+IJEl2~5_ z1uHv?U~NUwirUW5W$3t5w^r(-i`KR{t5mVpy35l6YAvtUx{JmAZa^N>&UBdB{zqn# zd%yGeedqkn`Of5fRhyO+=pX41K~SJNS(yQzA?(-B2mId38A}3>k2dSFnGC|ovDvLg z+C*^}w~gXZF4_n|uG?nq3&G7Czel~H@{)PaEW3>Nr&_Od|90M|7vEmjJ)E7V${qdi zPlIT#vE%a-4}QO|WSw*A!DRcN4?DUJpFMhQ_)dA|v*w&-r*53y{@n=OLF8xg5{Cnb znqB|wMB)?sUNLc7zCgbwlzkh5N;}(APHk-3Mtu2sz>s%h?8vS6&-6dId2C>DSK^sK ziu=IplOXRvjZ&I+c->~(h;IH=PXG9j?v8sm&rX)J-)i*CTJr@}vYT9-% zwRw5E<4~KVNh03b7Q|a!+eHZUpY7barxDNW4KJ71Z%nu#Us;Dgon?KyW>3^}YgfOa zXnpp?S9p)P&3z;zarnR|Ezx(XKD*vSjQ#NP{qBZ;zbEQ-Yki6e6WSsxJAeGm&9ZCm zvi@~F^-|690ogW zV`!^|!(tM8YY`*oa)F-nBtElEqnU)aI3`#Cd>}5uhG0AtF`JR;9u7uT3_vCV`dJT$ z4xAt)gK}7l>;_6zOj(!}(;-O1q`$4mZt|o<8W74vnSrST?266UGD)q`PI|Bu!;+zmQ)JDEjn#P4nH~smpTwPE{UmpfF|g8TWJ;@{hz(DzlylkrWu(MK`Cc*T2Y8sT<;$R4ifnuQmIFAN6QlXF(>kT4U zgb@HoK;W=csMo`Uh&1wzD8(;@5iW#rQlf|T z7$$*5e2UUbq#}VpD)vB;23exjZYDrEX)}>WAvQ~%N5K*+u><-Y0EGCBX1h_}TmPH1V0mKq) zp8^1n9ONQX*eQas+I3c|NzP?M;;^2RY7IC}B*73$f}sE?%Ex7>M1~1)9PeIhuPV*t^t4njg9F3* z^sS*j7TC;t1?kX+pJ7VFpQ;<1pQ7y0rio5Vv(JyD4&5DG>HEdrr=&gKI?uOX?u={v z+i2|7!7Z*1_qjzn_0V4eH$+Fb;PnOfZc}GJ3h*A>aXET-PG{7GxaQhTcf-(2u<(MUnh zk%&s&ze3y#+cV3)P9ONsjcuck?!G2jvn^}IK#MH&<4u~c?tP&0c62>2?5%&NJNRbn zUMP20Ii8U&b{}2RcOqhk&mZ1B9_}@`n;L#Cd!^S>@A6t`v0_0(&p|T>bI> z2}wa|OM$79eEcQT>^Rla7?G}%ht`w@9jiO&yuP5S2@*U!S@xZZtgEJXEN@H=_+zNF z%eeB<3qBA3u{;dff9z0D#W%Lm%F5_ZUrxEzcOc}PXl*c-R2}o)zEwwegl2aKn%i#9 Yzjdr?x2;a80o8%jsx)QehTM|>0f6af00000 literal 0 HcmV?d00001 diff --git a/smiley_pack/icons/respect/cc0.png b/smiley_pack/icons/respect/cc0.png new file mode 100644 index 0000000000000000000000000000000000000000..51ebdf1fc1be3a5bb42c11051c89467254762aeb GIT binary patch literal 4669 zcmeHLdsGuw8jlKwMPaod#rj|x)S{ToOfuv#B_K_ZM2tp67gnuKG7}id%VaP?SA0+v zbp>&?Dxy^spFm}OQN#yEM2jm?#I@41QmW$C7JLgw)V&Fac-nJ%JZJkKIVYLi?|$F! ze&6r=-FtGgNI*(CYT+gDs8|r6z{C+Y$ZRp`Xgvin zX=Vzd?6i)>vfnhQXMEs*yxN=mrOU!G`_S6mf|F6%v;EhvQf-+xD?t}M=XLq)2lt{v zptLJ-vC4qBf;d6`#a%w%~d^m6QIJ07>cZ06}h&9v{+KEvcqC8jn_ef>XAI^>_$3;S=WWH+RH zln$OEi!B_;{*brgRK%0z?e(<-A9yzOPYm!c`0H>MtJfE_Or}=KWN(TACFCv2kt!VH zhE~p=QOOzP`KkZB3+h=%e8)5<98`bdy>ohUUB&IIaPrl4yGzC1#h&cQfP=og%Vl_} z_p%0d=HZNg9W)etA} zOyH;yx}U81o0m1UmaWYG+J4NYudhb zLnB**+MBPBov12P?(}fJ)YJzBkE`K13+tafFENNFFF7MH7aVWb*jl8PBSZ2$VD=xBB=8KK>b{dE)K{XNAnhZRGG-)WF-Czc)W3j>`?Pfxo zLNSnrN}`QYPRohY9Ec{RoWF#r5S3X*CDV!p7HaB(N%7hRDOw51iHz_Lx8nf7KrsYl zH|UL4+%Dy~adGh7WrjJB+l5JyauQT(NM^E75XQrJ2sheJ&*yU@yrFOlsl(&s<2xb1 zNXkiO7&8vTHk*xS6YxxyBp8)QBrw8<`Ft+$;9Ap+3}NRQt-&sc4h%VE)mmsXLz|3{ z3zN{8QW+_S1LmPO`5DYARTsR`+Q|ao1GW=p808_b!2oxUurkr}0Z3;;zZqeT2YVEb zqpYS>iPZ^ou?hvH5E8d)H(YwnbwJ@cp48YY2Rz=@gGDfLVcSX1;NTLm9cN8G| z9Z!bVy(R0N+*~v6a=Ir1!n<(a@qSag+ZlMNRJh!vO?9QGluJ3T^>NaqrAgfVmC}Ww zA_Aqjq>ezj7=j{PjYuTo3i)9oR3t=%8cfm+N@=t*gi%Ympa3|J1~?j&)DS42;tDXK zmWv5=1eXwCe6EH>5Q$DB<|8QC4Pvr|2C5|V-LrB*kpK$SP+C-r3Atj4M8L)P5)qdW z^T80&kP;z+h_sZ*4Ml44@g|Fb0PUm=L=pv?jY;ka7vXr6S}Eo5dB|IfT2C-K5Fq7D zq>ZWew-fQSfttz?E;dmS9|L4aL|ArJWOu{EY+qnpVintgWrUNPvQe3`()Byk}5i$4Igu$H!!>%*qO~v8xuQ&;J zJ9Il_KwO6n9A4logu4#IPR>9Ef8?vP7k}gu5Y)5Cd-2;tR}Wq9#lU+x_o%CfuJ>Z# zy_|d0^?#$w`|Wj#GJ;=0HgH+m_jTiSaM9|kiH(u70$CPT{`vI5=Yi!=HA(WcDFga8z%^W+7n=V; zaOREVaTOuP1h3IW>zAmo5RW0AMMYx^^>VYr)8C_CKhKXL;j!X+WNWT7>+|o=dFYU=`#HyBOkWbpYV&}-B?0im-n$Z(PSQJ& z%ZrMAs2cT|!Idl&7m!%kJ+TiAQU;O!1|ZX;{Yp@aEY zAiL_&;Gna&st?~kGHkKaXVb$y>+ALeMoiWoYxv~V_)|OMT8@`~9;>TC5<`yM9eVc9 zdHrW@m!B$gZabI4)Hzp_NFF>FMc-O|qF3>^f*(R}rnDu_{w9yNec_ns;XFt%?TX2v z@X2;AEvUScd^wA3V}+LR9+@`g8nS|NeQ~z5@*a7j7 zP_uAt&IIS(hR0KfC7H!jUaTqEPryd9ck!q-7Ri$;&d8nTAGE98b8<#W)Zcicb{)T(x#HS}${XA8wN(`( hn)jxpd^Gq~A2PwVG$Qu(3ZMg)GJ2A{__I07{s-^H&x!y5 literal 0 HcmV?d00001 diff --git a/smiley_pack/icons/respect/ccby.png b/smiley_pack/icons/respect/ccby.png new file mode 100644 index 0000000000000000000000000000000000000000..69d237d25027f8c992fc2a30025b1358667814c5 GIT binary patch literal 4407 zcmeHLdr(tX8V`0?UWQgc5JkL1-9ffD_a?a^$t9rz;SnVeB~ozLwm0{lz+Licav=d- zYDIK(T?*Af+d|b*+GSiHpu6}O7Eu%y*Y#1iYdb2tYDZmBw6s$>7krrAAD%9B1iR@vTBp8v6* zWk-KtRM_^2BSb^X=X=`f;)52vuRc?$dQ|y_p`hf!sf9cLyg3b(KbZS`^(@b=z{9mR~>$uYCW@BxH~F!o%j|$^Tj^n@x%ARYtVDiWhd5vsHZuKYu8tNGbib4 zdh@RI_5{Hf)XrVnP}z**e<+EGOZmk#*~-pV%^aUMyB&F<@!NjiB@pt;UO@P06PdQ=~_Vi7n;Jqx}LTIS0vl-KNv?*UztiGW9PT6Eb`g zA4b&9sC{nd9Qg0Tg9bYOT|3a)pL90!{ z%Q9DbzGtQW@2JmNYi{=3xcbfVUmb~bZQ5|I%AXF7J$5OhZeC<@z4+%o{ae>vT9@0> zV2-tE>uY}bb@ z$LfGJArPov^EfEF5O9bIpwhXxJMNS%|6ayPKZ!82ukLWv!oEC3542=N`utHH6v?>{AGEJv9jA-x_ ze;O(^B`7>Fz<3#*c{jP;6#VjvVP!<8x(O`(KI0tbdx zp(X{OQQB;x;#6|ELP-yL!_Z`^-D#y@I$0}~4={%<-)n;>oJ=(6G$N@OA6+q6D9#KO zG@=aFR^%DoFtS#V%~3p?5`|QzkmE2KnVgWT6r(~p!0CdO$YV-yv5fHU@M$4oFpyY^ zuTu!%U5Bxd$xc9VcBj#9w`fGXO9-zyvaN^5iJ>@3OK|{#;!=Xdm83*&luAgcf+VEB z#HA!YM&8b_=92#<%^w~_J(%)z)&=dCc$WrGR5o~fa5gx#u->DDAl^ekQuJU5E~*$X zUOyq$;1*p#+42GG9z*3iyw3heDVPDR0yraw2?Gk0FjEAol&F*_gEN!@S1N%DH;+em z+0C4ra)QKs$Rp$mmZz61B*vSlh2y2&1%S^2Bn-us=no0Qh62X;o-rJ;8v6k!YOlbU zCIj^b*I@I4y$~B|hC`h3ZRaQa4CUe{v;d(ejZBE&NxCNKnh*mM5}vHCNxCM)z=VV+ ztLy(pSHS3X3fSPUAUC`$J&6ephZn6WrX^`w0ac}RK7%uVM|z%1AP9uF^uQ1w!H2ao z;i506)2H~}@q0OBcC1w6Zh`k)olcu*j5%LX-I|rXbmscGwhtCF#V5D>MN4+ReQ{;@ zK%hJ1&WS0-wwZ6?(PyrGB4i_T7u@;8zj^BgV*7_(bK5#wG%ufOsa;|^(Le3>>hAus z-u|15Dn9MOk!0!Ao~9KQ=B`zhn(J*#t{dh#+Oaipy+{Ap8ThPCcwQLhS9vY;=)a~f zy&JhIb9vp7-aUJwLfgMv+ZWN_l9+8ty|?IA;ECW}RM<{v|A8N1svh>hKL*ZBJ3uX<`VxW{3C$s2-+iaR=j(Nc>>0Gr*=>(j z-HP8F9F$$wz5Cm3J089i=6|obFXwN0_wSc?y4GlVt|vZ?y(H%DMbgd2o-2*Je`CvH zPL_W(HOjfUFo=G1b(gSudSG+>zQ@&T-n-Uxx8|(q-K@(4bN=Ixe$RByScr!0y&wIqKQ7Vi=@oEZsL5c;$B6n1JcLE|zJ9EdG+ka#xIp?hPt#7aO z?X~xuot)5Me`|~R77zqk^8&bG;5yszHJ=84RiUnTz@;WFB3cuMYH>=HLM)MDIL!tn zhQo9cF$C#;l7+_3s>PYV?VQ8jY`W61j`loA(b!>Udh6OZZXGY96MWadxfM!xOTe|6K zMf=MIonO|P-pjRbz2lyo6}{@WGxuvxN)xY9udRt}a*n@w`K0P``^m@!C)FXt|6K1K zAM$R7} z$!WLw7EYPNc5TDYG#&an)1~s4vI`llA@>i*5z;=%x|q51m($<$ zm>h8Xp)WknRpkG&Y0eH`{kz;M=NVaw%o_ToOLskj7iFwU*;i#^W0RRP3oA>%>ekrS zR-J&ndj~Z>P~F*EgbM;qr;~u@islC)LWPWoiWCBjsFNu{*FliGr%s6qlQ0cVfF(%e zY<%yPYCKLNV&kLee3-A~V2P4|G!+(}791f=OA@j~cux-tcO3!10y58qu-w zMqUKm8_Xm;&Ir*YvGLLTP#j00!f-SqjR+Hbb&^yH-opatt`donFs|Py1$biP6Ezwo zLLzCkTB4RpRHzb2WEP7>f+-{lg#Zu)^#-{H)e+?CB?gKS4lbq^sw7H{L?Oo+I8lKj zMZ?D9fgkriKbexxAETG6M^ylNkaVb$L?*%{nT#|(Lap&l1tg;h{b__c0<2L|7^YUF zsDzkrDkj$~8BZY+j>RieR8nI(A|VNrVln_#gHg#7hV+K zMhU0@6%j;Y8cbyZN+C)gM-ifufUZQP*gZzu^}Sv4C#}FDQv_m^MJEVdU6}-$n2r)yWK2L{z+?uKPJvOT zKsb?Itq^Ops0#B=06GG#Kzkas!mTh)l=DQiHW4$-0uYP$*^a>q_NF#R5Qc2^A~m4@=^Lu$~7t1M=9`8;K}Zq zl)i{3ym^+Tgt_@e=a8Z0<=Rz+JBrGmhgz1BeUkqXSTbw+eBZZIXDRm)2<`QkcARv5|J};Y^r}Y#v%BlV^=u`?%!n9{cX@rUn-xRveBwR5ZfZu!TOm%hH+39+E-*=A5<|`lyg@WJe<9++t_Yph8R`0leEH^JN@Y#hY znf@2JuQL=GC1K9VaZ$s|Ry*^)Z7S?D>nkdh+UzMUU6$9>(6CE%E~d4$HDBuL5)~EY z_@=x2gi}!BvAT@;j*j!{lC9ta^*n$7?b9rA`>|U$Zfxt^8oAihOlO%bYn!G?PF~#5 z&|rGAxw$~9P}IMDdv)=@+S;fsg0shaJ)x(Fn;Uz>+L)M`UVi@mZ1hxFnI*2WveL<- zv_PZPS}OHZ*4bED>0iGwDX*$>IuvBu*wT{S!E`zs7Z(SKD4*WFcklPX{n(EWADZ>y zp-*Tty0 ze@|^Kr=#FrC;yo%gYm4VCn!~`Ev>AKgJNQ1sVz-S;k$Mn^4RHD{CAJo=;*#z2ZzN8 z3G97G4jyd0cmV0i`^`z;)fF%+Co3p8_;!2yF^5Hq(tGOb>kGToFQl7HmL3X9TNfSj z`NMq?D@$`Wnb!OyU^i!RI2=LS;KH!FN=P^Bok_-kII?I;bvbBVi02#3J?*o8 G^M3&g)*ssd literal 0 HcmV?d00001 diff --git a/smiley_pack/smiley_pack.php b/smiley_pack/smiley_pack.php index 4361b2f5..343ea262 100644 --- a/smiley_pack/smiley_pack.php +++ b/smiley_pack/smiley_pack.php @@ -2,30 +2,28 @@ /* * Name: Smiley Pack * Description: Pack of smileys that make master too AOLish. - * Version: 1.05 + * Version: 1.06 * Author: Thomas Willingham (based on Mike Macgirvin's Adult Smile template) * Author: Matthias Ebers * All smileys from sites offering them as Public Domain */ -use Friendica\App; use Friendica\Core\Hook; use Friendica\DI; -function smiley_pack_install() { +function smiley_pack_install() +{ Hook::register('smilie', 'addon/smiley_pack/smiley_pack.php', 'smiley_pack_smilies'); } function smiley_pack_smilies(array &$b) { -#Smileys are split into various directories by the intended range of emotions. This is in case we get too big and need to modularise things. We can then cut and paste the right lines, move the right directory, and just change the name of the addon to happy_smilies or whatever. + #Smileys are split into various directories by the intended range of emotions. This is in case we get too big and need to modularise things. We can then cut and paste the right lines, move the right directory, and just change the name of the addon to happy_smilies or whatever. -#Be careful with invocation strings. If you have a smiley called foo, and another called foobar, typing :foobar will call foo. Avoid this with clever naming, using ~ instead of : -#when all else fails. + #Be careful with invocation strings. If you have a smiley called foo, and another called foobar, typing :foobar will call foo. Avoid this with clever naming, using ~ instead of : + #when all else fails. - - -#Animal smileys. + #Animal smileys. $b['texts'][] = ':bunnyflowers:'; $b['icons'][] = '' . ':bunnyflowers:' . ''; @@ -50,7 +48,7 @@ function smiley_pack_smilies(array &$b) $b['texts'][] = ':cow:'; $b['icons'][] = '' . ':cow:' . ''; - + $b['texts'][] = ':crab:'; $b['icons'][] = '' . ':crab:' . ''; @@ -71,7 +69,7 @@ function smiley_pack_smilies(array &$b) $b['texts'][] = ':horse:'; $b['icons'][] = '' . ':horse:' . ''; - + $b['texts'][] = ':parrot:'; $b['icons'][] = '' . ':parrot:' . ''; @@ -99,16 +97,13 @@ function smiley_pack_smilies(array &$b) $b['texts'][] = ':pig:'; $b['icons'][] = '' . ':pig:' . ''; - - -#Baby Smileys + #Baby Smileys $b['texts'][] = ':baby:'; $b['icons'][] = '' . ':baby:' . ''; $b['texts'][] = ':babycot:'; $b['icons'][] = '' . ':babycot:' . ''; - $b['texts'][] = ':pregnant:'; $b['icons'][] = '' . ':pregnant:' . ''; @@ -116,11 +111,10 @@ function smiley_pack_smilies(array &$b) $b['texts'][] = ':stork:'; $b['icons'][] = '' . ':stork:' . ''; - -#Confused Smileys + #Confused Smileys $b['texts'][] = ':confused:'; $b['icons'][] = '' . ':confused:' . ''; - + $b['texts'][] = ':shrug:'; $b['icons'][] = '' . ':shrug:' . ''; @@ -130,13 +124,12 @@ function smiley_pack_smilies(array &$b) $b['texts'][] = ':dazed:'; $b['icons'][] = '' . ':dazed:' . ''; - -#Cool Smileys + #Cool Smileys $b['texts'][] = ':affro:'; $b['icons'][] = '' . ':affro:' . ''; -#Devil/Angel Smileys + #Devil/Angel Smileys $b['texts'][] = ':angel:'; $b['icons'][] = '' . ':angel:' . ''; @@ -152,20 +145,20 @@ function smiley_pack_smilies(array &$b) $b['texts'][] = ':devillish:'; $b['icons'][] = '' . ':devillish:' . ''; - + $b['texts'][] = ':daseesaw:'; $b['icons'][] = '' . ':daseesaw:' . ''; $b['texts'][] = ':turnevil:'; $b['icons'][] = '' . ':turnevil:' . ''; - + $b['texts'][] = ':saint:'; $b['icons'][] = '' . ':saint:' . ''; $b['texts'][] = ':graveside:'; $b['icons'][] = '' . ':graveside:' . ''; -#Unpleasent smileys. + #Unpleasent smileys. $b['texts'][] = ':toilet:'; $b['icons'][] = '' . ':toilet:' . ''; @@ -176,7 +169,7 @@ function smiley_pack_smilies(array &$b) $b['texts'][] = ':fartblush:'; $b['icons'][] = '' . ':fartblush:' . ''; -#Drinks + #Drinks $b['texts'][] = ':tea:'; $b['icons'][] = '' . ':tea:' . ''; @@ -184,7 +177,7 @@ function smiley_pack_smilies(array &$b) $b['texts'][] = ':drool:'; $b['icons'][] = '' . ':drool:' . ''; -#Sad smileys + #Sad smileys $b['texts'][] = ':crying:'; $b['icons'][] = '' . ':crying:' . ''; @@ -195,12 +188,12 @@ function smiley_pack_smilies(array &$b) $b['texts'][] = ':sigh:'; $b['icons'][] = '' . ':sigh:' . ''; -#Smoking - only one smiley in here, maybe it needs moving elsewhere? + #Smoking - only one smiley in here, maybe it needs moving elsewhere? $b['texts'][] = ':smoking:'; $b['icons'][] = '' . ':smoking:' . ''; -#Sport smileys + #Sport smileys $b['texts'][] = ':basketball:'; $b['icons'][] = '' . ':basketball:' . ''; @@ -231,11 +224,11 @@ function smiley_pack_smilies(array &$b) $b['texts'][] = ':snooker:'; $b['icons'][] = '' . ':snooker:' . ''; - + $b['texts'][] = ':horseriding:'; $b['icons'][] = '' . ':horseriding:' . ''; -#Love smileys + #Love smileys $b['texts'][] = ':iloveyou:'; $b['icons'][] = '' . ':iloveyou:' . ''; @@ -255,7 +248,7 @@ function smiley_pack_smilies(array &$b) $b['texts'][] = ':loveheart:'; $b['icons'][] = '' . ':loveheart:' . ''; -#Tired/Sleep smileys + #Tired/Sleep smileys $b['texts'][] = ':countsheep'; $b['icons'][] = '' . ':countsheep:' . ''; @@ -269,7 +262,7 @@ function smiley_pack_smilies(array &$b) $b['texts'][] = ':yawn:'; $b['icons'][] = '' . ':yawn:' . ''; -#Fight/Flame/Violent smileys + #Fight/Flame/Violent smileys $b['texts'][] = ':2guns:'; $b['icons'][] = '' . ':2guns:' . ''; @@ -313,7 +306,7 @@ function smiley_pack_smilies(array &$b) $b['texts'][] = ':acid:'; $b['icons'][] = '' . ':acid:' . ''; -#Fantasy smileys - monsters and dragons fantasy. The other type of fantasy belongs in adult smileys + #Fantasy smileys - monsters and dragons fantasy. The other type of fantasy belongs in adult smileys $b['texts'][] = ':alienmonster:'; $b['icons'][] = '' . ':alienmonster:' . ''; @@ -336,7 +329,7 @@ function smiley_pack_smilies(array &$b) $b['texts'][] = ':mummy:'; $b['icons'][] = '' . ':mummy:' . ''; -#Food smileys + #Food smileys $b['texts'][] = ':apple:'; $b['icons'][] = '' . ':apple:' . ''; @@ -368,7 +361,7 @@ function smiley_pack_smilies(array &$b) $b['texts'][] = ':birthdaycake:'; $b['icons'][] = '' . ':birthdaycake:' . ''; -#Happy smileys + #Happy smileys $b['texts'][] = ':cloud9:'; $b['icons'][] = '' . ':cloud9:' . ''; @@ -376,7 +369,7 @@ function smiley_pack_smilies(array &$b) $b['texts'][] = ':tearsofjoy:'; $b['icons'][] = '' . ':tearsofjoy:' . ''; -#Repsect smileys + #Repsect smileys $b['texts'][] = ':bow:'; $b['icons'][] = '' . ':bow:' . ''; @@ -390,7 +383,19 @@ function smiley_pack_smilies(array &$b) $b['texts'][] = ':number1:'; $b['icons'][] = '' . ':number1:' . ''; -#Laugh smileys + $b['texts'][] = ':cc_cc:'; + $b['icons'][] = '' . ':cc_cc:' . ''; + + $b['texts'][] = ':cc_by:'; + $b['icons'][] = '' . ':cc_by:' . ''; + + $b['texts'][] = ':cc_sa:'; + $b['icons'][] = '' . ':cc_sa:' . ''; + + $b['texts'][] = ':cc_0:'; + $b['icons'][] = '' . ':cc_0:' . ''; + + #Laugh smileys $b['texts'][] = ':hahaha:'; $b['icons'][] = '' . ':hahaha:' . ''; @@ -401,24 +406,23 @@ function smiley_pack_smilies(array &$b) $b['texts'][] = ':rofl:'; $b['icons'][] = '' . ':rofl:' . ''; -#Music smileys + #Music smileys $b['texts'][] = ':drums:'; $b['icons'][] = '' . ':drums:' . ''; - $b['texts'][] = ':guitar:'; $b['icons'][] = '' . ':guitar:' . ''; $b['texts'][] = ':trumpet:'; $b['icons'][] = '' . ':trumpet:' . ''; -#Smileys that used to be in core + #Smileys that used to be in core $b['texts'][] = ':headbang:'; $b['icons'][] = '' . ':headbang:' . ''; - $b['texts'][] = ':beard:'; + $b['texts'][] = ':beard:'; $b['icons'][] = '' . ':beard:' . ''; $b['texts'][] = ':whitebeard:'; @@ -436,7 +440,7 @@ function smiley_pack_smilies(array &$b) $b['texts'][] = ':headdesk:'; $b['icons'][] = '' . ':headdesk:' . ''; -#These two are still in core, so oldcore isn't strictly right, but we don't want too many directories + #These two are still in core, so oldcore isn't strictly right, but we don't want too many directories $b['texts'][] = ':-d'; $b['icons'][] = '' . ':-d' . ''; @@ -444,8 +448,8 @@ function smiley_pack_smilies(array &$b) $b['texts'][] = ':-o'; $b['icons'][] = '' . ':-o' . ''; -# Regex killers - stick these at the bottom so they appear at the end of the English and -# at the start of $OtherLanguage. + # Regex killers - stick these at the bottom so they appear at the end of the English and + # at the start of $OtherLanguage. $b['texts'][] = ':cool:'; $b['icons'][] = '' . ':cool:' . ''; @@ -455,7 +459,7 @@ function smiley_pack_smilies(array &$b) $b['texts'][] = ':golf:'; $b['icons'][] = '' . ':golf:' . ''; - + $b['texts'][] = ':football:'; $b['icons'][] = '' . ':football:' . ''; @@ -480,63 +484,167 @@ function smiley_pack_smilies(array &$b) $b['texts'][] = ':gangs:'; $b['icons'][] = '' . ':gangs:' . ''; - $b['texts'][] = ':dj:'; $b['icons'][] = '' . ':dj:' . ''; - $b['texts'][] = ':elvis:'; $b['icons'][] = '' . ':elivs:' . ''; $b['texts'][] = ':violin:'; $b['icons'][] = '' . ':violin:' . ''; -# New Gif Emoji (@one@loma.ml) -# Fediverse + # New Gif Emoji (@one@loma.ml) + # Fediverse $b['texts'][] = ':friendica:'; - $b['icons'][] = '' . ':friendica:' . ''; - + $b['icons'][] = '' . ':friendica:' . ''; + + $b['texts'][] = ':fediverse:'; + $b['icons'][] = '' . ':fediverse:' . ''; + $b['texts'][] = ':mastodon:'; $b['icons'][] = '' . ':mastodon:' . ''; - + $b['texts'][] = ':pleroma:'; $b['icons'][] = '' . ':pleroma:' . ''; - + $b['texts'][] = ':misskey:'; $b['icons'][] = '' . ':misskey:' . ''; - + $b['texts'][] = ':diaspora:'; - $b['icons'][] = '' . ':diaspora:' . ''; - + $b['icons'][] = '' . ':diaspora:' . ''; + $b['texts'][] = ':hubzilla:'; - $b['icons'][] = '' . ':hubzilla:' . ''; - + $b['icons'][] = '' . ':hubzilla:' . ''; + $b['texts'][] = ':pixelfed:'; $b['icons'][] = '' . ':pixelfeed:' . ''; - + $b['texts'][] = ':nextcloud:'; $b['icons'][] = '' . ':nextcloud:' . ''; - + $b['texts'][] = ':activitypub:'; $b['icons'][] = '' . ':activitypub:' . ''; - -# ccc + + # ccc $b['texts'][] = ':ccc event:'; $b['icons'][] = '' . ':ccc event:' . ''; - -# Commercial + + # Commercial $b['texts'][] = ':youtube:'; $b['icons'][] = '' . ':youtube:' . ''; - + $b['texts'][] = ':spotify:'; $b['icons'][] = '' . ':spotify:' . ''; - + $b['texts'][] = ':twitter:'; $b['icons'][] = '' . ':twitter:' . ''; - + $b['texts'][] = ':twitch:'; $b['icons'][] = '' . ':twitch:' . ''; + + $b['texts'][] = ':facebook:'; + $b['icons'][] = '' . ':facebook:' . ''; + + $b['texts'][] = ':threads:'; + $b['icons'][] = '' . ':threads:' . ''; + + $b['texts'][] = ':google:'; + $b['icons'][] = '' . ':google:' . ''; + + $b['texts'][] = ':signal:'; + $b['icons'][] = '' . ':signal:' . ''; + + $b['texts'][] = ':tiktok:'; + $b['icons'][] = '' . ':tiktok:' . ''; + + $b['texts'][] = ':whatsapp:'; + $b['icons'][] = '' . ':whatsapp:' . ''; + + $b['texts'][] = ':instagram:'; + $b['icons'][] = '' . ':instagram:' . ''; + + $b['texts'][] = ':telegram:'; + $b['icons'][] = '' . ':telegram:' . ''; + + $b['texts'][] = ':windows:'; + $b['icons'][] = '' . ':windows:' . ''; + + $b['texts'][] = ':github:'; + $b['icons'][] = '' . ':github:' . ''; + + $b['texts'][] = ':threema:'; + $b['icons'][] = '' . ':threema:' . ''; + + # nonCommercial + + $b['texts'][] = ':invidious:'; + $b['icons'][] = '' . ':invidious:' . ''; + + $b['texts'][] = ':bluesky:'; + $b['icons'][] = '' . ':bluesky:' . ''; + + $b['texts'][] = ':vivaldi:'; + $b['icons'][] = '' . ':vivaldi:' . ''; + + # opensource + + $b['texts'][] = ':firefox:'; + $b['icons'][] = '' . ':firefox:' . ''; + + $b['texts'][] = ':linuxopensuse:'; + $b['icons'][] = '' . ':linuxopensuse:' . ''; + + $b['texts'][] = ':linuxdebian:'; + $b['icons'][] = '' . ':linuxdebian:' . ''; + + $b['texts'][] = ':linuxfedora:'; + $b['icons'][] = '' . ':linuxfedora:' . ''; + + $b['texts'][] = ':linuxubuntu:'; + $b['icons'][] = '' . ':linuxubuntu:' . ''; + + $b['texts'][] = ':linuxmint:'; + $b['icons'][] = '' . ':linuxmint:' . ''; + + $b['texts'][] = ':fdroid:'; + $b['icons'][] = '' . ':fdroid:' . ''; + + $b['texts'][] = ':tutanota:'; + $b['icons'][] = '' . ':tutanota:' . ''; + + $b['texts'][] = ':raspi:'; + $b['icons'][] = '' . ':raspi:' . ''; + + $b['texts'][] = ':linux:'; + $b['icons'][] = '' . ':linux:' . ''; + + $b['texts'][] = ':kde:'; + $b['icons'][] = '' . ':kde:' . ''; + + $b['texts'][] = ':firefoxnightly:'; + $b['icons'][] = '' . ':firefoxnightly:' . ''; + + $b['texts'][] = ':archlinux:'; + $b['icons'][] = '' . ':archlinux:' . ''; + + $b['texts'][] = ':thunderbird:'; + $b['icons'][] = '' . ':thunderbird:' . ''; + + $b['texts'][] = ':vivaldi:'; + $b['icons'][] = '' . ':vivaldi:' . ''; + + $b['texts'][] = ':jabber:'; + $b['icons'][] = '' . ':jabber:' . ''; + + $b['texts'][] = ':matrix:'; + $b['icons'][] = '' . ':matrix:' . ''; + + $b['texts'][] = ':xmpp:'; + $b['icons'][] = '' . ':xmpp:' . ''; + + $b['texts'][] = ':foss:'; + $b['icons'][] = '' . ':foss:' . ''; } From 6f3ba10466a78d174d17594b8e2f0fe3a1ceb967 Mon Sep 17 00:00:00 2001 From: Michael Date: Sat, 14 Sep 2024 14:40:48 +0000 Subject: [PATCH 029/222] Bluesky: Preparation for video posts --- bluesky/bluesky.php | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/bluesky/bluesky.php b/bluesky/bluesky.php index 181e8d2d..f4e2f456 100644 --- a/bluesky/bluesky.php +++ b/bluesky/bluesky.php @@ -1410,6 +1410,19 @@ function bluesky_add_media(stdClass $embed, array $item, int $fetch_uid, int $le } break; + case 'app.bsky.embed.video#view': + $media = [ + 'uri-id' => $item['uri-id'], + 'type' => Post\Media::HLS, + 'url' => $embed->playlist, + 'preview' => $embed->thumbnail, + 'description' => $embed->alt ?? '', + 'height' => $embed->aspectRatio->height, + 'width' => $embed->aspectRatio->width, + ]; + Post\Media::insert($media); + break; + case 'app.bsky.embed.external#view': $media = [ 'uri-id' => $item['uri-id'], From f8f63532f4297db73f6cfc578ef4a5e8959db61c Mon Sep 17 00:00:00 2001 From: Michael Date: Sun, 29 Sep 2024 18:19:38 +0000 Subject: [PATCH 030/222] Bluesky: New option to complete threads --- bluesky/bluesky.php | 203 ++++++++++++++++------- bluesky/bluesky_feed.php | 8 +- bluesky/bluesky_notifications.php | 8 +- bluesky/bluesky_timeline.php | 8 +- bluesky/lang/C/messages.po | 168 +++++++++---------- bluesky/templates/connector_settings.tpl | 1 + 6 files changed, 235 insertions(+), 161 deletions(-) diff --git a/bluesky/bluesky.php b/bluesky/bluesky.php index f4e2f456..73b19612 100644 --- a/bluesky/bluesky.php +++ b/bluesky/bluesky.php @@ -1,7 +1,7 @@ * @@ -10,6 +10,8 @@ * - Outgoing mentions * * At some point in time: + * - post videos + * - direct messages * - Sending Quote shares https://atproto.com/lexicons/app-bsky-embed#appbskyembedrecord and https://atproto.com/lexicons/app-bsky-embed#appbskyembedrecordwithmedia * * Possibly not possible: @@ -151,7 +153,7 @@ function bluesky_probe_detect(array &$hookData) } $data = bluesky_xrpc_get($pconfig['uid'], 'app.bsky.actor.getProfile', ['actor' => $did]); - if (empty($data)) { + if (empty($data) || empty($data->did)) { return; } @@ -346,15 +348,16 @@ function bluesky_settings(array &$data) return; } - $enabled = DI::pConfig()->get(DI::userSession()->getLocalUserId(), 'bluesky', 'post') ?? false; - $def_enabled = DI::pConfig()->get(DI::userSession()->getLocalUserId(), 'bluesky', 'post_by_default') ?? false; - $pds = DI::pConfig()->get(DI::userSession()->getLocalUserId(), 'bluesky', 'pds'); - $handle = DI::pConfig()->get(DI::userSession()->getLocalUserId(), 'bluesky', 'handle'); - $did = bluesky_get_user_did(DI::userSession()->getLocalUserId()); - $token = DI::pConfig()->get(DI::userSession()->getLocalUserId(), 'bluesky', 'access_token'); - $import = DI::pConfig()->get(DI::userSession()->getLocalUserId(), 'bluesky', 'import') ?? false; - $import_feeds = DI::pConfig()->get(DI::userSession()->getLocalUserId(), 'bluesky', 'import_feeds') ?? false; - $custom_handle = DI::pConfig()->get(DI::userSession()->getLocalUserId(), 'bluesky', 'friendica_handle') ?? false; + $enabled = DI::pConfig()->get(DI::userSession()->getLocalUserId(), 'bluesky', 'post') ?? false; + $def_enabled = DI::pConfig()->get(DI::userSession()->getLocalUserId(), 'bluesky', 'post_by_default') ?? false; + $pds = DI::pConfig()->get(DI::userSession()->getLocalUserId(), 'bluesky', 'pds'); + $handle = DI::pConfig()->get(DI::userSession()->getLocalUserId(), 'bluesky', 'handle'); + $did = bluesky_get_user_did(DI::userSession()->getLocalUserId()); + $token = DI::pConfig()->get(DI::userSession()->getLocalUserId(), 'bluesky', 'access_token'); + $import = DI::pConfig()->get(DI::userSession()->getLocalUserId(), 'bluesky', 'import') ?? false; + $import_feeds = DI::pConfig()->get(DI::userSession()->getLocalUserId(), 'bluesky', 'import_feeds') ?? false; + $complete_threads = DI::pConfig()->get(DI::userSession()->getLocalUserId(), 'bluesky', 'complete_threads') ?? false; + $custom_handle = DI::pConfig()->get(DI::userSession()->getLocalUserId(), 'bluesky', 'friendica_handle') ?? false; if (DI::config()->get('bluesky', 'friendica_handles')) { $self = User::getById(DI::userSession()->getLocalUserId(), ['nickname']); @@ -369,16 +372,17 @@ function bluesky_settings(array &$data) $t = Renderer::getMarkupTemplate('connector_settings.tpl', 'addon/bluesky/'); $html = Renderer::replaceMacros($t, [ - '$enable' => ['bluesky', DI::l10n()->t('Enable Bluesky Post Addon'), $enabled], - '$bydefault' => ['bluesky_bydefault', DI::l10n()->t('Post to Bluesky by default'), $def_enabled], - '$import' => ['bluesky_import', DI::l10n()->t('Import the remote timeline'), $import], - '$import_feeds' => ['bluesky_import_feeds', DI::l10n()->t('Import the pinned feeds'), $import_feeds, DI::l10n()->t('When activated, Posts will be imported from all the feeds that you pinned in Bluesky.')], - '$custom_handle' => $friendica_handle, - '$pds' => ['bluesky_pds', DI::l10n()->t('Personal Data Server'), $pds, DI::l10n()->t('The personal data server (PDS) is the system that hosts your profile.'), '', 'readonly'], - '$handle' => ['bluesky_handle', DI::l10n()->t('Bluesky handle'), $handle, '', '', $custom_handle ? 'readonly' : ''], - '$did' => ['bluesky_did', DI::l10n()->t('Bluesky DID'), $did, DI::l10n()->t('This is the unique identifier. It will be fetched automatically, when the handle is entered.'), '', 'readonly'], - '$password' => ['bluesky_password', DI::l10n()->t('Bluesky app password'), '', DI::l10n()->t("Please don't add your real password here, but instead create a specific app password in the Bluesky settings.")], - '$status' => bluesky_get_status($handle, $did, $pds, $token), + '$enable' => ['bluesky', DI::l10n()->t('Enable Bluesky Post Addon'), $enabled], + '$bydefault' => ['bluesky_bydefault', DI::l10n()->t('Post to Bluesky by default'), $def_enabled], + '$import' => ['bluesky_import', DI::l10n()->t('Import the remote timeline'), $import], + '$import_feeds' => ['bluesky_import_feeds', DI::l10n()->t('Import the pinned feeds'), $import_feeds, DI::l10n()->t('When activated, Posts will be imported from all the feeds that you pinned in Bluesky.')], + '$complete_threads' => ['bluesky_complete_threads', DI::l10n()->t('Complete the threads'), $complete_threads, DI::l10n()->t('When activated, the system fetches additional replies for the posts in the timeline. This leads to more complete threads.')], + '$custom_handle' => $friendica_handle, + '$pds' => ['bluesky_pds', DI::l10n()->t('Personal Data Server'), $pds, DI::l10n()->t('The personal data server (PDS) is the system that hosts your profile.'), '', 'readonly'], + '$handle' => ['bluesky_handle', DI::l10n()->t('Bluesky handle'), $handle, '', '', $custom_handle ? 'readonly' : ''], + '$did' => ['bluesky_did', DI::l10n()->t('Bluesky DID'), $did, DI::l10n()->t('This is the unique identifier. It will be fetched automatically, when the handle is entered.'), '', 'readonly'], + '$password' => ['bluesky_password', DI::l10n()->t('Bluesky app password'), '', DI::l10n()->t("Please don't add your real password here, but instead create a specific app password in the Bluesky settings.")], + '$status' => bluesky_get_status($handle, $did, $pds, $token), ]); $data = [ @@ -446,6 +450,7 @@ function bluesky_settings_post(array &$b) DI::pConfig()->set(DI::userSession()->getLocalUserId(), 'bluesky', 'handle', $handle); DI::pConfig()->set(DI::userSession()->getLocalUserId(), 'bluesky', 'import', intval($_POST['bluesky_import'])); DI::pConfig()->set(DI::userSession()->getLocalUserId(), 'bluesky', 'import_feeds', intval($_POST['bluesky_import_feeds'])); + DI::pConfig()->set(DI::userSession()->getLocalUserId(), 'bluesky', 'complete_threads', intval($_POST['bluesky_complete_threads'])); DI::pConfig()->set(DI::userSession()->getLocalUserId(), 'bluesky', 'friendica_handle', intval($_POST['bluesky_friendica_handle'] ?? false)); if (!empty($handle)) { @@ -534,15 +539,15 @@ function bluesky_cron() Logger::debug('Refresh the token', ['uid' => $pconfig['uid']]); bluesky_get_token($pconfig['uid']); - Worker::add(['priority' => Worker::PRIORITY_MEDIUM, 'force_priority' => true], 'addon/bluesky/bluesky_notifications.php', $pconfig['uid'], $last); + Worker::add(['priority' => Worker::PRIORITY_MEDIUM, 'force_priority' => true], 'addon/bluesky/bluesky_notifications.php', $pconfig['uid']); if (DI::pConfig()->get($pconfig['uid'], 'bluesky', 'import')) { - Worker::add(['priority' => Worker::PRIORITY_MEDIUM, 'force_priority' => true], 'addon/bluesky/bluesky_timeline.php', $pconfig['uid'], $last); + Worker::add(['priority' => Worker::PRIORITY_MEDIUM, 'force_priority' => true], 'addon/bluesky/bluesky_timeline.php', $pconfig['uid']); } if (DI::pConfig()->get($pconfig['uid'], 'bluesky', 'import_feeds')) { Logger::debug('Fetch feeds for user', ['uid' => $pconfig['uid']]); $feeds = bluesky_get_feeds($pconfig['uid']); foreach ($feeds as $feed) { - Worker::add(['priority' => Worker::PRIORITY_MEDIUM, 'force_priority' => true], 'addon/bluesky/bluesky_feed.php', $pconfig['uid'], $feed, $last); + Worker::add(['priority' => Worker::PRIORITY_MEDIUM, 'force_priority' => true], 'addon/bluesky/bluesky_feed.php', $pconfig['uid'], $feed); } } Logger::debug('Polling done for user', ['uid' => $pconfig['uid']]); @@ -710,7 +715,7 @@ function bluesky_create_activity(array $item, stdClass $parent = null) } $activity = bluesky_xrpc_post($uid, 'com.atproto.repo.createRecord', $post); - if (empty($activity)) { + if (empty($activity->uri)) { return; } Logger::debug('Activity done', ['return' => $activity]); @@ -794,7 +799,7 @@ function bluesky_create_post(array $item, stdClass $root = null, stdClass $paren ]; $parent = bluesky_xrpc_post($uid, 'com.atproto.repo.createRecord', $post); - if (empty($parent)) { + if (empty($parent->uri)) { if ($part == 0) { Worker::defer(); } @@ -972,7 +977,7 @@ function bluesky_upload_blob(int $uid, array $photo): ?stdClass Logger::info('Uploading', ['uid' => $uid, 'retrial' => $retrial, 'height' => $new_height, 'width' => $new_width, 'size' => $new_size, 'orig-height' => $height, 'orig-width' => $width, 'orig-size' => $size]); $data = bluesky_post($uid, '/xrpc/com.atproto.repo.uploadBlob', $content, ['Content-type' => $photo['type'], 'Authorization' => ['Bearer ' . bluesky_get_token($uid)]]); - if (empty($data)) { + if (empty($data) || empty($data->blob)) { Logger::info('Uploading failed', ['uid' => $uid, 'retrial' => $retrial, 'height' => $new_height, 'width' => $new_width, 'size' => $new_size, 'orig-height' => $height, 'orig-width' => $width, 'orig-size' => $size]); return null; } @@ -993,7 +998,7 @@ function bluesky_delete_post(string $uri, int $uid) Logger::debug('Deleted', ['parts' => $parts]); } -function bluesky_fetch_timeline(int $uid, int $last_poll) +function bluesky_fetch_timeline(int $uid) { $data = bluesky_xrpc_get($uid, 'app.bsky.feed.getTimeline'); if (empty($data)) { @@ -1004,15 +1009,44 @@ function bluesky_fetch_timeline(int $uid, int $last_poll) return; } + $last_post = DBA::selectFirst('post-thread-user', ['received'], ['network' => Protocol::BLUESKY, 'uid' => $uid], ['order' => ['received' => true]]); + $last_poll = !empty($last_post['received']) ? strtotime($last_post['received']) : 0; + foreach (array_reverse($data->feed) as $entry) { + $causer = bluesky_get_contact($entry->post->author, 0, $uid); + if (!empty($entry->reply)) { + if (!empty($entry->reply->root)) { + bluesky_complete_post($entry->reply->root, $uid, Item::PR_COMMENT, $causer['id'], $last_poll); + } + if (!empty($entry->reply->parent)) { + bluesky_complete_post($entry->reply->parent, $uid, Item::PR_COMMENT, $causer['id'], $last_poll); + } + } bluesky_process_post($entry->post, $uid, $uid, Item::PR_NONE, 0, 0, $last_poll); if (!empty($entry->reason)) { bluesky_process_reason($entry->reason, bluesky_get_uri($entry->post), $uid); } } +} - // @todo Support paging - // [cursor] => 1684670516000::bafyreidq3ilwslmlx72jf5vrk367xcc63s6lrhzlyup2bi3zwcvso6w2vi +function bluesky_complete_post(stdClass $post, int $uid, int $post_reason, int $causer, int $last_poll): int +{ + $complete = DI::pConfig()->get($uid, 'bluesky', 'complete_threads'); + $existing_uri = bluesky_fetch_post(bluesky_get_uri($post), $uid); + if (!empty($existing_uri)) { + $comments = Post::countPosts(['thr-parent' => $existing_uri, 'gravity' => Item::GRAVITY_COMMENT]); + if (($post->replyCount <= $comments) || !$complete) { + return bluesky_fetch_uri_id($existing_uri, $uid); + } + } + + if ($complete) { + $uri = bluesky_fetch_missing_post($post->uri, $uid, $uid, $post_reason, $causer, 0, $last_poll, '', true); + $uri_id = bluesky_fetch_uri_id($uri, $uid); + } else { + $uri_id = bluesky_process_post($post, $uid, $uid, $post_reason, $causer, 0, $last_poll); + } + return $uri_id; } function bluesky_process_reason(stdClass $reason, string $uri, int $uid) @@ -1056,12 +1090,16 @@ function bluesky_process_reason(stdClass $reason, string $uri, int $uid) } } -function bluesky_fetch_notifications(int $uid, int $last_poll) +function bluesky_fetch_notifications(int $uid) { $data = bluesky_xrpc_get($uid, 'app.bsky.notification.listNotifications'); if (empty($data->notifications)) { return; } + + $last_post = DBA::selectFirst('post-thread-user', ['received'], ['network' => Protocol::BLUESKY, 'uid' => $uid], ['order' => ['received' => true]]); + $last_poll = !empty($last_post['received']) ? strtotime($last_post['received']) : 0; + foreach ($data->notifications as $notification) { $uri = bluesky_get_uri($notification); if (Post::exists(['uri' => $uri, 'uid' => $uid]) || Post::exists(['extid' => $uri, 'uid' => $uid])) { @@ -1071,7 +1109,7 @@ function bluesky_fetch_notifications(int $uid, int $last_poll) Logger::debug('Process notification', ['uid' => $uid, 'reason' => $notification->reason, 'uri' => $uri, 'indexedAt' => $notification->indexedAt]); switch ($notification->reason) { case 'like': - $item = bluesky_get_header($notification, $uri, $uid, $uid); + $item = bluesky_get_header($notification, $uri, $uid, $uid, $last_poll); $item['gravity'] = Item::GRAVITY_ACTIVITY; $item['body'] = $item['verb'] = Activity::LIKE; $item['thr-parent'] = bluesky_get_uri($notification->record->subject); @@ -1085,7 +1123,7 @@ function bluesky_fetch_notifications(int $uid, int $last_poll) break; case 'repost': - $item = bluesky_get_header($notification, $uri, $uid, $uid); + $item = bluesky_get_header($notification, $uri, $uid, $uid, $last_poll); $item['gravity'] = Item::GRAVITY_ACTIVITY; $item['body'] = $item['verb'] = Activity::ANNOUNCE; $item['thr-parent'] = bluesky_get_uri($notification->record->subject); @@ -1128,7 +1166,7 @@ function bluesky_fetch_notifications(int $uid, int $last_poll) } } -function bluesky_fetch_feed(int $uid, string $feed, int $last_poll) +function bluesky_fetch_feed(int $uid, string $feed) { $data = bluesky_xrpc_get($uid, 'app.bsky.feed.getFeed', ['feed' => $feed]); if (empty($data)) { @@ -1139,8 +1177,11 @@ function bluesky_fetch_feed(int $uid, string $feed, int $last_poll) return; } + $last_post = DBA::selectFirst('post-thread-user', ['received'], ['network' => Protocol::BLUESKY, 'uid' => $uid], ['order' => ['received' => true]]); + $last_poll = !empty($last_post['received']) ? strtotime($last_post['received']) : 0; + $feeddata = bluesky_xrpc_get($uid, 'app.bsky.feed.getFeedGenerator', ['feed' => $feed]); - if (!empty($feeddata)) { + if (!empty($feeddata) && !empty($feeddata->view)) { $feedurl = $feeddata->view->uri; $feedname = $feeddata->view->displayName; } else { @@ -1153,10 +1194,11 @@ function bluesky_fetch_feed(int $uid, string $feed, int $last_poll) $languages = $entry->post->record->langs ?? []; if (!Relay::isWantedLanguage($entry->post->record->text, 0, $contact['id'] ?? 0, $languages)) { - Logger::debug('Unwanted language detected', ['text' => $entry->post->record->text]); + Logger::debug('Unwanted language detected', ['languages' => $languages, 'text' => $entry->post->record->text]); continue; } - $uri_id = bluesky_process_post($entry->post, $uid, $uid, Item::PR_TAG, 0, 0, $last_poll); + $causer = bluesky_get_contact($entry->post->author, 0, $uid); + $uri_id = bluesky_complete_post($entry->post, $uid, Item::PR_TAG, $causer['id'], $last_poll); if (!empty($uri_id)) { $stored = Post\Category::storeFileByURIId($uri_id, $uid, Post\Category::SUBCRIPTION, $feedname, $feedurl); Logger::debug('Stored tag subscription for user', ['uri-id' => $uri_id, 'uid' => $uid, 'name' => $feedname, 'url' => $feedurl, 'stored' => $stored]); @@ -1184,7 +1226,7 @@ function bluesky_process_post(stdClass $post, int $uid, int $fetch_uid, int $pos Logger::debug('Importing post', ['uid' => $uid, 'indexedAt' => $post->indexedAt, 'uri' => $post->uri, 'cid' => $post->cid, 'root' => $post->record->reply->root ?? '']); - $item = bluesky_get_header($post, $uri, $uid, $fetch_uid); + $item = bluesky_get_header($post, $uri, $uid, $fetch_uid, $last_poll); $item = bluesky_get_content($item, $post->record, $uri, $uid, $fetch_uid, $level, $last_poll); if (empty($item)) { return 0; @@ -1208,7 +1250,7 @@ function bluesky_process_post(stdClass $post, int $uid, int $fetch_uid, int $pos return bluesky_fetch_uri_id($uri, $uid); } -function bluesky_get_header(stdClass $post, string $uri, int $uid, int $fetch_uid): array +function bluesky_get_header(stdClass $post, string $uri, int $uid, int $fetch_uid, int $last_poll = 0): array { $parts = bluesky_get_uri_parts($uri); if (empty($post->author) || empty($post->cid) || empty($parts->rkey)) { @@ -1221,6 +1263,7 @@ function bluesky_get_header(stdClass $post, string $uri, int $uid, int $fetch_ui 'wall' => false, 'uri' => $uri, 'guid' => $post->cid, + 'received' => DateTimeFormat::utc($post->indexedAt, DateTimeFormat::MYSQL), 'private' => Item::UNLISTED, 'verb' => Activity::POST, 'contact-id' => $contact['id'], @@ -1231,6 +1274,10 @@ function bluesky_get_header(stdClass $post, string $uri, int $uid, int $fetch_ui 'source' => json_encode($post), ]; + if (($last_poll != 0) && strtotime($item['received']) < $last_poll) { + unset($item['received']); + } + $account = Contact::selectFirstAccountUser(['pid'], ['id' => $contact['id']]); $item['author-id'] = $account['pid']; @@ -1329,10 +1376,6 @@ function bluesky_get_content(array $item, stdClass $record, string $uri, int $ui $item['created'] = DateTimeFormat::utc($record->createdAt, DateTimeFormat::MYSQL); $item['transmitted-languages'] = $record->langs ?? []; - if (($last_poll != 0) && strtotime($item['created']) > $last_poll) { - $item['received'] = $item['created']; - } - return $item; } @@ -1422,7 +1465,7 @@ function bluesky_add_media(stdClass $embed, array $item, int $fetch_uid, int $le ]; Post\Media::insert($media); break; - + case 'app.bsky.embed.external#view': $media = [ 'uri-id' => $item['uri-id'], @@ -1522,10 +1565,10 @@ function bluesky_get_uri_parts(string $uri): ?stdClass return $class; } -function bluesky_fetch_missing_post(string $uri, int $uid, int $fetch_uid, int $post_reason, int $causer, int $level, int $last_poll, string $fallback = ''): string +function bluesky_fetch_missing_post(string $uri, int $uid, int $fetch_uid, int $post_reason, int $causer, int $level, int $last_poll, string $fallback = '', bool $always_fetch = false): string { $fetched_uri = bluesky_fetch_post($uri, $uid); - if (!empty($fetched_uri)) { + if (!$always_fetch && !empty($fetched_uri)) { return $fetched_uri; } @@ -1545,7 +1588,7 @@ function bluesky_fetch_missing_post(string $uri, int $uid, int $fetch_uid, int $ Logger::debug('Fetch missing post', ['level' => $level, 'uid' => $uid, 'uri' => $uri]); $data = bluesky_xrpc_get($fetch_uid, 'app.bsky.feed.getPostThread', ['uri' => $fetch_uri]); - if (empty($data)) { + if (empty($data) || empty($data->thread)) { Logger::info('Thread was not fetched', ['level' => $level, 'uid' => $uid, 'uri' => $uri, 'fallback' => $fallback]); return $fallback; } @@ -1556,9 +1599,31 @@ function bluesky_fetch_missing_post(string $uri, int $uid, int $fetch_uid, int $ $causer = Contact::getPublicContactId($causer, $uid); } + if (!empty($data->thread->parent)) { + $parents = bluesky_fetch_parents($data->thread->parent, $uid); + + foreach ($parents as $parent) { + $uri_id = bluesky_process_post($parent, $uid, $fetch_uid, Item::PR_FETCHED, $causer, $level, $last_poll); + Logger::debug('Parent created', ['uri-id' => $uri_id]); + } + } + return bluesky_process_thread($data->thread, $uid, $fetch_uid, $post_reason, $causer, $level, $last_poll); } +function bluesky_fetch_parents(stdClass $parent, int $uid, array $parents = []): array +{ + if (!empty($parent->parent)) { + $parents = bluesky_fetch_parents($parent->parent, $uid, $parents); + } + + if (empty(bluesky_fetch_post(bluesky_get_uri($parent->post), $uid))) { + $parents[] = $parent->post; + } + + return $parents; +} + function bluesky_fetch_post(string $uri, int $uid): string { if (Post::exists(['uri' => $uri, 'uid' => [$uid, 0]])) { @@ -1694,7 +1759,7 @@ function bluesky_get_contact_fields(stdClass $author, int $uid, int $fetch_uid, } $data = bluesky_get(BLUESKY_DIRECTORY . '/' . $author->did); - if (!empty($data)) { + if (!empty($data)) { $fields['baseurl'] = bluesky_get_pds('', $data); if (!empty($fields['baseurl'])) { GServer::check($fields['baseurl'], Protocol::BLUESKY); @@ -1877,6 +1942,13 @@ function bluesky_get_did(string $handle, int $uid): string return $did; } + // The profile page can contain hints to the DID as well + $did = bluesky_get_did_by_profile('https://' . $handle); + if ($did != '') { + Logger::debug('Got DID by profile page', ['handle' => $handle, 'did' => $did]); + return $did; + } + // And finally we use the default PDS from Bluesky. $data = bluesky_get(BLUESKY_PDS . '/xrpc/com.atproto.identity.resolveHandle?handle=' . urlencode($handle)); if (!empty($data) && !empty($data->did)) { @@ -1996,7 +2068,7 @@ function bluesky_refresh_token(int $uid): string $token = DI::pConfig()->get($uid, 'bluesky', 'refresh_token'); $data = bluesky_post($uid, '/xrpc/com.atproto.server.refreshSession', '', ['Authorization' => ['Bearer ' . $token]]); - if (empty($data)) { + if (empty($data) || empty($data->accessJwt)) { return ''; } @@ -2015,7 +2087,7 @@ function bluesky_create_token(int $uid, string $password): string } $data = bluesky_post($uid, '/xrpc/com.atproto.server.createSession', json_encode(['identifier' => $did, 'password' => $password]), ['Content-type' => 'application/json']); - if (empty($data)) { + if (empty($data) || empty($data->accessJwt)) { DI::pConfig()->set($uid, 'bluesky', 'status', BLUEKSY_STATUS_TOKEN_FAIL); return ''; } @@ -2052,14 +2124,18 @@ function bluesky_post(int $uid, string $url, string $params, array $headers): ?s return null; } + $data = json_decode($curlResult->getBodyString()); if (!$curlResult->isSuccess()) { - Logger::notice('API Error', ['error' => json_decode($curlResult->getBodyString()) ?: $curlResult->getBodyString()]); - DI::pConfig()->set($uid, 'bluesky', 'status', BLUEKSY_STATUS_API_FAIL); - return null; + Logger::notice('API Error', ['url' => $url, 'code' => $curlResult->getReturnCode(), 'error' => $data ?: $curlResult->getBodyString()]); + if (!$data) { + DI::pConfig()->set($uid, 'bluesky', 'status', BLUEKSY_STATUS_API_FAIL); + return null; + } + $data->code = $curlResult->getReturnCode(); } DI::pConfig()->set($uid, 'bluesky', 'status', BLUEKSY_STATUS_SUCCESS); - return json_decode($curlResult->getBodyString()); + return $data; } function bluesky_xrpc_get(int $uid, string $url, array $parameters = []): ?stdClass @@ -2073,7 +2149,14 @@ function bluesky_xrpc_get(int $uid, string $url, array $parameters = []): ?stdCl return null; } - $data = bluesky_get($pds . '/xrpc/' . $url, HttpClientAccept::JSON, [HttpClientOptions::HEADERS => ['Authorization' => ['Bearer ' . bluesky_get_token($uid)]]]); + $headers = ['Authorization' => ['Bearer ' . bluesky_get_token($uid)]]; + + $languages = User::getWantedLanguages($uid); + if (!empty($languages)) { + $headers['Accept-Language'] = implode(',', $languages); + } + + $data = bluesky_get($pds . '/xrpc/' . $url, HttpClientAccept::JSON, [HttpClientOptions::HEADERS => $headers]); DI::pConfig()->set($uid, 'bluesky', 'status', is_null($data) ? BLUEKSY_STATUS_API_FAIL : BLUEKSY_STATUS_SUCCESS); return $data; } @@ -2087,11 +2170,15 @@ function bluesky_get(string $url, string $accept_content = HttpClientAccept::DEF return null; } + $data = json_decode($curlResult->getBodyString()); if (!$curlResult->isSuccess()) { - Logger::notice('API Error', ['url' => $url, 'error' => json_decode($curlResult->getBodyString()) ?: $curlResult->getBodyString()]); - return null; + Logger::notice('API Error', ['url' => $url, 'code' => $curlResult->getReturnCode(), 'error' => $data ?: $curlResult->getBodyString()]); + if (!$data) { + return null; + } + $data->code = $curlResult->getReturnCode(); } Item::incrementInbound(Protocol::BLUESKY); - return json_decode($curlResult->getBodyString()); + return $data; } diff --git a/bluesky/bluesky_feed.php b/bluesky/bluesky_feed.php index c9a54223..a20ef1b9 100644 --- a/bluesky/bluesky_feed.php +++ b/bluesky/bluesky_feed.php @@ -6,11 +6,11 @@ function bluesky_feed_run($argv, $argc) { require_once 'addon/bluesky/bluesky.php'; - if ($argc != 4) { + if ($argc < 3) { return; } - Logger::debug('Importing feed - start', ['user' => $argv[1], 'feed' => $argv[2], 'last_poll' => $argv[3]]); - bluesky_fetch_feed($argv[1], $argv[2], $argv[3]); - Logger::debug('Importing feed - done', ['user' => $argv[1], 'feed' => $argv[2], 'last_poll' => $argv[3]]); + Logger::debug('Importing feed - start', ['user' => $argv[1], 'feed' => $argv[2]]); + bluesky_fetch_feed($argv[1], $argv[2]); + Logger::debug('Importing feed - done', ['user' => $argv[1], 'feed' => $argv[2]]); } diff --git a/bluesky/bluesky_notifications.php b/bluesky/bluesky_notifications.php index ad35dfe0..1fbc8f67 100644 --- a/bluesky/bluesky_notifications.php +++ b/bluesky/bluesky_notifications.php @@ -6,11 +6,11 @@ function bluesky_notifications_run($argv, $argc) { require_once 'addon/bluesky/bluesky.php'; - if ($argc != 3) { + if ($argc < 2) { return; } - Logger::notice('importing notifications - start', ['user' => $argv[1], 'last_poll' => $argv[2]]); - bluesky_fetch_notifications($argv[1], $argv[2]); - Logger::notice('importing notifications - done', ['user' => $argv[1], 'last_poll' => $argv[2]]); + Logger::notice('importing notifications - start', ['user' => $argv[1]]); + bluesky_fetch_notifications($argv[1]); + Logger::notice('importing notifications - done', ['user' => $argv[1]]); } diff --git a/bluesky/bluesky_timeline.php b/bluesky/bluesky_timeline.php index 22ef2224..fda846ba 100644 --- a/bluesky/bluesky_timeline.php +++ b/bluesky/bluesky_timeline.php @@ -6,11 +6,11 @@ function bluesky_timeline_run($argv, $argc) { require_once 'addon/bluesky/bluesky.php'; - if ($argc != 3) { + if ($argc < 2) { return; } - Logger::notice('importing timeline - start', ['user' => $argv[1], 'last_poll' => $argv[2]]); - bluesky_fetch_timeline($argv[1], $argv[2]); - Logger::notice('importing timeline - done', ['user' => $argv[1], 'last_poll' => $argv[2]]); + Logger::notice('importing timeline - start', ['user' => $argv[1]]); + bluesky_fetch_timeline($argv[1]); + Logger::notice('importing timeline - done', ['user' => $argv[1]]); } diff --git a/bluesky/lang/C/messages.po b/bluesky/lang/C/messages.po index 9521ab89..d573972c 100644 --- a/bluesky/lang/C/messages.po +++ b/bluesky/lang/C/messages.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2024-03-22 05:31+0000\n" +"POT-Creation-Date: 2024-09-29 18:16+0000\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -17,131 +17,117 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -#: bluesky.php:325 +#: bluesky.php:335 msgid "Save Settings" msgstr "" -#: bluesky.php:326 +#: bluesky.php:336 msgid "Allow your users to use your hostname for their Bluesky handles" msgstr "" -#: bluesky.php:326 +#: bluesky.php:336 #, php-format -msgid "" -"Before enabling this option, you have to setup a wildcard domain " -"configuration and you have to enable wildcard requests in your webserver " -"configuration. On Apache this is done by adding \"ServerAlias *.%s\" to your " -"HTTP configuration. You don't need to change the HTTPS configuration." +msgid "Before enabling this option, you have to setup a wildcard domain configuration and you have to enable wildcard requests in your webserver configuration. On Apache this is done by adding \"ServerAlias *.%s\" to your HTTP configuration. You don't need to change the HTTPS configuration." msgstr "" -#: bluesky.php:354 +#: bluesky.php:365 #, php-format msgid "Allow to use %s as your Bluesky handle." msgstr "" -#: bluesky.php:354 +#: bluesky.php:365 #, php-format -msgid "" -"When enabled, you can use %s as your Bluesky handle. After you enabled this " -"option, please go to https://bsky.app/settings and select to change your " -"handle. Select that you have got your own domain. Then enter %s and select " -"\"No DNS Panel\". Then select \"Verify Text File\"." -msgstr "" - -#: bluesky.php:361 -msgid "Enable Bluesky Post Addon" -msgstr "" - -#: bluesky.php:362 -msgid "Post to Bluesky by default" -msgstr "" - -#: bluesky.php:363 -msgid "Import the remote timeline" -msgstr "" - -#: bluesky.php:364 -msgid "Import the pinned feeds" -msgstr "" - -#: bluesky.php:364 -msgid "" -"When activated, Posts will be imported from all the feeds that you pinned in " -"Bluesky." -msgstr "" - -#: bluesky.php:366 -msgid "Personal Data Server" -msgstr "" - -#: bluesky.php:366 -msgid "The personal data server (PDS) is the system that hosts your profile." -msgstr "" - -#: bluesky.php:367 -msgid "Bluesky handle" -msgstr "" - -#: bluesky.php:368 -msgid "Bluesky DID" -msgstr "" - -#: bluesky.php:368 -msgid "" -"This is the unique identifier. It will be fetched automatically, when the " -"handle is entered." -msgstr "" - -#: bluesky.php:369 -msgid "Bluesky app password" -msgstr "" - -#: bluesky.php:369 -msgid "" -"Please don't add your real password here, but instead create a specific app " -"password in the Bluesky settings." +msgid "When enabled, you can use %s as your Bluesky handle. After you enabled this option, please go to https://bsky.app/settings and select to change your handle. Select that you have got your own domain. Then enter %s and select \"No DNS Panel\". Then select \"Verify Text File\"." msgstr "" #: bluesky.php:375 +msgid "Enable Bluesky Post Addon" +msgstr "" + +#: bluesky.php:376 +msgid "Post to Bluesky by default" +msgstr "" + +#: bluesky.php:377 +msgid "Import the remote timeline" +msgstr "" + +#: bluesky.php:378 +msgid "Import the pinned feeds" +msgstr "" + +#: bluesky.php:378 +msgid "When activated, Posts will be imported from all the feeds that you pinned in Bluesky." +msgstr "" + +#: bluesky.php:379 +msgid "Complete the threads" +msgstr "" + +#: bluesky.php:379 +msgid "When activated, the system fetches additional replies for the posts in the timeline. This leads to more complete threads." +msgstr "" + +#: bluesky.php:381 +msgid "Personal Data Server" +msgstr "" + +#: bluesky.php:381 +msgid "The personal data server (PDS) is the system that hosts your profile." +msgstr "" + +#: bluesky.php:382 +msgid "Bluesky handle" +msgstr "" + +#: bluesky.php:383 +msgid "Bluesky DID" +msgstr "" + +#: bluesky.php:383 +msgid "This is the unique identifier. It will be fetched automatically, when the handle is entered." +msgstr "" + +#: bluesky.php:384 +msgid "Bluesky app password" +msgstr "" + +#: bluesky.php:384 +msgid "Please don't add your real password here, but instead create a specific app password in the Bluesky settings." +msgstr "" + +#: bluesky.php:390 msgid "Bluesky Import/Export" msgstr "" -#: bluesky.php:385 -msgid "" -"You are not authenticated. Please enter your handle and the app password." +#: bluesky.php:400 +msgid "You are not authenticated. Please enter your handle and the app password." msgstr "" -#: bluesky.php:405 -msgid "" -"You are authenticated to Bluesky. For security reasons the password isn't " -"stored." +#: bluesky.php:420 +msgid "You are authenticated to Bluesky. For security reasons the password isn't stored." msgstr "" -#: bluesky.php:407 -msgid "" -"The communication with the personal data server service (PDS) is established." +#: bluesky.php:422 +msgid "The communication with the personal data server service (PDS) is established." msgstr "" -#: bluesky.php:409 +#: bluesky.php:424 msgid "Communication issues with the personal data server service (PDS)." msgstr "" -#: bluesky.php:411 -msgid "" -"The DID for the provided handle could not be detected. Please check if you " -"entered the correct handle." +#: bluesky.php:426 +msgid "The DID for the provided handle could not be detected. Please check if you entered the correct handle." msgstr "" -#: bluesky.php:413 +#: bluesky.php:428 msgid "The personal data server service (PDS) could not be detected." msgstr "" -#: bluesky.php:415 -msgid "" -"The authentication with the provided handle and password failed. Please " -"check if you entered the correct password." +#: bluesky.php:430 +msgid "The authentication with the provided handle and password failed. Please check if you entered the correct password." msgstr "" -#: bluesky.php:484 +#: bluesky.php:492 msgid "Post to Bluesky" msgstr "" diff --git a/bluesky/templates/connector_settings.tpl b/bluesky/templates/connector_settings.tpl index 3ebea827..a85bcd89 100644 --- a/bluesky/templates/connector_settings.tpl +++ b/bluesky/templates/connector_settings.tpl @@ -3,6 +3,7 @@ {{include file="field_checkbox.tpl" field=$bydefault}} {{include file="field_checkbox.tpl" field=$import}} {{include file="field_checkbox.tpl" field=$import_feeds}} +{{include file="field_checkbox.tpl" field=$complete_threads}} {{if $custom_handle}} {{include file="field_checkbox.tpl" field=$custom_handle}} {{/if}} From 08c17c9dd47388da281875c2def8d07d4a0085d6 Mon Sep 17 00:00:00 2001 From: Michael Date: Sat, 19 Oct 2024 07:41:24 +0000 Subject: [PATCH 031/222] Bluesky: Fixes "E_WARNING: Undefined property: stdClass::$post" --- bluesky/bluesky.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bluesky/bluesky.php b/bluesky/bluesky.php index 73b19612..95857b01 100644 --- a/bluesky/bluesky.php +++ b/bluesky/bluesky.php @@ -1617,7 +1617,7 @@ function bluesky_fetch_parents(stdClass $parent, int $uid, array $parents = []): $parents = bluesky_fetch_parents($parent->parent, $uid, $parents); } - if (empty(bluesky_fetch_post(bluesky_get_uri($parent->post), $uid))) { + if (!empty($parent->post) && empty(bluesky_fetch_post(bluesky_get_uri($parent->post), $uid))) { $parents[] = $parent->post; } From 586ebe96993bcf8ee3be35c13b2475cb1d527287 Mon Sep 17 00:00:00 2001 From: Michael Date: Wed, 23 Oct 2024 12:14:40 +0000 Subject: [PATCH 032/222] Bluesky: "block" now works / label names are now displayed --- bluesky/bluesky.php | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/bluesky/bluesky.php b/bluesky/bluesky.php index 95857b01..894b64d9 100644 --- a/bluesky/bluesky.php +++ b/bluesky/bluesky.php @@ -278,14 +278,12 @@ function bluesky_block(array &$hook_data) return; } - Logger::debug('Check if contact is bluesky', ['data' => $hook_data]); - $contact = DBA::selectFirst('contact', [], ['network' => Protocol::BLUESKY, 'url' => $hook_data['url'], 'uid' => [0, $hook_data['uid']]]); - if (empty($contact)) { + if ($hook_data['contact']['network'] != Protocol::BLUESKY) { return; } $record = [ - 'subject' => $contact['url'], + 'subject' => $hook_data['contact']['url'], 'createdAt' => DateTimeFormat::utcNow(DateTimeFormat::ATOM), '$type' => 'app.bsky.graph.block' ]; @@ -1297,6 +1295,7 @@ function bluesky_get_header(stdClass $post, string $uri, int $uid, int $fetch_ui // When "ver" is set to "1" it was flagged by some automated process. if (empty($label->ver)) { $item['sensitive'] = true; + $item['content-warning'] = $label->val ?? ''; Logger::debug('Sensitive content', ['uri-id' => $item['uri-id'], 'label' => $label]); } } From 8b694fbb4c6ee0a19fd7c3b30edca30d916523a9 Mon Sep 17 00:00:00 2001 From: Michael Date: Sun, 27 Oct 2024 04:50:45 +0000 Subject: [PATCH 033/222] Bluesky: Fix following of a contact and adding a post --- bluesky/bluesky.php | 33 ++++++++++++++++----------------- 1 file changed, 16 insertions(+), 17 deletions(-) diff --git a/bluesky/bluesky.php b/bluesky/bluesky.php index 894b64d9..45a56792 100644 --- a/bluesky/bluesky.php +++ b/bluesky/bluesky.php @@ -139,7 +139,7 @@ function bluesky_probe_detect(array &$hookData) return; } } elseif (Network::isValidHttpUrl($hookData['uri'])) { - $did = bluesky_get_did_by_profile($hookData['uri']); + $did = bluesky_get_did_by_profile($hookData['uri'], $pconfig['uid']); if (empty($did)) { return; } @@ -181,21 +181,21 @@ function bluesky_item_by_link(array &$hookData) return; } - $did = bluesky_get_did_by_profile($hookData['uri']); + if (!preg_match('#/profile/(.+)/post/(.+)#', $hookData['uri'], $matches)) { + return; + } + + $did = bluesky_get_did($matches[1], $hookData['uid']); if (empty($did)) { return; } - if (!preg_match('#/profile/.+/post/(.+)#', $hookData['uri'], $matches)) { - return; - } + Logger::debug('Found bluesky post', ['url' => $hookData['uri'], 'did' => $did, 'cid' => $matches[2]]); - Logger::debug('Found bluesky post', ['url' => $hookData['uri'], 'did' => $did, 'cid' => $matches[1]]); - - $uri = 'at://' . $did . '/app.bsky.feed.post/' . $matches[1]; + $uri = 'at://' . $did . '/app.bsky.feed.post/' . $matches[2]; $uri = bluesky_fetch_missing_post($uri, $hookData['uid'], $hookData['uid'], Item::PR_FETCHED, 0, 0, 0); - Logger::debug('Got post', ['did' => $did, 'cid' => $matches[1], 'result' => $uri]); + Logger::debug('Got post', ['did' => $did, 'cid' => $matches[2], 'result' => $uri]); if (!empty($uri)) { $item = Post::selectFirst(['id'], ['uri' => $uri, 'uid' => $hookData['uid']]); if (!empty($item['id'])) { @@ -1831,8 +1831,14 @@ function bluesky_get_preferences(int $uid): ?stdClass return $data; } -function bluesky_get_did_by_profile(string $url): string +function bluesky_get_did_by_profile(string $url, int $uid): string { + if (preg_match('#/profile/(.+)#', $url, $matches)) { + $did = bluesky_get_did($matches[1], $uid); + if (!empty($did)) { + return $did; + } + } try { $curlResult = DI::httpClient()->get($url, HttpClientAccept::HTML, [HttpClientOptions::REQUEST => HttpClientRequest::CONTACTINFO]); } catch (\Throwable $th) { @@ -1941,13 +1947,6 @@ function bluesky_get_did(string $handle, int $uid): string return $did; } - // The profile page can contain hints to the DID as well - $did = bluesky_get_did_by_profile('https://' . $handle); - if ($did != '') { - Logger::debug('Got DID by profile page', ['handle' => $handle, 'did' => $did]); - return $did; - } - // And finally we use the default PDS from Bluesky. $data = bluesky_get(BLUESKY_PDS . '/xrpc/com.atproto.identity.resolveHandle?handle=' . urlencode($handle)); if (!empty($data) && !empty($data->did)) { From 4165479079faf4a8bb63d08574e0ff10cd4950ab Mon Sep 17 00:00:00 2001 From: Michael Date: Wed, 30 Oct 2024 05:11:50 +0000 Subject: [PATCH 034/222] Bluesky: Fix probe mistake --- bluesky/bluesky.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/bluesky/bluesky.php b/bluesky/bluesky.php index 45a56792..af7d9ac7 100644 --- a/bluesky/bluesky.php +++ b/bluesky/bluesky.php @@ -181,7 +181,7 @@ function bluesky_item_by_link(array &$hookData) return; } - if (!preg_match('#/profile/(.+)/post/(.+)#', $hookData['uri'], $matches)) { + if (!preg_match('#^' . BLUESKY_WEB . '/profile/(.+)/post/(.+)#', $hookData['uri'], $matches)) { return; } @@ -1833,7 +1833,7 @@ function bluesky_get_preferences(int $uid): ?stdClass function bluesky_get_did_by_profile(string $url, int $uid): string { - if (preg_match('#/profile/(.+)#', $url, $matches)) { + if (preg_match('#^' . BLUESKY_WEB . '/profile/(.+)#', $url, $matches)) { $did = bluesky_get_did($matches[1], $uid); if (!empty($did)) { return $did; From e89b5b1466811a28c28cd95bd81417735809018f Mon Sep 17 00:00:00 2001 From: Tobias Diekershoff Date: Wed, 13 Nov 2024 10:10:25 +0100 Subject: [PATCH 035/222] deprecate fancybox addon replaces #1562 --- fancybox/fancybox.php | 1 + 1 file changed, 1 insertion(+) diff --git a/fancybox/fancybox.php b/fancybox/fancybox.php index 1a9ff634..73bbdab9 100644 --- a/fancybox/fancybox.php +++ b/fancybox/fancybox.php @@ -4,6 +4,7 @@ * Description: Open media attachments of posts into a fancybox overlay. * Version: 1.05 * Author: Grischa Brockhaus + * Status: Unsupported */ use Friendica\App; From 6a1cbe9040d13de472f4924f4fe44ee1e2524ffc Mon Sep 17 00:00:00 2001 From: Michael Date: Wed, 6 Nov 2024 17:45:30 +0000 Subject: [PATCH 036/222] Bluesky/Tumblr: Add "connector" parcel to each incoming post --- bluesky/bluesky.php | 7 +++++-- tumblr/tumblr.php | 3 ++- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/bluesky/bluesky.php b/bluesky/bluesky.php index af7d9ac7..4882a263 100644 --- a/bluesky/bluesky.php +++ b/bluesky/bluesky.php @@ -38,6 +38,7 @@ use Friendica\Core\Worker; use Friendica\Database\DBA; use Friendica\DI; use Friendica\Model\Contact; +use Friendica\Model\Conversation; use Friendica\Model\GServer; use Friendica\Model\Item; use Friendica\Model\ItemURI; @@ -1058,6 +1059,7 @@ function bluesky_process_reason(stdClass $reason, string $uri, int $uid) $item = [ 'network' => Protocol::BLUESKY, + 'protocol' => Conversation::PARCEL_CONNECTOR, 'uid' => $uid, 'wall' => false, 'uri' => $reason->by->did . '/app.bsky.feed.repost/' . $reason->indexedAt, @@ -1257,6 +1259,7 @@ function bluesky_get_header(stdClass $post, string $uri, int $uid, int $fetch_ui $contact = bluesky_get_contact($post->author, $uid, $fetch_uid); $item = [ 'network' => Protocol::BLUESKY, + 'protocol' => Conversation::PARCEL_CONNECTOR, 'uid' => $uid, 'wall' => false, 'uri' => $uri, @@ -1459,8 +1462,8 @@ function bluesky_add_media(stdClass $embed, array $item, int $fetch_uid, int $le 'url' => $embed->playlist, 'preview' => $embed->thumbnail, 'description' => $embed->alt ?? '', - 'height' => $embed->aspectRatio->height, - 'width' => $embed->aspectRatio->width, + 'height' => $embed->aspectRatio->height ?? null, + 'width' => $embed->aspectRatio->width ?? null, ]; Post\Media::insert($media); break; diff --git a/tumblr/tumblr.php b/tumblr/tumblr.php index dd34bd41..390c3c6c 100644 --- a/tumblr/tumblr.php +++ b/tumblr/tumblr.php @@ -22,6 +22,7 @@ use Friendica\Core\Worker; use Friendica\Database\DBA; use Friendica\DI; use Friendica\Model\Contact; +use Friendica\Model\Conversation; use Friendica\Model\Item; use Friendica\Model\Photo; use Friendica\Model\Post; @@ -31,7 +32,6 @@ use Friendica\Network\HTTPClient\Client\HttpClientAccept; use Friendica\Network\HTTPClient\Client\HttpClientOptions; use Friendica\Protocol\Activity; use Friendica\Util\DateTimeFormat; -use Friendica\Util\Network; use Friendica\Util\Strings; use GuzzleHttp\Client; use GuzzleHttp\Exception\RequestException; @@ -850,6 +850,7 @@ function tumblr_get_header(stdClass $post, string $uri, int $uid): array $contact = tumblr_get_contact($post->blog, $uid); $item = [ 'network' => Protocol::TUMBLR, + 'protocol' => Conversation::PARCEL_CONNECTOR, 'uid' => $uid, 'wall' => false, 'uri' => $uri, From c22e0ae8310e80c83373f608ab4e5b21660c594d Mon Sep 17 00:00:00 2001 From: Michael Date: Sat, 16 Nov 2024 05:42:00 +0000 Subject: [PATCH 037/222] Fix handling of the 'private' field / reformatted code --- bluesky/bluesky.php | 32 +++++++++++++++++----------- diaspora/diaspora.php | 47 ++++++++++++++++++++--------------------- dwpost/dwpost.php | 29 ++++++++++++------------- ijpost/ijpost.php | 22 ++++++++----------- libertree/libertree.php | 47 ++++++++++++++++++----------------------- ljpost/ljpost.php | 41 +++++++++++++++++------------------ pnut/pnut.php | 17 ++++++--------- pumpio/pumpio.php | 8 +++---- statusnet/statusnet.php | 10 +++++---- tumblr/tumblr.php | 14 +++++------- twitter/twitter.php | 6 +++--- wppost/wppost.php | 19 +++++------------ 12 files changed, 135 insertions(+), 157 deletions(-) diff --git a/bluesky/bluesky.php b/bluesky/bluesky.php index 4882a263..d719eecb 100644 --- a/bluesky/bluesky.php +++ b/bluesky/bluesky.php @@ -587,13 +587,13 @@ function bluesky_hook_fork(array &$b) if (DI::pConfig()->get($post['uid'], 'bluesky', 'import')) { // Don't post if it isn't a reply to a bluesky post - if (($post['parent'] != $post['id']) && !Post::exists(['id' => $post['parent'], 'network' => Protocol::BLUESKY])) { + if (($post['gravity'] != Item::GRAVITY_PARENT) && !Post::exists(['id' => $post['parent'], 'network' => Protocol::BLUESKY])) { Logger::notice('No bluesky parent found', ['item' => $post['id']]); $b['execute'] = false; return; } - } elseif (!strstr($post['postopts'] ?? '', 'bluesky') || ($post['parent'] != $post['id']) || $post['private']) { - DI::logger()->info('Activities are never exported when we don\'t import the bluesky timeline', ['uid' => $post['uid']]); + } elseif (!strstr($post['postopts'] ?? '', 'bluesky') || ($post['gravity'] != Item::GRAVITY_PARENT) || ($post['private'] == Item::PRIVATE)) { + DI::logger()->info('Post will not be exported', ['uid' => $post['uid'], 'postopts' => $post['postopts'], 'gravity' => $post['gravity'], 'private' => $post['private']]); $b['execute'] = false; return; } @@ -601,15 +601,11 @@ function bluesky_hook_fork(array &$b) function bluesky_post_local(array &$b) { - if ($b['edit']) { - return; - } - if (!DI::userSession()->getLocalUserId() || (DI::userSession()->getLocalUserId() != $b['uid'])) { return; } - if ($b['private'] || $b['parent']) { + if ($b['edit'] || ($b['private'] == Item::PRIVATE) || ($b['gravity'] != Item::GRAVITY_PARENT)) { return; } @@ -667,7 +663,7 @@ function bluesky_send(array &$b) bluesky_create_activity($b, $parent); } return; - } elseif ($b['private'] || !strstr($b['postopts'], 'bluesky')) { + } elseif (($b['private'] == Item::PRIVATE) || !strstr($b['postopts'], 'bluesky')) { return; } @@ -1481,6 +1477,18 @@ function bluesky_add_media(stdClass $embed, array $item, int $fetch_uid, int $le case 'app.bsky.embed.record#view': $original_uri = $uri = bluesky_get_uri($embed->record); + $type = '$type'; + if (!empty($embed->record->record->$type)) { + $embed_type = $embed->record->record->$type; + if ($embed_type == 'app.bsky.graph.starterpack') { + Logger::debug('Starterpacks are not fetched like posts', ['original-uri' => $original_uri]); + if (empty($item['body'])) { + // @todo process starterpack + $item['body'] = '[url=' . $embed->record->record->list . ']' . $embed->record->record->name . '[/url]'; + } + break; + } + } $uri = bluesky_fetch_missing_post($uri, $item['uid'], $fetch_uid, Item::PR_FETCHED, $item['contact-id'], $level, $last_poll); if ($uri) { $shared = Post::selectFirst(['uri-id'], ['uri' => $uri, 'uid' => [$item['uid'], 0]]); @@ -1603,13 +1611,13 @@ function bluesky_fetch_missing_post(string $uri, int $uid, int $fetch_uid, int $ if (!empty($data->thread->parent)) { $parents = bluesky_fetch_parents($data->thread->parent, $uid); - + foreach ($parents as $parent) { $uri_id = bluesky_process_post($parent, $uid, $fetch_uid, Item::PR_FETCHED, $causer, $level, $last_poll); Logger::debug('Parent created', ['uri-id' => $uri_id]); } } - + return bluesky_process_thread($data->thread, $uid, $fetch_uid, $post_reason, $causer, $level, $last_poll); } @@ -1618,7 +1626,7 @@ function bluesky_fetch_parents(stdClass $parent, int $uid, array $parents = []): if (!empty($parent->parent)) { $parents = bluesky_fetch_parents($parent->parent, $uid, $parents); } - + if (!empty($parent->post) && empty(bluesky_fetch_post(bluesky_get_uri($parent->post), $uid))) { $parents[] = $parent->post; } diff --git a/diaspora/diaspora.php b/diaspora/diaspora.php index cb2eb996..979204ba 100644 --- a/diaspora/diaspora.php +++ b/diaspora/diaspora.php @@ -17,6 +17,7 @@ use Friendica\Core\Renderer; use Friendica\Database\DBA; use Friendica\Core\Worker; use Friendica\DI; +use Friendica\Model\Item; use Friendica\Model\Post; function diaspora_install() @@ -120,15 +121,15 @@ function diaspora_settings(array &$data) function diaspora_settings_post(array &$b) { if (!empty($_POST['diaspora-submit'])) { - DI::pConfig()->set(DI::userSession()->getLocalUserId(),'diaspora', 'post' , intval($_POST['enabled'])); + DI::pConfig()->set(DI::userSession()->getLocalUserId(), 'diaspora', 'post', intval($_POST['enabled'])); if (intval($_POST['enabled'])) { if (isset($_POST['handle'])) { - DI::pConfig()->set(DI::userSession()->getLocalUserId(),'diaspora', 'handle' , trim($_POST['handle'])); - DI::pConfig()->set(DI::userSession()->getLocalUserId(),'diaspora', 'password' , trim($_POST['password'])); + DI::pConfig()->set(DI::userSession()->getLocalUserId(), 'diaspora', 'handle', trim($_POST['handle'])); + DI::pConfig()->set(DI::userSession()->getLocalUserId(), 'diaspora', 'password', trim($_POST['password'])); } if (!empty($_POST['aspect'])) { - DI::pConfig()->set(DI::userSession()->getLocalUserId(),'diaspora', 'aspect' , trim($_POST['aspect'])); - DI::pConfig()->set(DI::userSession()->getLocalUserId(),'diaspora', 'post_by_default', intval($_POST['post_by_default'])); + DI::pConfig()->set(DI::userSession()->getLocalUserId(), 'diaspora', 'aspect', trim($_POST['aspect'])); + DI::pConfig()->set(DI::userSession()->getLocalUserId(), 'diaspora', 'post_by_default', intval($_POST['post_by_default'])); } } else { DI::pConfig()->delete(DI::userSession()->getLocalUserId(), 'diaspora', 'password'); @@ -144,8 +145,10 @@ function diaspora_hook_fork(array &$b) $post = $b['data']; - if ($post['deleted'] || $post['private'] || ($post['created'] !== $post['edited']) || - !strstr($post['postopts'] ?? '', 'diaspora') || ($post['parent'] != $post['id'])) { + if ( + $post['deleted'] || ($post['private'] == Item::PRIVATE) || ($post['created'] !== $post['edited']) || + !strstr($post['postopts'] ?? '', 'diaspora') || ($post['gravity'] != Item::GRAVITY_PARENT) + ) { $b['execute'] = false; return; } @@ -153,23 +156,19 @@ function diaspora_hook_fork(array &$b) function diaspora_post_local(array &$b) { - if ($b['edit']) { - return; - } - if (!DI::userSession()->getLocalUserId() || (DI::userSession()->getLocalUserId() != $b['uid'])) { return; } - if ($b['private'] || $b['parent']) { + if ($b['edit'] || ($b['private'] == Item::PRIVATE) || ($b['gravity'] != Item::GRAVITY_PARENT)) { return; } - $diaspora_post = intval(DI::pConfig()->get(DI::userSession()->getLocalUserId(),'diaspora','post')); + $diaspora_post = intval(DI::pConfig()->get(DI::userSession()->getLocalUserId(), 'diaspora', 'post')); $diaspora_enable = (($diaspora_post && !empty($_REQUEST['diaspora_enable'])) ? intval($_REQUEST['diaspora_enable']) : 0); - if ($b['api_source'] && intval(DI::pConfig()->get(DI::userSession()->getLocalUserId(),'diaspora','post_by_default'))) { + if ($b['api_source'] && intval(DI::pConfig()->get(DI::userSession()->getLocalUserId(), 'diaspora', 'post_by_default'))) { $diaspora_enable = 1; } @@ -190,11 +189,11 @@ function diaspora_send(array &$b) Logger::notice('diaspora_send: invoked'); - if ($b['deleted'] || $b['private'] || ($b['created'] !== $b['edited'])) { + if ($b['deleted'] || ($b['private'] == Item::PRIVATE) || ($b['created'] !== $b['edited'])) { return; } - if (!strstr($b['postopts'],'diaspora')) { + if (!strstr($b['postopts'], 'diaspora')) { return; } @@ -214,9 +213,9 @@ function diaspora_send(array &$b) Logger::info('diaspora_send: prepare posting'); - $handle = DI::pConfig()->get($b['uid'],'diaspora','handle'); - $password = DI::pConfig()->get($b['uid'],'diaspora','password'); - $aspect = DI::pConfig()->get($b['uid'],'diaspora','aspect'); + $handle = DI::pConfig()->get($b['uid'], 'diaspora', 'handle'); + $password = DI::pConfig()->get($b['uid'], 'diaspora', 'password'); + $aspect = DI::pConfig()->get($b['uid'], 'diaspora', 'aspect'); if ($handle && $password) { Logger::info('diaspora_send: all values seem to be okay'); @@ -230,7 +229,7 @@ function diaspora_send(array &$b) // Removal of tags and mentions // #-tags $body = preg_replace('/#\[url\=(\w+.*?)\](\w+.*?)\[\/url\]/i', '#$2', $body); - // @-mentions + // @-mentions $body = preg_replace('/@\[url\=(\w+.*?)\](\w+.*?)\[\/url\]/i', '@$2', $body); // remove multiple newlines @@ -244,7 +243,7 @@ function diaspora_send(array &$b) // Adding the title if (strlen($title)) { - $body = "## ".html_entity_decode($title)."\n\n".$body; + $body = "## " . html_entity_decode($title) . "\n\n" . $body; } require_once "addon/diaspora/diasphp.php"; @@ -252,9 +251,9 @@ function diaspora_send(array &$b) try { Logger::info('diaspora_send: prepare'); $conn = new Diaspora_Connection($handle, $password); - Logger::info('diaspora_send: try to log in '.$handle); + Logger::info('diaspora_send: try to log in ' . $handle); $conn->logIn(); - Logger::info('diaspora_send: try to send '.$body); + Logger::info('diaspora_send: try to send ' . $body); $conn->provider = $hostname; $conn->postStatusMessage($body, $aspect); @@ -263,7 +262,7 @@ function diaspora_send(array &$b) } catch (Exception $e) { Logger::notice("diaspora_send: Error submitting the post: " . $e->getMessage()); - Logger::info('diaspora_send: requeueing '.$b['uid']); + Logger::info('diaspora_send: requeueing ' . $b['uid']); Worker::defer(); } diff --git a/dwpost/dwpost.php b/dwpost/dwpost.php index 4ad5021f..1ecd9764 100644 --- a/dwpost/dwpost.php +++ b/dwpost/dwpost.php @@ -14,6 +14,7 @@ use Friendica\Core\Hook; use Friendica\Core\Logger; use Friendica\Core\Renderer; use Friendica\DI; +use Friendica\Model\Item; use Friendica\Model\Post; use Friendica\Model\Tag; use Friendica\Model\User; @@ -88,24 +89,20 @@ function dwpost_settings_post(array &$b) function dwpost_post_local(array &$b) { - // This can probably be changed to allow editing by pointing to a different API endpoint - if ($b['edit']) { - return; - } - if ((!DI::userSession()->getLocalUserId()) || (DI::userSession()->getLocalUserId() != $b['uid'])) { return; } - if ($b['private'] || $b['parent']) { + // This can probably be changed to allow editing by pointing to a different API endpoint + if ($b['edit'] || ($b['private'] == Item::PRIVATE) || ($b['gravity'] != Item::GRAVITY_PARENT)) { return; } - $dw_post = intval(DI::pConfig()->get(DI::userSession()->getLocalUserId(),'dwpost','post')); + $dw_post = intval(DI::pConfig()->get(DI::userSession()->getLocalUserId(), 'dwpost', 'post')); $dw_enable = (($dw_post && !empty($_REQUEST['dwpost_enable'])) ? intval($_REQUEST['dwpost_enable']) : 0); - if ($b['api_source'] && intval(DI::pConfig()->get(DI::userSession()->getLocalUserId(),'dwpost','post_by_default'))) { + if ($b['api_source'] && intval(DI::pConfig()->get(DI::userSession()->getLocalUserId(), 'dwpost', 'post_by_default'))) { $dw_enable = 1; } @@ -122,7 +119,7 @@ function dwpost_post_local(array &$b) function dwpost_send(array &$b) { - if ($b['deleted'] || $b['private'] || ($b['created'] !== $b['edited'])) { + if ($b['deleted'] || ($b['private'] == Item::PRIVATE) || ($b['created'] !== $b['edited'])) { return; } @@ -145,8 +142,8 @@ function dwpost_send(array &$b) $user = User::getById($b['uid']); $tz = $user['timezone'] ?: 'UTC'; - $dw_username = DI::pConfig()->get($b['uid'],'dwpost','dw_username'); - $dw_password = DI::pConfig()->get($b['uid'],'dwpost','dw_password'); + $dw_username = DI::pConfig()->get($b['uid'], 'dwpost', 'dw_username'); + $dw_password = DI::pConfig()->get($b['uid'], 'dwpost', 'dw_password'); $dw_blog = 'http://www.dreamwidth.org/interface/xmlrpc'; if ($dw_username && $dw_password && $dw_blog) { @@ -156,11 +153,11 @@ function dwpost_send(array &$b) $tags = Tag::getCSVByURIId($b['uri-id'], [Tag::HASHTAG]); $date = DateTimeFormat::convert($b['created'], $tz); - $year = intval(substr($date,0,4)); - $mon = intval(substr($date,5,2)); - $day = intval(substr($date,8,2)); - $hour = intval(substr($date,11,2)); - $min = intval(substr($date,14,2)); + $year = intval(substr($date, 0, 4)); + $mon = intval(substr($date, 5, 2)); + $day = intval(substr($date, 8, 2)); + $hour = intval(substr($date, 11, 2)); + $min = intval(substr($date, 14, 2)); $xml = <<< EOT diff --git a/ijpost/ijpost.php b/ijpost/ijpost.php index 885bc289..f22dfff2 100644 --- a/ijpost/ijpost.php +++ b/ijpost/ijpost.php @@ -14,6 +14,7 @@ use Friendica\Core\Hook; use Friendica\Core\Logger; use Friendica\Core\Renderer; use Friendica\DI; +use Friendica\Model\Item; use Friendica\Model\Tag; use Friendica\Model\User; use Friendica\Util\DateTimeFormat; @@ -85,17 +86,12 @@ function ijpost_settings_post(array &$b) function ijpost_post_local(array &$b) { - // This can probably be changed to allow editing by pointing to a different API endpoint - - if ($b['edit']) { - return; - } - if (!DI::userSession()->getLocalUserId() || (DI::userSession()->getLocalUserId() != $b['uid'])) { return; } - if ($b['private'] || $b['parent']) { + // This can probably be changed to allow editing by pointing to a different API endpoint + if ($b['edit'] || ($b['private'] == Item::PRIVATE) || ($b['gravity'] != Item::GRAVITY_PARENT)) { return; } @@ -120,7 +116,7 @@ function ijpost_post_local(array &$b) function ijpost_send(array &$b) { - if ($b['deleted'] || $b['private'] || ($b['created'] !== $b['edited'])) { + if ($b['deleted'] || ($b['private'] == Item::PRIVATE) || ($b['created'] !== $b['edited'])) { return; } @@ -150,11 +146,11 @@ function ijpost_send(array &$b) $tags = Tag::getCSVByURIId($b['uri-id'], [Tag::HASHTAG]); $date = DateTimeFormat::convert($b['created'], $tz); - $year = intval(substr($date,0,4)); - $mon = intval(substr($date,5,2)); - $day = intval(substr($date,8,2)); - $hour = intval(substr($date,11,2)); - $min = intval(substr($date,14,2)); + $year = intval(substr($date, 0, 4)); + $mon = intval(substr($date, 5, 2)); + $day = intval(substr($date, 8, 2)); + $hour = intval(substr($date, 11, 2)); + $min = intval(substr($date, 14, 2)); $xml = <<< EOT diff --git a/libertree/libertree.php b/libertree/libertree.php index f69c0aab..1d997123 100644 --- a/libertree/libertree.php +++ b/libertree/libertree.php @@ -13,6 +13,7 @@ use Friendica\Core\Logger; use Friendica\Core\Renderer; use Friendica\Database\DBA; use Friendica\DI; +use Friendica\Model\Item; use Friendica\Model\Post; function libertree_install() @@ -74,13 +75,11 @@ function libertree_settings(array &$data) function libertree_settings_post(array &$b) { if (!empty($_POST['libertree-submit'])) { - DI::pConfig()->set(DI::userSession()->getLocalUserId(),'libertree','post',intval($_POST['libertree'])); - DI::pConfig()->set(DI::userSession()->getLocalUserId(),'libertree','post_by_default',intval($_POST['libertree_bydefault'])); - DI::pConfig()->set(DI::userSession()->getLocalUserId(),'libertree','libertree_api_token',trim($_POST['libertree_api_token'])); - DI::pConfig()->set(DI::userSession()->getLocalUserId(),'libertree','libertree_url',trim($_POST['libertree_url'])); - + DI::pConfig()->set(DI::userSession()->getLocalUserId(), 'libertree', 'post', intval($_POST['libertree'])); + DI::pConfig()->set(DI::userSession()->getLocalUserId(), 'libertree', 'post_by_default', intval($_POST['libertree_bydefault'])); + DI::pConfig()->set(DI::userSession()->getLocalUserId(), 'libertree', 'libertree_api_token', trim($_POST['libertree_api_token'])); + DI::pConfig()->set(DI::userSession()->getLocalUserId(), 'libertree', 'libertree_url', trim($_POST['libertree_url'])); } - } function libertree_hook_fork(array &$b) @@ -91,8 +90,10 @@ function libertree_hook_fork(array &$b) $post = $b['data']; - if ($post['deleted'] || $post['private'] || ($post['created'] !== $post['edited']) || - !strstr($post['postopts'], 'libertree') || ($post['parent'] != $post['id'])) { + if ( + $post['deleted'] || ($post['private'] == Item::PRIVATE) || ($post['created'] !== $post['edited']) || + !strstr($post['postopts'], 'libertree') || ($post['gravity'] != Item::GRAVITY_PARENT) + ) { $b['execute'] = false; return; } @@ -100,26 +101,20 @@ function libertree_hook_fork(array &$b) function libertree_post_local(array &$b) { - - // This can probably be changed to allow editing by pointing to a different API endpoint - - if ($b['edit']) { - return; - } - if (!DI::userSession()->getLocalUserId() || (DI::userSession()->getLocalUserId() != $b['uid'])) { return; } - if ($b['private'] || $b['parent']) { + // This can probably be changed to allow editing by pointing to a different API endpoint + if ($b['edit'] || ($b['private'] == Item::PRIVATE) || ($b['gravity'] != Item::GRAVITY_PARENT)) { return; } - $ltree_post = intval(DI::pConfig()->get(DI::userSession()->getLocalUserId(),'libertree','post')); + $ltree_post = intval(DI::pConfig()->get(DI::userSession()->getLocalUserId(), 'libertree', 'post')); $ltree_enable = (($ltree_post && !empty($_REQUEST['libertree_enable'])) ? intval($_REQUEST['libertree_enable']) : 0); - if ($b['api_source'] && intval(DI::pConfig()->get(DI::userSession()->getLocalUserId(),'libertree','post_by_default'))) { + if ($b['api_source'] && intval(DI::pConfig()->get(DI::userSession()->getLocalUserId(), 'libertree', 'post_by_default'))) { $ltree_enable = 1; } @@ -138,11 +133,11 @@ function libertree_send(array &$b) { Logger::notice('libertree_send: invoked'); - if ($b['deleted'] || $b['private'] || ($b['created'] !== $b['edited'])) { + if ($b['deleted'] || ($b['private'] == Item::PRIVATE) || ($b['created'] !== $b['edited'])) { return; } - if (! strstr($b['postopts'],'libertree')) { + if (! strstr($b['postopts'], 'libertree')) { return; } @@ -159,15 +154,15 @@ function libertree_send(array &$b) $b['body'] = Post\Media::addAttachmentsToBody($b['uri-id'], DI::contentItem()->addSharedPost($b)); - $ltree_api_token = DI::pConfig()->get($b['uid'],'libertree','libertree_api_token'); - $ltree_url = DI::pConfig()->get($b['uid'],'libertree','libertree_url'); + $ltree_api_token = DI::pConfig()->get($b['uid'], 'libertree', 'libertree_api_token'); + $ltree_url = DI::pConfig()->get($b['uid'], 'libertree', 'libertree_url'); $ltree_blog = "$ltree_url/api/v1/posts/create/?token=$ltree_api_token"; $ltree_source = DI::baseUrl()->getHost(); if ($b['app'] != "") - $ltree_source .= " (".$b['app'].")"; + $ltree_source .= " (" . $b['app'] . ")"; - if($ltree_url && $ltree_api_token && $ltree_blog && $ltree_source) { + if ($ltree_url && $ltree_api_token && $ltree_blog && $ltree_source) { $title = $b['title']; $body = $b['body']; // Insert a newline before and after a quote @@ -177,7 +172,7 @@ function libertree_send(array &$b) // Removal of tags and mentions // #-tags $body = preg_replace('/#\[url\=(\w+.*?)\](\w+.*?)\[\/url\]/i', '#$2', $body); - // @-mentions + // @-mentions $body = preg_replace('/@\[url\=(\w+.*?)\](\w+.*?)\[\/url\]/i', '@$2', $body); // remove multiple newlines @@ -198,7 +193,7 @@ function libertree_send(array &$b) $params = [ 'text' => $body, 'source' => $ltree_source - // 'token' => $ltree_api_token + // 'token' => $ltree_api_token ]; $result = DI::httpClient()->post($ltree_blog, $params)->getBodyString(); diff --git a/ljpost/ljpost.php b/ljpost/ljpost.php index fac44767..7acc6589 100644 --- a/ljpost/ljpost.php +++ b/ljpost/ljpost.php @@ -14,6 +14,7 @@ use Friendica\Core\Hook; use Friendica\Core\Logger; use Friendica\Core\Renderer; use Friendica\DI; +use Friendica\Model\Item; use Friendica\Model\Post; use Friendica\Model\Tag; use Friendica\Model\User; @@ -35,7 +36,7 @@ function ljpost_jot_nets(array &$jotnets_fields) return; } - if (DI::pConfig()->get(DI::userSession()->getLocalUserId(),'ljpost','post')) { + if (DI::pConfig()->get(DI::userSession()->getLocalUserId(), 'ljpost', 'post')) { $jotnets_fields[] = [ 'type' => 'checkbox', 'field' => [ @@ -57,7 +58,7 @@ function ljpost_settings(array &$data) $ij_username = DI::pConfig()->get(DI::userSession()->getLocalUserId(), 'ljpost', 'ij_username'); $def_enabled = DI::pConfig()->get(DI::userSession()->getLocalUserId(), 'ljpost', 'post_by_default'); - $t= Renderer::getMarkupTemplate('connector_settings.tpl', 'addon/ljpost/'); + $t = Renderer::getMarkupTemplate('connector_settings.tpl', 'addon/ljpost/'); $html = Renderer::replaceMacros($t, [ '$enabled' => ['ljpost', DI::l10n()->t('Enable LiveJournal Post Addon'), $enabled], '$username' => ['ij_username', DI::l10n()->t('LiveJournal username'), $ij_username], @@ -86,20 +87,16 @@ function ljpost_settings_post(array &$b) function ljpost_post_local(array &$b) { - // This can probably be changed to allow editing by pointing to a different API endpoint - if ($b['edit']) { - return; - } - if (!DI::userSession()->getLocalUserId() || (DI::userSession()->getLocalUserId() != $b['uid'])) { return; } - if ($b['private'] || $b['parent']) { + // This can probably be changed to allow editing by pointing to a different API endpoint + if ($b['edit'] || ($b['private'] == Item::PRIVATE) || ($b['gravity'] != Item::GRAVITY_PARENT)) { return; } - $lj_post = intval(DI::pConfig()->get(DI::userSession()->getLocalUserId(),'ljpost','post')); + $lj_post = intval(DI::pConfig()->get(DI::userSession()->getLocalUserId(), 'ljpost', 'post')); $lj_enable = (($lj_post && !empty($_REQUEST['ljpost_enable'])) ? intval($_REQUEST['ljpost_enable']) : 0); if ($b['api_source'] && intval(DI::pConfig()->get(DI::userSession()->getLocalUserId(), 'ljpost', 'post_by_default'))) { @@ -118,11 +115,11 @@ function ljpost_post_local(array &$b) function ljpost_send(array &$b) { - if ($b['deleted'] || $b['private'] || ($b['created'] !== $b['edited'])) { + if ($b['deleted'] || ($b['private'] == Item::PRIVATE) || ($b['created'] !== $b['edited'])) { return; } - if (!strstr($b['postopts'],'ljpost')) { + if (!strstr($b['postopts'], 'ljpost')) { return; } @@ -139,13 +136,13 @@ function ljpost_send(array &$b) $user = User::getById($b['uid']); $tz = $user['timezone'] ?: 'UTC'; - $lj_username = XML::escape(DI::pConfig()->get($b['uid'],'ljpost','lj_username')); - $lj_password = XML::escape(DI::pConfig()->get($b['uid'],'ljpost','lj_password')); - $lj_journal = XML::escape(DI::pConfig()->get($b['uid'],'ljpost','lj_journal')); -// if(! $lj_journal) -// $lj_journal = $lj_username; + $lj_username = XML::escape(DI::pConfig()->get($b['uid'], 'ljpost', 'lj_username')); + $lj_password = XML::escape(DI::pConfig()->get($b['uid'], 'ljpost', 'lj_password')); + $lj_journal = XML::escape(DI::pConfig()->get($b['uid'], 'ljpost', 'lj_journal')); + // if(! $lj_journal) + // $lj_journal = $lj_username; - $lj_blog = XML::escape(DI::pConfig()->get($b['uid'],'ljpost','lj_blog')); + $lj_blog = XML::escape(DI::pConfig()->get($b['uid'], 'ljpost', 'lj_blog')); if (!strlen($lj_blog)) { $lj_blog = XML::escape('http://www.livejournal.com/interface/xmlrpc'); } @@ -157,11 +154,11 @@ function ljpost_send(array &$b) $tags = Tag::getCSVByURIId($b['uri-id'], [Tag::HASHTAG]); $date = DateTimeFormat::convert($b['created'], $tz); - $year = intval(substr($date,0,4)); - $mon = intval(substr($date,5,2)); - $day = intval(substr($date,8,2)); - $hour = intval(substr($date,11,2)); - $min = intval(substr($date,14,2)); + $year = intval(substr($date, 0, 4)); + $mon = intval(substr($date, 5, 2)); + $day = intval(substr($date, 8, 2)); + $hour = intval(substr($date, 11, 2)); + $min = intval(substr($date, 14, 2)); $xml = <<< EOT diff --git a/pnut/pnut.php b/pnut/pnut.php index e84f208b..32f60f6d 100644 --- a/pnut/pnut.php +++ b/pnut/pnut.php @@ -18,6 +18,7 @@ use Friendica\Core\Logger; use Friendica\Core\Renderer; use Friendica\Core\System; use Friendica\DI; +use Friendica\Model\Item; use Friendica\Model\Photo; use phpnut\phpnutException; @@ -82,7 +83,7 @@ function pnut_connect() $o = DI::l10n()->t('Error fetching token. Please try again.', ['code' => $e->getCode(), 'message' => $e->getMessage()]); } - $o .= '
' . DI::l10n()->t("return to the connector page").''; + $o .= '
' . DI::l10n()->t("return to the connector page") . ''; return $o; } @@ -119,14 +120,14 @@ function pnut_settings(array &$data) } $redirectUri = DI::baseUrl() . '/pnut/connect'; - $scope = ['write_post','files']; + $scope = ['write_post', 'files']; $enabled = DI::pConfig()->get(DI::userSession()->getLocalUserId(), 'pnut', 'post') ?? false; $def_enabled = DI::pConfig()->get(DI::userSession()->getLocalUserId(), 'pnut', 'post_by_default') ?? false; $client_id = DI::config()->get('pnut', 'client_id'); $client_secret = DI::config()->get('pnut', 'client_secret'); $token = DI::pConfig()->get(DI::userSession()->getLocalUserId(), 'pnut', 'access_token'); - + $user_client = empty($client_id) || empty($client_secret); if ($user_client) { $client_id = DI::pConfig()->get(DI::userSession()->getLocalUserId(), 'pnut', 'client_id'); @@ -221,7 +222,7 @@ function pnut_hook_fork(array &$b) return; } - if (!strstr($post['postopts'] ?? '', 'pnut') || ($post['parent'] != $post['id']) || $post['private']) { + if (!strstr($post['postopts'] ?? '', 'pnut') || ($post['gravity'] != Item::GRAVITY_PARENT) || ($post['private'] == Item::PRIVATE)) { $b['execute'] = false; return; } @@ -229,15 +230,11 @@ function pnut_hook_fork(array &$b) function pnut_post_local(array &$b) { - if ($b['edit']) { - return; - } - if (!DI::userSession()->getLocalUserId() || (DI::userSession()->getLocalUserId() != $b['uid'])) { return; } - if ($b['private'] || $b['parent']) { + if ($b['edit'] || ($b['private'] == Item::PRIVATE) || ($b['gravity'] != Item::GRAVITY_PARENT)) { return; } @@ -265,7 +262,7 @@ function pnut_post_hook(array &$b) /** * Post to pnut.io */ - if ($b['deleted'] || $b['private'] || ($b['created'] !== $b['edited'])) { + if ($b['deleted'] || ($b['private'] == Item::PRIVATE) || ($b['created'] !== $b['edited'])) { return; } diff --git a/pumpio/pumpio.php b/pumpio/pumpio.php index 6600696e..2a8a530e 100644 --- a/pumpio/pumpio.php +++ b/pumpio/pumpio.php @@ -345,14 +345,14 @@ function pumpio_hook_fork(array &$b) if (DI::pConfig()->get($post['uid'], 'pumpio', 'import')) { // Don't fork if it isn't a reply to a pump.io post - if (($post['parent'] != $post['id']) && !Post::exists(['id' => $post['parent'], 'network' => Protocol::PUMPIO])) { + if (($post['gravity'] != Item::GRAVITY_PARENT) && !Post::exists(['id' => $post['parent'], 'network' => Protocol::PUMPIO])) { Logger::notice('No pump.io parent found for item ' . $post['id']); $b['execute'] = false; return; } } else { // Comments are never exported when we don't import the pumpio timeline - if (!strstr($post['postopts'], 'pumpio') || ($post['parent'] != $post['id']) || $post['private']) { + if (!strstr($post['postopts'], 'pumpio') || ($post['gravity'] != Item::GRAVITY_PARENT)|| ($post['private'] == Item::PRIVATE)) { $b['execute'] = false; return; } @@ -412,7 +412,7 @@ function pumpio_send(array &$b) Logger::notice('pumpio_send: receiver ', $receiver); - if (!count($receiver) && ($b['private'] || !strstr($b['postopts'], 'pumpio'))) { + if (!count($receiver) && ($b['private'] == Item::PRIVATE) || !strstr($b['postopts'], 'pumpio'))) { return; } @@ -1319,7 +1319,7 @@ function pumpio_getreceiver(array $b) { $receiver = []; - if (!$b['private']) { + if ($b['private'] != Item::PRIVATE)) { if (!strstr($b['postopts'], 'pumpio')) { return $receiver; } diff --git a/statusnet/statusnet.php b/statusnet/statusnet.php index f0372852..4bc32050 100644 --- a/statusnet/statusnet.php +++ b/statusnet/statusnet.php @@ -296,7 +296,7 @@ function statusnet_hook_fork(array &$b) $post = $b['data']; - if ($post['deleted'] || ($post['created'] !== $post['edited']) || strpos($post['postopts'] ?? '', 'statusnet') === false || ($post['parent'] != $post['id']) || $post['private']) { + if ($post['deleted'] || ($post['created'] !== $post['edited']) || strpos($post['postopts'] ?? '', 'statusnet') === false || ($post['gravity'] != Item::GRAVITY_PARENT) || ($post['private'] == Item::PRIVATE)) { $b['execute'] = false; return; } @@ -336,7 +336,7 @@ function statusnet_post_hook(array &$b) /** * Post to GNU Social */ - if ($b['deleted'] || $b['private'] || ($b['created'] !== $b['edited'])) { + if ($b['deleted'] || ($b['private'] == Item::PRIVATE) || ($b['created'] !== $b['edited'])) { return; } @@ -439,11 +439,13 @@ function statusnet_addon_admin_post() $secret = trim($_POST['secret'][$id]); $key = trim($_POST['key'][$id]); //$applicationname = (!empty($_POST['applicationname']) ? Strings::escapeTags(trim($_POST['applicationname'][$id])):''); - if ($sitename != '' && + if ( + $sitename != '' && $apiurl != '' && $secret != '' && $key != '' && - empty($_POST['delete'][$id])) { + empty($_POST['delete'][$id]) + ) { $sites[] = [ 'sitename' => $sitename, diff --git a/tumblr/tumblr.php b/tumblr/tumblr.php index 390c3c6c..1e9f5c7f 100644 --- a/tumblr/tumblr.php +++ b/tumblr/tumblr.php @@ -477,13 +477,13 @@ function tumblr_hook_fork(array &$b) if (DI::pConfig()->get($post['uid'], 'tumblr', 'import')) { // Don't post if it isn't a reply to a tumblr post - if (($post['parent'] != $post['id']) && !Post::exists(['id' => $post['parent'], 'network' => Protocol::TUMBLR])) { + if (($post['gravity'] != Item::GRAVITY_PARENT) && !Post::exists(['id' => $post['parent'], 'network' => Protocol::TUMBLR])) { Logger::notice('No tumblr parent found', ['item' => $post['id']]); $b['execute'] = false; return; } - } elseif (!strstr($post['postopts'] ?? '', 'tumblr') || ($post['parent'] != $post['id']) || $post['private']) { - DI::logger()->info('Activities are never exported when we don\'t import the tumblr timeline', ['uid' => $post['uid']]); + } elseif (!strstr($post['postopts'] ?? '', 'tumblr') || ($post['gravity'] != Item::GRAVITY_PARENT) || ($post['private'] == Item::PRIVATE)) { + DI::logger()->info('Post will not be exported', ['uid' => $post['uid'], 'postopts' => $post['postopts'], 'gravity' => $post['gravity'], 'private' => $post['private']]); $b['execute'] = false; return; } @@ -491,15 +491,11 @@ function tumblr_hook_fork(array &$b) function tumblr_post_local(array &$b) { - if ($b['edit']) { - return; - } - if (!DI::userSession()->getLocalUserId() || (DI::userSession()->getLocalUserId() != $b['uid'])) { return; } - if ($b['private'] || $b['parent']) { + if ($b['edit'] || ($b['private'] == Item::PRIVATE) || ($b['gravity'] != Item::GRAVITY_PARENT)) { return; } @@ -575,7 +571,7 @@ function tumblr_send(array &$b) } } return; - } elseif ($b['private'] || !strstr($b['postopts'], 'tumblr')) { + } elseif (($b['private'] == Item::PRIVATE) || !strstr($b['postopts'], 'tumblr')) { return; } diff --git a/twitter/twitter.php b/twitter/twitter.php index 11c163ef..10f8a2fb 100644 --- a/twitter/twitter.php +++ b/twitter/twitter.php @@ -170,7 +170,7 @@ function twitter_hook_fork(array &$b) $post = $b['data']; if ( - $post['deleted'] || $post['private'] || ($post['created'] !== $post['edited']) || + $post['deleted'] || ($post['private'] == Item::PRIVATE) || ($post['created'] !== $post['edited']) || !strstr($post['postopts'], 'twitter') || ($post['gravity'] != Item::GRAVITY_PARENT) ) { $b['execute'] = false; @@ -184,7 +184,7 @@ function twitter_post_local(array &$b) return; } - if ($b['edit'] || $b['private'] || $b['parent']) { + if ($b['edit'] || ($b['private'] == Item::PRIVATE) || ($b['gravity'] != Item::GRAVITY_PARENT)) { return; } @@ -211,7 +211,7 @@ function twitter_post_hook(array &$b) { DI::logger()->debug('Invoke post hook', $b); - if (($b['gravity'] != Item::GRAVITY_PARENT) || !strstr($b['postopts'], 'twitter') || $b['private'] || $b['deleted'] || ($b['created'] !== $b['edited'])) { + if (($b['gravity'] != Item::GRAVITY_PARENT) || !strstr($b['postopts'], 'twitter') || ($b['private'] == Item::PRIVATE) || $b['deleted'] || ($b['created'] !== $b['edited'])) { return; } diff --git a/wppost/wppost.php b/wppost/wppost.php index e27079aa..dba738de 100644 --- a/wppost/wppost.php +++ b/wppost/wppost.php @@ -108,8 +108,8 @@ function wppost_hook_fork(array &$b) $post = $b['data']; if ( - $post['deleted'] || $post['private'] || ($post['created'] !== $post['edited']) || - !strstr($post['postopts'] ?? '', 'wppost') || ($post['parent'] != $post['id']) + $post['deleted'] || ($post['private'] == Item::PRIVATE) || ($post['created'] !== $post['edited']) || + !strstr($post['postopts'] ?? '', 'wppost') || ($post['gravity'] != Item::GRAVITY_PARENT) ) { $b['execute'] = false; return; @@ -118,18 +118,12 @@ function wppost_hook_fork(array &$b) function wppost_post_local(array &$b) { - - // This can probably be changed to allow editing by pointing to a different API endpoint - - if ($b['edit']) { - return; - } - if (!DI::userSession()->getLocalUserId() || (DI::userSession()->getLocalUserId() != $b['uid'])) { return; } - if ($b['private'] || $b['parent']) { + // This can probably be changed to allow editing by pointing to a different API endpoint + if ($b['edit'] || ($b['private'] == Item::PRIVATE) || ($b['gravity'] != Item::GRAVITY_PARENT)) { return; } @@ -152,12 +146,9 @@ function wppost_post_local(array &$b) $b['postopts'] .= 'wppost'; } - - - function wppost_send(array &$b) { - if ($b['deleted'] || $b['private'] || ($b['created'] !== $b['edited'])) { + if ($b['deleted'] || ($b['private'] == Item::PRIVATE) || ($b['created'] !== $b['edited'])) { return; } From aa5130247b27093fbca5fa1126b857c83446eb14 Mon Sep 17 00:00:00 2001 From: Hypolite Petovan Date: Sat, 16 Nov 2024 21:19:06 -0500 Subject: [PATCH 038/222] [pumpio] Remove two superfluous parentheses - Thanks to @SteffenK9 for the report! --- pumpio/pumpio.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pumpio/pumpio.php b/pumpio/pumpio.php index 2a8a530e..5e053d7c 100644 --- a/pumpio/pumpio.php +++ b/pumpio/pumpio.php @@ -412,7 +412,7 @@ function pumpio_send(array &$b) Logger::notice('pumpio_send: receiver ', $receiver); - if (!count($receiver) && ($b['private'] == Item::PRIVATE) || !strstr($b['postopts'], 'pumpio'))) { + if (!count($receiver) && ($b['private'] == Item::PRIVATE) || !strstr($b['postopts'], 'pumpio')) { return; } @@ -1319,7 +1319,7 @@ function pumpio_getreceiver(array $b) { $receiver = []; - if ($b['private'] != Item::PRIVATE)) { + if ($b['private'] != Item::PRIVATE) { if (!strstr($b['postopts'], 'pumpio')) { return $receiver; } From a0c727ac35d3dadb3be077527af97612656c674f Mon Sep 17 00:00:00 2001 From: Hypolite Petovan Date: Sun, 17 Nov 2024 13:23:16 +0000 Subject: [PATCH 039/222] [advancedcontentfilter] Remove unused vendor files Thanks to @Art4 for the initial submission in https://github.com/friendica/friendica-addons/pull/1363 --- advancedcontentfilter/vendor/autoload.php | 18 + .../vendor/composer/ClassLoader.php | 202 +- .../vendor/composer/InstalledVersions.php | 359 +++ .../vendor/composer/autoload_classmap.php | 6 +- .../vendor/composer/autoload_files.php | 2 +- .../vendor/composer/autoload_namespaces.php | 2 +- .../vendor/composer/autoload_psr4.php | 4 +- .../vendor/composer/autoload_real.php | 53 +- .../vendor/composer/autoload_static.php | 8 +- .../vendor/composer/installed.json | 2354 +++++++++-------- .../vendor/composer/installed.php | 203 ++ .../vendor/composer/platform_check.php | 26 + .../vendor/psr/simple-cache/.editorconfig | 12 - .../vendor/psr/simple-cache/LICENSE.md | 21 - .../vendor/psr/simple-cache/README.md | 8 - .../vendor/psr/simple-cache/composer.json | 25 - .../psr/simple-cache/src/CacheException.php | 10 - .../psr/simple-cache/src/CacheInterface.php | 114 - .../src/InvalidArgumentException.php | 13 - .../vendor/symfony/cache/.gitignore | 3 - .../Adapter/AbstractRedisAdapterTest.php | 47 - .../cache/Tests/Adapter/AdapterTestCase.php | 175 -- .../cache/Tests/Adapter/ApcuAdapterTest.php | 124 - .../cache/Tests/Adapter/ArrayAdapterTest.php | 56 - .../cache/Tests/Adapter/ChainAdapterTest.php | 233 -- .../Tests/Adapter/DoctrineAdapterTest.php | 32 - .../Tests/Adapter/FilesystemAdapterTest.php | 61 - .../Tests/Adapter/MaxIdLengthAdapterTest.php | 87 - .../Tests/Adapter/MemcachedAdapterTest.php | 204 -- .../Adapter/NamespacedProxyAdapterTest.php | 26 - .../cache/Tests/Adapter/NullAdapterTest.php | 128 - .../cache/Tests/Adapter/PdoAdapterTest.php | 73 - .../Tests/Adapter/PdoDbalAdapterTest.php | 48 - .../Tests/Adapter/PhpArrayAdapterTest.php | 135 - .../PhpArrayAdapterWithFallbackTest.php | 51 - .../Tests/Adapter/PhpFilesAdapterTest.php | 47 - .../cache/Tests/Adapter/PredisAdapterTest.php | 53 - .../Adapter/PredisClusterAdapterTest.php | 26 - .../Adapter/PredisRedisClusterAdapterTest.php | 28 - .../cache/Tests/Adapter/ProxyAdapterTest.php | 69 - .../cache/Tests/Adapter/RedisAdapterTest.php | 92 - .../Tests/Adapter/RedisArrayAdapterTest.php | 24 - .../Tests/Adapter/RedisClusterAdapterTest.php | 27 - .../Tests/Adapter/SimpleCacheAdapterTest.php | 41 - .../Tests/Adapter/TagAwareAdapterTest.php | 338 --- ...TagAwareAndProxyAdapterIntegrationTest.php | 38 - .../Tests/Adapter/TraceableAdapterTest.php | 191 -- .../Adapter/TraceableTagAwareAdapterTest.php | 37 - .../symfony/cache/Tests/CacheItemTest.php | 77 - .../cache/Tests/DoctrineProviderTest.php | 45 - .../cache/Tests/Fixtures/ArrayCache.php | 52 - .../cache/Tests/Fixtures/ExternalAdapter.php | 76 - .../Tests/Simple/AbstractRedisCacheTest.php | 47 - .../cache/Tests/Simple/ApcuCacheTest.php | 35 - .../cache/Tests/Simple/ArrayCacheTest.php | 25 - .../cache/Tests/Simple/CacheTestCase.php | 150 -- .../cache/Tests/Simple/ChainCacheTest.php | 113 - .../cache/Tests/Simple/DoctrineCacheTest.php | 31 - .../Tests/Simple/FilesystemCacheTest.php | 34 - .../cache/Tests/Simple/MemcachedCacheTest.php | 178 -- .../Simple/MemcachedCacheTextModeTest.php | 25 - .../cache/Tests/Simple/NullCacheTest.php | 96 - .../cache/Tests/Simple/PdoCacheTest.php | 47 - .../cache/Tests/Simple/PdoDbalCacheTest.php | 48 - .../cache/Tests/Simple/PhpArrayCacheTest.php | 145 - .../Simple/PhpArrayCacheWithFallbackTest.php | 57 - .../cache/Tests/Simple/PhpFilesCacheTest.php | 42 - .../cache/Tests/Simple/Psr6CacheTest.php | 30 - .../Tests/Simple/RedisArrayCacheTest.php | 24 - .../cache/Tests/Simple/RedisCacheTest.php | 82 - .../Tests/Simple/RedisClusterCacheTest.php | 27 - .../cache/Tests/Simple/TraceableCacheTest.php | 171 -- .../cache/Tests/Traits/PdoPruneableTrait.php | 34 - .../vendor/symfony/cache/phpunit.xml.dist | 50 - .../vendor/symfony/polyfill-apcu/Apcu.php | 106 - .../vendor/symfony/polyfill-apcu/LICENSE | 19 - .../vendor/symfony/polyfill-apcu/README.md | 12 - .../symfony/polyfill-apcu/bootstrap.php | 83 - .../symfony/polyfill-apcu/bootstrap80.php | 75 - .../symfony/polyfill-apcu/composer.json | 35 - 80 files changed, 1986 insertions(+), 6019 deletions(-) create mode 100644 advancedcontentfilter/vendor/composer/InstalledVersions.php create mode 100644 advancedcontentfilter/vendor/composer/installed.php create mode 100644 advancedcontentfilter/vendor/composer/platform_check.php delete mode 100644 advancedcontentfilter/vendor/psr/simple-cache/.editorconfig delete mode 100644 advancedcontentfilter/vendor/psr/simple-cache/LICENSE.md delete mode 100644 advancedcontentfilter/vendor/psr/simple-cache/README.md delete mode 100644 advancedcontentfilter/vendor/psr/simple-cache/composer.json delete mode 100644 advancedcontentfilter/vendor/psr/simple-cache/src/CacheException.php delete mode 100644 advancedcontentfilter/vendor/psr/simple-cache/src/CacheInterface.php delete mode 100644 advancedcontentfilter/vendor/psr/simple-cache/src/InvalidArgumentException.php delete mode 100644 advancedcontentfilter/vendor/symfony/cache/.gitignore delete mode 100644 advancedcontentfilter/vendor/symfony/cache/Tests/Adapter/AbstractRedisAdapterTest.php delete mode 100644 advancedcontentfilter/vendor/symfony/cache/Tests/Adapter/AdapterTestCase.php delete mode 100644 advancedcontentfilter/vendor/symfony/cache/Tests/Adapter/ApcuAdapterTest.php delete mode 100644 advancedcontentfilter/vendor/symfony/cache/Tests/Adapter/ArrayAdapterTest.php delete mode 100644 advancedcontentfilter/vendor/symfony/cache/Tests/Adapter/ChainAdapterTest.php delete mode 100644 advancedcontentfilter/vendor/symfony/cache/Tests/Adapter/DoctrineAdapterTest.php delete mode 100644 advancedcontentfilter/vendor/symfony/cache/Tests/Adapter/FilesystemAdapterTest.php delete mode 100644 advancedcontentfilter/vendor/symfony/cache/Tests/Adapter/MaxIdLengthAdapterTest.php delete mode 100644 advancedcontentfilter/vendor/symfony/cache/Tests/Adapter/MemcachedAdapterTest.php delete mode 100644 advancedcontentfilter/vendor/symfony/cache/Tests/Adapter/NamespacedProxyAdapterTest.php delete mode 100644 advancedcontentfilter/vendor/symfony/cache/Tests/Adapter/NullAdapterTest.php delete mode 100644 advancedcontentfilter/vendor/symfony/cache/Tests/Adapter/PdoAdapterTest.php delete mode 100644 advancedcontentfilter/vendor/symfony/cache/Tests/Adapter/PdoDbalAdapterTest.php delete mode 100644 advancedcontentfilter/vendor/symfony/cache/Tests/Adapter/PhpArrayAdapterTest.php delete mode 100644 advancedcontentfilter/vendor/symfony/cache/Tests/Adapter/PhpArrayAdapterWithFallbackTest.php delete mode 100644 advancedcontentfilter/vendor/symfony/cache/Tests/Adapter/PhpFilesAdapterTest.php delete mode 100644 advancedcontentfilter/vendor/symfony/cache/Tests/Adapter/PredisAdapterTest.php delete mode 100644 advancedcontentfilter/vendor/symfony/cache/Tests/Adapter/PredisClusterAdapterTest.php delete mode 100644 advancedcontentfilter/vendor/symfony/cache/Tests/Adapter/PredisRedisClusterAdapterTest.php delete mode 100644 advancedcontentfilter/vendor/symfony/cache/Tests/Adapter/ProxyAdapterTest.php delete mode 100644 advancedcontentfilter/vendor/symfony/cache/Tests/Adapter/RedisAdapterTest.php delete mode 100644 advancedcontentfilter/vendor/symfony/cache/Tests/Adapter/RedisArrayAdapterTest.php delete mode 100644 advancedcontentfilter/vendor/symfony/cache/Tests/Adapter/RedisClusterAdapterTest.php delete mode 100644 advancedcontentfilter/vendor/symfony/cache/Tests/Adapter/SimpleCacheAdapterTest.php delete mode 100644 advancedcontentfilter/vendor/symfony/cache/Tests/Adapter/TagAwareAdapterTest.php delete mode 100644 advancedcontentfilter/vendor/symfony/cache/Tests/Adapter/TagAwareAndProxyAdapterIntegrationTest.php delete mode 100644 advancedcontentfilter/vendor/symfony/cache/Tests/Adapter/TraceableAdapterTest.php delete mode 100644 advancedcontentfilter/vendor/symfony/cache/Tests/Adapter/TraceableTagAwareAdapterTest.php delete mode 100644 advancedcontentfilter/vendor/symfony/cache/Tests/CacheItemTest.php delete mode 100644 advancedcontentfilter/vendor/symfony/cache/Tests/DoctrineProviderTest.php delete mode 100644 advancedcontentfilter/vendor/symfony/cache/Tests/Fixtures/ArrayCache.php delete mode 100644 advancedcontentfilter/vendor/symfony/cache/Tests/Fixtures/ExternalAdapter.php delete mode 100644 advancedcontentfilter/vendor/symfony/cache/Tests/Simple/AbstractRedisCacheTest.php delete mode 100644 advancedcontentfilter/vendor/symfony/cache/Tests/Simple/ApcuCacheTest.php delete mode 100644 advancedcontentfilter/vendor/symfony/cache/Tests/Simple/ArrayCacheTest.php delete mode 100644 advancedcontentfilter/vendor/symfony/cache/Tests/Simple/CacheTestCase.php delete mode 100644 advancedcontentfilter/vendor/symfony/cache/Tests/Simple/ChainCacheTest.php delete mode 100644 advancedcontentfilter/vendor/symfony/cache/Tests/Simple/DoctrineCacheTest.php delete mode 100644 advancedcontentfilter/vendor/symfony/cache/Tests/Simple/FilesystemCacheTest.php delete mode 100644 advancedcontentfilter/vendor/symfony/cache/Tests/Simple/MemcachedCacheTest.php delete mode 100644 advancedcontentfilter/vendor/symfony/cache/Tests/Simple/MemcachedCacheTextModeTest.php delete mode 100644 advancedcontentfilter/vendor/symfony/cache/Tests/Simple/NullCacheTest.php delete mode 100644 advancedcontentfilter/vendor/symfony/cache/Tests/Simple/PdoCacheTest.php delete mode 100644 advancedcontentfilter/vendor/symfony/cache/Tests/Simple/PdoDbalCacheTest.php delete mode 100644 advancedcontentfilter/vendor/symfony/cache/Tests/Simple/PhpArrayCacheTest.php delete mode 100644 advancedcontentfilter/vendor/symfony/cache/Tests/Simple/PhpArrayCacheWithFallbackTest.php delete mode 100644 advancedcontentfilter/vendor/symfony/cache/Tests/Simple/PhpFilesCacheTest.php delete mode 100644 advancedcontentfilter/vendor/symfony/cache/Tests/Simple/Psr6CacheTest.php delete mode 100644 advancedcontentfilter/vendor/symfony/cache/Tests/Simple/RedisArrayCacheTest.php delete mode 100644 advancedcontentfilter/vendor/symfony/cache/Tests/Simple/RedisCacheTest.php delete mode 100644 advancedcontentfilter/vendor/symfony/cache/Tests/Simple/RedisClusterCacheTest.php delete mode 100644 advancedcontentfilter/vendor/symfony/cache/Tests/Simple/TraceableCacheTest.php delete mode 100644 advancedcontentfilter/vendor/symfony/cache/Tests/Traits/PdoPruneableTrait.php delete mode 100644 advancedcontentfilter/vendor/symfony/cache/phpunit.xml.dist delete mode 100644 advancedcontentfilter/vendor/symfony/polyfill-apcu/Apcu.php delete mode 100644 advancedcontentfilter/vendor/symfony/polyfill-apcu/LICENSE delete mode 100644 advancedcontentfilter/vendor/symfony/polyfill-apcu/README.md delete mode 100644 advancedcontentfilter/vendor/symfony/polyfill-apcu/bootstrap.php delete mode 100644 advancedcontentfilter/vendor/symfony/polyfill-apcu/bootstrap80.php delete mode 100644 advancedcontentfilter/vendor/symfony/polyfill-apcu/composer.json diff --git a/advancedcontentfilter/vendor/autoload.php b/advancedcontentfilter/vendor/autoload.php index 3e6193fa..2d273a02 100644 --- a/advancedcontentfilter/vendor/autoload.php +++ b/advancedcontentfilter/vendor/autoload.php @@ -2,6 +2,24 @@ // autoload.php @generated by Composer +if (PHP_VERSION_ID < 50600) { + if (!headers_sent()) { + header('HTTP/1.1 500 Internal Server Error'); + } + $err = 'Composer 2.3.0 dropped support for autoloading on PHP <5.6 and you are running '.PHP_VERSION.', please upgrade PHP or use Composer 2.2 LTS via "composer self-update --2.2". Aborting.'.PHP_EOL; + if (!ini_get('display_errors')) { + if (PHP_SAPI === 'cli' || PHP_SAPI === 'phpdbg') { + fwrite(STDERR, $err); + } elseif (!headers_sent()) { + echo $err; + } + } + trigger_error( + $err, + E_USER_ERROR + ); +} + require_once __DIR__ . '/composer/autoload_real.php'; return ComposerAutoloaderInitAdvancedContentFilterAddon::getLoader(); diff --git a/advancedcontentfilter/vendor/composer/ClassLoader.php b/advancedcontentfilter/vendor/composer/ClassLoader.php index 03b9bb9c..7824d8f7 100644 --- a/advancedcontentfilter/vendor/composer/ClassLoader.php +++ b/advancedcontentfilter/vendor/composer/ClassLoader.php @@ -37,26 +37,81 @@ namespace Composer\Autoload; * * @author Fabien Potencier * @author Jordi Boggiano - * @see http://www.php-fig.org/psr/psr-0/ - * @see http://www.php-fig.org/psr/psr-4/ + * @see https://www.php-fig.org/psr/psr-0/ + * @see https://www.php-fig.org/psr/psr-4/ */ class ClassLoader { + /** @var \Closure(string):void */ + private static $includeFile; + + /** @var string|null */ + private $vendorDir; + // PSR-4 + /** + * @var array> + */ private $prefixLengthsPsr4 = array(); + /** + * @var array> + */ private $prefixDirsPsr4 = array(); + /** + * @var list + */ private $fallbackDirsPsr4 = array(); // PSR-0 + /** + * List of PSR-0 prefixes + * + * Structured as array('F (first letter)' => array('Foo\Bar (full prefix)' => array('path', 'path2'))) + * + * @var array>> + */ private $prefixesPsr0 = array(); + /** + * @var list + */ private $fallbackDirsPsr0 = array(); + /** @var bool */ private $useIncludePath = false; + + /** + * @var array + */ private $classMap = array(); + + /** @var bool */ private $classMapAuthoritative = false; + + /** + * @var array + */ private $missingClasses = array(); + + /** @var string|null */ private $apcuPrefix; + /** + * @var array + */ + private static $registeredLoaders = array(); + + /** + * @param string|null $vendorDir + */ + public function __construct($vendorDir = null) + { + $this->vendorDir = $vendorDir; + self::initializeIncludeClosure(); + } + + /** + * @return array> + */ public function getPrefixes() { if (!empty($this->prefixesPsr0)) { @@ -66,28 +121,42 @@ class ClassLoader return array(); } + /** + * @return array> + */ public function getPrefixesPsr4() { return $this->prefixDirsPsr4; } + /** + * @return list + */ public function getFallbackDirs() { return $this->fallbackDirsPsr0; } + /** + * @return list + */ public function getFallbackDirsPsr4() { return $this->fallbackDirsPsr4; } + /** + * @return array Array of classname => path + */ public function getClassMap() { return $this->classMap; } /** - * @param array $classMap Class to filename map + * @param array $classMap Class to filename map + * + * @return void */ public function addClassMap(array $classMap) { @@ -102,22 +171,25 @@ class ClassLoader * Registers a set of PSR-0 directories for a given prefix, either * appending or prepending to the ones previously set for this prefix. * - * @param string $prefix The prefix - * @param array|string $paths The PSR-0 root directories - * @param bool $prepend Whether to prepend the directories + * @param string $prefix The prefix + * @param list|string $paths The PSR-0 root directories + * @param bool $prepend Whether to prepend the directories + * + * @return void */ public function add($prefix, $paths, $prepend = false) { + $paths = (array) $paths; if (!$prefix) { if ($prepend) { $this->fallbackDirsPsr0 = array_merge( - (array) $paths, + $paths, $this->fallbackDirsPsr0 ); } else { $this->fallbackDirsPsr0 = array_merge( $this->fallbackDirsPsr0, - (array) $paths + $paths ); } @@ -126,19 +198,19 @@ class ClassLoader $first = $prefix[0]; if (!isset($this->prefixesPsr0[$first][$prefix])) { - $this->prefixesPsr0[$first][$prefix] = (array) $paths; + $this->prefixesPsr0[$first][$prefix] = $paths; return; } if ($prepend) { $this->prefixesPsr0[$first][$prefix] = array_merge( - (array) $paths, + $paths, $this->prefixesPsr0[$first][$prefix] ); } else { $this->prefixesPsr0[$first][$prefix] = array_merge( $this->prefixesPsr0[$first][$prefix], - (array) $paths + $paths ); } } @@ -147,25 +219,28 @@ class ClassLoader * Registers a set of PSR-4 directories for a given namespace, either * appending or prepending to the ones previously set for this namespace. * - * @param string $prefix The prefix/namespace, with trailing '\\' - * @param array|string $paths The PSR-4 base directories - * @param bool $prepend Whether to prepend the directories + * @param string $prefix The prefix/namespace, with trailing '\\' + * @param list|string $paths The PSR-4 base directories + * @param bool $prepend Whether to prepend the directories * * @throws \InvalidArgumentException + * + * @return void */ public function addPsr4($prefix, $paths, $prepend = false) { + $paths = (array) $paths; if (!$prefix) { // Register directories for the root namespace. if ($prepend) { $this->fallbackDirsPsr4 = array_merge( - (array) $paths, + $paths, $this->fallbackDirsPsr4 ); } else { $this->fallbackDirsPsr4 = array_merge( $this->fallbackDirsPsr4, - (array) $paths + $paths ); } } elseif (!isset($this->prefixDirsPsr4[$prefix])) { @@ -175,18 +250,18 @@ class ClassLoader throw new \InvalidArgumentException("A non-empty PSR-4 prefix must end with a namespace separator."); } $this->prefixLengthsPsr4[$prefix[0]][$prefix] = $length; - $this->prefixDirsPsr4[$prefix] = (array) $paths; + $this->prefixDirsPsr4[$prefix] = $paths; } elseif ($prepend) { // Prepend directories for an already registered namespace. $this->prefixDirsPsr4[$prefix] = array_merge( - (array) $paths, + $paths, $this->prefixDirsPsr4[$prefix] ); } else { // Append directories for an already registered namespace. $this->prefixDirsPsr4[$prefix] = array_merge( $this->prefixDirsPsr4[$prefix], - (array) $paths + $paths ); } } @@ -195,8 +270,10 @@ class ClassLoader * Registers a set of PSR-0 directories for a given prefix, * replacing any others previously set for this prefix. * - * @param string $prefix The prefix - * @param array|string $paths The PSR-0 base directories + * @param string $prefix The prefix + * @param list|string $paths The PSR-0 base directories + * + * @return void */ public function set($prefix, $paths) { @@ -211,10 +288,12 @@ class ClassLoader * Registers a set of PSR-4 directories for a given namespace, * replacing any others previously set for this namespace. * - * @param string $prefix The prefix/namespace, with trailing '\\' - * @param array|string $paths The PSR-4 base directories + * @param string $prefix The prefix/namespace, with trailing '\\' + * @param list|string $paths The PSR-4 base directories * * @throws \InvalidArgumentException + * + * @return void */ public function setPsr4($prefix, $paths) { @@ -234,6 +313,8 @@ class ClassLoader * Turns on searching the include path for class files. * * @param bool $useIncludePath + * + * @return void */ public function setUseIncludePath($useIncludePath) { @@ -256,6 +337,8 @@ class ClassLoader * that have not been registered with the class map. * * @param bool $classMapAuthoritative + * + * @return void */ public function setClassMapAuthoritative($classMapAuthoritative) { @@ -276,6 +359,8 @@ class ClassLoader * APCu prefix to use to cache found/not-found classes, if the extension is enabled. * * @param string|null $apcuPrefix + * + * @return void */ public function setApcuPrefix($apcuPrefix) { @@ -296,33 +381,55 @@ class ClassLoader * Registers this instance as an autoloader. * * @param bool $prepend Whether to prepend the autoloader or not + * + * @return void */ public function register($prepend = false) { spl_autoload_register(array($this, 'loadClass'), true, $prepend); + + if (null === $this->vendorDir) { + return; + } + + if ($prepend) { + self::$registeredLoaders = array($this->vendorDir => $this) + self::$registeredLoaders; + } else { + unset(self::$registeredLoaders[$this->vendorDir]); + self::$registeredLoaders[$this->vendorDir] = $this; + } } /** * Unregisters this instance as an autoloader. + * + * @return void */ public function unregister() { spl_autoload_unregister(array($this, 'loadClass')); + + if (null !== $this->vendorDir) { + unset(self::$registeredLoaders[$this->vendorDir]); + } } /** * Loads the given class or interface. * * @param string $class The name of the class - * @return bool|null True if loaded, null otherwise + * @return true|null True if loaded, null otherwise */ public function loadClass($class) { if ($file = $this->findFile($class)) { - includeFile($file); + $includeFile = self::$includeFile; + $includeFile($file); return true; } + + return null; } /** @@ -367,6 +474,21 @@ class ClassLoader return $file; } + /** + * Returns the currently registered loaders keyed by their corresponding vendor directories. + * + * @return array + */ + public static function getRegisteredLoaders() + { + return self::$registeredLoaders; + } + + /** + * @param string $class + * @param string $ext + * @return string|false + */ private function findFileWithExtension($class, $ext) { // PSR-4 lookup @@ -432,14 +554,26 @@ class ClassLoader return false; } -} -/** - * Scope isolated include. - * - * Prevents access to $this/self from included files. - */ -function includeFile($file) -{ - include $file; + /** + * @return void + */ + private static function initializeIncludeClosure() + { + if (self::$includeFile !== null) { + return; + } + + /** + * Scope isolated include. + * + * Prevents access to $this/self from included files. + * + * @param string $file + * @return void + */ + self::$includeFile = \Closure::bind(static function($file) { + include $file; + }, null, null); + } } diff --git a/advancedcontentfilter/vendor/composer/InstalledVersions.php b/advancedcontentfilter/vendor/composer/InstalledVersions.php new file mode 100644 index 00000000..51e734a7 --- /dev/null +++ b/advancedcontentfilter/vendor/composer/InstalledVersions.php @@ -0,0 +1,359 @@ + + * Jordi Boggiano + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Composer; + +use Composer\Autoload\ClassLoader; +use Composer\Semver\VersionParser; + +/** + * This class is copied in every Composer installed project and available to all + * + * See also https://getcomposer.org/doc/07-runtime.md#installed-versions + * + * To require its presence, you can require `composer-runtime-api ^2.0` + * + * @final + */ +class InstalledVersions +{ + /** + * @var mixed[]|null + * @psalm-var array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array}|array{}|null + */ + private static $installed; + + /** + * @var bool|null + */ + private static $canGetVendors; + + /** + * @var array[] + * @psalm-var array}> + */ + private static $installedByVendor = array(); + + /** + * Returns a list of all package names which are present, either by being installed, replaced or provided + * + * @return string[] + * @psalm-return list + */ + public static function getInstalledPackages() + { + $packages = array(); + foreach (self::getInstalled() as $installed) { + $packages[] = array_keys($installed['versions']); + } + + if (1 === \count($packages)) { + return $packages[0]; + } + + return array_keys(array_flip(\call_user_func_array('array_merge', $packages))); + } + + /** + * Returns a list of all package names with a specific type e.g. 'library' + * + * @param string $type + * @return string[] + * @psalm-return list + */ + public static function getInstalledPackagesByType($type) + { + $packagesByType = array(); + + foreach (self::getInstalled() as $installed) { + foreach ($installed['versions'] as $name => $package) { + if (isset($package['type']) && $package['type'] === $type) { + $packagesByType[] = $name; + } + } + } + + return $packagesByType; + } + + /** + * Checks whether the given package is installed + * + * This also returns true if the package name is provided or replaced by another package + * + * @param string $packageName + * @param bool $includeDevRequirements + * @return bool + */ + public static function isInstalled($packageName, $includeDevRequirements = true) + { + foreach (self::getInstalled() as $installed) { + if (isset($installed['versions'][$packageName])) { + return $includeDevRequirements || !isset($installed['versions'][$packageName]['dev_requirement']) || $installed['versions'][$packageName]['dev_requirement'] === false; + } + } + + return false; + } + + /** + * Checks whether the given package satisfies a version constraint + * + * e.g. If you want to know whether version 2.3+ of package foo/bar is installed, you would call: + * + * Composer\InstalledVersions::satisfies(new VersionParser, 'foo/bar', '^2.3') + * + * @param VersionParser $parser Install composer/semver to have access to this class and functionality + * @param string $packageName + * @param string|null $constraint A version constraint to check for, if you pass one you have to make sure composer/semver is required by your package + * @return bool + */ + public static function satisfies(VersionParser $parser, $packageName, $constraint) + { + $constraint = $parser->parseConstraints((string) $constraint); + $provided = $parser->parseConstraints(self::getVersionRanges($packageName)); + + return $provided->matches($constraint); + } + + /** + * Returns a version constraint representing all the range(s) which are installed for a given package + * + * It is easier to use this via isInstalled() with the $constraint argument if you need to check + * whether a given version of a package is installed, and not just whether it exists + * + * @param string $packageName + * @return string Version constraint usable with composer/semver + */ + public static function getVersionRanges($packageName) + { + foreach (self::getInstalled() as $installed) { + if (!isset($installed['versions'][$packageName])) { + continue; + } + + $ranges = array(); + if (isset($installed['versions'][$packageName]['pretty_version'])) { + $ranges[] = $installed['versions'][$packageName]['pretty_version']; + } + if (array_key_exists('aliases', $installed['versions'][$packageName])) { + $ranges = array_merge($ranges, $installed['versions'][$packageName]['aliases']); + } + if (array_key_exists('replaced', $installed['versions'][$packageName])) { + $ranges = array_merge($ranges, $installed['versions'][$packageName]['replaced']); + } + if (array_key_exists('provided', $installed['versions'][$packageName])) { + $ranges = array_merge($ranges, $installed['versions'][$packageName]['provided']); + } + + return implode(' || ', $ranges); + } + + throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed'); + } + + /** + * @param string $packageName + * @return string|null If the package is being replaced or provided but is not really installed, null will be returned as version, use satisfies or getVersionRanges if you need to know if a given version is present + */ + public static function getVersion($packageName) + { + foreach (self::getInstalled() as $installed) { + if (!isset($installed['versions'][$packageName])) { + continue; + } + + if (!isset($installed['versions'][$packageName]['version'])) { + return null; + } + + return $installed['versions'][$packageName]['version']; + } + + throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed'); + } + + /** + * @param string $packageName + * @return string|null If the package is being replaced or provided but is not really installed, null will be returned as version, use satisfies or getVersionRanges if you need to know if a given version is present + */ + public static function getPrettyVersion($packageName) + { + foreach (self::getInstalled() as $installed) { + if (!isset($installed['versions'][$packageName])) { + continue; + } + + if (!isset($installed['versions'][$packageName]['pretty_version'])) { + return null; + } + + return $installed['versions'][$packageName]['pretty_version']; + } + + throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed'); + } + + /** + * @param string $packageName + * @return string|null If the package is being replaced or provided but is not really installed, null will be returned as reference + */ + public static function getReference($packageName) + { + foreach (self::getInstalled() as $installed) { + if (!isset($installed['versions'][$packageName])) { + continue; + } + + if (!isset($installed['versions'][$packageName]['reference'])) { + return null; + } + + return $installed['versions'][$packageName]['reference']; + } + + throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed'); + } + + /** + * @param string $packageName + * @return string|null If the package is being replaced or provided but is not really installed, null will be returned as install path. Packages of type metapackages also have a null install path. + */ + public static function getInstallPath($packageName) + { + foreach (self::getInstalled() as $installed) { + if (!isset($installed['versions'][$packageName])) { + continue; + } + + return isset($installed['versions'][$packageName]['install_path']) ? $installed['versions'][$packageName]['install_path'] : null; + } + + throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed'); + } + + /** + * @return array + * @psalm-return array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool} + */ + public static function getRootPackage() + { + $installed = self::getInstalled(); + + return $installed[0]['root']; + } + + /** + * Returns the raw installed.php data for custom implementations + * + * @deprecated Use getAllRawData() instead which returns all datasets for all autoloaders present in the process. getRawData only returns the first dataset loaded, which may not be what you expect. + * @return array[] + * @psalm-return array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array} + */ + public static function getRawData() + { + @trigger_error('getRawData only returns the first dataset loaded, which may not be what you expect. Use getAllRawData() instead which returns all datasets for all autoloaders present in the process.', E_USER_DEPRECATED); + + if (null === self::$installed) { + // only require the installed.php file if this file is loaded from its dumped location, + // and not from its source location in the composer/composer package, see https://github.com/composer/composer/issues/9937 + if (substr(__DIR__, -8, 1) !== 'C') { + self::$installed = include __DIR__ . '/installed.php'; + } else { + self::$installed = array(); + } + } + + return self::$installed; + } + + /** + * Returns the raw data of all installed.php which are currently loaded for custom implementations + * + * @return array[] + * @psalm-return list}> + */ + public static function getAllRawData() + { + return self::getInstalled(); + } + + /** + * Lets you reload the static array from another file + * + * This is only useful for complex integrations in which a project needs to use + * this class but then also needs to execute another project's autoloader in process, + * and wants to ensure both projects have access to their version of installed.php. + * + * A typical case would be PHPUnit, where it would need to make sure it reads all + * the data it needs from this class, then call reload() with + * `require $CWD/vendor/composer/installed.php` (or similar) as input to make sure + * the project in which it runs can then also use this class safely, without + * interference between PHPUnit's dependencies and the project's dependencies. + * + * @param array[] $data A vendor/composer/installed.php data set + * @return void + * + * @psalm-param array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array} $data + */ + public static function reload($data) + { + self::$installed = $data; + self::$installedByVendor = array(); + } + + /** + * @return array[] + * @psalm-return list}> + */ + private static function getInstalled() + { + if (null === self::$canGetVendors) { + self::$canGetVendors = method_exists('Composer\Autoload\ClassLoader', 'getRegisteredLoaders'); + } + + $installed = array(); + + if (self::$canGetVendors) { + foreach (ClassLoader::getRegisteredLoaders() as $vendorDir => $loader) { + if (isset(self::$installedByVendor[$vendorDir])) { + $installed[] = self::$installedByVendor[$vendorDir]; + } elseif (is_file($vendorDir.'/composer/installed.php')) { + /** @var array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array} $required */ + $required = require $vendorDir.'/composer/installed.php'; + $installed[] = self::$installedByVendor[$vendorDir] = $required; + if (null === self::$installed && strtr($vendorDir.'/composer', '\\', '/') === strtr(__DIR__, '\\', '/')) { + self::$installed = $installed[count($installed) - 1]; + } + } + } + } + + if (null === self::$installed) { + // only require the installed.php file if this file is loaded from its dumped location, + // and not from its source location in the composer/composer package, see https://github.com/composer/composer/issues/9937 + if (substr(__DIR__, -8, 1) !== 'C') { + /** @var array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array} $required */ + $required = require __DIR__ . '/installed.php'; + self::$installed = $required; + } else { + self::$installed = array(); + } + } + + if (self::$installed !== array()) { + $installed[] = self::$installed; + } + + return $installed; + } +} diff --git a/advancedcontentfilter/vendor/composer/autoload_classmap.php b/advancedcontentfilter/vendor/composer/autoload_classmap.php index 9f79be5c..fe2a622a 100644 --- a/advancedcontentfilter/vendor/composer/autoload_classmap.php +++ b/advancedcontentfilter/vendor/composer/autoload_classmap.php @@ -2,11 +2,12 @@ // autoload_classmap.php @generated by Composer -$vendorDir = dirname(dirname(__FILE__)); +$vendorDir = dirname(__DIR__); $baseDir = dirname($vendorDir); return array( 'Attribute' => $vendorDir . '/symfony/polyfill-php80/Resources/stubs/Attribute.php', + 'Composer\\InstalledVersions' => $vendorDir . '/composer/InstalledVersions.php', 'FastRoute\\BadRouteException' => $vendorDir . '/nikic/fast-route/src/BadRouteException.php', 'FastRoute\\DataGenerator' => $vendorDir . '/nikic/fast-route/src/DataGenerator.php', 'FastRoute\\DataGenerator\\CharCountBased' => $vendorDir . '/nikic/fast-route/src/DataGenerator/CharCountBased.php', @@ -154,7 +155,6 @@ return array( 'Symfony\\Component\\Cache\\Adapter\\TagAwareAdapter' => $vendorDir . '/symfony/cache/Adapter/TagAwareAdapter.php', 'Symfony\\Component\\Cache\\Adapter\\TagAwareAdapterInterface' => $vendorDir . '/symfony/cache/Adapter/TagAwareAdapterInterface.php', 'Symfony\\Component\\Cache\\Adapter\\TraceableAdapter' => $vendorDir . '/symfony/cache/Adapter/TraceableAdapter.php', - 'Symfony\\Component\\Cache\\Adapter\\TraceableAdapterEvent' => $vendorDir . '/symfony/cache/Adapter/TraceableAdapter.php', 'Symfony\\Component\\Cache\\Adapter\\TraceableTagAwareAdapter' => $vendorDir . '/symfony/cache/Adapter/TraceableTagAwareAdapter.php', 'Symfony\\Component\\Cache\\CacheItem' => $vendorDir . '/symfony/cache/CacheItem.php', 'Symfony\\Component\\Cache\\DataCollector\\CacheDataCollector' => $vendorDir . '/symfony/cache/DataCollector/CacheDataCollector.php', @@ -188,7 +188,6 @@ return array( 'Symfony\\Component\\Cache\\Simple\\Psr6Cache' => $vendorDir . '/symfony/cache/Simple/Psr6Cache.php', 'Symfony\\Component\\Cache\\Simple\\RedisCache' => $vendorDir . '/symfony/cache/Simple/RedisCache.php', 'Symfony\\Component\\Cache\\Simple\\TraceableCache' => $vendorDir . '/symfony/cache/Simple/TraceableCache.php', - 'Symfony\\Component\\Cache\\Simple\\TraceableCacheEvent' => $vendorDir . '/symfony/cache/Simple/TraceableCache.php', 'Symfony\\Component\\Cache\\Traits\\AbstractAdapterTrait' => $vendorDir . '/symfony/cache/Traits/AbstractAdapterTrait.php', 'Symfony\\Component\\Cache\\Traits\\AbstractTrait' => $vendorDir . '/symfony/cache/Traits/AbstractTrait.php', 'Symfony\\Component\\Cache\\Traits\\ApcuTrait' => $vendorDir . '/symfony/cache/Traits/ApcuTrait.php', @@ -197,7 +196,6 @@ return array( 'Symfony\\Component\\Cache\\Traits\\DoctrineTrait' => $vendorDir . '/symfony/cache/Traits/DoctrineTrait.php', 'Symfony\\Component\\Cache\\Traits\\FilesystemCommonTrait' => $vendorDir . '/symfony/cache/Traits/FilesystemCommonTrait.php', 'Symfony\\Component\\Cache\\Traits\\FilesystemTrait' => $vendorDir . '/symfony/cache/Traits/FilesystemTrait.php', - 'Symfony\\Component\\Cache\\Traits\\LazyValue' => $vendorDir . '/symfony/cache/Traits/PhpFilesTrait.php', 'Symfony\\Component\\Cache\\Traits\\MemcachedTrait' => $vendorDir . '/symfony/cache/Traits/MemcachedTrait.php', 'Symfony\\Component\\Cache\\Traits\\PdoTrait' => $vendorDir . '/symfony/cache/Traits/PdoTrait.php', 'Symfony\\Component\\Cache\\Traits\\PhpArrayTrait' => $vendorDir . '/symfony/cache/Traits/PhpArrayTrait.php', diff --git a/advancedcontentfilter/vendor/composer/autoload_files.php b/advancedcontentfilter/vendor/composer/autoload_files.php index a5d3b964..aafd69e1 100644 --- a/advancedcontentfilter/vendor/composer/autoload_files.php +++ b/advancedcontentfilter/vendor/composer/autoload_files.php @@ -2,7 +2,7 @@ // autoload_files.php @generated by Composer -$vendorDir = dirname(dirname(__FILE__)); +$vendorDir = dirname(__DIR__); $baseDir = dirname($vendorDir); return array( diff --git a/advancedcontentfilter/vendor/composer/autoload_namespaces.php b/advancedcontentfilter/vendor/composer/autoload_namespaces.php index b7fc0125..15a2ff3a 100644 --- a/advancedcontentfilter/vendor/composer/autoload_namespaces.php +++ b/advancedcontentfilter/vendor/composer/autoload_namespaces.php @@ -2,7 +2,7 @@ // autoload_namespaces.php @generated by Composer -$vendorDir = dirname(dirname(__FILE__)); +$vendorDir = dirname(__DIR__); $baseDir = dirname($vendorDir); return array( diff --git a/advancedcontentfilter/vendor/composer/autoload_psr4.php b/advancedcontentfilter/vendor/composer/autoload_psr4.php index 3d716d56..4bf247ce 100644 --- a/advancedcontentfilter/vendor/composer/autoload_psr4.php +++ b/advancedcontentfilter/vendor/composer/autoload_psr4.php @@ -2,7 +2,7 @@ // autoload_psr4.php @generated by Composer -$vendorDir = dirname(dirname(__FILE__)); +$vendorDir = dirname(__DIR__); $baseDir = dirname($vendorDir); return array( @@ -16,7 +16,7 @@ return array( 'Slim\\' => array($vendorDir . '/slim/slim/Slim'), 'Psr\\Log\\' => array($vendorDir . '/psr/log/Psr/Log'), 'Psr\\Http\\Server\\' => array($vendorDir . '/psr/http-server-handler/src', $vendorDir . '/psr/http-server-middleware/src'), - 'Psr\\Http\\Message\\' => array($vendorDir . '/psr/http-factory/src', $vendorDir . '/psr/http-message/src'), + 'Psr\\Http\\Message\\' => array($vendorDir . '/psr/http-message/src', $vendorDir . '/psr/http-factory/src'), 'Psr\\Container\\' => array($vendorDir . '/psr/container/src'), 'Psr\\Cache\\' => array($vendorDir . '/psr/cache/src'), 'FastRoute\\' => array($vendorDir . '/nikic/fast-route/src'), diff --git a/advancedcontentfilter/vendor/composer/autoload_real.php b/advancedcontentfilter/vendor/composer/autoload_real.php index d6532d7d..b305aa00 100644 --- a/advancedcontentfilter/vendor/composer/autoload_real.php +++ b/advancedcontentfilter/vendor/composer/autoload_real.php @@ -22,52 +22,29 @@ class ComposerAutoloaderInitAdvancedContentFilterAddon return self::$loader; } + require __DIR__ . '/platform_check.php'; + spl_autoload_register(array('ComposerAutoloaderInitAdvancedContentFilterAddon', 'loadClassLoader'), true, true); - self::$loader = $loader = new \Composer\Autoload\ClassLoader(); + self::$loader = $loader = new \Composer\Autoload\ClassLoader(\dirname(__DIR__)); spl_autoload_unregister(array('ComposerAutoloaderInitAdvancedContentFilterAddon', 'loadClassLoader')); - $useStaticLoader = PHP_VERSION_ID >= 50600 && !defined('HHVM_VERSION') && (!function_exists('zend_loader_file_encoded') || !zend_loader_file_encoded()); - if ($useStaticLoader) { - require_once __DIR__ . '/autoload_static.php'; - - call_user_func(\Composer\Autoload\ComposerStaticInitAdvancedContentFilterAddon::getInitializer($loader)); - } else { - $map = require __DIR__ . '/autoload_namespaces.php'; - foreach ($map as $namespace => $path) { - $loader->set($namespace, $path); - } - - $map = require __DIR__ . '/autoload_psr4.php'; - foreach ($map as $namespace => $path) { - $loader->setPsr4($namespace, $path); - } - - $classMap = require __DIR__ . '/autoload_classmap.php'; - if ($classMap) { - $loader->addClassMap($classMap); - } - } + require __DIR__ . '/autoload_static.php'; + call_user_func(\Composer\Autoload\ComposerStaticInitAdvancedContentFilterAddon::getInitializer($loader)); $loader->register(true); - if ($useStaticLoader) { - $includeFiles = Composer\Autoload\ComposerStaticInitAdvancedContentFilterAddon::$files; - } else { - $includeFiles = require __DIR__ . '/autoload_files.php'; - } - foreach ($includeFiles as $fileIdentifier => $file) { - composerRequireAdvancedContentFilterAddon($fileIdentifier, $file); + $filesToLoad = \Composer\Autoload\ComposerStaticInitAdvancedContentFilterAddon::$files; + $requireFile = \Closure::bind(static function ($fileIdentifier, $file) { + if (empty($GLOBALS['__composer_autoload_files'][$fileIdentifier])) { + $GLOBALS['__composer_autoload_files'][$fileIdentifier] = true; + + require $file; + } + }, null, null); + foreach ($filesToLoad as $fileIdentifier => $file) { + $requireFile($fileIdentifier, $file); } return $loader; } } - -function composerRequireAdvancedContentFilterAddon($fileIdentifier, $file) -{ - if (empty($GLOBALS['__composer_autoload_files'][$fileIdentifier])) { - require $file; - - $GLOBALS['__composer_autoload_files'][$fileIdentifier] = true; - } -} diff --git a/advancedcontentfilter/vendor/composer/autoload_static.php b/advancedcontentfilter/vendor/composer/autoload_static.php index 57172a1a..8cc48b1a 100644 --- a/advancedcontentfilter/vendor/composer/autoload_static.php +++ b/advancedcontentfilter/vendor/composer/autoload_static.php @@ -83,8 +83,8 @@ class ComposerStaticInitAdvancedContentFilterAddon ), 'Psr\\Http\\Message\\' => array ( - 0 => __DIR__ . '/..' . '/psr/http-factory/src', - 1 => __DIR__ . '/..' . '/psr/http-message/src', + 0 => __DIR__ . '/..' . '/psr/http-message/src', + 1 => __DIR__ . '/..' . '/psr/http-factory/src', ), 'Psr\\Container\\' => array ( @@ -102,6 +102,7 @@ class ComposerStaticInitAdvancedContentFilterAddon public static $classMap = array ( 'Attribute' => __DIR__ . '/..' . '/symfony/polyfill-php80/Resources/stubs/Attribute.php', + 'Composer\\InstalledVersions' => __DIR__ . '/..' . '/composer/InstalledVersions.php', 'FastRoute\\BadRouteException' => __DIR__ . '/..' . '/nikic/fast-route/src/BadRouteException.php', 'FastRoute\\DataGenerator' => __DIR__ . '/..' . '/nikic/fast-route/src/DataGenerator.php', 'FastRoute\\DataGenerator\\CharCountBased' => __DIR__ . '/..' . '/nikic/fast-route/src/DataGenerator/CharCountBased.php', @@ -249,7 +250,6 @@ class ComposerStaticInitAdvancedContentFilterAddon 'Symfony\\Component\\Cache\\Adapter\\TagAwareAdapter' => __DIR__ . '/..' . '/symfony/cache/Adapter/TagAwareAdapter.php', 'Symfony\\Component\\Cache\\Adapter\\TagAwareAdapterInterface' => __DIR__ . '/..' . '/symfony/cache/Adapter/TagAwareAdapterInterface.php', 'Symfony\\Component\\Cache\\Adapter\\TraceableAdapter' => __DIR__ . '/..' . '/symfony/cache/Adapter/TraceableAdapter.php', - 'Symfony\\Component\\Cache\\Adapter\\TraceableAdapterEvent' => __DIR__ . '/..' . '/symfony/cache/Adapter/TraceableAdapter.php', 'Symfony\\Component\\Cache\\Adapter\\TraceableTagAwareAdapter' => __DIR__ . '/..' . '/symfony/cache/Adapter/TraceableTagAwareAdapter.php', 'Symfony\\Component\\Cache\\CacheItem' => __DIR__ . '/..' . '/symfony/cache/CacheItem.php', 'Symfony\\Component\\Cache\\DataCollector\\CacheDataCollector' => __DIR__ . '/..' . '/symfony/cache/DataCollector/CacheDataCollector.php', @@ -283,7 +283,6 @@ class ComposerStaticInitAdvancedContentFilterAddon 'Symfony\\Component\\Cache\\Simple\\Psr6Cache' => __DIR__ . '/..' . '/symfony/cache/Simple/Psr6Cache.php', 'Symfony\\Component\\Cache\\Simple\\RedisCache' => __DIR__ . '/..' . '/symfony/cache/Simple/RedisCache.php', 'Symfony\\Component\\Cache\\Simple\\TraceableCache' => __DIR__ . '/..' . '/symfony/cache/Simple/TraceableCache.php', - 'Symfony\\Component\\Cache\\Simple\\TraceableCacheEvent' => __DIR__ . '/..' . '/symfony/cache/Simple/TraceableCache.php', 'Symfony\\Component\\Cache\\Traits\\AbstractAdapterTrait' => __DIR__ . '/..' . '/symfony/cache/Traits/AbstractAdapterTrait.php', 'Symfony\\Component\\Cache\\Traits\\AbstractTrait' => __DIR__ . '/..' . '/symfony/cache/Traits/AbstractTrait.php', 'Symfony\\Component\\Cache\\Traits\\ApcuTrait' => __DIR__ . '/..' . '/symfony/cache/Traits/ApcuTrait.php', @@ -292,7 +291,6 @@ class ComposerStaticInitAdvancedContentFilterAddon 'Symfony\\Component\\Cache\\Traits\\DoctrineTrait' => __DIR__ . '/..' . '/symfony/cache/Traits/DoctrineTrait.php', 'Symfony\\Component\\Cache\\Traits\\FilesystemCommonTrait' => __DIR__ . '/..' . '/symfony/cache/Traits/FilesystemCommonTrait.php', 'Symfony\\Component\\Cache\\Traits\\FilesystemTrait' => __DIR__ . '/..' . '/symfony/cache/Traits/FilesystemTrait.php', - 'Symfony\\Component\\Cache\\Traits\\LazyValue' => __DIR__ . '/..' . '/symfony/cache/Traits/PhpFilesTrait.php', 'Symfony\\Component\\Cache\\Traits\\MemcachedTrait' => __DIR__ . '/..' . '/symfony/cache/Traits/MemcachedTrait.php', 'Symfony\\Component\\Cache\\Traits\\PdoTrait' => __DIR__ . '/..' . '/symfony/cache/Traits/PdoTrait.php', 'Symfony\\Component\\Cache\\Traits\\PhpArrayTrait' => __DIR__ . '/..' . '/symfony/cache/Traits/PhpArrayTrait.php', diff --git a/advancedcontentfilter/vendor/composer/installed.json b/advancedcontentfilter/vendor/composer/installed.json index 07e02c7f..70c2dc41 100644 --- a/advancedcontentfilter/vendor/composer/installed.json +++ b/advancedcontentfilter/vendor/composer/installed.json @@ -1,1190 +1,1212 @@ -[ - { - "name": "nikic/fast-route", - "version": "v1.3.0", - "version_normalized": "1.3.0.0", - "source": { - "type": "git", - "url": "https://github.com/nikic/FastRoute.git", - "reference": "181d480e08d9476e61381e04a71b34dc0432e812" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/nikic/FastRoute/zipball/181d480e08d9476e61381e04a71b34dc0432e812", - "reference": "181d480e08d9476e61381e04a71b34dc0432e812", - "shasum": "" - }, - "require": { - "php": ">=5.4.0" - }, - "require-dev": { - "phpunit/phpunit": "^4.8.35|~5.7" - }, - "time": "2018-02-13T20:26:39+00:00", - "type": "library", - "installation-source": "dist", - "autoload": { - "psr-4": { - "FastRoute\\": "src/" +{ + "packages": [ + { + "name": "nikic/fast-route", + "version": "v1.3.0", + "version_normalized": "1.3.0.0", + "source": { + "type": "git", + "url": "https://github.com/nikic/FastRoute.git", + "reference": "181d480e08d9476e61381e04a71b34dc0432e812" }, - "files": [ - "src/functions.php" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Nikita Popov", - "email": "nikic@php.net" - } - ], - "description": "Fast request router for PHP", - "keywords": [ - "router", - "routing" - ] - }, - { - "name": "psr/cache", - "version": "1.0.1", - "version_normalized": "1.0.1.0", - "source": { - "type": "git", - "url": "https://github.com/php-fig/cache.git", - "reference": "d11b50ad223250cf17b86e38383413f5a6764bf8" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/php-fig/cache/zipball/d11b50ad223250cf17b86e38383413f5a6764bf8", - "reference": "d11b50ad223250cf17b86e38383413f5a6764bf8", - "shasum": "" - }, - "require": { - "php": ">=5.3.0" - }, - "time": "2016-08-06T20:24:11+00:00", - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.0.x-dev" - } - }, - "installation-source": "dist", - "autoload": { - "psr-4": { - "Psr\\Cache\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "PHP-FIG", - "homepage": "http://www.php-fig.org/" - } - ], - "description": "Common interface for caching libraries", - "keywords": [ - "cache", - "psr", - "psr-6" - ] - }, - { - "name": "psr/container", - "version": "1.1.2", - "version_normalized": "1.1.2.0", - "source": { - "type": "git", - "url": "https://github.com/php-fig/container.git", - "reference": "513e0666f7216c7459170d56df27dfcefe1689ea" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/php-fig/container/zipball/513e0666f7216c7459170d56df27dfcefe1689ea", - "reference": "513e0666f7216c7459170d56df27dfcefe1689ea", - "shasum": "" - }, - "require": { - "php": ">=7.4.0" - }, - "time": "2021-11-05T16:50:12+00:00", - "type": "library", - "installation-source": "dist", - "autoload": { - "psr-4": { - "Psr\\Container\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "PHP-FIG", - "homepage": "https://www.php-fig.org/" - } - ], - "description": "Common Container Interface (PHP FIG PSR-11)", - "homepage": "https://github.com/php-fig/container", - "keywords": [ - "PSR-11", - "container", - "container-interface", - "container-interop", - "psr" - ] - }, - { - "name": "psr/http-factory", - "version": "1.0.2", - "version_normalized": "1.0.2.0", - "source": { - "type": "git", - "url": "https://github.com/php-fig/http-factory.git", - "reference": "e616d01114759c4c489f93b099585439f795fe35" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/php-fig/http-factory/zipball/e616d01114759c4c489f93b099585439f795fe35", - "reference": "e616d01114759c4c489f93b099585439f795fe35", - "shasum": "" - }, - "require": { - "php": ">=7.0.0", - "psr/http-message": "^1.0 || ^2.0" - }, - "time": "2023-04-10T20:10:41+00:00", - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.0.x-dev" - } - }, - "installation-source": "dist", - "autoload": { - "psr-4": { - "Psr\\Http\\Message\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "PHP-FIG", - "homepage": "https://www.php-fig.org/" - } - ], - "description": "Common interfaces for PSR-7 HTTP message factories", - "keywords": [ - "factory", - "http", - "message", - "psr", - "psr-17", - "psr-7", - "request", - "response" - ] - }, - { - "name": "psr/http-message", - "version": "2.0", - "version_normalized": "2.0.0.0", - "source": { - "type": "git", - "url": "https://github.com/php-fig/http-message.git", - "reference": "402d35bcb92c70c026d1a6a9883f06b2ead23d71" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/php-fig/http-message/zipball/402d35bcb92c70c026d1a6a9883f06b2ead23d71", - "reference": "402d35bcb92c70c026d1a6a9883f06b2ead23d71", - "shasum": "" - }, - "require": { - "php": "^7.2 || ^8.0" - }, - "time": "2023-04-04T09:54:51+00:00", - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.0.x-dev" - } - }, - "installation-source": "dist", - "autoload": { - "psr-4": { - "Psr\\Http\\Message\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "PHP-FIG", - "homepage": "https://www.php-fig.org/" - } - ], - "description": "Common interface for HTTP messages", - "homepage": "https://github.com/php-fig/http-message", - "keywords": [ - "http", - "http-message", - "psr", - "psr-7", - "request", - "response" - ] - }, - { - "name": "psr/http-server-handler", - "version": "1.0.2", - "version_normalized": "1.0.2.0", - "source": { - "type": "git", - "url": "https://github.com/php-fig/http-server-handler.git", - "reference": "84c4fb66179be4caaf8e97bd239203245302e7d4" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/php-fig/http-server-handler/zipball/84c4fb66179be4caaf8e97bd239203245302e7d4", - "reference": "84c4fb66179be4caaf8e97bd239203245302e7d4", - "shasum": "" - }, - "require": { - "php": ">=7.0", - "psr/http-message": "^1.0 || ^2.0" - }, - "time": "2023-04-10T20:06:20+00:00", - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.0.x-dev" - } - }, - "installation-source": "dist", - "autoload": { - "psr-4": { - "Psr\\Http\\Server\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "PHP-FIG", - "homepage": "https://www.php-fig.org/" - } - ], - "description": "Common interface for HTTP server-side request handler", - "keywords": [ - "handler", - "http", - "http-interop", - "psr", - "psr-15", - "psr-7", - "request", - "response", - "server" - ] - }, - { - "name": "psr/http-server-middleware", - "version": "1.0.2", - "version_normalized": "1.0.2.0", - "source": { - "type": "git", - "url": "https://github.com/php-fig/http-server-middleware.git", - "reference": "c1481f747daaa6a0782775cd6a8c26a1bf4a3829" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/php-fig/http-server-middleware/zipball/c1481f747daaa6a0782775cd6a8c26a1bf4a3829", - "reference": "c1481f747daaa6a0782775cd6a8c26a1bf4a3829", - "shasum": "" - }, - "require": { - "php": ">=7.0", - "psr/http-message": "^1.0 || ^2.0", - "psr/http-server-handler": "^1.0" - }, - "time": "2023-04-11T06:14:47+00:00", - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.0.x-dev" - } - }, - "installation-source": "dist", - "autoload": { - "psr-4": { - "Psr\\Http\\Server\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "PHP-FIG", - "homepage": "https://www.php-fig.org/" - } - ], - "description": "Common interface for HTTP server-side middleware", - "keywords": [ - "http", - "http-interop", - "middleware", - "psr", - "psr-15", - "psr-7", - "request", - "response" - ] - }, - { - "name": "psr/log", - "version": "1.1.4", - "version_normalized": "1.1.4.0", - "source": { - "type": "git", - "url": "https://github.com/php-fig/log.git", - "reference": "d49695b909c3b7628b6289db5479a1c204601f11" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/php-fig/log/zipball/d49695b909c3b7628b6289db5479a1c204601f11", - "reference": "d49695b909c3b7628b6289db5479a1c204601f11", - "shasum": "" - }, - "require": { - "php": ">=5.3.0" - }, - "time": "2021-05-03T11:20:27+00:00", - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.1.x-dev" - } - }, - "installation-source": "dist", - "autoload": { - "psr-4": { - "Psr\\Log\\": "Psr/Log/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "PHP-FIG", - "homepage": "https://www.php-fig.org/" - } - ], - "description": "Common interface for logging libraries", - "homepage": "https://github.com/php-fig/log", - "keywords": [ - "log", - "psr", - "psr-3" - ] - }, - { - "name": "slim/slim", - "version": "4.13.0", - "version_normalized": "4.13.0.0", - "source": { - "type": "git", - "url": "https://github.com/slimphp/Slim.git", - "reference": "038fd5713d5a41636fdff0e8dcceedecdd17fc17" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/slimphp/Slim/zipball/038fd5713d5a41636fdff0e8dcceedecdd17fc17", - "reference": "038fd5713d5a41636fdff0e8dcceedecdd17fc17", - "shasum": "" - }, - "require": { - "ext-json": "*", - "nikic/fast-route": "^1.3", - "php": "^7.4 || ^8.0", - "psr/container": "^1.0 || ^2.0", - "psr/http-factory": "^1.0", - "psr/http-message": "^1.1 || ^2.0", - "psr/http-server-handler": "^1.0", - "psr/http-server-middleware": "^1.0", - "psr/log": "^1.1 || ^2.0 || ^3.0" - }, - "require-dev": { - "adriansuter/php-autoload-override": "^1.4", - "ext-simplexml": "*", - "guzzlehttp/psr7": "^2.6", - "httpsoft/http-message": "^1.1", - "httpsoft/http-server-request": "^1.1", - "laminas/laminas-diactoros": "^2.17 || ^3", - "nyholm/psr7": "^1.8", - "nyholm/psr7-server": "^1.1", - "phpspec/prophecy": "^1.19", - "phpspec/prophecy-phpunit": "^2.1", - "phpstan/phpstan": "^1.10", - "phpunit/phpunit": "^9.6", - "slim/http": "^1.3", - "slim/psr7": "^1.6", - "squizlabs/php_codesniffer": "^3.9" - }, - "suggest": { - "ext-simplexml": "Needed to support XML format in BodyParsingMiddleware", - "ext-xml": "Needed to support XML format in BodyParsingMiddleware", - "php-di/php-di": "PHP-DI is the recommended container library to be used with Slim", - "slim/psr7": "Slim PSR-7 implementation. See https://www.slimframework.com/docs/v4/start/installation.html for more information." - }, - "time": "2024-03-03T21:25:30+00:00", - "type": "library", - "installation-source": "dist", - "autoload": { - "psr-4": { - "Slim\\": "Slim" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Josh Lockhart", - "email": "hello@joshlockhart.com", - "homepage": "https://joshlockhart.com" + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/nikic/FastRoute/zipball/181d480e08d9476e61381e04a71b34dc0432e812", + "reference": "181d480e08d9476e61381e04a71b34dc0432e812", + "shasum": "" }, - { - "name": "Andrew Smith", - "email": "a.smith@silentworks.co.uk", - "homepage": "http://silentworks.co.uk" + "require": { + "php": ">=5.4.0" }, - { - "name": "Rob Allen", - "email": "rob@akrabat.com", - "homepage": "http://akrabat.com" + "require-dev": { + "phpunit/phpunit": "^4.8.35|~5.7" }, - { - "name": "Pierre Berube", - "email": "pierre@lgse.com", - "homepage": "http://www.lgse.com" + "time": "2018-02-13T20:26:39+00:00", + "type": "library", + "installation-source": "dist", + "autoload": { + "psr-4": { + "FastRoute\\": "src/" + }, + "files": [ + "src/functions.php" + ] }, - { - "name": "Gabriel Manricks", - "email": "gmanricks@me.com", - "homepage": "http://gabrielmanricks.com" - } - ], - "description": "Slim is a PHP micro framework that helps you quickly write simple yet powerful web applications and APIs", - "homepage": "https://www.slimframework.com", - "keywords": [ - "api", - "framework", - "micro", - "router" - ], - "funding": [ - { - "url": "https://opencollective.com/slimphp", - "type": "open_collective" - }, - { - "url": "https://tidelift.com/funding/github/packagist/slim/slim", - "type": "tidelift" - } - ] - }, - { - "name": "symfony/cache", - "version": "v4.4.48", - "version_normalized": "4.4.48.0", - "source": { - "type": "git", - "url": "https://github.com/symfony/cache.git", - "reference": "3b98ed664887ad197b8ede3da2432787212eb915" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/cache/zipball/3b98ed664887ad197b8ede3da2432787212eb915", - "reference": "3b98ed664887ad197b8ede3da2432787212eb915", - "shasum": "" - }, - "require": { - "php": ">=7.1.3", - "psr/cache": "^1.0|^2.0", - "psr/log": "^1|^2|^3", - "symfony/cache-contracts": "^1.1.7|^2", - "symfony/polyfill-php73": "^1.9", - "symfony/polyfill-php80": "^1.16", - "symfony/service-contracts": "^1.1|^2", - "symfony/var-exporter": "^4.2|^5.0" - }, - "conflict": { - "doctrine/dbal": "<2.7", - "symfony/dependency-injection": "<3.4", - "symfony/http-kernel": "<4.4|>=5.0", - "symfony/var-dumper": "<4.4" - }, - "provide": { - "psr/cache-implementation": "1.0|2.0", - "psr/simple-cache-implementation": "1.0|2.0", - "symfony/cache-implementation": "1.0|2.0" - }, - "require-dev": { - "cache/integration-tests": "dev-master", - "doctrine/cache": "^1.6|^2.0", - "doctrine/dbal": "^2.7|^3.0", - "predis/predis": "^1.1", - "psr/simple-cache": "^1.0|^2.0", - "symfony/config": "^4.2|^5.0", - "symfony/dependency-injection": "^3.4|^4.1|^5.0", - "symfony/filesystem": "^4.4|^5.0", - "symfony/http-kernel": "^4.4", - "symfony/var-dumper": "^4.4|^5.0" - }, - "time": "2022-10-17T20:21:54+00:00", - "type": "library", - "installation-source": "dist", - "autoload": { - "psr-4": { - "Symfony\\Component\\Cache\\": "" - }, - "exclude-from-classmap": [ - "/Tests/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Nicolas Grekas", - "email": "p@tchwork.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Provides extended PSR-6, PSR-16 (and tags) implementations", - "homepage": "https://symfony.com", - "keywords": [ - "caching", - "psr6" - ], - "funding": [ - { - "url": "https://symfony.com/sponsor", - "type": "custom" - }, - { - "url": "https://github.com/fabpot", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", - "type": "tidelift" - } - ] - }, - { - "name": "symfony/cache-contracts", - "version": "v2.5.2", - "version_normalized": "2.5.2.0", - "source": { - "type": "git", - "url": "https://github.com/symfony/cache-contracts.git", - "reference": "64be4a7acb83b6f2bf6de9a02cee6dad41277ebc" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/cache-contracts/zipball/64be4a7acb83b6f2bf6de9a02cee6dad41277ebc", - "reference": "64be4a7acb83b6f2bf6de9a02cee6dad41277ebc", - "shasum": "" - }, - "require": { - "php": ">=7.2.5", - "psr/cache": "^1.0|^2.0|^3.0" - }, - "suggest": { - "symfony/cache-implementation": "" - }, - "time": "2022-01-02T09:53:40+00:00", - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "2.5-dev" - }, - "thanks": { - "name": "symfony/contracts", - "url": "https://github.com/symfony/contracts" - } - }, - "installation-source": "dist", - "autoload": { - "psr-4": { - "Symfony\\Contracts\\Cache\\": "" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Nicolas Grekas", - "email": "p@tchwork.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Generic abstractions related to caching", - "homepage": "https://symfony.com", - "keywords": [ - "abstractions", - "contracts", - "decoupling", - "interfaces", - "interoperability", - "standards" - ], - "funding": [ - { - "url": "https://symfony.com/sponsor", - "type": "custom" - }, - { - "url": "https://github.com/fabpot", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", - "type": "tidelift" - } - ] - }, - { - "name": "symfony/deprecation-contracts", - "version": "v2.5.2", - "version_normalized": "2.5.2.0", - "source": { - "type": "git", - "url": "https://github.com/symfony/deprecation-contracts.git", - "reference": "e8b495ea28c1d97b5e0c121748d6f9b53d075c66" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/e8b495ea28c1d97b5e0c121748d6f9b53d075c66", - "reference": "e8b495ea28c1d97b5e0c121748d6f9b53d075c66", - "shasum": "" - }, - "require": { - "php": ">=7.1" - }, - "time": "2022-01-02T09:53:40+00:00", - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "2.5-dev" - }, - "thanks": { - "name": "symfony/contracts", - "url": "https://github.com/symfony/contracts" - } - }, - "installation-source": "dist", - "autoload": { - "files": [ - "function.php" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Nicolas Grekas", - "email": "p@tchwork.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "A generic function and convention to trigger deprecation notices", - "homepage": "https://symfony.com", - "funding": [ - { - "url": "https://symfony.com/sponsor", - "type": "custom" - }, - { - "url": "https://github.com/fabpot", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", - "type": "tidelift" - } - ] - }, - { - "name": "symfony/expression-language", - "version": "v3.4.47", - "version_normalized": "3.4.47.0", - "source": { - "type": "git", - "url": "https://github.com/symfony/expression-language.git", - "reference": "de38e66398fca1fcb9c48e80279910e6889cb28f" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/expression-language/zipball/de38e66398fca1fcb9c48e80279910e6889cb28f", - "reference": "de38e66398fca1fcb9c48e80279910e6889cb28f", - "shasum": "" - }, - "require": { - "php": "^5.5.9|>=7.0.8", - "symfony/cache": "~3.1|~4.0", - "symfony/polyfill-php70": "~1.6" - }, - "time": "2020-10-24T10:57:07+00:00", - "type": "library", - "installation-source": "dist", - "autoload": { - "psr-4": { - "Symfony\\Component\\ExpressionLanguage\\": "" - }, - "exclude-from-classmap": [ - "/Tests/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Symfony ExpressionLanguage Component", - "homepage": "https://symfony.com", - "funding": [ - { - "url": "https://symfony.com/sponsor", - "type": "custom" - }, - { - "url": "https://github.com/fabpot", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", - "type": "tidelift" - } - ] - }, - { - "name": "symfony/polyfill-php70", - "version": "v1.20.0", - "version_normalized": "1.20.0.0", - "source": { - "type": "git", - "url": "https://github.com/symfony/polyfill-php70.git", - "reference": "5f03a781d984aae42cebd18e7912fa80f02ee644" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php70/zipball/5f03a781d984aae42cebd18e7912fa80f02ee644", - "reference": "5f03a781d984aae42cebd18e7912fa80f02ee644", - "shasum": "" - }, - "require": { - "php": ">=7.1" - }, - "time": "2020-10-23T14:02:19+00:00", - "type": "metapackage", - "extra": { - "branch-alias": { - "dev-main": "1.20-dev" - }, - "thanks": { - "name": "symfony/polyfill", - "url": "https://github.com/symfony/polyfill" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Nicolas Grekas", - "email": "p@tchwork.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Symfony polyfill backporting some PHP 7.0+ features to lower PHP versions", - "homepage": "https://symfony.com", - "keywords": [ - "compatibility", - "polyfill", - "portable", - "shim" - ], - "funding": [ - { - "url": "https://symfony.com/sponsor", - "type": "custom" - }, - { - "url": "https://github.com/fabpot", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", - "type": "tidelift" - } - ] - }, - { - "name": "symfony/polyfill-php73", - "version": "v1.29.0", - "version_normalized": "1.29.0.0", - "source": { - "type": "git", - "url": "https://github.com/symfony/polyfill-php73.git", - "reference": "21bd091060673a1177ae842c0ef8fe30893114d2" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php73/zipball/21bd091060673a1177ae842c0ef8fe30893114d2", - "reference": "21bd091060673a1177ae842c0ef8fe30893114d2", - "shasum": "" - }, - "require": { - "php": ">=7.1" - }, - "time": "2024-01-29T20:11:03+00:00", - "type": "library", - "extra": { - "thanks": { - "name": "symfony/polyfill", - "url": "https://github.com/symfony/polyfill" - } - }, - "installation-source": "dist", - "autoload": { - "files": [ - "bootstrap.php" + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" ], - "psr-4": { - "Symfony\\Polyfill\\Php73\\": "" - }, - "classmap": [ - "Resources/stubs" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Nicolas Grekas", - "email": "p@tchwork.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Symfony polyfill backporting some PHP 7.3+ features to lower PHP versions", - "homepage": "https://symfony.com", - "keywords": [ - "compatibility", - "polyfill", - "portable", - "shim" - ], - "funding": [ - { - "url": "https://symfony.com/sponsor", - "type": "custom" - }, - { - "url": "https://github.com/fabpot", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", - "type": "tidelift" - } - ] - }, - { - "name": "symfony/polyfill-php80", - "version": "v1.29.0", - "version_normalized": "1.29.0.0", - "source": { - "type": "git", - "url": "https://github.com/symfony/polyfill-php80.git", - "reference": "87b68208d5c1188808dd7839ee1e6c8ec3b02f1b" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/87b68208d5c1188808dd7839ee1e6c8ec3b02f1b", - "reference": "87b68208d5c1188808dd7839ee1e6c8ec3b02f1b", - "shasum": "" - }, - "require": { - "php": ">=7.1" - }, - "time": "2024-01-29T20:11:03+00:00", - "type": "library", - "extra": { - "thanks": { - "name": "symfony/polyfill", - "url": "https://github.com/symfony/polyfill" - } - }, - "installation-source": "dist", - "autoload": { - "files": [ - "bootstrap.php" + "authors": [ + { + "name": "Nikita Popov", + "email": "nikic@php.net" + } ], - "psr-4": { - "Symfony\\Polyfill\\Php80\\": "" - }, - "classmap": [ - "Resources/stubs" - ] + "description": "Fast request router for PHP", + "keywords": [ + "router", + "routing" + ], + "install-path": "../nikic/fast-route" }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Ion Bazan", - "email": "ion.bazan@gmail.com" + { + "name": "psr/cache", + "version": "1.0.1", + "version_normalized": "1.0.1.0", + "source": { + "type": "git", + "url": "https://github.com/php-fig/cache.git", + "reference": "d11b50ad223250cf17b86e38383413f5a6764bf8" }, - { - "name": "Nicolas Grekas", - "email": "p@tchwork.com" + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/cache/zipball/d11b50ad223250cf17b86e38383413f5a6764bf8", + "reference": "d11b50ad223250cf17b86e38383413f5a6764bf8", + "shasum": "" }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Symfony polyfill backporting some PHP 8.0+ features to lower PHP versions", - "homepage": "https://symfony.com", - "keywords": [ - "compatibility", - "polyfill", - "portable", - "shim" - ], - "funding": [ - { - "url": "https://symfony.com/sponsor", - "type": "custom" + "require": { + "php": ">=5.3.0" }, - { - "url": "https://github.com/fabpot", - "type": "github" + "time": "2016-08-06T20:24:11+00:00", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } }, - { - "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", - "type": "tidelift" - } - ] - }, - { - "name": "symfony/service-contracts", - "version": "v2.5.2", - "version_normalized": "2.5.2.0", - "source": { - "type": "git", - "url": "https://github.com/symfony/service-contracts.git", - "reference": "4b426aac47d6427cc1a1d0f7e2ac724627f5966c" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/service-contracts/zipball/4b426aac47d6427cc1a1d0f7e2ac724627f5966c", - "reference": "4b426aac47d6427cc1a1d0f7e2ac724627f5966c", - "shasum": "" - }, - "require": { - "php": ">=7.2.5", - "psr/container": "^1.1", - "symfony/deprecation-contracts": "^2.1|^3" - }, - "conflict": { - "ext-psr": "<1.1|>=2" - }, - "suggest": { - "symfony/service-implementation": "" - }, - "time": "2022-05-30T19:17:29+00:00", - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "2.5-dev" + "installation-source": "dist", + "autoload": { + "psr-4": { + "Psr\\Cache\\": "src/" + } }, - "thanks": { - "name": "symfony/contracts", - "url": "https://github.com/symfony/contracts" - } + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "http://www.php-fig.org/" + } + ], + "description": "Common interface for caching libraries", + "keywords": [ + "cache", + "psr", + "psr-6" + ], + "install-path": "../psr/cache" }, - "installation-source": "dist", - "autoload": { - "psr-4": { - "Symfony\\Contracts\\Service\\": "" - } + { + "name": "psr/container", + "version": "1.1.2", + "version_normalized": "1.1.2.0", + "source": { + "type": "git", + "url": "https://github.com/php-fig/container.git", + "reference": "513e0666f7216c7459170d56df27dfcefe1689ea" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/container/zipball/513e0666f7216c7459170d56df27dfcefe1689ea", + "reference": "513e0666f7216c7459170d56df27dfcefe1689ea", + "shasum": "" + }, + "require": { + "php": ">=7.4.0" + }, + "time": "2021-11-05T16:50:12+00:00", + "type": "library", + "installation-source": "dist", + "autoload": { + "psr-4": { + "Psr\\Container\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "https://www.php-fig.org/" + } + ], + "description": "Common Container Interface (PHP FIG PSR-11)", + "homepage": "https://github.com/php-fig/container", + "keywords": [ + "PSR-11", + "container", + "container-interface", + "container-interop", + "psr" + ], + "install-path": "../psr/container" }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Nicolas Grekas", - "email": "p@tchwork.com" + { + "name": "psr/http-factory", + "version": "1.0.2", + "version_normalized": "1.0.2.0", + "source": { + "type": "git", + "url": "https://github.com/php-fig/http-factory.git", + "reference": "e616d01114759c4c489f93b099585439f795fe35" }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Generic abstractions related to writing services", - "homepage": "https://symfony.com", - "keywords": [ - "abstractions", - "contracts", - "decoupling", - "interfaces", - "interoperability", - "standards" - ], - "funding": [ - { - "url": "https://symfony.com/sponsor", - "type": "custom" + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/http-factory/zipball/e616d01114759c4c489f93b099585439f795fe35", + "reference": "e616d01114759c4c489f93b099585439f795fe35", + "shasum": "" }, - { - "url": "https://github.com/fabpot", - "type": "github" + "require": { + "php": ">=7.0.0", + "psr/http-message": "^1.0 || ^2.0" }, - { - "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", - "type": "tidelift" - } - ] - }, - { - "name": "symfony/var-exporter", - "version": "v5.4.35", - "version_normalized": "5.4.35.0", - "source": { - "type": "git", - "url": "https://github.com/symfony/var-exporter.git", - "reference": "abb0a151b62d6b07e816487e20040464af96cae7" + "time": "2023-04-10T20:10:41+00:00", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "installation-source": "dist", + "autoload": { + "psr-4": { + "Psr\\Http\\Message\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "https://www.php-fig.org/" + } + ], + "description": "Common interfaces for PSR-7 HTTP message factories", + "keywords": [ + "factory", + "http", + "message", + "psr", + "psr-17", + "psr-7", + "request", + "response" + ], + "install-path": "../psr/http-factory" }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/var-exporter/zipball/abb0a151b62d6b07e816487e20040464af96cae7", - "reference": "abb0a151b62d6b07e816487e20040464af96cae7", - "shasum": "" - }, - "require": { - "php": ">=7.2.5", - "symfony/polyfill-php80": "^1.16" - }, - "require-dev": { - "symfony/var-dumper": "^4.4.9|^5.0.9|^6.0" - }, - "time": "2024-01-23T13:51:25+00:00", - "type": "library", - "installation-source": "dist", - "autoload": { - "psr-4": { - "Symfony\\Component\\VarExporter\\": "" + { + "name": "psr/http-message", + "version": "2.0", + "version_normalized": "2.0.0.0", + "source": { + "type": "git", + "url": "https://github.com/php-fig/http-message.git", + "reference": "402d35bcb92c70c026d1a6a9883f06b2ead23d71" }, - "exclude-from-classmap": [ - "/Tests/" - ] + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/http-message/zipball/402d35bcb92c70c026d1a6a9883f06b2ead23d71", + "reference": "402d35bcb92c70c026d1a6a9883f06b2ead23d71", + "shasum": "" + }, + "require": { + "php": "^7.2 || ^8.0" + }, + "time": "2023-04-04T09:54:51+00:00", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0.x-dev" + } + }, + "installation-source": "dist", + "autoload": { + "psr-4": { + "Psr\\Http\\Message\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "https://www.php-fig.org/" + } + ], + "description": "Common interface for HTTP messages", + "homepage": "https://github.com/php-fig/http-message", + "keywords": [ + "http", + "http-message", + "psr", + "psr-7", + "request", + "response" + ], + "install-path": "../psr/http-message" }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Nicolas Grekas", - "email": "p@tchwork.com" + { + "name": "psr/http-server-handler", + "version": "1.0.2", + "version_normalized": "1.0.2.0", + "source": { + "type": "git", + "url": "https://github.com/php-fig/http-server-handler.git", + "reference": "84c4fb66179be4caaf8e97bd239203245302e7d4" }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Allows exporting any serializable PHP data structure to plain PHP code", - "homepage": "https://symfony.com", - "keywords": [ - "clone", - "construct", - "export", - "hydrate", - "instantiate", - "serialize" - ], - "funding": [ - { - "url": "https://symfony.com/sponsor", - "type": "custom" + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/http-server-handler/zipball/84c4fb66179be4caaf8e97bd239203245302e7d4", + "reference": "84c4fb66179be4caaf8e97bd239203245302e7d4", + "shasum": "" }, - { - "url": "https://github.com/fabpot", - "type": "github" + "require": { + "php": ">=7.0", + "psr/http-message": "^1.0 || ^2.0" }, - { - "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", - "type": "tidelift" - } - ] - } -] + "time": "2023-04-10T20:06:20+00:00", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "installation-source": "dist", + "autoload": { + "psr-4": { + "Psr\\Http\\Server\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "https://www.php-fig.org/" + } + ], + "description": "Common interface for HTTP server-side request handler", + "keywords": [ + "handler", + "http", + "http-interop", + "psr", + "psr-15", + "psr-7", + "request", + "response", + "server" + ], + "install-path": "../psr/http-server-handler" + }, + { + "name": "psr/http-server-middleware", + "version": "1.0.2", + "version_normalized": "1.0.2.0", + "source": { + "type": "git", + "url": "https://github.com/php-fig/http-server-middleware.git", + "reference": "c1481f747daaa6a0782775cd6a8c26a1bf4a3829" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/http-server-middleware/zipball/c1481f747daaa6a0782775cd6a8c26a1bf4a3829", + "reference": "c1481f747daaa6a0782775cd6a8c26a1bf4a3829", + "shasum": "" + }, + "require": { + "php": ">=7.0", + "psr/http-message": "^1.0 || ^2.0", + "psr/http-server-handler": "^1.0" + }, + "time": "2023-04-11T06:14:47+00:00", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "installation-source": "dist", + "autoload": { + "psr-4": { + "Psr\\Http\\Server\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "https://www.php-fig.org/" + } + ], + "description": "Common interface for HTTP server-side middleware", + "keywords": [ + "http", + "http-interop", + "middleware", + "psr", + "psr-15", + "psr-7", + "request", + "response" + ], + "install-path": "../psr/http-server-middleware" + }, + { + "name": "psr/log", + "version": "1.1.4", + "version_normalized": "1.1.4.0", + "source": { + "type": "git", + "url": "https://github.com/php-fig/log.git", + "reference": "d49695b909c3b7628b6289db5479a1c204601f11" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/log/zipball/d49695b909c3b7628b6289db5479a1c204601f11", + "reference": "d49695b909c3b7628b6289db5479a1c204601f11", + "shasum": "" + }, + "require": { + "php": ">=5.3.0" + }, + "time": "2021-05-03T11:20:27+00:00", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.1.x-dev" + } + }, + "installation-source": "dist", + "autoload": { + "psr-4": { + "Psr\\Log\\": "Psr/Log/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "https://www.php-fig.org/" + } + ], + "description": "Common interface for logging libraries", + "homepage": "https://github.com/php-fig/log", + "keywords": [ + "log", + "psr", + "psr-3" + ], + "install-path": "../psr/log" + }, + { + "name": "slim/slim", + "version": "4.13.0", + "version_normalized": "4.13.0.0", + "source": { + "type": "git", + "url": "https://github.com/slimphp/Slim.git", + "reference": "038fd5713d5a41636fdff0e8dcceedecdd17fc17" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/slimphp/Slim/zipball/038fd5713d5a41636fdff0e8dcceedecdd17fc17", + "reference": "038fd5713d5a41636fdff0e8dcceedecdd17fc17", + "shasum": "" + }, + "require": { + "ext-json": "*", + "nikic/fast-route": "^1.3", + "php": "^7.4 || ^8.0", + "psr/container": "^1.0 || ^2.0", + "psr/http-factory": "^1.0", + "psr/http-message": "^1.1 || ^2.0", + "psr/http-server-handler": "^1.0", + "psr/http-server-middleware": "^1.0", + "psr/log": "^1.1 || ^2.0 || ^3.0" + }, + "require-dev": { + "adriansuter/php-autoload-override": "^1.4", + "ext-simplexml": "*", + "guzzlehttp/psr7": "^2.6", + "httpsoft/http-message": "^1.1", + "httpsoft/http-server-request": "^1.1", + "laminas/laminas-diactoros": "^2.17 || ^3", + "nyholm/psr7": "^1.8", + "nyholm/psr7-server": "^1.1", + "phpspec/prophecy": "^1.19", + "phpspec/prophecy-phpunit": "^2.1", + "phpstan/phpstan": "^1.10", + "phpunit/phpunit": "^9.6", + "slim/http": "^1.3", + "slim/psr7": "^1.6", + "squizlabs/php_codesniffer": "^3.9" + }, + "suggest": { + "ext-simplexml": "Needed to support XML format in BodyParsingMiddleware", + "ext-xml": "Needed to support XML format in BodyParsingMiddleware", + "php-di/php-di": "PHP-DI is the recommended container library to be used with Slim", + "slim/psr7": "Slim PSR-7 implementation. See https://www.slimframework.com/docs/v4/start/installation.html for more information." + }, + "time": "2024-03-03T21:25:30+00:00", + "type": "library", + "installation-source": "dist", + "autoload": { + "psr-4": { + "Slim\\": "Slim" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Josh Lockhart", + "email": "hello@joshlockhart.com", + "homepage": "https://joshlockhart.com" + }, + { + "name": "Andrew Smith", + "email": "a.smith@silentworks.co.uk", + "homepage": "http://silentworks.co.uk" + }, + { + "name": "Rob Allen", + "email": "rob@akrabat.com", + "homepage": "http://akrabat.com" + }, + { + "name": "Pierre Berube", + "email": "pierre@lgse.com", + "homepage": "http://www.lgse.com" + }, + { + "name": "Gabriel Manricks", + "email": "gmanricks@me.com", + "homepage": "http://gabrielmanricks.com" + } + ], + "description": "Slim is a PHP micro framework that helps you quickly write simple yet powerful web applications and APIs", + "homepage": "https://www.slimframework.com", + "keywords": [ + "api", + "framework", + "micro", + "router" + ], + "funding": [ + { + "url": "https://opencollective.com/slimphp", + "type": "open_collective" + }, + { + "url": "https://tidelift.com/funding/github/packagist/slim/slim", + "type": "tidelift" + } + ], + "install-path": "../slim/slim" + }, + { + "name": "symfony/cache", + "version": "v4.4.48", + "version_normalized": "4.4.48.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/cache.git", + "reference": "3b98ed664887ad197b8ede3da2432787212eb915" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/cache/zipball/3b98ed664887ad197b8ede3da2432787212eb915", + "reference": "3b98ed664887ad197b8ede3da2432787212eb915", + "shasum": "" + }, + "require": { + "php": ">=7.1.3", + "psr/cache": "^1.0|^2.0", + "psr/log": "^1|^2|^3", + "symfony/cache-contracts": "^1.1.7|^2", + "symfony/polyfill-php73": "^1.9", + "symfony/polyfill-php80": "^1.16", + "symfony/service-contracts": "^1.1|^2", + "symfony/var-exporter": "^4.2|^5.0" + }, + "conflict": { + "doctrine/dbal": "<2.7", + "symfony/dependency-injection": "<3.4", + "symfony/http-kernel": "<4.4|>=5.0", + "symfony/var-dumper": "<4.4" + }, + "provide": { + "psr/cache-implementation": "1.0|2.0", + "psr/simple-cache-implementation": "1.0|2.0", + "symfony/cache-implementation": "1.0|2.0" + }, + "require-dev": { + "cache/integration-tests": "dev-master", + "doctrine/cache": "^1.6|^2.0", + "doctrine/dbal": "^2.7|^3.0", + "predis/predis": "^1.1", + "psr/simple-cache": "^1.0|^2.0", + "symfony/config": "^4.2|^5.0", + "symfony/dependency-injection": "^3.4|^4.1|^5.0", + "symfony/filesystem": "^4.4|^5.0", + "symfony/http-kernel": "^4.4", + "symfony/var-dumper": "^4.4|^5.0" + }, + "time": "2022-10-17T20:21:54+00:00", + "type": "library", + "installation-source": "dist", + "autoload": { + "psr-4": { + "Symfony\\Component\\Cache\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Provides extended PSR-6, PSR-16 (and tags) implementations", + "homepage": "https://symfony.com", + "keywords": [ + "caching", + "psr6" + ], + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "install-path": "../symfony/cache" + }, + { + "name": "symfony/cache-contracts", + "version": "v2.5.2", + "version_normalized": "2.5.2.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/cache-contracts.git", + "reference": "64be4a7acb83b6f2bf6de9a02cee6dad41277ebc" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/cache-contracts/zipball/64be4a7acb83b6f2bf6de9a02cee6dad41277ebc", + "reference": "64be4a7acb83b6f2bf6de9a02cee6dad41277ebc", + "shasum": "" + }, + "require": { + "php": ">=7.2.5", + "psr/cache": "^1.0|^2.0|^3.0" + }, + "suggest": { + "symfony/cache-implementation": "" + }, + "time": "2022-01-02T09:53:40+00:00", + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "2.5-dev" + }, + "thanks": { + "name": "symfony/contracts", + "url": "https://github.com/symfony/contracts" + } + }, + "installation-source": "dist", + "autoload": { + "psr-4": { + "Symfony\\Contracts\\Cache\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Generic abstractions related to caching", + "homepage": "https://symfony.com", + "keywords": [ + "abstractions", + "contracts", + "decoupling", + "interfaces", + "interoperability", + "standards" + ], + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "install-path": "../symfony/cache-contracts" + }, + { + "name": "symfony/deprecation-contracts", + "version": "v2.5.2", + "version_normalized": "2.5.2.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/deprecation-contracts.git", + "reference": "e8b495ea28c1d97b5e0c121748d6f9b53d075c66" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/e8b495ea28c1d97b5e0c121748d6f9b53d075c66", + "reference": "e8b495ea28c1d97b5e0c121748d6f9b53d075c66", + "shasum": "" + }, + "require": { + "php": ">=7.1" + }, + "time": "2022-01-02T09:53:40+00:00", + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "2.5-dev" + }, + "thanks": { + "name": "symfony/contracts", + "url": "https://github.com/symfony/contracts" + } + }, + "installation-source": "dist", + "autoload": { + "files": [ + "function.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "A generic function and convention to trigger deprecation notices", + "homepage": "https://symfony.com", + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "install-path": "../symfony/deprecation-contracts" + }, + { + "name": "symfony/expression-language", + "version": "v3.4.47", + "version_normalized": "3.4.47.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/expression-language.git", + "reference": "de38e66398fca1fcb9c48e80279910e6889cb28f" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/expression-language/zipball/de38e66398fca1fcb9c48e80279910e6889cb28f", + "reference": "de38e66398fca1fcb9c48e80279910e6889cb28f", + "shasum": "" + }, + "require": { + "php": "^5.5.9|>=7.0.8", + "symfony/cache": "~3.1|~4.0", + "symfony/polyfill-php70": "~1.6" + }, + "time": "2020-10-24T10:57:07+00:00", + "type": "library", + "installation-source": "dist", + "autoload": { + "psr-4": { + "Symfony\\Component\\ExpressionLanguage\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony ExpressionLanguage Component", + "homepage": "https://symfony.com", + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "install-path": "../symfony/expression-language" + }, + { + "name": "symfony/polyfill-php70", + "version": "v1.20.0", + "version_normalized": "1.20.0.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-php70.git", + "reference": "5f03a781d984aae42cebd18e7912fa80f02ee644" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-php70/zipball/5f03a781d984aae42cebd18e7912fa80f02ee644", + "reference": "5f03a781d984aae42cebd18e7912fa80f02ee644", + "shasum": "" + }, + "require": { + "php": ">=7.1" + }, + "time": "2020-10-23T14:02:19+00:00", + "type": "metapackage", + "extra": { + "branch-alias": { + "dev-main": "1.20-dev" + }, + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill backporting some PHP 7.0+ features to lower PHP versions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "polyfill", + "portable", + "shim" + ], + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "install-path": null + }, + { + "name": "symfony/polyfill-php73", + "version": "v1.29.0", + "version_normalized": "1.29.0.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-php73.git", + "reference": "21bd091060673a1177ae842c0ef8fe30893114d2" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-php73/zipball/21bd091060673a1177ae842c0ef8fe30893114d2", + "reference": "21bd091060673a1177ae842c0ef8fe30893114d2", + "shasum": "" + }, + "require": { + "php": ">=7.1" + }, + "time": "2024-01-29T20:11:03+00:00", + "type": "library", + "extra": { + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" + } + }, + "installation-source": "dist", + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Php73\\": "" + }, + "classmap": [ + "Resources/stubs" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill backporting some PHP 7.3+ features to lower PHP versions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "polyfill", + "portable", + "shim" + ], + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "install-path": "../symfony/polyfill-php73" + }, + { + "name": "symfony/polyfill-php80", + "version": "v1.29.0", + "version_normalized": "1.29.0.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-php80.git", + "reference": "87b68208d5c1188808dd7839ee1e6c8ec3b02f1b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/87b68208d5c1188808dd7839ee1e6c8ec3b02f1b", + "reference": "87b68208d5c1188808dd7839ee1e6c8ec3b02f1b", + "shasum": "" + }, + "require": { + "php": ">=7.1" + }, + "time": "2024-01-29T20:11:03+00:00", + "type": "library", + "extra": { + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" + } + }, + "installation-source": "dist", + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Php80\\": "" + }, + "classmap": [ + "Resources/stubs" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "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" + } + ], + "description": "Symfony polyfill backporting some PHP 8.0+ features to lower PHP versions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "polyfill", + "portable", + "shim" + ], + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "install-path": "../symfony/polyfill-php80" + }, + { + "name": "symfony/service-contracts", + "version": "v2.5.2", + "version_normalized": "2.5.2.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/service-contracts.git", + "reference": "4b426aac47d6427cc1a1d0f7e2ac724627f5966c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/service-contracts/zipball/4b426aac47d6427cc1a1d0f7e2ac724627f5966c", + "reference": "4b426aac47d6427cc1a1d0f7e2ac724627f5966c", + "shasum": "" + }, + "require": { + "php": ">=7.2.5", + "psr/container": "^1.1", + "symfony/deprecation-contracts": "^2.1|^3" + }, + "conflict": { + "ext-psr": "<1.1|>=2" + }, + "suggest": { + "symfony/service-implementation": "" + }, + "time": "2022-05-30T19:17:29+00:00", + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "2.5-dev" + }, + "thanks": { + "name": "symfony/contracts", + "url": "https://github.com/symfony/contracts" + } + }, + "installation-source": "dist", + "autoload": { + "psr-4": { + "Symfony\\Contracts\\Service\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Generic abstractions related to writing services", + "homepage": "https://symfony.com", + "keywords": [ + "abstractions", + "contracts", + "decoupling", + "interfaces", + "interoperability", + "standards" + ], + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "install-path": "../symfony/service-contracts" + }, + { + "name": "symfony/var-exporter", + "version": "v5.4.35", + "version_normalized": "5.4.35.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/var-exporter.git", + "reference": "abb0a151b62d6b07e816487e20040464af96cae7" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/var-exporter/zipball/abb0a151b62d6b07e816487e20040464af96cae7", + "reference": "abb0a151b62d6b07e816487e20040464af96cae7", + "shasum": "" + }, + "require": { + "php": ">=7.2.5", + "symfony/polyfill-php80": "^1.16" + }, + "require-dev": { + "symfony/var-dumper": "^4.4.9|^5.0.9|^6.0" + }, + "time": "2024-01-23T13:51:25+00:00", + "type": "library", + "installation-source": "dist", + "autoload": { + "psr-4": { + "Symfony\\Component\\VarExporter\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Allows exporting any serializable PHP data structure to plain PHP code", + "homepage": "https://symfony.com", + "keywords": [ + "clone", + "construct", + "export", + "hydrate", + "instantiate", + "serialize" + ], + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "install-path": "../symfony/var-exporter" + } + ], + "dev": false, + "dev-package-names": [] +} diff --git a/advancedcontentfilter/vendor/composer/installed.php b/advancedcontentfilter/vendor/composer/installed.php new file mode 100644 index 00000000..010b1da9 --- /dev/null +++ b/advancedcontentfilter/vendor/composer/installed.php @@ -0,0 +1,203 @@ + array( + 'name' => 'friendica-addons/advancedcontentfilter', + 'pretty_version' => 'dev-develop', + 'version' => 'dev-develop', + 'reference' => 'feb7722f723b21e76fdf20a7ce4b42fa5ffcdcb9', + 'type' => 'friendica-addon', + 'install_path' => __DIR__ . '/../../', + 'aliases' => array(), + 'dev' => false, + ), + 'versions' => array( + 'friendica-addons/advancedcontentfilter' => array( + 'pretty_version' => 'dev-develop', + 'version' => 'dev-develop', + 'reference' => 'feb7722f723b21e76fdf20a7ce4b42fa5ffcdcb9', + 'type' => 'friendica-addon', + 'install_path' => __DIR__ . '/../../', + 'aliases' => array(), + 'dev_requirement' => false, + ), + 'nikic/fast-route' => array( + 'pretty_version' => 'v1.3.0', + 'version' => '1.3.0.0', + 'reference' => '181d480e08d9476e61381e04a71b34dc0432e812', + 'type' => 'library', + 'install_path' => __DIR__ . '/../nikic/fast-route', + 'aliases' => array(), + 'dev_requirement' => false, + ), + 'psr/cache' => array( + 'pretty_version' => '1.0.1', + 'version' => '1.0.1.0', + 'reference' => 'd11b50ad223250cf17b86e38383413f5a6764bf8', + 'type' => 'library', + 'install_path' => __DIR__ . '/../psr/cache', + 'aliases' => array(), + 'dev_requirement' => false, + ), + 'psr/cache-implementation' => array( + 'dev_requirement' => false, + 'provided' => array( + 0 => '1.0|2.0', + ), + ), + 'psr/container' => array( + 'pretty_version' => '1.1.2', + 'version' => '1.1.2.0', + 'reference' => '513e0666f7216c7459170d56df27dfcefe1689ea', + 'type' => 'library', + 'install_path' => __DIR__ . '/../psr/container', + 'aliases' => array(), + 'dev_requirement' => false, + ), + 'psr/http-factory' => array( + 'pretty_version' => '1.0.2', + 'version' => '1.0.2.0', + 'reference' => 'e616d01114759c4c489f93b099585439f795fe35', + 'type' => 'library', + 'install_path' => __DIR__ . '/../psr/http-factory', + 'aliases' => array(), + 'dev_requirement' => false, + ), + 'psr/http-message' => array( + 'pretty_version' => '2.0', + 'version' => '2.0.0.0', + 'reference' => '402d35bcb92c70c026d1a6a9883f06b2ead23d71', + 'type' => 'library', + 'install_path' => __DIR__ . '/../psr/http-message', + 'aliases' => array(), + 'dev_requirement' => false, + ), + 'psr/http-server-handler' => array( + 'pretty_version' => '1.0.2', + 'version' => '1.0.2.0', + 'reference' => '84c4fb66179be4caaf8e97bd239203245302e7d4', + 'type' => 'library', + 'install_path' => __DIR__ . '/../psr/http-server-handler', + 'aliases' => array(), + 'dev_requirement' => false, + ), + 'psr/http-server-middleware' => array( + 'pretty_version' => '1.0.2', + 'version' => '1.0.2.0', + 'reference' => 'c1481f747daaa6a0782775cd6a8c26a1bf4a3829', + 'type' => 'library', + 'install_path' => __DIR__ . '/../psr/http-server-middleware', + 'aliases' => array(), + 'dev_requirement' => false, + ), + 'psr/log' => array( + 'pretty_version' => '1.1.4', + 'version' => '1.1.4.0', + 'reference' => 'd49695b909c3b7628b6289db5479a1c204601f11', + 'type' => 'library', + 'install_path' => __DIR__ . '/../psr/log', + 'aliases' => array(), + 'dev_requirement' => false, + ), + 'psr/simple-cache-implementation' => array( + 'dev_requirement' => false, + 'provided' => array( + 0 => '1.0|2.0', + ), + ), + 'slim/slim' => array( + 'pretty_version' => '4.13.0', + 'version' => '4.13.0.0', + 'reference' => '038fd5713d5a41636fdff0e8dcceedecdd17fc17', + 'type' => 'library', + 'install_path' => __DIR__ . '/../slim/slim', + 'aliases' => array(), + 'dev_requirement' => false, + ), + 'symfony/cache' => array( + 'pretty_version' => 'v4.4.48', + 'version' => '4.4.48.0', + 'reference' => '3b98ed664887ad197b8ede3da2432787212eb915', + 'type' => 'library', + 'install_path' => __DIR__ . '/../symfony/cache', + 'aliases' => array(), + 'dev_requirement' => false, + ), + 'symfony/cache-contracts' => array( + 'pretty_version' => 'v2.5.2', + 'version' => '2.5.2.0', + 'reference' => '64be4a7acb83b6f2bf6de9a02cee6dad41277ebc', + 'type' => 'library', + 'install_path' => __DIR__ . '/../symfony/cache-contracts', + 'aliases' => array(), + 'dev_requirement' => false, + ), + 'symfony/cache-implementation' => array( + 'dev_requirement' => false, + 'provided' => array( + 0 => '1.0|2.0', + ), + ), + 'symfony/deprecation-contracts' => array( + 'pretty_version' => 'v2.5.2', + 'version' => '2.5.2.0', + 'reference' => 'e8b495ea28c1d97b5e0c121748d6f9b53d075c66', + 'type' => 'library', + 'install_path' => __DIR__ . '/../symfony/deprecation-contracts', + 'aliases' => array(), + 'dev_requirement' => false, + ), + 'symfony/expression-language' => array( + 'pretty_version' => 'v3.4.47', + 'version' => '3.4.47.0', + 'reference' => 'de38e66398fca1fcb9c48e80279910e6889cb28f', + 'type' => 'library', + 'install_path' => __DIR__ . '/../symfony/expression-language', + 'aliases' => array(), + 'dev_requirement' => false, + ), + 'symfony/polyfill-php70' => array( + 'pretty_version' => 'v1.20.0', + 'version' => '1.20.0.0', + 'reference' => '5f03a781d984aae42cebd18e7912fa80f02ee644', + 'type' => 'metapackage', + 'install_path' => null, + 'aliases' => array(), + 'dev_requirement' => false, + ), + 'symfony/polyfill-php73' => array( + 'pretty_version' => 'v1.29.0', + 'version' => '1.29.0.0', + 'reference' => '21bd091060673a1177ae842c0ef8fe30893114d2', + 'type' => 'library', + 'install_path' => __DIR__ . '/../symfony/polyfill-php73', + 'aliases' => array(), + 'dev_requirement' => false, + ), + 'symfony/polyfill-php80' => array( + 'pretty_version' => 'v1.29.0', + 'version' => '1.29.0.0', + 'reference' => '87b68208d5c1188808dd7839ee1e6c8ec3b02f1b', + 'type' => 'library', + 'install_path' => __DIR__ . '/../symfony/polyfill-php80', + 'aliases' => array(), + 'dev_requirement' => false, + ), + 'symfony/service-contracts' => array( + 'pretty_version' => 'v2.5.2', + 'version' => '2.5.2.0', + 'reference' => '4b426aac47d6427cc1a1d0f7e2ac724627f5966c', + 'type' => 'library', + 'install_path' => __DIR__ . '/../symfony/service-contracts', + 'aliases' => array(), + 'dev_requirement' => false, + ), + 'symfony/var-exporter' => array( + 'pretty_version' => 'v5.4.35', + 'version' => '5.4.35.0', + 'reference' => 'abb0a151b62d6b07e816487e20040464af96cae7', + 'type' => 'library', + 'install_path' => __DIR__ . '/../symfony/var-exporter', + 'aliases' => array(), + 'dev_requirement' => false, + ), + ), +); diff --git a/advancedcontentfilter/vendor/composer/platform_check.php b/advancedcontentfilter/vendor/composer/platform_check.php new file mode 100644 index 00000000..580fa960 --- /dev/null +++ b/advancedcontentfilter/vendor/composer/platform_check.php @@ -0,0 +1,26 @@ += 70400)) { + $issues[] = 'Your Composer dependencies require a PHP version ">= 7.4.0". You are running ' . PHP_VERSION . '.'; +} + +if ($issues) { + if (!headers_sent()) { + header('HTTP/1.1 500 Internal Server Error'); + } + if (!ini_get('display_errors')) { + if (PHP_SAPI === 'cli' || PHP_SAPI === 'phpdbg') { + fwrite(STDERR, 'Composer detected issues in your platform:' . PHP_EOL.PHP_EOL . implode(PHP_EOL, $issues) . PHP_EOL.PHP_EOL); + } elseif (!headers_sent()) { + echo 'Composer detected issues in your platform:' . PHP_EOL.PHP_EOL . str_replace('You are running '.PHP_VERSION.'.', '', implode(PHP_EOL, $issues)) . PHP_EOL.PHP_EOL; + } + } + trigger_error( + 'Composer detected issues in your platform: ' . implode(' ', $issues), + E_USER_ERROR + ); +} diff --git a/advancedcontentfilter/vendor/psr/simple-cache/.editorconfig b/advancedcontentfilter/vendor/psr/simple-cache/.editorconfig deleted file mode 100644 index 48542cbb..00000000 --- a/advancedcontentfilter/vendor/psr/simple-cache/.editorconfig +++ /dev/null @@ -1,12 +0,0 @@ -; This file is for unifying the coding style for different editors and IDEs. -; More information at http://editorconfig.org - -root = true - -[*] -charset = utf-8 -indent_size = 4 -indent_style = space -end_of_line = lf -insert_final_newline = true -trim_trailing_whitespace = true diff --git a/advancedcontentfilter/vendor/psr/simple-cache/LICENSE.md b/advancedcontentfilter/vendor/psr/simple-cache/LICENSE.md deleted file mode 100644 index e49a7c85..00000000 --- a/advancedcontentfilter/vendor/psr/simple-cache/LICENSE.md +++ /dev/null @@ -1,21 +0,0 @@ -# The MIT License (MIT) - -Copyright (c) 2016 PHP Framework Interoperability Group - -> 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/advancedcontentfilter/vendor/psr/simple-cache/README.md b/advancedcontentfilter/vendor/psr/simple-cache/README.md deleted file mode 100644 index 43641d17..00000000 --- a/advancedcontentfilter/vendor/psr/simple-cache/README.md +++ /dev/null @@ -1,8 +0,0 @@ -PHP FIG Simple Cache PSR -======================== - -This repository holds all interfaces related to PSR-16. - -Note that this is not a cache implementation of its own. It is merely an interface that describes a cache implementation. See [the specification](https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-16-simple-cache.md) for more details. - -You can find implementations of the specification by looking for packages providing the [psr/simple-cache-implementation](https://packagist.org/providers/psr/simple-cache-implementation) virtual package. diff --git a/advancedcontentfilter/vendor/psr/simple-cache/composer.json b/advancedcontentfilter/vendor/psr/simple-cache/composer.json deleted file mode 100644 index 2978fa55..00000000 --- a/advancedcontentfilter/vendor/psr/simple-cache/composer.json +++ /dev/null @@ -1,25 +0,0 @@ -{ - "name": "psr/simple-cache", - "description": "Common interfaces for simple caching", - "keywords": ["psr", "psr-16", "cache", "simple-cache", "caching"], - "license": "MIT", - "authors": [ - { - "name": "PHP-FIG", - "homepage": "http://www.php-fig.org/" - } - ], - "require": { - "php": ">=5.3.0" - }, - "autoload": { - "psr-4": { - "Psr\\SimpleCache\\": "src/" - } - }, - "extra": { - "branch-alias": { - "dev-master": "1.0.x-dev" - } - } -} diff --git a/advancedcontentfilter/vendor/psr/simple-cache/src/CacheException.php b/advancedcontentfilter/vendor/psr/simple-cache/src/CacheException.php deleted file mode 100644 index eba53815..00000000 --- a/advancedcontentfilter/vendor/psr/simple-cache/src/CacheException.php +++ /dev/null @@ -1,10 +0,0 @@ - value pairs. Cache keys that do not exist or are stale will have $default as value. - * - * @throws \Psr\SimpleCache\InvalidArgumentException - * MUST be thrown if $keys is neither an array nor a Traversable, - * or if any of the $keys are not a legal value. - */ - public function getMultiple($keys, $default = null); - - /** - * Persists a set of key => value pairs in the cache, with an optional TTL. - * - * @param iterable $values A list of key => value pairs for a multiple-set operation. - * @param null|int|\DateInterval $ttl Optional. The TTL value of this item. If no value is sent and - * the driver supports TTL then the library may set a default value - * for it or let the driver take care of that. - * - * @return bool True on success and false on failure. - * - * @throws \Psr\SimpleCache\InvalidArgumentException - * MUST be thrown if $values is neither an array nor a Traversable, - * or if any of the $values are not a legal value. - */ - public function setMultiple($values, $ttl = null); - - /** - * Deletes multiple cache items in a single operation. - * - * @param iterable $keys A list of string-based keys to be deleted. - * - * @return bool True if the items were successfully removed. False if there was an error. - * - * @throws \Psr\SimpleCache\InvalidArgumentException - * MUST be thrown if $keys is neither an array nor a Traversable, - * or if any of the $keys are not a legal value. - */ - public function deleteMultiple($keys); - - /** - * Determines whether an item is present in the cache. - * - * NOTE: It is recommended that has() is only to be used for cache warming type purposes - * and not to be used within your live applications operations for get/set, as this method - * is subject to a race condition where your has() will return true and immediately after, - * another script can remove it making the state of your app out of date. - * - * @param string $key The cache item key. - * - * @return bool - * - * @throws \Psr\SimpleCache\InvalidArgumentException - * MUST be thrown if the $key string is not a legal value. - */ - public function has($key); -} diff --git a/advancedcontentfilter/vendor/psr/simple-cache/src/InvalidArgumentException.php b/advancedcontentfilter/vendor/psr/simple-cache/src/InvalidArgumentException.php deleted file mode 100644 index 6a9524a2..00000000 --- a/advancedcontentfilter/vendor/psr/simple-cache/src/InvalidArgumentException.php +++ /dev/null @@ -1,13 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Cache\Tests\Adapter; - -use Symfony\Component\Cache\Adapter\RedisAdapter; - -abstract class AbstractRedisAdapterTest extends AdapterTestCase -{ - protected $skippedTests = [ - 'testExpiration' => 'Testing expiration slows down the test suite', - 'testHasItemReturnsFalseWhenDeferredItemIsExpired' => 'Testing expiration slows down the test suite', - 'testDefaultLifeTime' => 'Testing expiration slows down the test suite', - ]; - - protected static $redis; - - public function createCachePool($defaultLifetime = 0) - { - return new RedisAdapter(self::$redis, str_replace('\\', '.', __CLASS__), $defaultLifetime); - } - - public static function setUpBeforeClass() - { - if (!\extension_loaded('redis')) { - self::markTestSkipped('Extension redis required.'); - } - try { - (new \Redis())->connect(getenv('REDIS_HOST')); - } catch (\Exception $e) { - self::markTestSkipped($e->getMessage()); - } - } - - public static function tearDownAfterClass() - { - self::$redis = null; - } -} diff --git a/advancedcontentfilter/vendor/symfony/cache/Tests/Adapter/AdapterTestCase.php b/advancedcontentfilter/vendor/symfony/cache/Tests/Adapter/AdapterTestCase.php deleted file mode 100644 index 5758a286..00000000 --- a/advancedcontentfilter/vendor/symfony/cache/Tests/Adapter/AdapterTestCase.php +++ /dev/null @@ -1,175 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Cache\Tests\Adapter; - -use Cache\IntegrationTests\CachePoolTest; -use Psr\Cache\CacheItemPoolInterface; -use Symfony\Component\Cache\PruneableInterface; - -abstract class AdapterTestCase extends CachePoolTest -{ - protected function setUp() - { - parent::setUp(); - - if (!\array_key_exists('testDeferredSaveWithoutCommit', $this->skippedTests) && \defined('HHVM_VERSION')) { - $this->skippedTests['testDeferredSaveWithoutCommit'] = 'Destructors are called late on HHVM.'; - } - - if (!\array_key_exists('testPrune', $this->skippedTests) && !$this->createCachePool() instanceof PruneableInterface) { - $this->skippedTests['testPrune'] = 'Not a pruneable cache pool.'; - } - } - - public function testDefaultLifeTime() - { - if (isset($this->skippedTests[__FUNCTION__])) { - $this->markTestSkipped($this->skippedTests[__FUNCTION__]); - } - - $cache = $this->createCachePool(2); - - $item = $cache->getItem('key.dlt'); - $item->set('value'); - $cache->save($item); - sleep(1); - - $item = $cache->getItem('key.dlt'); - $this->assertTrue($item->isHit()); - - sleep(2); - $item = $cache->getItem('key.dlt'); - $this->assertFalse($item->isHit()); - } - - public function testExpiration() - { - if (isset($this->skippedTests[__FUNCTION__])) { - $this->markTestSkipped($this->skippedTests[__FUNCTION__]); - } - - $cache = $this->createCachePool(); - $cache->save($cache->getItem('k1')->set('v1')->expiresAfter(2)); - $cache->save($cache->getItem('k2')->set('v2')->expiresAfter(366 * 86400)); - - sleep(3); - $item = $cache->getItem('k1'); - $this->assertFalse($item->isHit()); - $this->assertNull($item->get(), "Item's value must be null when isHit() is false."); - - $item = $cache->getItem('k2'); - $this->assertTrue($item->isHit()); - $this->assertSame('v2', $item->get()); - } - - public function testNotUnserializable() - { - if (isset($this->skippedTests[__FUNCTION__])) { - $this->markTestSkipped($this->skippedTests[__FUNCTION__]); - } - - $cache = $this->createCachePool(); - - $item = $cache->getItem('foo'); - $cache->save($item->set(new NotUnserializable())); - - $item = $cache->getItem('foo'); - $this->assertFalse($item->isHit()); - - foreach ($cache->getItems(['foo']) as $item) { - } - $cache->save($item->set(new NotUnserializable())); - - foreach ($cache->getItems(['foo']) as $item) { - } - $this->assertFalse($item->isHit()); - } - - public function testPrune() - { - if (isset($this->skippedTests[__FUNCTION__])) { - $this->markTestSkipped($this->skippedTests[__FUNCTION__]); - } - - if (!method_exists($this, 'isPruned')) { - $this->fail('Test classes for pruneable caches must implement `isPruned($cache, $name)` method.'); - } - - /** @var PruneableInterface|CacheItemPoolInterface $cache */ - $cache = $this->createCachePool(); - - $doSet = function ($name, $value, \DateInterval $expiresAfter = null) use ($cache) { - $item = $cache->getItem($name); - $item->set($value); - - if ($expiresAfter) { - $item->expiresAfter($expiresAfter); - } - - $cache->save($item); - }; - - $doSet('foo', 'foo-val', new \DateInterval('PT05S')); - $doSet('bar', 'bar-val', new \DateInterval('PT10S')); - $doSet('baz', 'baz-val', new \DateInterval('PT15S')); - $doSet('qux', 'qux-val', new \DateInterval('PT20S')); - - sleep(30); - $cache->prune(); - $this->assertTrue($this->isPruned($cache, 'foo')); - $this->assertTrue($this->isPruned($cache, 'bar')); - $this->assertTrue($this->isPruned($cache, 'baz')); - $this->assertTrue($this->isPruned($cache, 'qux')); - - $doSet('foo', 'foo-val'); - $doSet('bar', 'bar-val', new \DateInterval('PT20S')); - $doSet('baz', 'baz-val', new \DateInterval('PT40S')); - $doSet('qux', 'qux-val', new \DateInterval('PT80S')); - - $cache->prune(); - $this->assertFalse($this->isPruned($cache, 'foo')); - $this->assertFalse($this->isPruned($cache, 'bar')); - $this->assertFalse($this->isPruned($cache, 'baz')); - $this->assertFalse($this->isPruned($cache, 'qux')); - - sleep(30); - $cache->prune(); - $this->assertFalse($this->isPruned($cache, 'foo')); - $this->assertTrue($this->isPruned($cache, 'bar')); - $this->assertFalse($this->isPruned($cache, 'baz')); - $this->assertFalse($this->isPruned($cache, 'qux')); - - sleep(30); - $cache->prune(); - $this->assertFalse($this->isPruned($cache, 'foo')); - $this->assertTrue($this->isPruned($cache, 'baz')); - $this->assertFalse($this->isPruned($cache, 'qux')); - - sleep(30); - $cache->prune(); - $this->assertFalse($this->isPruned($cache, 'foo')); - $this->assertTrue($this->isPruned($cache, 'qux')); - } -} - -class NotUnserializable implements \Serializable -{ - public function serialize() - { - return serialize(123); - } - - public function unserialize($ser) - { - throw new \Exception(__CLASS__); - } -} diff --git a/advancedcontentfilter/vendor/symfony/cache/Tests/Adapter/ApcuAdapterTest.php b/advancedcontentfilter/vendor/symfony/cache/Tests/Adapter/ApcuAdapterTest.php deleted file mode 100644 index f55a1b9b..00000000 --- a/advancedcontentfilter/vendor/symfony/cache/Tests/Adapter/ApcuAdapterTest.php +++ /dev/null @@ -1,124 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Cache\Tests\Adapter; - -use Psr\Log\NullLogger; -use Symfony\Component\Cache\Adapter\ApcuAdapter; - -class ApcuAdapterTest extends AdapterTestCase -{ - protected $skippedTests = [ - 'testExpiration' => 'Testing expiration slows down the test suite', - 'testHasItemReturnsFalseWhenDeferredItemIsExpired' => 'Testing expiration slows down the test suite', - 'testDefaultLifeTime' => 'Testing expiration slows down the test suite', - ]; - - public function createCachePool($defaultLifetime = 0) - { - if (!\function_exists('apcu_fetch') || !filter_var(ini_get('apc.enabled'), \FILTER_VALIDATE_BOOLEAN)) { - $this->markTestSkipped('APCu extension is required.'); - } - if ('cli' === \PHP_SAPI && !filter_var(ini_get('apc.enable_cli'), \FILTER_VALIDATE_BOOLEAN)) { - if ('testWithCliSapi' !== $this->getName()) { - $this->markTestSkipped('apc.enable_cli=1 is required.'); - } - } - if ('\\' === \DIRECTORY_SEPARATOR) { - $this->markTestSkipped('Fails transiently on Windows.'); - } - - return new ApcuAdapter(str_replace('\\', '.', __CLASS__), $defaultLifetime); - } - - public function testUnserializable() - { - $pool = $this->createCachePool(); - - $item = $pool->getItem('foo'); - $item->set(function () {}); - - $this->assertFalse($pool->save($item)); - - $item = $pool->getItem('foo'); - $this->assertFalse($item->isHit()); - } - - public function testVersion() - { - $namespace = str_replace('\\', '.', static::class); - - $pool1 = new ApcuAdapter($namespace, 0, 'p1'); - - $item = $pool1->getItem('foo'); - $this->assertFalse($item->isHit()); - $this->assertTrue($pool1->save($item->set('bar'))); - - $item = $pool1->getItem('foo'); - $this->assertTrue($item->isHit()); - $this->assertSame('bar', $item->get()); - - $pool2 = new ApcuAdapter($namespace, 0, 'p2'); - - $item = $pool2->getItem('foo'); - $this->assertFalse($item->isHit()); - $this->assertNull($item->get()); - - $item = $pool1->getItem('foo'); - $this->assertFalse($item->isHit()); - $this->assertNull($item->get()); - } - - public function testNamespace() - { - $namespace = str_replace('\\', '.', static::class); - - $pool1 = new ApcuAdapter($namespace.'_1', 0, 'p1'); - - $item = $pool1->getItem('foo'); - $this->assertFalse($item->isHit()); - $this->assertTrue($pool1->save($item->set('bar'))); - - $item = $pool1->getItem('foo'); - $this->assertTrue($item->isHit()); - $this->assertSame('bar', $item->get()); - - $pool2 = new ApcuAdapter($namespace.'_2', 0, 'p1'); - - $item = $pool2->getItem('foo'); - $this->assertFalse($item->isHit()); - $this->assertNull($item->get()); - - $item = $pool1->getItem('foo'); - $this->assertTrue($item->isHit()); - $this->assertSame('bar', $item->get()); - } - - public function testWithCliSapi() - { - try { - // disable PHPUnit error handler to mimic a production environment - $isCalled = false; - set_error_handler(function () use (&$isCalled) { - $isCalled = true; - }); - $pool = new ApcuAdapter(str_replace('\\', '.', __CLASS__)); - $pool->setLogger(new NullLogger()); - - $item = $pool->getItem('foo'); - $item->isHit(); - $pool->save($item->set('bar')); - $this->assertFalse($isCalled); - } finally { - restore_error_handler(); - } - } -} diff --git a/advancedcontentfilter/vendor/symfony/cache/Tests/Adapter/ArrayAdapterTest.php b/advancedcontentfilter/vendor/symfony/cache/Tests/Adapter/ArrayAdapterTest.php deleted file mode 100644 index e6adc9d0..00000000 --- a/advancedcontentfilter/vendor/symfony/cache/Tests/Adapter/ArrayAdapterTest.php +++ /dev/null @@ -1,56 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Cache\Tests\Adapter; - -use Symfony\Component\Cache\Adapter\ArrayAdapter; - -/** - * @group time-sensitive - */ -class ArrayAdapterTest extends AdapterTestCase -{ - protected $skippedTests = [ - 'testDeferredSaveWithoutCommit' => 'Assumes a shared cache which ArrayAdapter is not.', - 'testSaveWithoutExpire' => 'Assumes a shared cache which ArrayAdapter is not.', - ]; - - public function createCachePool($defaultLifetime = 0) - { - return new ArrayAdapter($defaultLifetime); - } - - public function testGetValuesHitAndMiss() - { - /** @var ArrayAdapter $cache */ - $cache = $this->createCachePool(); - - // Hit - $item = $cache->getItem('foo'); - $item->set('4711'); - $cache->save($item); - - $fooItem = $cache->getItem('foo'); - $this->assertTrue($fooItem->isHit()); - $this->assertEquals('4711', $fooItem->get()); - - // Miss (should be present as NULL in $values) - $cache->getItem('bar'); - - $values = $cache->getValues(); - - $this->assertCount(2, $values); - $this->assertArrayHasKey('foo', $values); - $this->assertSame(serialize('4711'), $values['foo']); - $this->assertArrayHasKey('bar', $values); - $this->assertNull($values['bar']); - } -} diff --git a/advancedcontentfilter/vendor/symfony/cache/Tests/Adapter/ChainAdapterTest.php b/advancedcontentfilter/vendor/symfony/cache/Tests/Adapter/ChainAdapterTest.php deleted file mode 100644 index be811d6f..00000000 --- a/advancedcontentfilter/vendor/symfony/cache/Tests/Adapter/ChainAdapterTest.php +++ /dev/null @@ -1,233 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Cache\Tests\Adapter; - -use PHPUnit\Framework\MockObject\MockObject; -use Symfony\Component\Cache\Adapter\AdapterInterface; -use Symfony\Component\Cache\Adapter\ArrayAdapter; -use Symfony\Component\Cache\Adapter\ChainAdapter; -use Symfony\Component\Cache\Adapter\FilesystemAdapter; -use Symfony\Component\Cache\PruneableInterface; -use Symfony\Component\Cache\Tests\Fixtures\ExternalAdapter; - -/** - * @author Kévin Dunglas - * @group time-sensitive - */ -class ChainAdapterTest extends AdapterTestCase -{ - public function createCachePool($defaultLifetime = 0) - { - return new ChainAdapter([new ArrayAdapter($defaultLifetime), new ExternalAdapter($defaultLifetime), new FilesystemAdapter('', $defaultLifetime)], $defaultLifetime); - } - - public function testEmptyAdaptersException() - { - $this->expectException('Symfony\Component\Cache\Exception\InvalidArgumentException'); - $this->expectExceptionMessage('At least one adapter must be specified.'); - new ChainAdapter([]); - } - - public function testInvalidAdapterException() - { - $this->expectException('Symfony\Component\Cache\Exception\InvalidArgumentException'); - $this->expectExceptionMessage('The class "stdClass" does not implement'); - new ChainAdapter([new \stdClass()]); - } - - public function testPrune() - { - if (isset($this->skippedTests[__FUNCTION__])) { - $this->markTestSkipped($this->skippedTests[__FUNCTION__]); - } - - $cache = new ChainAdapter([ - $this->getPruneableMock(), - $this->getNonPruneableMock(), - $this->getPruneableMock(), - ]); - $this->assertTrue($cache->prune()); - - $cache = new ChainAdapter([ - $this->getPruneableMock(), - $this->getFailingPruneableMock(), - $this->getPruneableMock(), - ]); - $this->assertFalse($cache->prune()); - } - - public function testMultipleCachesExpirationWhenCommonTtlIsNotSet() - { - if (isset($this->skippedTests[__FUNCTION__])) { - $this->markTestSkipped($this->skippedTests[__FUNCTION__]); - } - - $adapter1 = new ArrayAdapter(4); - $adapter2 = new ArrayAdapter(2); - - $cache = new ChainAdapter([$adapter1, $adapter2]); - - $cache->save($cache->getItem('key')->set('value')); - - $item = $adapter1->getItem('key'); - $this->assertTrue($item->isHit()); - $this->assertEquals('value', $item->get()); - - $item = $adapter2->getItem('key'); - $this->assertTrue($item->isHit()); - $this->assertEquals('value', $item->get()); - - sleep(2); - - $item = $adapter1->getItem('key'); - $this->assertTrue($item->isHit()); - $this->assertEquals('value', $item->get()); - - $item = $adapter2->getItem('key'); - $this->assertFalse($item->isHit()); - - sleep(2); - - $item = $adapter1->getItem('key'); - $this->assertFalse($item->isHit()); - - $adapter2->save($adapter2->getItem('key1')->set('value1')); - - $item = $cache->getItem('key1'); - $this->assertTrue($item->isHit()); - $this->assertEquals('value1', $item->get()); - - sleep(2); - - $item = $adapter1->getItem('key1'); - $this->assertTrue($item->isHit()); - $this->assertEquals('value1', $item->get()); - - $item = $adapter2->getItem('key1'); - $this->assertFalse($item->isHit()); - - sleep(2); - - $item = $adapter1->getItem('key1'); - $this->assertFalse($item->isHit()); - } - - public function testMultipleCachesExpirationWhenCommonTtlIsSet() - { - if (isset($this->skippedTests[__FUNCTION__])) { - $this->markTestSkipped($this->skippedTests[__FUNCTION__]); - } - - $adapter1 = new ArrayAdapter(4); - $adapter2 = new ArrayAdapter(2); - - $cache = new ChainAdapter([$adapter1, $adapter2], 6); - - $cache->save($cache->getItem('key')->set('value')); - - $item = $adapter1->getItem('key'); - $this->assertTrue($item->isHit()); - $this->assertEquals('value', $item->get()); - - $item = $adapter2->getItem('key'); - $this->assertTrue($item->isHit()); - $this->assertEquals('value', $item->get()); - - sleep(2); - - $item = $adapter1->getItem('key'); - $this->assertTrue($item->isHit()); - $this->assertEquals('value', $item->get()); - - $item = $adapter2->getItem('key'); - $this->assertFalse($item->isHit()); - - sleep(2); - - $item = $adapter1->getItem('key'); - $this->assertFalse($item->isHit()); - - $adapter2->save($adapter2->getItem('key1')->set('value1')); - - $item = $cache->getItem('key1'); - $this->assertTrue($item->isHit()); - $this->assertEquals('value1', $item->get()); - - sleep(2); - - $item = $adapter1->getItem('key1'); - $this->assertTrue($item->isHit()); - $this->assertEquals('value1', $item->get()); - - $item = $adapter2->getItem('key1'); - $this->assertFalse($item->isHit()); - - sleep(2); - - $item = $adapter1->getItem('key1'); - $this->assertTrue($item->isHit()); - $this->assertEquals('value1', $item->get()); - - sleep(2); - - $item = $adapter1->getItem('key1'); - $this->assertFalse($item->isHit()); - } - - /** - * @return MockObject|PruneableCacheInterface - */ - private function getPruneableMock() - { - $pruneable = $this - ->getMockBuilder(PruneableCacheInterface::class) - ->getMock(); - - $pruneable - ->expects($this->atLeastOnce()) - ->method('prune') - ->willReturn(true); - - return $pruneable; - } - - /** - * @return MockObject|PruneableCacheInterface - */ - private function getFailingPruneableMock() - { - $pruneable = $this - ->getMockBuilder(PruneableCacheInterface::class) - ->getMock(); - - $pruneable - ->expects($this->atLeastOnce()) - ->method('prune') - ->willReturn(false); - - return $pruneable; - } - - /** - * @return MockObject|AdapterInterface - */ - private function getNonPruneableMock() - { - return $this - ->getMockBuilder(AdapterInterface::class) - ->getMock(); - } -} - -interface PruneableCacheInterface extends PruneableInterface, AdapterInterface -{ -} diff --git a/advancedcontentfilter/vendor/symfony/cache/Tests/Adapter/DoctrineAdapterTest.php b/advancedcontentfilter/vendor/symfony/cache/Tests/Adapter/DoctrineAdapterTest.php deleted file mode 100644 index 8f520cb5..00000000 --- a/advancedcontentfilter/vendor/symfony/cache/Tests/Adapter/DoctrineAdapterTest.php +++ /dev/null @@ -1,32 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Cache\Tests\Adapter; - -use Symfony\Component\Cache\Adapter\DoctrineAdapter; -use Symfony\Component\Cache\Tests\Fixtures\ArrayCache; - -/** - * @group time-sensitive - */ -class DoctrineAdapterTest extends AdapterTestCase -{ - protected $skippedTests = [ - 'testDeferredSaveWithoutCommit' => 'Assumes a shared cache which ArrayCache is not.', - 'testSaveWithoutExpire' => 'Assumes a shared cache which ArrayCache is not.', - 'testNotUnserializable' => 'ArrayCache does not use serialize/unserialize', - ]; - - public function createCachePool($defaultLifetime = 0) - { - return new DoctrineAdapter(new ArrayCache($defaultLifetime), '', $defaultLifetime); - } -} diff --git a/advancedcontentfilter/vendor/symfony/cache/Tests/Adapter/FilesystemAdapterTest.php b/advancedcontentfilter/vendor/symfony/cache/Tests/Adapter/FilesystemAdapterTest.php deleted file mode 100644 index fa830682..00000000 --- a/advancedcontentfilter/vendor/symfony/cache/Tests/Adapter/FilesystemAdapterTest.php +++ /dev/null @@ -1,61 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Cache\Tests\Adapter; - -use Psr\Cache\CacheItemPoolInterface; -use Symfony\Component\Cache\Adapter\FilesystemAdapter; - -/** - * @group time-sensitive - */ -class FilesystemAdapterTest extends AdapterTestCase -{ - public function createCachePool($defaultLifetime = 0) - { - return new FilesystemAdapter('', $defaultLifetime); - } - - public static function tearDownAfterClass() - { - self::rmdir(sys_get_temp_dir().'/symfony-cache'); - } - - public static function rmdir($dir) - { - if (!file_exists($dir)) { - return; - } - if (!$dir || 0 !== strpos(\dirname($dir), sys_get_temp_dir())) { - throw new \Exception(__METHOD__."() operates only on subdirs of system's temp dir"); - } - $children = new \RecursiveIteratorIterator( - new \RecursiveDirectoryIterator($dir, \RecursiveDirectoryIterator::SKIP_DOTS), - \RecursiveIteratorIterator::CHILD_FIRST - ); - foreach ($children as $child) { - if ($child->isDir()) { - rmdir($child); - } else { - unlink($child); - } - } - rmdir($dir); - } - - protected function isPruned(CacheItemPoolInterface $cache, $name) - { - $getFileMethod = (new \ReflectionObject($cache))->getMethod('getFile'); - $getFileMethod->setAccessible(true); - - return !file_exists($getFileMethod->invoke($cache, $name)); - } -} diff --git a/advancedcontentfilter/vendor/symfony/cache/Tests/Adapter/MaxIdLengthAdapterTest.php b/advancedcontentfilter/vendor/symfony/cache/Tests/Adapter/MaxIdLengthAdapterTest.php deleted file mode 100644 index 536e2c2d..00000000 --- a/advancedcontentfilter/vendor/symfony/cache/Tests/Adapter/MaxIdLengthAdapterTest.php +++ /dev/null @@ -1,87 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Cache\Tests\Adapter; - -use PHPUnit\Framework\TestCase; -use Symfony\Component\Cache\Adapter\AbstractAdapter; - -class MaxIdLengthAdapterTest extends TestCase -{ - public function testLongKey() - { - $cache = $this->getMockBuilder(MaxIdLengthAdapter::class) - ->setConstructorArgs([str_repeat('-', 10)]) - ->setMethods(['doHave', 'doFetch', 'doDelete', 'doSave', 'doClear']) - ->getMock(); - - $cache->expects($this->exactly(2)) - ->method('doHave') - ->withConsecutive( - [$this->equalTo('----------:0GTYWa9n4ed8vqNlOT2iEr:')], - [$this->equalTo('----------:---------------------------------------')] - ); - - $cache->hasItem(str_repeat('-', 40)); - $cache->hasItem(str_repeat('-', 39)); - } - - public function testLongKeyVersioning() - { - $cache = $this->getMockBuilder(MaxIdLengthAdapter::class) - ->setConstructorArgs([str_repeat('-', 26)]) - ->getMock(); - - $cache - ->method('doFetch') - ->willReturn(['2:']); - - $reflectionClass = new \ReflectionClass(AbstractAdapter::class); - - $reflectionMethod = $reflectionClass->getMethod('getId'); - $reflectionMethod->setAccessible(true); - - // No versioning enabled - $this->assertEquals('--------------------------:------------', $reflectionMethod->invokeArgs($cache, [str_repeat('-', 12)])); - $this->assertLessThanOrEqual(50, \strlen($reflectionMethod->invokeArgs($cache, [str_repeat('-', 12)]))); - $this->assertLessThanOrEqual(50, \strlen($reflectionMethod->invokeArgs($cache, [str_repeat('-', 23)]))); - $this->assertLessThanOrEqual(50, \strlen($reflectionMethod->invokeArgs($cache, [str_repeat('-', 40)]))); - - $reflectionProperty = $reflectionClass->getProperty('versioningIsEnabled'); - $reflectionProperty->setAccessible(true); - $reflectionProperty->setValue($cache, true); - - // Versioning enabled - $this->assertEquals('--------------------------:2:------------', $reflectionMethod->invokeArgs($cache, [str_repeat('-', 12)])); - $this->assertLessThanOrEqual(50, \strlen($reflectionMethod->invokeArgs($cache, [str_repeat('-', 12)]))); - $this->assertLessThanOrEqual(50, \strlen($reflectionMethod->invokeArgs($cache, [str_repeat('-', 23)]))); - $this->assertLessThanOrEqual(50, \strlen($reflectionMethod->invokeArgs($cache, [str_repeat('-', 40)]))); - } - - public function testTooLongNamespace() - { - $this->expectException('Symfony\Component\Cache\Exception\InvalidArgumentException'); - $this->expectExceptionMessage('Namespace must be 26 chars max, 40 given ("----------------------------------------")'); - $this->getMockBuilder(MaxIdLengthAdapter::class) - ->setConstructorArgs([str_repeat('-', 40)]) - ->getMock(); - } -} - -abstract class MaxIdLengthAdapter extends AbstractAdapter -{ - protected $maxIdLength = 50; - - public function __construct($ns) - { - parent::__construct($ns); - } -} diff --git a/advancedcontentfilter/vendor/symfony/cache/Tests/Adapter/MemcachedAdapterTest.php b/advancedcontentfilter/vendor/symfony/cache/Tests/Adapter/MemcachedAdapterTest.php deleted file mode 100644 index a9a397dd..00000000 --- a/advancedcontentfilter/vendor/symfony/cache/Tests/Adapter/MemcachedAdapterTest.php +++ /dev/null @@ -1,204 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Cache\Tests\Adapter; - -use Symfony\Component\Cache\Adapter\AbstractAdapter; -use Symfony\Component\Cache\Adapter\MemcachedAdapter; - -class MemcachedAdapterTest extends AdapterTestCase -{ - protected $skippedTests = [ - 'testHasItemReturnsFalseWhenDeferredItemIsExpired' => 'Testing expiration slows down the test suite', - 'testDefaultLifeTime' => 'Testing expiration slows down the test suite', - ]; - - protected static $client; - - public static function setUpBeforeClass() - { - if (!MemcachedAdapter::isSupported()) { - self::markTestSkipped('Extension memcached >=2.2.0 required.'); - } - self::$client = AbstractAdapter::createConnection('memcached://'.getenv('MEMCACHED_HOST'), ['binary_protocol' => false]); - self::$client->get('foo'); - $code = self::$client->getResultCode(); - - if (\Memcached::RES_SUCCESS !== $code && \Memcached::RES_NOTFOUND !== $code) { - self::markTestSkipped('Memcached error: '.strtolower(self::$client->getResultMessage())); - } - } - - public function createCachePool($defaultLifetime = 0) - { - $client = $defaultLifetime ? AbstractAdapter::createConnection('memcached://'.getenv('MEMCACHED_HOST')) : self::$client; - - return new MemcachedAdapter($client, str_replace('\\', '.', __CLASS__), $defaultLifetime); - } - - public function testOptions() - { - $client = MemcachedAdapter::createConnection([], [ - 'libketama_compatible' => false, - 'distribution' => 'modula', - 'compression' => true, - 'serializer' => 'php', - 'hash' => 'md5', - ]); - - $this->assertSame(\Memcached::SERIALIZER_PHP, $client->getOption(\Memcached::OPT_SERIALIZER)); - $this->assertSame(\Memcached::HASH_MD5, $client->getOption(\Memcached::OPT_HASH)); - $this->assertTrue($client->getOption(\Memcached::OPT_COMPRESSION)); - $this->assertSame(0, $client->getOption(\Memcached::OPT_LIBKETAMA_COMPATIBLE)); - $this->assertSame(\Memcached::DISTRIBUTION_MODULA, $client->getOption(\Memcached::OPT_DISTRIBUTION)); - } - - /** - * @dataProvider provideBadOptions - */ - public function testBadOptions($name, $value) - { - if (\PHP_VERSION_ID < 80000) { - $this->expectException('ErrorException'); - $this->expectExceptionMessage('constant(): Couldn\'t find constant Memcached::'); - } else { - $this->expectException('Error'); - $this->expectExceptionMessage('Undefined constant Memcached::'); - } - - MemcachedAdapter::createConnection([], [$name => $value]); - } - - public function provideBadOptions() - { - return [ - ['foo', 'bar'], - ['hash', 'zyx'], - ['serializer', 'zyx'], - ['distribution', 'zyx'], - ]; - } - - public function testDefaultOptions() - { - $this->assertTrue(MemcachedAdapter::isSupported()); - - $client = MemcachedAdapter::createConnection([]); - - $this->assertTrue($client->getOption(\Memcached::OPT_COMPRESSION)); - $this->assertSame(1, $client->getOption(\Memcached::OPT_BINARY_PROTOCOL)); - $this->assertSame(1, $client->getOption(\Memcached::OPT_TCP_NODELAY)); - $this->assertSame(1, $client->getOption(\Memcached::OPT_LIBKETAMA_COMPATIBLE)); - } - - public function testOptionSerializer() - { - $this->expectException('Symfony\Component\Cache\Exception\CacheException'); - $this->expectExceptionMessage('MemcachedAdapter: "serializer" option must be "php" or "igbinary".'); - if (!\Memcached::HAVE_JSON) { - $this->markTestSkipped('Memcached::HAVE_JSON required'); - } - - new MemcachedAdapter(MemcachedAdapter::createConnection([], ['serializer' => 'json'])); - } - - /** - * @dataProvider provideServersSetting - */ - public function testServersSetting($dsn, $host, $port) - { - $client1 = MemcachedAdapter::createConnection($dsn); - $client2 = MemcachedAdapter::createConnection([$dsn]); - $client3 = MemcachedAdapter::createConnection([[$host, $port]]); - $expect = [ - 'host' => $host, - 'port' => $port, - ]; - - $f = function ($s) { return ['host' => $s['host'], 'port' => $s['port']]; }; - $this->assertSame([$expect], array_map($f, $client1->getServerList())); - $this->assertSame([$expect], array_map($f, $client2->getServerList())); - $this->assertSame([$expect], array_map($f, $client3->getServerList())); - } - - public function provideServersSetting() - { - yield [ - 'memcached://127.0.0.1/50', - '127.0.0.1', - 11211, - ]; - yield [ - 'memcached://localhost:11222?weight=25', - 'localhost', - 11222, - ]; - if (filter_var(ini_get('memcached.use_sasl'), \FILTER_VALIDATE_BOOLEAN)) { - yield [ - 'memcached://user:password@127.0.0.1?weight=50', - '127.0.0.1', - 11211, - ]; - } - yield [ - 'memcached:///var/run/memcached.sock?weight=25', - '/var/run/memcached.sock', - 0, - ]; - yield [ - 'memcached:///var/local/run/memcached.socket?weight=25', - '/var/local/run/memcached.socket', - 0, - ]; - if (filter_var(ini_get('memcached.use_sasl'), \FILTER_VALIDATE_BOOLEAN)) { - yield [ - 'memcached://user:password@/var/local/run/memcached.socket?weight=25', - '/var/local/run/memcached.socket', - 0, - ]; - } - } - - /** - * @dataProvider provideDsnWithOptions - */ - public function testDsnWithOptions($dsn, array $options, array $expectedOptions) - { - $client = MemcachedAdapter::createConnection($dsn, $options); - - foreach ($expectedOptions as $option => $expect) { - $this->assertSame($expect, $client->getOption($option)); - } - } - - public function provideDsnWithOptions() - { - if (!class_exists('\Memcached')) { - self::markTestSkipped('Extension memcached required.'); - } - - yield [ - 'memcached://localhost:11222?retry_timeout=10', - [\Memcached::OPT_RETRY_TIMEOUT => 8], - [\Memcached::OPT_RETRY_TIMEOUT => 10], - ]; - yield [ - 'memcached://localhost:11222?socket_recv_size=1&socket_send_size=2', - [\Memcached::OPT_RETRY_TIMEOUT => 8], - [\Memcached::OPT_SOCKET_RECV_SIZE => 1, \Memcached::OPT_SOCKET_SEND_SIZE => 2, \Memcached::OPT_RETRY_TIMEOUT => 8], - ]; - } - - public function testClear() - { - $this->assertTrue($this->createCachePool()->clear()); - } -} diff --git a/advancedcontentfilter/vendor/symfony/cache/Tests/Adapter/NamespacedProxyAdapterTest.php b/advancedcontentfilter/vendor/symfony/cache/Tests/Adapter/NamespacedProxyAdapterTest.php deleted file mode 100644 index c2714033..00000000 --- a/advancedcontentfilter/vendor/symfony/cache/Tests/Adapter/NamespacedProxyAdapterTest.php +++ /dev/null @@ -1,26 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Cache\Tests\Adapter; - -use Symfony\Component\Cache\Adapter\ArrayAdapter; -use Symfony\Component\Cache\Adapter\ProxyAdapter; - -/** - * @group time-sensitive - */ -class NamespacedProxyAdapterTest extends ProxyAdapterTest -{ - public function createCachePool($defaultLifetime = 0) - { - return new ProxyAdapter(new ArrayAdapter($defaultLifetime), 'foo', $defaultLifetime); - } -} diff --git a/advancedcontentfilter/vendor/symfony/cache/Tests/Adapter/NullAdapterTest.php b/advancedcontentfilter/vendor/symfony/cache/Tests/Adapter/NullAdapterTest.php deleted file mode 100644 index b771fa0e..00000000 --- a/advancedcontentfilter/vendor/symfony/cache/Tests/Adapter/NullAdapterTest.php +++ /dev/null @@ -1,128 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Cache\Tests\Adapter; - -use PHPUnit\Framework\TestCase; -use Psr\Cache\CacheItemInterface; -use Symfony\Component\Cache\Adapter\NullAdapter; - -/** - * @group time-sensitive - */ -class NullAdapterTest extends TestCase -{ - public function createCachePool() - { - return new NullAdapter(); - } - - public function testGetItem() - { - $adapter = $this->createCachePool(); - - $item = $adapter->getItem('key'); - $this->assertFalse($item->isHit()); - $this->assertNull($item->get(), "Item's value must be null when isHit is false."); - } - - public function testHasItem() - { - $this->assertFalse($this->createCachePool()->hasItem('key')); - } - - public function testGetItems() - { - $adapter = $this->createCachePool(); - - $keys = ['foo', 'bar', 'baz', 'biz']; - - /** @var CacheItemInterface[] $items */ - $items = $adapter->getItems($keys); - $count = 0; - - foreach ($items as $key => $item) { - $itemKey = $item->getKey(); - - $this->assertEquals($itemKey, $key, 'Keys must be preserved when fetching multiple items'); - $this->assertContains($key, $keys, 'Cache key can not change.'); - $this->assertFalse($item->isHit()); - - // Remove $key for $keys - foreach ($keys as $k => $v) { - if ($v === $key) { - unset($keys[$k]); - } - } - - ++$count; - } - - $this->assertSame(4, $count); - } - - public function testIsHit() - { - $adapter = $this->createCachePool(); - - $item = $adapter->getItem('key'); - $this->assertFalse($item->isHit()); - } - - public function testClear() - { - $this->assertTrue($this->createCachePool()->clear()); - } - - public function testDeleteItem() - { - $this->assertTrue($this->createCachePool()->deleteItem('key')); - } - - public function testDeleteItems() - { - $this->assertTrue($this->createCachePool()->deleteItems(['key', 'foo', 'bar'])); - } - - public function testSave() - { - $adapter = $this->createCachePool(); - - $item = $adapter->getItem('key'); - $this->assertFalse($item->isHit()); - $this->assertNull($item->get(), "Item's value must be null when isHit is false."); - - $this->assertFalse($adapter->save($item)); - } - - public function testDeferredSave() - { - $adapter = $this->createCachePool(); - - $item = $adapter->getItem('key'); - $this->assertFalse($item->isHit()); - $this->assertNull($item->get(), "Item's value must be null when isHit is false."); - - $this->assertFalse($adapter->saveDeferred($item)); - } - - public function testCommit() - { - $adapter = $this->createCachePool(); - - $item = $adapter->getItem('key'); - $this->assertFalse($item->isHit()); - $this->assertNull($item->get(), "Item's value must be null when isHit is false."); - - $this->assertFalse($adapter->saveDeferred($item)); - $this->assertFalse($this->createCachePool()->commit()); - } -} diff --git a/advancedcontentfilter/vendor/symfony/cache/Tests/Adapter/PdoAdapterTest.php b/advancedcontentfilter/vendor/symfony/cache/Tests/Adapter/PdoAdapterTest.php deleted file mode 100644 index dd2a9118..00000000 --- a/advancedcontentfilter/vendor/symfony/cache/Tests/Adapter/PdoAdapterTest.php +++ /dev/null @@ -1,73 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Cache\Tests\Adapter; - -use Symfony\Component\Cache\Adapter\PdoAdapter; -use Symfony\Component\Cache\Tests\Traits\PdoPruneableTrait; - -/** - * @group time-sensitive - */ -class PdoAdapterTest extends AdapterTestCase -{ - use PdoPruneableTrait; - - protected static $dbFile; - - public static function setUpBeforeClass() - { - if (!\extension_loaded('pdo_sqlite')) { - self::markTestSkipped('Extension pdo_sqlite required.'); - } - - self::$dbFile = tempnam(sys_get_temp_dir(), 'sf_sqlite_cache'); - - $pool = new PdoAdapter('sqlite:'.self::$dbFile); - $pool->createTable(); - } - - public static function tearDownAfterClass() - { - @unlink(self::$dbFile); - } - - public function createCachePool($defaultLifetime = 0) - { - return new PdoAdapter('sqlite:'.self::$dbFile, 'ns', $defaultLifetime); - } - - public function testCleanupExpiredItems() - { - $pdo = new \PDO('sqlite:'.self::$dbFile); - - $getCacheItemCount = function () use ($pdo) { - return (int) $pdo->query('SELECT COUNT(*) FROM cache_items')->fetch(\PDO::FETCH_COLUMN); - }; - - $this->assertSame(0, $getCacheItemCount()); - - $cache = $this->createCachePool(); - - $item = $cache->getItem('some_nice_key'); - $item->expiresAfter(1); - $item->set(1); - - $cache->save($item); - $this->assertSame(1, $getCacheItemCount()); - - sleep(2); - - $newItem = $cache->getItem($item->getKey()); - $this->assertFalse($newItem->isHit()); - $this->assertSame(0, $getCacheItemCount(), 'PDOAdapter must clean up expired items'); - } -} diff --git a/advancedcontentfilter/vendor/symfony/cache/Tests/Adapter/PdoDbalAdapterTest.php b/advancedcontentfilter/vendor/symfony/cache/Tests/Adapter/PdoDbalAdapterTest.php deleted file mode 100644 index aa53958c..00000000 --- a/advancedcontentfilter/vendor/symfony/cache/Tests/Adapter/PdoDbalAdapterTest.php +++ /dev/null @@ -1,48 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Cache\Tests\Adapter; - -use Doctrine\DBAL\DriverManager; -use Symfony\Component\Cache\Adapter\PdoAdapter; -use Symfony\Component\Cache\Tests\Traits\PdoPruneableTrait; - -/** - * @group time-sensitive - */ -class PdoDbalAdapterTest extends AdapterTestCase -{ - use PdoPruneableTrait; - - protected static $dbFile; - - public static function setUpBeforeClass() - { - if (!\extension_loaded('pdo_sqlite')) { - self::markTestSkipped('Extension pdo_sqlite required.'); - } - - self::$dbFile = tempnam(sys_get_temp_dir(), 'sf_sqlite_cache'); - - $pool = new PdoAdapter(DriverManager::getConnection(['driver' => 'pdo_sqlite', 'path' => self::$dbFile])); - $pool->createTable(); - } - - public static function tearDownAfterClass() - { - @unlink(self::$dbFile); - } - - public function createCachePool($defaultLifetime = 0) - { - return new PdoAdapter(DriverManager::getConnection(['driver' => 'pdo_sqlite', 'path' => self::$dbFile]), '', $defaultLifetime); - } -} diff --git a/advancedcontentfilter/vendor/symfony/cache/Tests/Adapter/PhpArrayAdapterTest.php b/advancedcontentfilter/vendor/symfony/cache/Tests/Adapter/PhpArrayAdapterTest.php deleted file mode 100644 index f88a7187..00000000 --- a/advancedcontentfilter/vendor/symfony/cache/Tests/Adapter/PhpArrayAdapterTest.php +++ /dev/null @@ -1,135 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Cache\Tests\Adapter; - -use Psr\Cache\CacheItemInterface; -use Symfony\Component\Cache\Adapter\NullAdapter; -use Symfony\Component\Cache\Adapter\PhpArrayAdapter; - -/** - * @group time-sensitive - */ -class PhpArrayAdapterTest extends AdapterTestCase -{ - protected $skippedTests = [ - 'testBasicUsage' => 'PhpArrayAdapter is read-only.', - 'testBasicUsageWithLongKey' => 'PhpArrayAdapter is read-only.', - 'testClear' => 'PhpArrayAdapter is read-only.', - 'testClearWithDeferredItems' => 'PhpArrayAdapter is read-only.', - 'testDeleteItem' => 'PhpArrayAdapter is read-only.', - 'testSaveExpired' => 'PhpArrayAdapter is read-only.', - 'testSaveWithoutExpire' => 'PhpArrayAdapter is read-only.', - 'testDeferredSave' => 'PhpArrayAdapter is read-only.', - 'testDeferredSaveWithoutCommit' => 'PhpArrayAdapter is read-only.', - 'testDeleteItems' => 'PhpArrayAdapter is read-only.', - 'testDeleteDeferredItem' => 'PhpArrayAdapter is read-only.', - 'testCommit' => 'PhpArrayAdapter is read-only.', - 'testSaveDeferredWhenChangingValues' => 'PhpArrayAdapter is read-only.', - 'testSaveDeferredOverwrite' => 'PhpArrayAdapter is read-only.', - 'testIsHitDeferred' => 'PhpArrayAdapter is read-only.', - - 'testExpiresAt' => 'PhpArrayAdapter does not support expiration.', - 'testExpiresAtWithNull' => 'PhpArrayAdapter does not support expiration.', - 'testExpiresAfterWithNull' => 'PhpArrayAdapter does not support expiration.', - 'testDeferredExpired' => 'PhpArrayAdapter does not support expiration.', - 'testExpiration' => 'PhpArrayAdapter does not support expiration.', - - 'testGetItemInvalidKeys' => 'PhpArrayAdapter does not throw exceptions on invalid key.', - 'testGetItemsInvalidKeys' => 'PhpArrayAdapter does not throw exceptions on invalid key.', - 'testHasItemInvalidKeys' => 'PhpArrayAdapter does not throw exceptions on invalid key.', - 'testDeleteItemInvalidKeys' => 'PhpArrayAdapter does not throw exceptions on invalid key.', - 'testDeleteItemsInvalidKeys' => 'PhpArrayAdapter does not throw exceptions on invalid key.', - - 'testDefaultLifeTime' => 'PhpArrayAdapter does not allow configuring a default lifetime.', - 'testPrune' => 'PhpArrayAdapter just proxies', - ]; - - protected static $file; - - public static function setUpBeforeClass() - { - self::$file = sys_get_temp_dir().'/symfony-cache/php-array-adapter-test.php'; - } - - protected function tearDown() - { - $this->createCachePool()->clear(); - - if (file_exists(sys_get_temp_dir().'/symfony-cache')) { - FilesystemAdapterTest::rmdir(sys_get_temp_dir().'/symfony-cache'); - } - } - - public function createCachePool() - { - return new PhpArrayAdapterWrapper(self::$file, new NullAdapter()); - } - - public function testStore() - { - $arrayWithRefs = []; - $arrayWithRefs[0] = 123; - $arrayWithRefs[1] = &$arrayWithRefs[0]; - - $object = (object) [ - 'foo' => 'bar', - 'foo2' => 'bar2', - ]; - - $expected = [ - 'null' => null, - 'serializedString' => serialize($object), - 'arrayWithRefs' => $arrayWithRefs, - 'object' => $object, - 'arrayWithObject' => ['bar' => $object], - ]; - - $adapter = $this->createCachePool(); - $adapter->warmUp($expected); - - foreach ($expected as $key => $value) { - $this->assertSame(serialize($value), serialize($adapter->getItem($key)->get()), 'Warm up should create a PHP file that OPCache can load in memory'); - } - } - - public function testStoredFile() - { - $expected = [ - 'integer' => 42, - 'float' => 42.42, - 'boolean' => true, - 'array_simple' => ['foo', 'bar'], - 'array_associative' => ['foo' => 'bar', 'foo2' => 'bar2'], - ]; - - $adapter = $this->createCachePool(); - $adapter->warmUp($expected); - - $values = eval(substr(file_get_contents(self::$file), 6)); - - $this->assertSame($expected, $values, 'Warm up should create a PHP file that OPCache can load in memory'); - } -} - -class PhpArrayAdapterWrapper extends PhpArrayAdapter -{ - public function save(CacheItemInterface $item) - { - \call_user_func(\Closure::bind(function () use ($item) { - $this->values[$item->getKey()] = $item->get(); - $this->warmUp($this->values); - $this->values = eval(substr(file_get_contents($this->file), 6)); - }, $this, PhpArrayAdapter::class)); - - return true; - } -} diff --git a/advancedcontentfilter/vendor/symfony/cache/Tests/Adapter/PhpArrayAdapterWithFallbackTest.php b/advancedcontentfilter/vendor/symfony/cache/Tests/Adapter/PhpArrayAdapterWithFallbackTest.php deleted file mode 100644 index 0bfd5c39..00000000 --- a/advancedcontentfilter/vendor/symfony/cache/Tests/Adapter/PhpArrayAdapterWithFallbackTest.php +++ /dev/null @@ -1,51 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Cache\Tests\Adapter; - -use Symfony\Component\Cache\Adapter\FilesystemAdapter; -use Symfony\Component\Cache\Adapter\PhpArrayAdapter; - -/** - * @group time-sensitive - */ -class PhpArrayAdapterWithFallbackTest extends AdapterTestCase -{ - protected $skippedTests = [ - 'testGetItemInvalidKeys' => 'PhpArrayAdapter does not throw exceptions on invalid key.', - 'testGetItemsInvalidKeys' => 'PhpArrayAdapter does not throw exceptions on invalid key.', - 'testHasItemInvalidKeys' => 'PhpArrayAdapter does not throw exceptions on invalid key.', - 'testDeleteItemInvalidKeys' => 'PhpArrayAdapter does not throw exceptions on invalid key.', - 'testDeleteItemsInvalidKeys' => 'PhpArrayAdapter does not throw exceptions on invalid key.', - 'testPrune' => 'PhpArrayAdapter just proxies', - ]; - - protected static $file; - - public static function setUpBeforeClass() - { - self::$file = sys_get_temp_dir().'/symfony-cache/php-array-adapter-test.php'; - } - - protected function tearDown() - { - $this->createCachePool()->clear(); - - if (file_exists(sys_get_temp_dir().'/symfony-cache')) { - FilesystemAdapterTest::rmdir(sys_get_temp_dir().'/symfony-cache'); - } - } - - public function createCachePool($defaultLifetime = 0) - { - return new PhpArrayAdapter(self::$file, new FilesystemAdapter('php-array-fallback', $defaultLifetime)); - } -} diff --git a/advancedcontentfilter/vendor/symfony/cache/Tests/Adapter/PhpFilesAdapterTest.php b/advancedcontentfilter/vendor/symfony/cache/Tests/Adapter/PhpFilesAdapterTest.php deleted file mode 100644 index 247160d5..00000000 --- a/advancedcontentfilter/vendor/symfony/cache/Tests/Adapter/PhpFilesAdapterTest.php +++ /dev/null @@ -1,47 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Cache\Tests\Adapter; - -use Psr\Cache\CacheItemPoolInterface; -use Symfony\Component\Cache\Adapter\PhpFilesAdapter; - -/** - * @group time-sensitive - */ -class PhpFilesAdapterTest extends AdapterTestCase -{ - protected $skippedTests = [ - 'testDefaultLifeTime' => 'PhpFilesAdapter does not allow configuring a default lifetime.', - ]; - - public function createCachePool() - { - if (!PhpFilesAdapter::isSupported()) { - $this->markTestSkipped('OPcache extension is not enabled.'); - } - - return new PhpFilesAdapter('sf-cache'); - } - - public static function tearDownAfterClass() - { - FilesystemAdapterTest::rmdir(sys_get_temp_dir().'/symfony-cache'); - } - - protected function isPruned(CacheItemPoolInterface $cache, $name) - { - $getFileMethod = (new \ReflectionObject($cache))->getMethod('getFile'); - $getFileMethod->setAccessible(true); - - return !file_exists($getFileMethod->invoke($cache, $name)); - } -} diff --git a/advancedcontentfilter/vendor/symfony/cache/Tests/Adapter/PredisAdapterTest.php b/advancedcontentfilter/vendor/symfony/cache/Tests/Adapter/PredisAdapterTest.php deleted file mode 100644 index 6aadbf26..00000000 --- a/advancedcontentfilter/vendor/symfony/cache/Tests/Adapter/PredisAdapterTest.php +++ /dev/null @@ -1,53 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Cache\Tests\Adapter; - -use Predis\Connection\StreamConnection; -use Symfony\Component\Cache\Adapter\RedisAdapter; - -class PredisAdapterTest extends AbstractRedisAdapterTest -{ - public static function setUpBeforeClass() - { - parent::setUpBeforeClass(); - self::$redis = new \Predis\Client(['host' => getenv('REDIS_HOST')]); - } - - public function testCreateConnection() - { - $redisHost = getenv('REDIS_HOST'); - - $redis = RedisAdapter::createConnection('redis://'.$redisHost.'/1', ['class' => \Predis\Client::class, 'timeout' => 3]); - $this->assertInstanceOf(\Predis\Client::class, $redis); - - $connection = $redis->getConnection(); - $this->assertInstanceOf(StreamConnection::class, $connection); - - $params = [ - 'scheme' => 'tcp', - 'host' => $redisHost, - 'path' => '', - 'dbindex' => '1', - 'port' => 6379, - 'class' => 'Predis\Client', - 'timeout' => 3, - 'persistent' => 0, - 'persistent_id' => null, - 'read_timeout' => 0, - 'retry_interval' => 0, - 'lazy' => false, - 'database' => '1', - 'password' => null, - ]; - $this->assertSame($params, $connection->getParameters()->toArray()); - } -} diff --git a/advancedcontentfilter/vendor/symfony/cache/Tests/Adapter/PredisClusterAdapterTest.php b/advancedcontentfilter/vendor/symfony/cache/Tests/Adapter/PredisClusterAdapterTest.php deleted file mode 100644 index 1afabaf1..00000000 --- a/advancedcontentfilter/vendor/symfony/cache/Tests/Adapter/PredisClusterAdapterTest.php +++ /dev/null @@ -1,26 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Cache\Tests\Adapter; - -class PredisClusterAdapterTest extends AbstractRedisAdapterTest -{ - public static function setUpBeforeClass() - { - parent::setUpBeforeClass(); - self::$redis = new \Predis\Client([['host' => getenv('REDIS_HOST')]]); - } - - public static function tearDownAfterClass() - { - self::$redis = null; - } -} diff --git a/advancedcontentfilter/vendor/symfony/cache/Tests/Adapter/PredisRedisClusterAdapterTest.php b/advancedcontentfilter/vendor/symfony/cache/Tests/Adapter/PredisRedisClusterAdapterTest.php deleted file mode 100644 index 5b09919e..00000000 --- a/advancedcontentfilter/vendor/symfony/cache/Tests/Adapter/PredisRedisClusterAdapterTest.php +++ /dev/null @@ -1,28 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Cache\Tests\Adapter; - -class PredisRedisClusterAdapterTest extends AbstractRedisAdapterTest -{ - public static function setUpBeforeClass() - { - if (!$hosts = getenv('REDIS_CLUSTER_HOSTS')) { - self::markTestSkipped('REDIS_CLUSTER_HOSTS env var is not defined.'); - } - self::$redis = new \Predis\Client(explode(' ', $hosts), ['cluster' => 'redis']); - } - - public static function tearDownAfterClass() - { - self::$redis = null; - } -} diff --git a/advancedcontentfilter/vendor/symfony/cache/Tests/Adapter/ProxyAdapterTest.php b/advancedcontentfilter/vendor/symfony/cache/Tests/Adapter/ProxyAdapterTest.php deleted file mode 100644 index 810cb31a..00000000 --- a/advancedcontentfilter/vendor/symfony/cache/Tests/Adapter/ProxyAdapterTest.php +++ /dev/null @@ -1,69 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Cache\Tests\Adapter; - -use Psr\Cache\CacheItemInterface; -use Symfony\Component\Cache\Adapter\ArrayAdapter; -use Symfony\Component\Cache\Adapter\ProxyAdapter; -use Symfony\Component\Cache\CacheItem; - -/** - * @group time-sensitive - */ -class ProxyAdapterTest extends AdapterTestCase -{ - protected $skippedTests = [ - 'testDeferredSaveWithoutCommit' => 'Assumes a shared cache which ArrayAdapter is not.', - 'testSaveWithoutExpire' => 'Assumes a shared cache which ArrayAdapter is not.', - 'testPrune' => 'ProxyAdapter just proxies', - ]; - - public function createCachePool($defaultLifetime = 0) - { - return new ProxyAdapter(new ArrayAdapter(), '', $defaultLifetime); - } - - public function testProxyfiedItem() - { - $this->expectException('Exception'); - $this->expectExceptionMessage('OK bar'); - $item = new CacheItem(); - $pool = new ProxyAdapter(new TestingArrayAdapter($item)); - - $proxyItem = $pool->getItem('foo'); - - $this->assertNotSame($item, $proxyItem); - $pool->save($proxyItem->set('bar')); - } -} - -class TestingArrayAdapter extends ArrayAdapter -{ - private $item; - - public function __construct(CacheItemInterface $item) - { - $this->item = $item; - } - - public function getItem($key) - { - return $this->item; - } - - public function save(CacheItemInterface $item) - { - if ($item === $this->item) { - throw new \Exception('OK '.$item->get()); - } - } -} diff --git a/advancedcontentfilter/vendor/symfony/cache/Tests/Adapter/RedisAdapterTest.php b/advancedcontentfilter/vendor/symfony/cache/Tests/Adapter/RedisAdapterTest.php deleted file mode 100644 index 6ec6321a..00000000 --- a/advancedcontentfilter/vendor/symfony/cache/Tests/Adapter/RedisAdapterTest.php +++ /dev/null @@ -1,92 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Cache\Tests\Adapter; - -use Symfony\Component\Cache\Adapter\AbstractAdapter; -use Symfony\Component\Cache\Adapter\RedisAdapter; -use Symfony\Component\Cache\Traits\RedisProxy; - -class RedisAdapterTest extends AbstractRedisAdapterTest -{ - public static function setUpBeforeClass() - { - parent::setUpBeforeClass(); - self::$redis = AbstractAdapter::createConnection('redis://'.getenv('REDIS_HOST'), ['lazy' => true]); - } - - public function createCachePool($defaultLifetime = 0) - { - $adapter = parent::createCachePool($defaultLifetime); - $this->assertInstanceOf(RedisProxy::class, self::$redis); - - return $adapter; - } - - public function testCreateConnection() - { - $redisHost = getenv('REDIS_HOST'); - - $redis = RedisAdapter::createConnection('redis://'.$redisHost); - $this->assertInstanceOf(\Redis::class, $redis); - $this->assertTrue($redis->isConnected()); - $this->assertSame(0, $redis->getDbNum()); - - $redis = RedisAdapter::createConnection('redis://'.$redisHost.'/2'); - $this->assertSame(2, $redis->getDbNum()); - - $redis = RedisAdapter::createConnection('redis://'.$redisHost, ['timeout' => 3]); - $this->assertEquals(3, $redis->getTimeout()); - - $redis = RedisAdapter::createConnection('redis://'.$redisHost.'?timeout=4'); - $this->assertEquals(4, $redis->getTimeout()); - - $redis = RedisAdapter::createConnection('redis://'.$redisHost, ['read_timeout' => 5]); - $this->assertEquals(5, $redis->getReadTimeout()); - } - - /** - * @dataProvider provideFailedCreateConnection - */ - public function testFailedCreateConnection($dsn) - { - $this->expectException('Symfony\Component\Cache\Exception\InvalidArgumentException'); - $this->expectExceptionMessage('Redis connection '); - RedisAdapter::createConnection($dsn); - } - - public function provideFailedCreateConnection() - { - return [ - ['redis://localhost:1234'], - ['redis://foo@localhost'], - ['redis://localhost/123'], - ]; - } - - /** - * @dataProvider provideInvalidCreateConnection - */ - public function testInvalidCreateConnection($dsn) - { - $this->expectException('Symfony\Component\Cache\Exception\InvalidArgumentException'); - $this->expectExceptionMessage('Invalid Redis DSN'); - RedisAdapter::createConnection($dsn); - } - - public function provideInvalidCreateConnection() - { - return [ - ['foo://localhost'], - ['redis://'], - ]; - } -} diff --git a/advancedcontentfilter/vendor/symfony/cache/Tests/Adapter/RedisArrayAdapterTest.php b/advancedcontentfilter/vendor/symfony/cache/Tests/Adapter/RedisArrayAdapterTest.php deleted file mode 100644 index bd9def32..00000000 --- a/advancedcontentfilter/vendor/symfony/cache/Tests/Adapter/RedisArrayAdapterTest.php +++ /dev/null @@ -1,24 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Cache\Tests\Adapter; - -class RedisArrayAdapterTest extends AbstractRedisAdapterTest -{ - public static function setUpBeforeClass() - { - parent::setupBeforeClass(); - if (!class_exists('RedisArray')) { - self::markTestSkipped('The RedisArray class is required.'); - } - self::$redis = new \RedisArray([getenv('REDIS_HOST')], ['lazy_connect' => true]); - } -} diff --git a/advancedcontentfilter/vendor/symfony/cache/Tests/Adapter/RedisClusterAdapterTest.php b/advancedcontentfilter/vendor/symfony/cache/Tests/Adapter/RedisClusterAdapterTest.php deleted file mode 100644 index 9c339d2d..00000000 --- a/advancedcontentfilter/vendor/symfony/cache/Tests/Adapter/RedisClusterAdapterTest.php +++ /dev/null @@ -1,27 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Cache\Tests\Adapter; - -class RedisClusterAdapterTest extends AbstractRedisAdapterTest -{ - public static function setUpBeforeClass() - { - if (!class_exists('RedisCluster')) { - self::markTestSkipped('The RedisCluster class is required.'); - } - if (!$hosts = getenv('REDIS_CLUSTER_HOSTS')) { - self::markTestSkipped('REDIS_CLUSTER_HOSTS env var is not defined.'); - } - - self::$redis = new \RedisCluster(null, explode(' ', $hosts)); - } -} diff --git a/advancedcontentfilter/vendor/symfony/cache/Tests/Adapter/SimpleCacheAdapterTest.php b/advancedcontentfilter/vendor/symfony/cache/Tests/Adapter/SimpleCacheAdapterTest.php deleted file mode 100644 index d8470a2e..00000000 --- a/advancedcontentfilter/vendor/symfony/cache/Tests/Adapter/SimpleCacheAdapterTest.php +++ /dev/null @@ -1,41 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Cache\Tests\Adapter; - -use Symfony\Component\Cache\Adapter\SimpleCacheAdapter; -use Symfony\Component\Cache\Simple\ArrayCache; -use Symfony\Component\Cache\Simple\FilesystemCache; - -/** - * @group time-sensitive - */ -class SimpleCacheAdapterTest extends AdapterTestCase -{ - protected $skippedTests = [ - 'testPrune' => 'SimpleCache just proxies', - ]; - - public function createCachePool($defaultLifetime = 0) - { - return new SimpleCacheAdapter(new FilesystemCache(), '', $defaultLifetime); - } - - public function testValidCacheKeyWithNamespace() - { - $cache = new SimpleCacheAdapter(new ArrayCache(), 'some_namespace', 0); - $item = $cache->getItem('my_key'); - $item->set('someValue'); - $cache->save($item); - - $this->assertTrue($cache->getItem('my_key')->isHit(), 'Stored item is successfully retrieved.'); - } -} diff --git a/advancedcontentfilter/vendor/symfony/cache/Tests/Adapter/TagAwareAdapterTest.php b/advancedcontentfilter/vendor/symfony/cache/Tests/Adapter/TagAwareAdapterTest.php deleted file mode 100644 index 11907a03..00000000 --- a/advancedcontentfilter/vendor/symfony/cache/Tests/Adapter/TagAwareAdapterTest.php +++ /dev/null @@ -1,338 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Cache\Tests\Adapter; - -use PHPUnit\Framework\MockObject\MockObject; -use Psr\Cache\CacheItemInterface; -use Symfony\Component\Cache\Adapter\AdapterInterface; -use Symfony\Component\Cache\Adapter\ArrayAdapter; -use Symfony\Component\Cache\Adapter\FilesystemAdapter; -use Symfony\Component\Cache\Adapter\TagAwareAdapter; - -/** - * @group time-sensitive - */ -class TagAwareAdapterTest extends AdapterTestCase -{ - public function createCachePool($defaultLifetime = 0) - { - return new TagAwareAdapter(new FilesystemAdapter('', $defaultLifetime)); - } - - public static function tearDownAfterClass() - { - FilesystemAdapterTest::rmdir(sys_get_temp_dir().'/symfony-cache'); - } - - public function testInvalidTag() - { - $this->expectException('Psr\Cache\InvalidArgumentException'); - $pool = $this->createCachePool(); - $item = $pool->getItem('foo'); - $item->tag(':'); - } - - public function testInvalidateTags() - { - $pool = $this->createCachePool(); - - $i0 = $pool->getItem('i0'); - $i1 = $pool->getItem('i1'); - $i2 = $pool->getItem('i2'); - $i3 = $pool->getItem('i3'); - $foo = $pool->getItem('foo'); - - $pool->save($i0->tag('bar')); - $pool->save($i1->tag('foo')); - $pool->save($i2->tag('foo')->tag('bar')); - $pool->save($i3->tag('foo')->tag('baz')); - $pool->save($foo); - - $pool->invalidateTags(['bar']); - - $this->assertFalse($pool->getItem('i0')->isHit()); - $this->assertTrue($pool->getItem('i1')->isHit()); - $this->assertFalse($pool->getItem('i2')->isHit()); - $this->assertTrue($pool->getItem('i3')->isHit()); - $this->assertTrue($pool->getItem('foo')->isHit()); - - $pool->invalidateTags(['foo']); - - $this->assertFalse($pool->getItem('i1')->isHit()); - $this->assertFalse($pool->getItem('i3')->isHit()); - $this->assertTrue($pool->getItem('foo')->isHit()); - - $anotherPoolInstance = $this->createCachePool(); - - $this->assertFalse($anotherPoolInstance->getItem('i1')->isHit()); - $this->assertFalse($anotherPoolInstance->getItem('i3')->isHit()); - $this->assertTrue($anotherPoolInstance->getItem('foo')->isHit()); - } - - public function testInvalidateCommits() - { - $pool1 = $this->createCachePool(); - - $foo = $pool1->getItem('foo'); - $foo->tag('tag'); - - $pool1->saveDeferred($foo->set('foo')); - $pool1->invalidateTags(['tag']); - - $pool2 = $this->createCachePool(); - $foo = $pool2->getItem('foo'); - - $this->assertTrue($foo->isHit()); - } - - public function testTagsAreCleanedOnSave() - { - $pool = $this->createCachePool(); - - $i = $pool->getItem('k'); - $pool->save($i->tag('foo')); - - $i = $pool->getItem('k'); - $pool->save($i->tag('bar')); - - $pool->invalidateTags(['foo']); - $this->assertTrue($pool->getItem('k')->isHit()); - } - - public function testTagsAreCleanedOnDelete() - { - $pool = $this->createCachePool(); - - $i = $pool->getItem('k'); - $pool->save($i->tag('foo')); - $pool->deleteItem('k'); - - $pool->save($pool->getItem('k')); - $pool->invalidateTags(['foo']); - - $this->assertTrue($pool->getItem('k')->isHit()); - } - - public function testTagItemExpiry() - { - $pool = $this->createCachePool(10); - - $item = $pool->getItem('foo'); - $item->tag(['baz']); - $item->expiresAfter(100); - - $pool->save($item); - $pool->invalidateTags(['baz']); - $this->assertFalse($pool->getItem('foo')->isHit()); - - sleep(20); - - $this->assertFalse($pool->getItem('foo')->isHit()); - } - - public function testGetPreviousTags() - { - $pool = $this->createCachePool(); - - $i = $pool->getItem('k'); - $pool->save($i->tag('foo')); - - $i = $pool->getItem('k'); - $this->assertSame(['foo' => 'foo'], $i->getPreviousTags()); - } - - public function testPrune() - { - $cache = new TagAwareAdapter($this->getPruneableMock()); - $this->assertTrue($cache->prune()); - - $cache = new TagAwareAdapter($this->getNonPruneableMock()); - $this->assertFalse($cache->prune()); - - $cache = new TagAwareAdapter($this->getFailingPruneableMock()); - $this->assertFalse($cache->prune()); - } - - public function testKnownTagVersionsTtl() - { - $itemsPool = new FilesystemAdapter('', 10); - $tagsPool = $this - ->getMockBuilder(AdapterInterface::class) - ->getMock(); - - $pool = new TagAwareAdapter($itemsPool, $tagsPool, 10); - - $item = $pool->getItem('foo'); - $item->tag(['baz']); - $item->expiresAfter(100); - - $tag = $this->getMockBuilder(CacheItemInterface::class)->getMock(); - $tag->expects(self::exactly(2))->method('get')->willReturn(10); - - $tagsPool->expects(self::exactly(2))->method('getItems')->willReturn([ - 'baz'.TagAwareAdapter::TAGS_PREFIX => $tag, - ]); - - $pool->save($item); - $this->assertTrue($pool->getItem('foo')->isHit()); - $this->assertTrue($pool->getItem('foo')->isHit()); - - sleep(20); - - $this->assertTrue($pool->getItem('foo')->isHit()); - - sleep(5); - - $this->assertTrue($pool->getItem('foo')->isHit()); - } - - public function testTagEntryIsCreatedForItemWithoutTags() - { - $pool = $this->createCachePool(); - - $itemKey = 'foo'; - $item = $pool->getItem($itemKey); - $pool->save($item); - - $adapter = new FilesystemAdapter(); - $this->assertTrue($adapter->hasItem(TagAwareAdapter::TAGS_PREFIX.$itemKey)); - } - - public function testHasItemReturnsFalseWhenPoolDoesNotHaveItemTags() - { - $pool = $this->createCachePool(); - - $itemKey = 'foo'; - $item = $pool->getItem($itemKey); - $pool->save($item); - - $anotherPool = $this->createCachePool(); - - $adapter = new FilesystemAdapter(); - $adapter->deleteItem(TagAwareAdapter::TAGS_PREFIX.$itemKey); //simulate item losing tags pair - - $this->assertFalse($anotherPool->hasItem($itemKey)); - } - - public function testGetItemReturnsCacheMissWhenPoolDoesNotHaveItemTags() - { - $pool = $this->createCachePool(); - - $itemKey = 'foo'; - $item = $pool->getItem($itemKey); - $pool->save($item); - - $anotherPool = $this->createCachePool(); - - $adapter = new FilesystemAdapter(); - $adapter->deleteItem(TagAwareAdapter::TAGS_PREFIX.$itemKey); //simulate item losing tags pair - - $item = $anotherPool->getItem($itemKey); - $this->assertFalse($item->isHit()); - } - - public function testHasItemReturnsFalseWhenPoolDoesNotHaveItemAndOnlyHasTags() - { - $pool = $this->createCachePool(); - - $itemKey = 'foo'; - $item = $pool->getItem($itemKey); - $pool->save($item); - - $anotherPool = $this->createCachePool(); - - $adapter = new FilesystemAdapter(); - $adapter->deleteItem($itemKey); //simulate losing item but keeping tags - - $this->assertFalse($anotherPool->hasItem($itemKey)); - } - - public function testInvalidateTagsWithArrayAdapter() - { - $adapter = new TagAwareAdapter(new ArrayAdapter()); - - $item = $adapter->getItem('foo'); - - $this->assertFalse($item->isHit()); - - $item->tag('bar'); - $item->expiresAfter(100); - $adapter->save($item); - - $this->assertTrue($adapter->getItem('foo')->isHit()); - - $adapter->invalidateTags(['bar']); - - $this->assertFalse($adapter->getItem('foo')->isHit()); - } - - public function testGetItemReturnsCacheMissWhenPoolDoesNotHaveItemAndOnlyHasTags() - { - $pool = $this->createCachePool(); - - $itemKey = 'foo'; - $item = $pool->getItem($itemKey); - $pool->save($item); - - $anotherPool = $this->createCachePool(); - - $adapter = new FilesystemAdapter(); - $adapter->deleteItem($itemKey); //simulate losing item but keeping tags - - $item = $anotherPool->getItem($itemKey); - $this->assertFalse($item->isHit()); - } - - /** - * @return MockObject|PruneableCacheInterface - */ - private function getPruneableMock() - { - $pruneable = $this - ->getMockBuilder(PruneableCacheInterface::class) - ->getMock(); - - $pruneable - ->expects($this->atLeastOnce()) - ->method('prune') - ->willReturn(true); - - return $pruneable; - } - - /** - * @return MockObject|PruneableCacheInterface - */ - private function getFailingPruneableMock() - { - $pruneable = $this - ->getMockBuilder(PruneableCacheInterface::class) - ->getMock(); - - $pruneable - ->expects($this->atLeastOnce()) - ->method('prune') - ->willReturn(false); - - return $pruneable; - } - - /** - * @return MockObject|AdapterInterface - */ - private function getNonPruneableMock() - { - return $this - ->getMockBuilder(AdapterInterface::class) - ->getMock(); - } -} diff --git a/advancedcontentfilter/vendor/symfony/cache/Tests/Adapter/TagAwareAndProxyAdapterIntegrationTest.php b/advancedcontentfilter/vendor/symfony/cache/Tests/Adapter/TagAwareAndProxyAdapterIntegrationTest.php deleted file mode 100644 index b11c1f28..00000000 --- a/advancedcontentfilter/vendor/symfony/cache/Tests/Adapter/TagAwareAndProxyAdapterIntegrationTest.php +++ /dev/null @@ -1,38 +0,0 @@ -getItem('foo'); - $item->tag(['tag1', 'tag2']); - $item->set('bar'); - $cache->save($item); - - $this->assertSame('bar', $cache->getItem('foo')->get()); - } - - public function dataProvider() - { - return [ - [new ArrayAdapter()], - // also testing with a non-AdapterInterface implementation - // because the ProxyAdapter behaves slightly different for those - [new ExternalAdapter()], - ]; - } -} diff --git a/advancedcontentfilter/vendor/symfony/cache/Tests/Adapter/TraceableAdapterTest.php b/advancedcontentfilter/vendor/symfony/cache/Tests/Adapter/TraceableAdapterTest.php deleted file mode 100644 index 35eba7d7..00000000 --- a/advancedcontentfilter/vendor/symfony/cache/Tests/Adapter/TraceableAdapterTest.php +++ /dev/null @@ -1,191 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Cache\Tests\Adapter; - -use Symfony\Component\Cache\Adapter\FilesystemAdapter; -use Symfony\Component\Cache\Adapter\TraceableAdapter; - -/** - * @group time-sensitive - */ -class TraceableAdapterTest extends AdapterTestCase -{ - protected $skippedTests = [ - 'testPrune' => 'TraceableAdapter just proxies', - ]; - - public function createCachePool($defaultLifetime = 0) - { - return new TraceableAdapter(new FilesystemAdapter('', $defaultLifetime)); - } - - public function testGetItemMissTrace() - { - $pool = $this->createCachePool(); - $pool->getItem('k'); - $calls = $pool->getCalls(); - $this->assertCount(1, $calls); - - $call = $calls[0]; - $this->assertSame('getItem', $call->name); - $this->assertSame(['k' => false], $call->result); - $this->assertSame(0, $call->hits); - $this->assertSame(1, $call->misses); - $this->assertNotEmpty($call->start); - $this->assertNotEmpty($call->end); - } - - public function testGetItemHitTrace() - { - $pool = $this->createCachePool(); - $item = $pool->getItem('k')->set('foo'); - $pool->save($item); - $pool->getItem('k'); - $calls = $pool->getCalls(); - $this->assertCount(3, $calls); - - $call = $calls[2]; - $this->assertSame(1, $call->hits); - $this->assertSame(0, $call->misses); - } - - public function testGetItemsMissTrace() - { - $pool = $this->createCachePool(); - $arg = ['k0', 'k1']; - $items = $pool->getItems($arg); - foreach ($items as $item) { - } - $calls = $pool->getCalls(); - $this->assertCount(1, $calls); - - $call = $calls[0]; - $this->assertSame('getItems', $call->name); - $this->assertSame(['k0' => false, 'k1' => false], $call->result); - $this->assertSame(2, $call->misses); - $this->assertNotEmpty($call->start); - $this->assertNotEmpty($call->end); - } - - public function testHasItemMissTrace() - { - $pool = $this->createCachePool(); - $pool->hasItem('k'); - $calls = $pool->getCalls(); - $this->assertCount(1, $calls); - - $call = $calls[0]; - $this->assertSame('hasItem', $call->name); - $this->assertSame(['k' => false], $call->result); - $this->assertNotEmpty($call->start); - $this->assertNotEmpty($call->end); - } - - public function testHasItemHitTrace() - { - $pool = $this->createCachePool(); - $item = $pool->getItem('k')->set('foo'); - $pool->save($item); - $pool->hasItem('k'); - $calls = $pool->getCalls(); - $this->assertCount(3, $calls); - - $call = $calls[2]; - $this->assertSame('hasItem', $call->name); - $this->assertSame(['k' => true], $call->result); - $this->assertNotEmpty($call->start); - $this->assertNotEmpty($call->end); - } - - public function testDeleteItemTrace() - { - $pool = $this->createCachePool(); - $pool->deleteItem('k'); - $calls = $pool->getCalls(); - $this->assertCount(1, $calls); - - $call = $calls[0]; - $this->assertSame('deleteItem', $call->name); - $this->assertSame(['k' => true], $call->result); - $this->assertSame(0, $call->hits); - $this->assertSame(0, $call->misses); - $this->assertNotEmpty($call->start); - $this->assertNotEmpty($call->end); - } - - public function testDeleteItemsTrace() - { - $pool = $this->createCachePool(); - $arg = ['k0', 'k1']; - $pool->deleteItems($arg); - $calls = $pool->getCalls(); - $this->assertCount(1, $calls); - - $call = $calls[0]; - $this->assertSame('deleteItems', $call->name); - $this->assertSame(['keys' => $arg, 'result' => true], $call->result); - $this->assertSame(0, $call->hits); - $this->assertSame(0, $call->misses); - $this->assertNotEmpty($call->start); - $this->assertNotEmpty($call->end); - } - - public function testSaveTrace() - { - $pool = $this->createCachePool(); - $item = $pool->getItem('k')->set('foo'); - $pool->save($item); - $calls = $pool->getCalls(); - $this->assertCount(2, $calls); - - $call = $calls[1]; - $this->assertSame('save', $call->name); - $this->assertSame(['k' => true], $call->result); - $this->assertSame(0, $call->hits); - $this->assertSame(0, $call->misses); - $this->assertNotEmpty($call->start); - $this->assertNotEmpty($call->end); - } - - public function testSaveDeferredTrace() - { - $pool = $this->createCachePool(); - $item = $pool->getItem('k')->set('foo'); - $pool->saveDeferred($item); - $calls = $pool->getCalls(); - $this->assertCount(2, $calls); - - $call = $calls[1]; - $this->assertSame('saveDeferred', $call->name); - $this->assertSame(['k' => true], $call->result); - $this->assertSame(0, $call->hits); - $this->assertSame(0, $call->misses); - $this->assertNotEmpty($call->start); - $this->assertNotEmpty($call->end); - } - - public function testCommitTrace() - { - $pool = $this->createCachePool(); - $pool->commit(); - $calls = $pool->getCalls(); - $this->assertCount(1, $calls); - - $call = $calls[0]; - $this->assertSame('commit', $call->name); - $this->assertTrue($call->result); - $this->assertSame(0, $call->hits); - $this->assertSame(0, $call->misses); - $this->assertNotEmpty($call->start); - $this->assertNotEmpty($call->end); - } -} diff --git a/advancedcontentfilter/vendor/symfony/cache/Tests/Adapter/TraceableTagAwareAdapterTest.php b/advancedcontentfilter/vendor/symfony/cache/Tests/Adapter/TraceableTagAwareAdapterTest.php deleted file mode 100644 index 5cd4185c..00000000 --- a/advancedcontentfilter/vendor/symfony/cache/Tests/Adapter/TraceableTagAwareAdapterTest.php +++ /dev/null @@ -1,37 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Cache\Tests\Adapter; - -use Symfony\Component\Cache\Adapter\FilesystemAdapter; -use Symfony\Component\Cache\Adapter\TagAwareAdapter; -use Symfony\Component\Cache\Adapter\TraceableTagAwareAdapter; - -/** - * @group time-sensitive - */ -class TraceableTagAwareAdapterTest extends TraceableAdapterTest -{ - public function testInvalidateTags() - { - $pool = new TraceableTagAwareAdapter(new TagAwareAdapter(new FilesystemAdapter())); - $pool->invalidateTags(['foo']); - $calls = $pool->getCalls(); - $this->assertCount(1, $calls); - - $call = $calls[0]; - $this->assertSame('invalidateTags', $call->name); - $this->assertSame(0, $call->hits); - $this->assertSame(0, $call->misses); - $this->assertNotEmpty($call->start); - $this->assertNotEmpty($call->end); - } -} diff --git a/advancedcontentfilter/vendor/symfony/cache/Tests/CacheItemTest.php b/advancedcontentfilter/vendor/symfony/cache/Tests/CacheItemTest.php deleted file mode 100644 index 28c681d1..00000000 --- a/advancedcontentfilter/vendor/symfony/cache/Tests/CacheItemTest.php +++ /dev/null @@ -1,77 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Cache\Tests; - -use PHPUnit\Framework\TestCase; -use Symfony\Component\Cache\CacheItem; - -class CacheItemTest extends TestCase -{ - public function testValidKey() - { - $this->assertSame('foo', CacheItem::validateKey('foo')); - } - - /** - * @dataProvider provideInvalidKey - */ - public function testInvalidKey($key) - { - $this->expectException('Symfony\Component\Cache\Exception\InvalidArgumentException'); - $this->expectExceptionMessage('Cache key'); - CacheItem::validateKey($key); - } - - public function provideInvalidKey() - { - return [ - [''], - ['{'], - ['}'], - ['('], - [')'], - ['/'], - ['\\'], - ['@'], - [':'], - [true], - [null], - [1], - [1.1], - [[[]]], - [new \Exception('foo')], - ]; - } - - public function testTag() - { - $item = new CacheItem(); - - $this->assertSame($item, $item->tag('foo')); - $this->assertSame($item, $item->tag(['bar', 'baz'])); - - \call_user_func(\Closure::bind(function () use ($item) { - $this->assertSame(['foo' => 'foo', 'bar' => 'bar', 'baz' => 'baz'], $item->tags); - }, $this, CacheItem::class)); - } - - /** - * @dataProvider provideInvalidKey - */ - public function testInvalidTag($tag) - { - $this->expectException('Symfony\Component\Cache\Exception\InvalidArgumentException'); - $this->expectExceptionMessage('Cache tag'); - $item = new CacheItem(); - $item->tag($tag); - } -} diff --git a/advancedcontentfilter/vendor/symfony/cache/Tests/DoctrineProviderTest.php b/advancedcontentfilter/vendor/symfony/cache/Tests/DoctrineProviderTest.php deleted file mode 100644 index 91a5516a..00000000 --- a/advancedcontentfilter/vendor/symfony/cache/Tests/DoctrineProviderTest.php +++ /dev/null @@ -1,45 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Cache\Tests; - -use Doctrine\Common\Cache\CacheProvider; -use PHPUnit\Framework\TestCase; -use Symfony\Component\Cache\Adapter\ArrayAdapter; -use Symfony\Component\Cache\DoctrineProvider; - -class DoctrineProviderTest extends TestCase -{ - public function testProvider() - { - $pool = new ArrayAdapter(); - $cache = new DoctrineProvider($pool); - - $this->assertInstanceOf(CacheProvider::class, $cache); - - $key = '{}()/\@:'; - - $this->assertTrue($cache->delete($key)); - $this->assertFalse($cache->contains($key)); - - $this->assertTrue($cache->save($key, 'bar')); - $this->assertTrue($cache->contains($key)); - $this->assertSame('bar', $cache->fetch($key)); - - $this->assertTrue($cache->delete($key)); - $this->assertFalse($cache->fetch($key)); - $this->assertTrue($cache->save($key, 'bar')); - - $cache->flushAll(); - $this->assertFalse($cache->fetch($key)); - $this->assertFalse($cache->contains($key)); - } -} diff --git a/advancedcontentfilter/vendor/symfony/cache/Tests/Fixtures/ArrayCache.php b/advancedcontentfilter/vendor/symfony/cache/Tests/Fixtures/ArrayCache.php deleted file mode 100644 index 13b4f330..00000000 --- a/advancedcontentfilter/vendor/symfony/cache/Tests/Fixtures/ArrayCache.php +++ /dev/null @@ -1,52 +0,0 @@ -doContains($id) ? $this->data[$id][0] : false; - } - - protected function doContains($id) - { - if (!isset($this->data[$id])) { - return false; - } - - $expiry = $this->data[$id][1]; - - return !$expiry || time() < $expiry || !$this->doDelete($id); - } - - protected function doSave($id, $data, $lifeTime = 0) - { - $this->data[$id] = [$data, $lifeTime ? time() + $lifeTime : false]; - - return true; - } - - protected function doDelete($id) - { - unset($this->data[$id]); - - return true; - } - - protected function doFlush() - { - $this->data = []; - - return true; - } - - protected function doGetStats() - { - return null; - } -} diff --git a/advancedcontentfilter/vendor/symfony/cache/Tests/Fixtures/ExternalAdapter.php b/advancedcontentfilter/vendor/symfony/cache/Tests/Fixtures/ExternalAdapter.php deleted file mode 100644 index be1f9901..00000000 --- a/advancedcontentfilter/vendor/symfony/cache/Tests/Fixtures/ExternalAdapter.php +++ /dev/null @@ -1,76 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Cache\Tests\Fixtures; - -use Psr\Cache\CacheItemInterface; -use Psr\Cache\CacheItemPoolInterface; -use Symfony\Component\Cache\Adapter\ArrayAdapter; - -/** - * Adapter not implementing the {@see \Symfony\Component\Cache\Adapter\AdapterInterface}. - * - * @author Kévin Dunglas - */ -class ExternalAdapter implements CacheItemPoolInterface -{ - private $cache; - - public function __construct($defaultLifetime = 0) - { - $this->cache = new ArrayAdapter($defaultLifetime); - } - - public function getItem($key) - { - return $this->cache->getItem($key); - } - - public function getItems(array $keys = []) - { - return $this->cache->getItems($keys); - } - - public function hasItem($key) - { - return $this->cache->hasItem($key); - } - - public function clear() - { - return $this->cache->clear(); - } - - public function deleteItem($key) - { - return $this->cache->deleteItem($key); - } - - public function deleteItems(array $keys) - { - return $this->cache->deleteItems($keys); - } - - public function save(CacheItemInterface $item) - { - return $this->cache->save($item); - } - - public function saveDeferred(CacheItemInterface $item) - { - return $this->cache->saveDeferred($item); - } - - public function commit() - { - return $this->cache->commit(); - } -} diff --git a/advancedcontentfilter/vendor/symfony/cache/Tests/Simple/AbstractRedisCacheTest.php b/advancedcontentfilter/vendor/symfony/cache/Tests/Simple/AbstractRedisCacheTest.php deleted file mode 100644 index 7a6cabe8..00000000 --- a/advancedcontentfilter/vendor/symfony/cache/Tests/Simple/AbstractRedisCacheTest.php +++ /dev/null @@ -1,47 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Cache\Tests\Simple; - -use Symfony\Component\Cache\Simple\RedisCache; - -abstract class AbstractRedisCacheTest extends CacheTestCase -{ - protected $skippedTests = [ - 'testSetTtl' => 'Testing expiration slows down the test suite', - 'testSetMultipleTtl' => 'Testing expiration slows down the test suite', - 'testDefaultLifeTime' => 'Testing expiration slows down the test suite', - ]; - - protected static $redis; - - public function createSimpleCache($defaultLifetime = 0) - { - return new RedisCache(self::$redis, str_replace('\\', '.', __CLASS__), $defaultLifetime); - } - - public static function setUpBeforeClass() - { - if (!\extension_loaded('redis')) { - self::markTestSkipped('Extension redis required.'); - } - try { - (new \Redis())->connect(getenv('REDIS_HOST')); - } catch (\Exception $e) { - self::markTestSkipped($e->getMessage()); - } - } - - public static function tearDownAfterClass() - { - self::$redis = null; - } -} diff --git a/advancedcontentfilter/vendor/symfony/cache/Tests/Simple/ApcuCacheTest.php b/advancedcontentfilter/vendor/symfony/cache/Tests/Simple/ApcuCacheTest.php deleted file mode 100644 index fad0c043..00000000 --- a/advancedcontentfilter/vendor/symfony/cache/Tests/Simple/ApcuCacheTest.php +++ /dev/null @@ -1,35 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Cache\Tests\Simple; - -use Symfony\Component\Cache\Simple\ApcuCache; - -class ApcuCacheTest extends CacheTestCase -{ - protected $skippedTests = [ - 'testSetTtl' => 'Testing expiration slows down the test suite', - 'testSetMultipleTtl' => 'Testing expiration slows down the test suite', - 'testDefaultLifeTime' => 'Testing expiration slows down the test suite', - ]; - - public function createSimpleCache($defaultLifetime = 0) - { - if (!\function_exists('apcu_fetch') || !filter_var(ini_get('apc.enabled'), \FILTER_VALIDATE_BOOLEAN) || ('cli' === \PHP_SAPI && !filter_var(ini_get('apc.enable_cli'), \FILTER_VALIDATE_BOOLEAN))) { - $this->markTestSkipped('APCu extension is required.'); - } - if ('\\' === \DIRECTORY_SEPARATOR) { - $this->markTestSkipped('Fails transiently on Windows.'); - } - - return new ApcuCache(str_replace('\\', '.', __CLASS__), $defaultLifetime); - } -} diff --git a/advancedcontentfilter/vendor/symfony/cache/Tests/Simple/ArrayCacheTest.php b/advancedcontentfilter/vendor/symfony/cache/Tests/Simple/ArrayCacheTest.php deleted file mode 100644 index 26c3e14d..00000000 --- a/advancedcontentfilter/vendor/symfony/cache/Tests/Simple/ArrayCacheTest.php +++ /dev/null @@ -1,25 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Cache\Tests\Simple; - -use Symfony\Component\Cache\Simple\ArrayCache; - -/** - * @group time-sensitive - */ -class ArrayCacheTest extends CacheTestCase -{ - public function createSimpleCache($defaultLifetime = 0) - { - return new ArrayCache($defaultLifetime); - } -} diff --git a/advancedcontentfilter/vendor/symfony/cache/Tests/Simple/CacheTestCase.php b/advancedcontentfilter/vendor/symfony/cache/Tests/Simple/CacheTestCase.php deleted file mode 100644 index ff9944a3..00000000 --- a/advancedcontentfilter/vendor/symfony/cache/Tests/Simple/CacheTestCase.php +++ /dev/null @@ -1,150 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Cache\Tests\Simple; - -use Cache\IntegrationTests\SimpleCacheTest; -use Psr\SimpleCache\CacheInterface; -use Symfony\Component\Cache\PruneableInterface; - -abstract class CacheTestCase extends SimpleCacheTest -{ - protected function setUp() - { - parent::setUp(); - - if (!\array_key_exists('testPrune', $this->skippedTests) && !$this->createSimpleCache() instanceof PruneableInterface) { - $this->skippedTests['testPrune'] = 'Not a pruneable cache pool.'; - } - } - - public static function validKeys() - { - if (\defined('HHVM_VERSION')) { - return parent::validKeys(); - } - - return array_merge(parent::validKeys(), [["a\0b"]]); - } - - public function testDefaultLifeTime() - { - if (isset($this->skippedTests[__FUNCTION__])) { - $this->markTestSkipped($this->skippedTests[__FUNCTION__]); - } - - $cache = $this->createSimpleCache(2); - $cache->clear(); - - $cache->set('key.dlt', 'value'); - sleep(1); - - $this->assertSame('value', $cache->get('key.dlt')); - - sleep(2); - $this->assertNull($cache->get('key.dlt')); - - $cache->clear(); - } - - public function testNotUnserializable() - { - if (isset($this->skippedTests[__FUNCTION__])) { - $this->markTestSkipped($this->skippedTests[__FUNCTION__]); - } - - $cache = $this->createSimpleCache(); - $cache->clear(); - - $cache->set('foo', new NotUnserializable()); - - $this->assertNull($cache->get('foo')); - - $cache->setMultiple(['foo' => new NotUnserializable()]); - - foreach ($cache->getMultiple(['foo']) as $value) { - } - $this->assertNull($value); - - $cache->clear(); - } - - public function testPrune() - { - if (isset($this->skippedTests[__FUNCTION__])) { - $this->markTestSkipped($this->skippedTests[__FUNCTION__]); - } - - if (!method_exists($this, 'isPruned')) { - $this->fail('Test classes for pruneable caches must implement `isPruned($cache, $name)` method.'); - } - - /** @var PruneableInterface|CacheInterface $cache */ - $cache = $this->createSimpleCache(); - $cache->clear(); - - $cache->set('foo', 'foo-val', new \DateInterval('PT05S')); - $cache->set('bar', 'bar-val', new \DateInterval('PT10S')); - $cache->set('baz', 'baz-val', new \DateInterval('PT15S')); - $cache->set('qux', 'qux-val', new \DateInterval('PT20S')); - - sleep(30); - $cache->prune(); - $this->assertTrue($this->isPruned($cache, 'foo')); - $this->assertTrue($this->isPruned($cache, 'bar')); - $this->assertTrue($this->isPruned($cache, 'baz')); - $this->assertTrue($this->isPruned($cache, 'qux')); - - $cache->set('foo', 'foo-val'); - $cache->set('bar', 'bar-val', new \DateInterval('PT20S')); - $cache->set('baz', 'baz-val', new \DateInterval('PT40S')); - $cache->set('qux', 'qux-val', new \DateInterval('PT80S')); - - $cache->prune(); - $this->assertFalse($this->isPruned($cache, 'foo')); - $this->assertFalse($this->isPruned($cache, 'bar')); - $this->assertFalse($this->isPruned($cache, 'baz')); - $this->assertFalse($this->isPruned($cache, 'qux')); - - sleep(30); - $cache->prune(); - $this->assertFalse($this->isPruned($cache, 'foo')); - $this->assertTrue($this->isPruned($cache, 'bar')); - $this->assertFalse($this->isPruned($cache, 'baz')); - $this->assertFalse($this->isPruned($cache, 'qux')); - - sleep(30); - $cache->prune(); - $this->assertFalse($this->isPruned($cache, 'foo')); - $this->assertTrue($this->isPruned($cache, 'baz')); - $this->assertFalse($this->isPruned($cache, 'qux')); - - sleep(30); - $cache->prune(); - $this->assertFalse($this->isPruned($cache, 'foo')); - $this->assertTrue($this->isPruned($cache, 'qux')); - - $cache->clear(); - } -} - -class NotUnserializable implements \Serializable -{ - public function serialize() - { - return serialize(123); - } - - public function unserialize($ser) - { - throw new \Exception(__CLASS__); - } -} diff --git a/advancedcontentfilter/vendor/symfony/cache/Tests/Simple/ChainCacheTest.php b/advancedcontentfilter/vendor/symfony/cache/Tests/Simple/ChainCacheTest.php deleted file mode 100644 index f216bc1f..00000000 --- a/advancedcontentfilter/vendor/symfony/cache/Tests/Simple/ChainCacheTest.php +++ /dev/null @@ -1,113 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Cache\Tests\Simple; - -use PHPUnit\Framework\MockObject\MockObject; -use Psr\SimpleCache\CacheInterface; -use Symfony\Component\Cache\PruneableInterface; -use Symfony\Component\Cache\Simple\ArrayCache; -use Symfony\Component\Cache\Simple\ChainCache; -use Symfony\Component\Cache\Simple\FilesystemCache; - -/** - * @group time-sensitive - */ -class ChainCacheTest extends CacheTestCase -{ - public function createSimpleCache($defaultLifetime = 0) - { - return new ChainCache([new ArrayCache($defaultLifetime), new FilesystemCache('', $defaultLifetime)], $defaultLifetime); - } - - public function testEmptyCachesException() - { - $this->expectException('Symfony\Component\Cache\Exception\InvalidArgumentException'); - $this->expectExceptionMessage('At least one cache must be specified.'); - new ChainCache([]); - } - - public function testInvalidCacheException() - { - $this->expectException('Symfony\Component\Cache\Exception\InvalidArgumentException'); - $this->expectExceptionMessage('The class "stdClass" does not implement'); - new ChainCache([new \stdClass()]); - } - - public function testPrune() - { - if (isset($this->skippedTests[__FUNCTION__])) { - $this->markTestSkipped($this->skippedTests[__FUNCTION__]); - } - - $cache = new ChainCache([ - $this->getPruneableMock(), - $this->getNonPruneableMock(), - $this->getPruneableMock(), - ]); - $this->assertTrue($cache->prune()); - - $cache = new ChainCache([ - $this->getPruneableMock(), - $this->getFailingPruneableMock(), - $this->getPruneableMock(), - ]); - $this->assertFalse($cache->prune()); - } - - /** - * @return MockObject|PruneableCacheInterface - */ - private function getPruneableMock() - { - $pruneable = $this - ->getMockBuilder(PruneableCacheInterface::class) - ->getMock(); - - $pruneable - ->expects($this->atLeastOnce()) - ->method('prune') - ->willReturn(true); - - return $pruneable; - } - - /** - * @return MockObject|PruneableCacheInterface - */ - private function getFailingPruneableMock() - { - $pruneable = $this - ->getMockBuilder(PruneableCacheInterface::class) - ->getMock(); - - $pruneable - ->expects($this->atLeastOnce()) - ->method('prune') - ->willReturn(false); - - return $pruneable; - } - - /** - * @return MockObject|CacheInterface - */ - private function getNonPruneableMock() - { - return $this - ->getMockBuilder(CacheInterface::class) - ->getMock(); - } -} - -interface PruneableCacheInterface extends PruneableInterface, CacheInterface -{ -} diff --git a/advancedcontentfilter/vendor/symfony/cache/Tests/Simple/DoctrineCacheTest.php b/advancedcontentfilter/vendor/symfony/cache/Tests/Simple/DoctrineCacheTest.php deleted file mode 100644 index af4331d6..00000000 --- a/advancedcontentfilter/vendor/symfony/cache/Tests/Simple/DoctrineCacheTest.php +++ /dev/null @@ -1,31 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Cache\Tests\Simple; - -use Symfony\Component\Cache\Simple\DoctrineCache; -use Symfony\Component\Cache\Tests\Fixtures\ArrayCache; - -/** - * @group time-sensitive - */ -class DoctrineCacheTest extends CacheTestCase -{ - protected $skippedTests = [ - 'testObjectDoesNotChangeInCache' => 'ArrayCache does not use serialize/unserialize', - 'testNotUnserializable' => 'ArrayCache does not use serialize/unserialize', - ]; - - public function createSimpleCache($defaultLifetime = 0) - { - return new DoctrineCache(new ArrayCache($defaultLifetime), '', $defaultLifetime); - } -} diff --git a/advancedcontentfilter/vendor/symfony/cache/Tests/Simple/FilesystemCacheTest.php b/advancedcontentfilter/vendor/symfony/cache/Tests/Simple/FilesystemCacheTest.php deleted file mode 100644 index 620305a5..00000000 --- a/advancedcontentfilter/vendor/symfony/cache/Tests/Simple/FilesystemCacheTest.php +++ /dev/null @@ -1,34 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Cache\Tests\Simple; - -use Psr\SimpleCache\CacheInterface; -use Symfony\Component\Cache\Simple\FilesystemCache; - -/** - * @group time-sensitive - */ -class FilesystemCacheTest extends CacheTestCase -{ - public function createSimpleCache($defaultLifetime = 0) - { - return new FilesystemCache('', $defaultLifetime); - } - - protected function isPruned(CacheInterface $cache, $name) - { - $getFileMethod = (new \ReflectionObject($cache))->getMethod('getFile'); - $getFileMethod->setAccessible(true); - - return !file_exists($getFileMethod->invoke($cache, $name)); - } -} diff --git a/advancedcontentfilter/vendor/symfony/cache/Tests/Simple/MemcachedCacheTest.php b/advancedcontentfilter/vendor/symfony/cache/Tests/Simple/MemcachedCacheTest.php deleted file mode 100644 index 6df682e9..00000000 --- a/advancedcontentfilter/vendor/symfony/cache/Tests/Simple/MemcachedCacheTest.php +++ /dev/null @@ -1,178 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Cache\Tests\Simple; - -use Symfony\Component\Cache\Adapter\AbstractAdapter; -use Symfony\Component\Cache\Simple\MemcachedCache; - -class MemcachedCacheTest extends CacheTestCase -{ - protected $skippedTests = [ - 'testSetTtl' => 'Testing expiration slows down the test suite', - 'testSetMultipleTtl' => 'Testing expiration slows down the test suite', - 'testDefaultLifeTime' => 'Testing expiration slows down the test suite', - ]; - - protected static $client; - - public static function setUpBeforeClass() - { - if (!MemcachedCache::isSupported()) { - self::markTestSkipped('Extension memcached >=2.2.0 required.'); - } - self::$client = AbstractAdapter::createConnection('memcached://'.getenv('MEMCACHED_HOST')); - self::$client->get('foo'); - $code = self::$client->getResultCode(); - - if (\Memcached::RES_SUCCESS !== $code && \Memcached::RES_NOTFOUND !== $code) { - self::markTestSkipped('Memcached error: '.strtolower(self::$client->getResultMessage())); - } - } - - public function createSimpleCache($defaultLifetime = 0) - { - $client = $defaultLifetime ? AbstractAdapter::createConnection('memcached://'.getenv('MEMCACHED_HOST'), ['binary_protocol' => false]) : self::$client; - - return new MemcachedCache($client, str_replace('\\', '.', __CLASS__), $defaultLifetime); - } - - public function testCreatePersistentConnectionShouldNotDupServerList() - { - $instance = MemcachedCache::createConnection('memcached://'.getenv('MEMCACHED_HOST'), ['persistent_id' => 'persistent']); - $this->assertCount(1, $instance->getServerList()); - - $instance = MemcachedCache::createConnection('memcached://'.getenv('MEMCACHED_HOST'), ['persistent_id' => 'persistent']); - $this->assertCount(1, $instance->getServerList()); - } - - public function testOptions() - { - $client = MemcachedCache::createConnection([], [ - 'libketama_compatible' => false, - 'distribution' => 'modula', - 'compression' => true, - 'serializer' => 'php', - 'hash' => 'md5', - ]); - - $this->assertSame(\Memcached::SERIALIZER_PHP, $client->getOption(\Memcached::OPT_SERIALIZER)); - $this->assertSame(\Memcached::HASH_MD5, $client->getOption(\Memcached::OPT_HASH)); - $this->assertTrue($client->getOption(\Memcached::OPT_COMPRESSION)); - $this->assertSame(0, $client->getOption(\Memcached::OPT_LIBKETAMA_COMPATIBLE)); - $this->assertSame(\Memcached::DISTRIBUTION_MODULA, $client->getOption(\Memcached::OPT_DISTRIBUTION)); - } - - /** - * @dataProvider provideBadOptions - */ - public function testBadOptions($name, $value) - { - if (\PHP_VERSION_ID < 80000) { - $this->expectException('ErrorException'); - $this->expectExceptionMessage('constant(): Couldn\'t find constant Memcached::'); - } else { - $this->expectException('Error'); - $this->expectExceptionMessage('Undefined constant Memcached::'); - } - - MemcachedCache::createConnection([], [$name => $value]); - } - - public function provideBadOptions() - { - return [ - ['foo', 'bar'], - ['hash', 'zyx'], - ['serializer', 'zyx'], - ['distribution', 'zyx'], - ]; - } - - public function testDefaultOptions() - { - $this->assertTrue(MemcachedCache::isSupported()); - - $client = MemcachedCache::createConnection([]); - - $this->assertTrue($client->getOption(\Memcached::OPT_COMPRESSION)); - $this->assertSame(1, $client->getOption(\Memcached::OPT_BINARY_PROTOCOL)); - $this->assertSame(1, $client->getOption(\Memcached::OPT_LIBKETAMA_COMPATIBLE)); - } - - public function testOptionSerializer() - { - $this->expectException('Symfony\Component\Cache\Exception\CacheException'); - $this->expectExceptionMessage('MemcachedAdapter: "serializer" option must be "php" or "igbinary".'); - if (!\Memcached::HAVE_JSON) { - $this->markTestSkipped('Memcached::HAVE_JSON required'); - } - - new MemcachedCache(MemcachedCache::createConnection([], ['serializer' => 'json'])); - } - - /** - * @dataProvider provideServersSetting - */ - public function testServersSetting($dsn, $host, $port) - { - $client1 = MemcachedCache::createConnection($dsn); - $client2 = MemcachedCache::createConnection([$dsn]); - $client3 = MemcachedCache::createConnection([[$host, $port]]); - $expect = [ - 'host' => $host, - 'port' => $port, - ]; - - $f = function ($s) { return ['host' => $s['host'], 'port' => $s['port']]; }; - $this->assertSame([$expect], array_map($f, $client1->getServerList())); - $this->assertSame([$expect], array_map($f, $client2->getServerList())); - $this->assertSame([$expect], array_map($f, $client3->getServerList())); - } - - public function provideServersSetting() - { - yield [ - 'memcached://127.0.0.1/50', - '127.0.0.1', - 11211, - ]; - yield [ - 'memcached://localhost:11222?weight=25', - 'localhost', - 11222, - ]; - if (filter_var(ini_get('memcached.use_sasl'), \FILTER_VALIDATE_BOOLEAN)) { - yield [ - 'memcached://user:password@127.0.0.1?weight=50', - '127.0.0.1', - 11211, - ]; - } - yield [ - 'memcached:///var/run/memcached.sock?weight=25', - '/var/run/memcached.sock', - 0, - ]; - yield [ - 'memcached:///var/local/run/memcached.socket?weight=25', - '/var/local/run/memcached.socket', - 0, - ]; - if (filter_var(ini_get('memcached.use_sasl'), \FILTER_VALIDATE_BOOLEAN)) { - yield [ - 'memcached://user:password@/var/local/run/memcached.socket?weight=25', - '/var/local/run/memcached.socket', - 0, - ]; - } - } -} diff --git a/advancedcontentfilter/vendor/symfony/cache/Tests/Simple/MemcachedCacheTextModeTest.php b/advancedcontentfilter/vendor/symfony/cache/Tests/Simple/MemcachedCacheTextModeTest.php deleted file mode 100644 index 13865a60..00000000 --- a/advancedcontentfilter/vendor/symfony/cache/Tests/Simple/MemcachedCacheTextModeTest.php +++ /dev/null @@ -1,25 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Cache\Tests\Simple; - -use Symfony\Component\Cache\Adapter\AbstractAdapter; -use Symfony\Component\Cache\Simple\MemcachedCache; - -class MemcachedCacheTextModeTest extends MemcachedCacheTest -{ - public function createSimpleCache($defaultLifetime = 0) - { - $client = AbstractAdapter::createConnection('memcached://'.getenv('MEMCACHED_HOST'), ['binary_protocol' => false]); - - return new MemcachedCache($client, str_replace('\\', '.', __CLASS__), $defaultLifetime); - } -} diff --git a/advancedcontentfilter/vendor/symfony/cache/Tests/Simple/NullCacheTest.php b/advancedcontentfilter/vendor/symfony/cache/Tests/Simple/NullCacheTest.php deleted file mode 100644 index 31f42c32..00000000 --- a/advancedcontentfilter/vendor/symfony/cache/Tests/Simple/NullCacheTest.php +++ /dev/null @@ -1,96 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Cache\Tests\Simple; - -use PHPUnit\Framework\TestCase; -use Symfony\Component\Cache\Simple\NullCache; - -/** - * @group time-sensitive - */ -class NullCacheTest extends TestCase -{ - public function createCachePool() - { - return new NullCache(); - } - - public function testGetItem() - { - $cache = $this->createCachePool(); - - $this->assertNull($cache->get('key')); - } - - public function testHas() - { - $this->assertFalse($this->createCachePool()->has('key')); - } - - public function testGetMultiple() - { - $cache = $this->createCachePool(); - - $keys = ['foo', 'bar', 'baz', 'biz']; - - $default = new \stdClass(); - $items = $cache->getMultiple($keys, $default); - $count = 0; - - foreach ($items as $key => $item) { - $this->assertContains($key, $keys, 'Cache key can not change.'); - $this->assertSame($default, $item); - - // Remove $key for $keys - foreach ($keys as $k => $v) { - if ($v === $key) { - unset($keys[$k]); - } - } - - ++$count; - } - - $this->assertSame(4, $count); - } - - public function testClear() - { - $this->assertTrue($this->createCachePool()->clear()); - } - - public function testDelete() - { - $this->assertTrue($this->createCachePool()->delete('key')); - } - - public function testDeleteMultiple() - { - $this->assertTrue($this->createCachePool()->deleteMultiple(['key', 'foo', 'bar'])); - } - - public function testSet() - { - $cache = $this->createCachePool(); - - $this->assertFalse($cache->set('key', 'val')); - $this->assertNull($cache->get('key')); - } - - public function testSetMultiple() - { - $cache = $this->createCachePool(); - - $this->assertFalse($cache->setMultiple(['key' => 'val'])); - $this->assertNull($cache->get('key')); - } -} diff --git a/advancedcontentfilter/vendor/symfony/cache/Tests/Simple/PdoCacheTest.php b/advancedcontentfilter/vendor/symfony/cache/Tests/Simple/PdoCacheTest.php deleted file mode 100644 index f5a26341..00000000 --- a/advancedcontentfilter/vendor/symfony/cache/Tests/Simple/PdoCacheTest.php +++ /dev/null @@ -1,47 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Cache\Tests\Simple; - -use Symfony\Component\Cache\Simple\PdoCache; -use Symfony\Component\Cache\Tests\Traits\PdoPruneableTrait; - -/** - * @group time-sensitive - */ -class PdoCacheTest extends CacheTestCase -{ - use PdoPruneableTrait; - - protected static $dbFile; - - public static function setUpBeforeClass() - { - if (!\extension_loaded('pdo_sqlite')) { - self::markTestSkipped('Extension pdo_sqlite required.'); - } - - self::$dbFile = tempnam(sys_get_temp_dir(), 'sf_sqlite_cache'); - - $pool = new PdoCache('sqlite:'.self::$dbFile); - $pool->createTable(); - } - - public static function tearDownAfterClass() - { - @unlink(self::$dbFile); - } - - public function createSimpleCache($defaultLifetime = 0) - { - return new PdoCache('sqlite:'.self::$dbFile, 'ns', $defaultLifetime); - } -} diff --git a/advancedcontentfilter/vendor/symfony/cache/Tests/Simple/PdoDbalCacheTest.php b/advancedcontentfilter/vendor/symfony/cache/Tests/Simple/PdoDbalCacheTest.php deleted file mode 100644 index 4da2b603..00000000 --- a/advancedcontentfilter/vendor/symfony/cache/Tests/Simple/PdoDbalCacheTest.php +++ /dev/null @@ -1,48 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Cache\Tests\Simple; - -use Doctrine\DBAL\DriverManager; -use Symfony\Component\Cache\Simple\PdoCache; -use Symfony\Component\Cache\Tests\Traits\PdoPruneableTrait; - -/** - * @group time-sensitive - */ -class PdoDbalCacheTest extends CacheTestCase -{ - use PdoPruneableTrait; - - protected static $dbFile; - - public static function setUpBeforeClass() - { - if (!\extension_loaded('pdo_sqlite')) { - self::markTestSkipped('Extension pdo_sqlite required.'); - } - - self::$dbFile = tempnam(sys_get_temp_dir(), 'sf_sqlite_cache'); - - $pool = new PdoCache(DriverManager::getConnection(['driver' => 'pdo_sqlite', 'path' => self::$dbFile])); - $pool->createTable(); - } - - public static function tearDownAfterClass() - { - @unlink(self::$dbFile); - } - - public function createSimpleCache($defaultLifetime = 0) - { - return new PdoCache(DriverManager::getConnection(['driver' => 'pdo_sqlite', 'path' => self::$dbFile]), '', $defaultLifetime); - } -} diff --git a/advancedcontentfilter/vendor/symfony/cache/Tests/Simple/PhpArrayCacheTest.php b/advancedcontentfilter/vendor/symfony/cache/Tests/Simple/PhpArrayCacheTest.php deleted file mode 100644 index bcd7dea5..00000000 --- a/advancedcontentfilter/vendor/symfony/cache/Tests/Simple/PhpArrayCacheTest.php +++ /dev/null @@ -1,145 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Cache\Tests\Simple; - -use Symfony\Component\Cache\Simple\NullCache; -use Symfony\Component\Cache\Simple\PhpArrayCache; -use Symfony\Component\Cache\Tests\Adapter\FilesystemAdapterTest; - -/** - * @group time-sensitive - */ -class PhpArrayCacheTest extends CacheTestCase -{ - protected $skippedTests = [ - 'testBasicUsageWithLongKey' => 'PhpArrayCache does no writes', - - 'testDelete' => 'PhpArrayCache does no writes', - 'testDeleteMultiple' => 'PhpArrayCache does no writes', - 'testDeleteMultipleGenerator' => 'PhpArrayCache does no writes', - - 'testSetTtl' => 'PhpArrayCache does no expiration', - 'testSetMultipleTtl' => 'PhpArrayCache does no expiration', - 'testSetExpiredTtl' => 'PhpArrayCache does no expiration', - 'testSetMultipleExpiredTtl' => 'PhpArrayCache does no expiration', - - 'testGetInvalidKeys' => 'PhpArrayCache does no validation', - 'testGetMultipleInvalidKeys' => 'PhpArrayCache does no validation', - 'testSetInvalidKeys' => 'PhpArrayCache does no validation', - 'testDeleteInvalidKeys' => 'PhpArrayCache does no validation', - 'testDeleteMultipleInvalidKeys' => 'PhpArrayCache does no validation', - 'testSetInvalidTtl' => 'PhpArrayCache does no validation', - 'testSetMultipleInvalidKeys' => 'PhpArrayCache does no validation', - 'testSetMultipleInvalidTtl' => 'PhpArrayCache does no validation', - 'testHasInvalidKeys' => 'PhpArrayCache does no validation', - 'testSetValidData' => 'PhpArrayCache does no validation', - - 'testDefaultLifeTime' => 'PhpArrayCache does not allow configuring a default lifetime.', - 'testPrune' => 'PhpArrayCache just proxies', - ]; - - protected static $file; - - public static function setUpBeforeClass() - { - self::$file = sys_get_temp_dir().'/symfony-cache/php-array-adapter-test.php'; - } - - protected function tearDown() - { - $this->createSimpleCache()->clear(); - - if (file_exists(sys_get_temp_dir().'/symfony-cache')) { - FilesystemAdapterTest::rmdir(sys_get_temp_dir().'/symfony-cache'); - } - } - - public function createSimpleCache() - { - return new PhpArrayCacheWrapper(self::$file, new NullCache()); - } - - public function testStore() - { - $arrayWithRefs = []; - $arrayWithRefs[0] = 123; - $arrayWithRefs[1] = &$arrayWithRefs[0]; - - $object = (object) [ - 'foo' => 'bar', - 'foo2' => 'bar2', - ]; - - $expected = [ - 'null' => null, - 'serializedString' => serialize($object), - 'arrayWithRefs' => $arrayWithRefs, - 'object' => $object, - 'arrayWithObject' => ['bar' => $object], - ]; - - $cache = new PhpArrayCache(self::$file, new NullCache()); - $cache->warmUp($expected); - - foreach ($expected as $key => $value) { - $this->assertSame(serialize($value), serialize($cache->get($key)), 'Warm up should create a PHP file that OPCache can load in memory'); - } - } - - public function testStoredFile() - { - $expected = [ - 'integer' => 42, - 'float' => 42.42, - 'boolean' => true, - 'array_simple' => ['foo', 'bar'], - 'array_associative' => ['foo' => 'bar', 'foo2' => 'bar2'], - ]; - - $cache = new PhpArrayCache(self::$file, new NullCache()); - $cache->warmUp($expected); - - $values = eval(substr(file_get_contents(self::$file), 6)); - - $this->assertSame($expected, $values, 'Warm up should create a PHP file that OPCache can load in memory'); - } -} - -class PhpArrayCacheWrapper extends PhpArrayCache -{ - public function set($key, $value, $ttl = null) - { - \call_user_func(\Closure::bind(function () use ($key, $value) { - $this->values[$key] = $value; - $this->warmUp($this->values); - $this->values = eval(substr(file_get_contents($this->file), 6)); - }, $this, PhpArrayCache::class)); - - return true; - } - - public function setMultiple($values, $ttl = null) - { - if (!\is_array($values) && !$values instanceof \Traversable) { - return parent::setMultiple($values, $ttl); - } - \call_user_func(\Closure::bind(function () use ($values) { - foreach ($values as $key => $value) { - $this->values[$key] = $value; - } - $this->warmUp($this->values); - $this->values = eval(substr(file_get_contents($this->file), 6)); - }, $this, PhpArrayCache::class)); - - return true; - } -} diff --git a/advancedcontentfilter/vendor/symfony/cache/Tests/Simple/PhpArrayCacheWithFallbackTest.php b/advancedcontentfilter/vendor/symfony/cache/Tests/Simple/PhpArrayCacheWithFallbackTest.php deleted file mode 100644 index b08c1604..00000000 --- a/advancedcontentfilter/vendor/symfony/cache/Tests/Simple/PhpArrayCacheWithFallbackTest.php +++ /dev/null @@ -1,57 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Cache\Tests\Simple; - -use Symfony\Component\Cache\Simple\FilesystemCache; -use Symfony\Component\Cache\Simple\PhpArrayCache; -use Symfony\Component\Cache\Tests\Adapter\FilesystemAdapterTest; - -/** - * @group time-sensitive - */ -class PhpArrayCacheWithFallbackTest extends CacheTestCase -{ - protected $skippedTests = [ - 'testGetInvalidKeys' => 'PhpArrayCache does no validation', - 'testGetMultipleInvalidKeys' => 'PhpArrayCache does no validation', - 'testDeleteInvalidKeys' => 'PhpArrayCache does no validation', - 'testDeleteMultipleInvalidKeys' => 'PhpArrayCache does no validation', - //'testSetValidData' => 'PhpArrayCache does no validation', - 'testSetInvalidKeys' => 'PhpArrayCache does no validation', - 'testSetInvalidTtl' => 'PhpArrayCache does no validation', - 'testSetMultipleInvalidKeys' => 'PhpArrayCache does no validation', - 'testSetMultipleInvalidTtl' => 'PhpArrayCache does no validation', - 'testHasInvalidKeys' => 'PhpArrayCache does no validation', - 'testPrune' => 'PhpArrayCache just proxies', - ]; - - protected static $file; - - public static function setUpBeforeClass() - { - self::$file = sys_get_temp_dir().'/symfony-cache/php-array-adapter-test.php'; - } - - protected function tearDown() - { - $this->createSimpleCache()->clear(); - - if (file_exists(sys_get_temp_dir().'/symfony-cache')) { - FilesystemAdapterTest::rmdir(sys_get_temp_dir().'/symfony-cache'); - } - } - - public function createSimpleCache($defaultLifetime = 0) - { - return new PhpArrayCache(self::$file, new FilesystemCache('php-array-fallback', $defaultLifetime)); - } -} diff --git a/advancedcontentfilter/vendor/symfony/cache/Tests/Simple/PhpFilesCacheTest.php b/advancedcontentfilter/vendor/symfony/cache/Tests/Simple/PhpFilesCacheTest.php deleted file mode 100644 index 936f29a4..00000000 --- a/advancedcontentfilter/vendor/symfony/cache/Tests/Simple/PhpFilesCacheTest.php +++ /dev/null @@ -1,42 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Cache\Tests\Simple; - -use Psr\SimpleCache\CacheInterface; -use Symfony\Component\Cache\Simple\PhpFilesCache; - -/** - * @group time-sensitive - */ -class PhpFilesCacheTest extends CacheTestCase -{ - protected $skippedTests = [ - 'testDefaultLifeTime' => 'PhpFilesCache does not allow configuring a default lifetime.', - ]; - - public function createSimpleCache() - { - if (!PhpFilesCache::isSupported()) { - $this->markTestSkipped('OPcache extension is not enabled.'); - } - - return new PhpFilesCache('sf-cache'); - } - - protected function isPruned(CacheInterface $cache, $name) - { - $getFileMethod = (new \ReflectionObject($cache))->getMethod('getFile'); - $getFileMethod->setAccessible(true); - - return !file_exists($getFileMethod->invoke($cache, $name)); - } -} diff --git a/advancedcontentfilter/vendor/symfony/cache/Tests/Simple/Psr6CacheTest.php b/advancedcontentfilter/vendor/symfony/cache/Tests/Simple/Psr6CacheTest.php deleted file mode 100644 index 1bc75c90..00000000 --- a/advancedcontentfilter/vendor/symfony/cache/Tests/Simple/Psr6CacheTest.php +++ /dev/null @@ -1,30 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Cache\Tests\Simple; - -use Symfony\Component\Cache\Adapter\FilesystemAdapter; -use Symfony\Component\Cache\Simple\Psr6Cache; - -/** - * @group time-sensitive - */ -class Psr6CacheTest extends CacheTestCase -{ - protected $skippedTests = [ - 'testPrune' => 'Psr6Cache just proxies', - ]; - - public function createSimpleCache($defaultLifetime = 0) - { - return new Psr6Cache(new FilesystemAdapter('', $defaultLifetime)); - } -} diff --git a/advancedcontentfilter/vendor/symfony/cache/Tests/Simple/RedisArrayCacheTest.php b/advancedcontentfilter/vendor/symfony/cache/Tests/Simple/RedisArrayCacheTest.php deleted file mode 100644 index ec5e4c06..00000000 --- a/advancedcontentfilter/vendor/symfony/cache/Tests/Simple/RedisArrayCacheTest.php +++ /dev/null @@ -1,24 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Cache\Tests\Simple; - -class RedisArrayCacheTest extends AbstractRedisCacheTest -{ - public static function setUpBeforeClass() - { - parent::setupBeforeClass(); - if (!class_exists('RedisArray')) { - self::markTestSkipped('The RedisArray class is required.'); - } - self::$redis = new \RedisArray([getenv('REDIS_HOST')], ['lazy_connect' => true]); - } -} diff --git a/advancedcontentfilter/vendor/symfony/cache/Tests/Simple/RedisCacheTest.php b/advancedcontentfilter/vendor/symfony/cache/Tests/Simple/RedisCacheTest.php deleted file mode 100644 index 8e3f6088..00000000 --- a/advancedcontentfilter/vendor/symfony/cache/Tests/Simple/RedisCacheTest.php +++ /dev/null @@ -1,82 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Cache\Tests\Simple; - -use Symfony\Component\Cache\Simple\RedisCache; - -class RedisCacheTest extends AbstractRedisCacheTest -{ - public static function setUpBeforeClass() - { - parent::setupBeforeClass(); - self::$redis = RedisCache::createConnection('redis://'.getenv('REDIS_HOST')); - } - - public function testCreateConnection() - { - $redisHost = getenv('REDIS_HOST'); - - $redis = RedisCache::createConnection('redis://'.$redisHost); - $this->assertInstanceOf(\Redis::class, $redis); - $this->assertTrue($redis->isConnected()); - $this->assertSame(0, $redis->getDbNum()); - - $redis = RedisCache::createConnection('redis://'.$redisHost.'/2'); - $this->assertSame(2, $redis->getDbNum()); - - $redis = RedisCache::createConnection('redis://'.$redisHost, ['timeout' => 3]); - $this->assertEquals(3, $redis->getTimeout()); - - $redis = RedisCache::createConnection('redis://'.$redisHost.'?timeout=4'); - $this->assertEquals(4, $redis->getTimeout()); - - $redis = RedisCache::createConnection('redis://'.$redisHost, ['read_timeout' => 5]); - $this->assertEquals(5, $redis->getReadTimeout()); - } - - /** - * @dataProvider provideFailedCreateConnection - */ - public function testFailedCreateConnection($dsn) - { - $this->expectException('Symfony\Component\Cache\Exception\InvalidArgumentException'); - $this->expectExceptionMessage('Redis connection '); - RedisCache::createConnection($dsn); - } - - public function provideFailedCreateConnection() - { - return [ - ['redis://localhost:1234'], - ['redis://foo@localhost'], - ['redis://localhost/123'], - ]; - } - - /** - * @dataProvider provideInvalidCreateConnection - */ - public function testInvalidCreateConnection($dsn) - { - $this->expectException('Symfony\Component\Cache\Exception\InvalidArgumentException'); - $this->expectExceptionMessage('Invalid Redis DSN'); - RedisCache::createConnection($dsn); - } - - public function provideInvalidCreateConnection() - { - return [ - ['foo://localhost'], - ['redis://'], - ]; - } -} diff --git a/advancedcontentfilter/vendor/symfony/cache/Tests/Simple/RedisClusterCacheTest.php b/advancedcontentfilter/vendor/symfony/cache/Tests/Simple/RedisClusterCacheTest.php deleted file mode 100644 index 6b7f8039..00000000 --- a/advancedcontentfilter/vendor/symfony/cache/Tests/Simple/RedisClusterCacheTest.php +++ /dev/null @@ -1,27 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Cache\Tests\Simple; - -class RedisClusterCacheTest extends AbstractRedisCacheTest -{ - public static function setUpBeforeClass() - { - if (!class_exists('RedisCluster')) { - self::markTestSkipped('The RedisCluster class is required.'); - } - if (!$hosts = getenv('REDIS_CLUSTER_HOSTS')) { - self::markTestSkipped('REDIS_CLUSTER_HOSTS env var is not defined.'); - } - - self::$redis = new \RedisCluster(null, explode(' ', $hosts)); - } -} diff --git a/advancedcontentfilter/vendor/symfony/cache/Tests/Simple/TraceableCacheTest.php b/advancedcontentfilter/vendor/symfony/cache/Tests/Simple/TraceableCacheTest.php deleted file mode 100644 index e684caf3..00000000 --- a/advancedcontentfilter/vendor/symfony/cache/Tests/Simple/TraceableCacheTest.php +++ /dev/null @@ -1,171 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Cache\Tests\Simple; - -use Symfony\Component\Cache\Simple\FilesystemCache; -use Symfony\Component\Cache\Simple\TraceableCache; - -/** - * @group time-sensitive - */ -class TraceableCacheTest extends CacheTestCase -{ - protected $skippedTests = [ - 'testPrune' => 'TraceableCache just proxies', - ]; - - public function createSimpleCache($defaultLifetime = 0) - { - return new TraceableCache(new FilesystemCache('', $defaultLifetime)); - } - - public function testGetMissTrace() - { - $pool = $this->createSimpleCache(); - $pool->get('k'); - $calls = $pool->getCalls(); - $this->assertCount(1, $calls); - - $call = $calls[0]; - $this->assertSame('get', $call->name); - $this->assertSame(['k' => false], $call->result); - $this->assertSame(0, $call->hits); - $this->assertSame(1, $call->misses); - $this->assertNotEmpty($call->start); - $this->assertNotEmpty($call->end); - } - - public function testGetHitTrace() - { - $pool = $this->createSimpleCache(); - $pool->set('k', 'foo'); - $pool->get('k'); - $calls = $pool->getCalls(); - $this->assertCount(2, $calls); - - $call = $calls[1]; - $this->assertSame(1, $call->hits); - $this->assertSame(0, $call->misses); - } - - public function testGetMultipleMissTrace() - { - $pool = $this->createSimpleCache(); - $pool->set('k1', 123); - $values = $pool->getMultiple(['k0', 'k1']); - foreach ($values as $value) { - } - $calls = $pool->getCalls(); - $this->assertCount(2, $calls); - - $call = $calls[1]; - $this->assertSame('getMultiple', $call->name); - $this->assertSame(['k1' => true, 'k0' => false], $call->result); - $this->assertSame(1, $call->misses); - $this->assertNotEmpty($call->start); - $this->assertNotEmpty($call->end); - } - - public function testHasMissTrace() - { - $pool = $this->createSimpleCache(); - $pool->has('k'); - $calls = $pool->getCalls(); - $this->assertCount(1, $calls); - - $call = $calls[0]; - $this->assertSame('has', $call->name); - $this->assertSame(['k' => false], $call->result); - $this->assertNotEmpty($call->start); - $this->assertNotEmpty($call->end); - } - - public function testHasHitTrace() - { - $pool = $this->createSimpleCache(); - $pool->set('k', 'foo'); - $pool->has('k'); - $calls = $pool->getCalls(); - $this->assertCount(2, $calls); - - $call = $calls[1]; - $this->assertSame('has', $call->name); - $this->assertSame(['k' => true], $call->result); - $this->assertNotEmpty($call->start); - $this->assertNotEmpty($call->end); - } - - public function testDeleteTrace() - { - $pool = $this->createSimpleCache(); - $pool->delete('k'); - $calls = $pool->getCalls(); - $this->assertCount(1, $calls); - - $call = $calls[0]; - $this->assertSame('delete', $call->name); - $this->assertSame(['k' => true], $call->result); - $this->assertSame(0, $call->hits); - $this->assertSame(0, $call->misses); - $this->assertNotEmpty($call->start); - $this->assertNotEmpty($call->end); - } - - public function testDeleteMultipleTrace() - { - $pool = $this->createSimpleCache(); - $arg = ['k0', 'k1']; - $pool->deleteMultiple($arg); - $calls = $pool->getCalls(); - $this->assertCount(1, $calls); - - $call = $calls[0]; - $this->assertSame('deleteMultiple', $call->name); - $this->assertSame(['keys' => $arg, 'result' => true], $call->result); - $this->assertSame(0, $call->hits); - $this->assertSame(0, $call->misses); - $this->assertNotEmpty($call->start); - $this->assertNotEmpty($call->end); - } - - public function testTraceSetTrace() - { - $pool = $this->createSimpleCache(); - $pool->set('k', 'foo'); - $calls = $pool->getCalls(); - $this->assertCount(1, $calls); - - $call = $calls[0]; - $this->assertSame('set', $call->name); - $this->assertSame(['k' => true], $call->result); - $this->assertSame(0, $call->hits); - $this->assertSame(0, $call->misses); - $this->assertNotEmpty($call->start); - $this->assertNotEmpty($call->end); - } - - public function testSetMultipleTrace() - { - $pool = $this->createSimpleCache(); - $pool->setMultiple(['k' => 'foo']); - $calls = $pool->getCalls(); - $this->assertCount(1, $calls); - - $call = $calls[0]; - $this->assertSame('setMultiple', $call->name); - $this->assertSame(['keys' => ['k'], 'result' => true], $call->result); - $this->assertSame(0, $call->hits); - $this->assertSame(0, $call->misses); - $this->assertNotEmpty($call->start); - $this->assertNotEmpty($call->end); - } -} diff --git a/advancedcontentfilter/vendor/symfony/cache/Tests/Traits/PdoPruneableTrait.php b/advancedcontentfilter/vendor/symfony/cache/Tests/Traits/PdoPruneableTrait.php deleted file mode 100644 index c405de70..00000000 --- a/advancedcontentfilter/vendor/symfony/cache/Tests/Traits/PdoPruneableTrait.php +++ /dev/null @@ -1,34 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Cache\Tests\Traits; - -trait PdoPruneableTrait -{ - protected function isPruned($cache, $name) - { - $o = new \ReflectionObject($cache); - - if (!$o->hasMethod('getConnection')) { - self::fail('Cache does not have "getConnection()" method.'); - } - - $getPdoConn = $o->getMethod('getConnection'); - $getPdoConn->setAccessible(true); - - /** @var \Doctrine\DBAL\Statement|\PDOStatement $select */ - $select = $getPdoConn->invoke($cache)->prepare('SELECT 1 FROM cache_items WHERE item_id LIKE :id'); - $select->bindValue(':id', sprintf('%%%s', $name)); - $result = $select->execute(); - - return 1 !== (int) (\is_object($result) ? $result->fetchOne() : $select->fetch(\PDO::FETCH_COLUMN)); - } -} diff --git a/advancedcontentfilter/vendor/symfony/cache/phpunit.xml.dist b/advancedcontentfilter/vendor/symfony/cache/phpunit.xml.dist deleted file mode 100644 index c35458ca..00000000 --- a/advancedcontentfilter/vendor/symfony/cache/phpunit.xml.dist +++ /dev/null @@ -1,50 +0,0 @@ - - - - - - - - - - - - ./Tests/ - - - - - - ./ - - ./Tests - ./vendor - - - - - - - - - - - Cache\IntegrationTests - Doctrine\Common\Cache - Symfony\Component\Cache - Symfony\Component\Cache\Tests\Fixtures - Symfony\Component\Cache\Traits - - - - - - - diff --git a/advancedcontentfilter/vendor/symfony/polyfill-apcu/Apcu.php b/advancedcontentfilter/vendor/symfony/polyfill-apcu/Apcu.php deleted file mode 100644 index 4dc5bf9a..00000000 --- a/advancedcontentfilter/vendor/symfony/polyfill-apcu/Apcu.php +++ /dev/null @@ -1,106 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Polyfill\Apcu; - -/** - * Apcu for Zend Server Data Cache. - * - * @author Kate Gray - * @author Nicolas Grekas - * - * @internal - */ -final class Apcu -{ - public static function apcu_add($key, $var = null, $ttl = 0) - { - if (!\is_array($key)) { - return apc_add($key, $var, $ttl); - } - - $errors = []; - foreach ($key as $k => $v) { - if (!apc_add($k, $v, $ttl)) { - $errors[$k] = -1; - } - } - - return $errors; - } - - public static function apcu_store($key, $var = null, $ttl = 0) - { - if (!\is_array($key)) { - return apc_store($key, $var, $ttl); - } - - $errors = []; - foreach ($key as $k => $v) { - if (!apc_store($k, $v, $ttl)) { - $errors[$k] = -1; - } - } - - return $errors; - } - - public static function apcu_exists($keys) - { - if (!\is_array($keys)) { - return apc_exists($keys); - } - - $existing = []; - foreach ($keys as $k) { - if (apc_exists($k)) { - $existing[$k] = true; - } - } - - return $existing; - } - - public static function apcu_fetch($key, &$success = null) - { - if (!\is_array($key)) { - return apc_fetch($key, $success); - } - - $succeeded = true; - $values = []; - foreach ($key as $k) { - $v = apc_fetch($k, $success); - if ($success) { - $values[$k] = $v; - } else { - $succeeded = false; - } - } - $success = $succeeded; - - return $values; - } - - public static function apcu_delete($key) - { - if (!\is_array($key)) { - return apc_delete($key); - } - - $success = true; - foreach ($key as $k) { - $success = apc_delete($k) && $success; - } - - return $success; - } -} diff --git a/advancedcontentfilter/vendor/symfony/polyfill-apcu/LICENSE b/advancedcontentfilter/vendor/symfony/polyfill-apcu/LICENSE deleted file mode 100644 index 6e3afce6..00000000 --- a/advancedcontentfilter/vendor/symfony/polyfill-apcu/LICENSE +++ /dev/null @@ -1,19 +0,0 @@ -Copyright (c) 2015-present 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/advancedcontentfilter/vendor/symfony/polyfill-apcu/README.md b/advancedcontentfilter/vendor/symfony/polyfill-apcu/README.md deleted file mode 100644 index 57f4bf6b..00000000 --- a/advancedcontentfilter/vendor/symfony/polyfill-apcu/README.md +++ /dev/null @@ -1,12 +0,0 @@ -Symfony Polyfill / APCu -======================== - -This component provides `apcu_*` functions and the `APCuIterator` class to users of the legacy APC extension. - -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/advancedcontentfilter/vendor/symfony/polyfill-apcu/bootstrap.php b/advancedcontentfilter/vendor/symfony/polyfill-apcu/bootstrap.php deleted file mode 100644 index 96b2706a..00000000 --- a/advancedcontentfilter/vendor/symfony/polyfill-apcu/bootstrap.php +++ /dev/null @@ -1,83 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -use Symfony\Polyfill\Apcu as p; - -if (!extension_loaded('apc') && !extension_loaded('apcu')) { - return; -} - -if (\PHP_VERSION_ID >= 80000) { - return require __DIR__.'/bootstrap80.php'; -} - -if (extension_loaded('Zend Data Cache')) { - if (!function_exists('apcu_add')) { - function apcu_add($key, $value = null, $ttl = 0) { return p\Apcu::apcu_add($key, $value, $ttl); } - } - if (!function_exists('apcu_delete')) { - function apcu_delete($key) { return p\Apcu::apcu_delete($key); } - } - if (!function_exists('apcu_exists')) { - function apcu_exists($key) { return p\Apcu::apcu_exists($key); } - } - if (!function_exists('apcu_fetch')) { - function apcu_fetch($key, &$success = null) { return p\Apcu::apcu_fetch($key, $success); } - } - if (!function_exists('apcu_store')) { - function apcu_store($key, $value = null, $ttl = 0) { return p\Apcu::apcu_store($key, $value, $ttl); } - } -} else { - if (!function_exists('apcu_add')) { - function apcu_add($key, $value = null, $ttl = 0) { return apc_add($key, $value, $ttl); } - } - if (!function_exists('apcu_delete')) { - function apcu_delete($key) { return apc_delete($key); } - } - if (!function_exists('apcu_exists')) { - function apcu_exists($key) { return apc_exists($key); } - } - if (!function_exists('apcu_fetch')) { - function apcu_fetch($key, &$success = null) { return apc_fetch($key, $success); } - } - if (!function_exists('apcu_store')) { - function apcu_store($key, $value = null, $ttl = 0) { return apc_store($key, $value, $ttl); } - } -} - -if (!function_exists('apcu_cache_info')) { - function apcu_cache_info($limited = false) { return apc_cache_info('user', $limited); } -} -if (!function_exists('apcu_cas')) { - function apcu_cas($key, $old, $new) { return apc_cas($key, $old, $new); } -} -if (!function_exists('apcu_clear_cache')) { - function apcu_clear_cache() { return apc_clear_cache('user'); } -} -if (!function_exists('apcu_dec')) { - function apcu_dec($key, $step = 1, &$success = false) { return apc_dec($key, $step, $success); } -} -if (!function_exists('apcu_inc')) { - function apcu_inc($key, $step = 1, &$success = false) { return apc_inc($key, $step, $success); } -} -if (!function_exists('apcu_sma_info')) { - function apcu_sma_info($limited = false) { return apc_sma_info($limited); } -} - -if (!class_exists('APCuIterator', false) && class_exists('APCIterator', false)) { - class APCuIterator extends APCIterator - { - public function __construct($search = null, $format = \APC_ITER_ALL, $chunk_size = 100, $list = \APC_LIST_ACTIVE) - { - parent::__construct('user', $search, $format, $chunk_size, $list); - } - } -} diff --git a/advancedcontentfilter/vendor/symfony/polyfill-apcu/bootstrap80.php b/advancedcontentfilter/vendor/symfony/polyfill-apcu/bootstrap80.php deleted file mode 100644 index 69e9f160..00000000 --- a/advancedcontentfilter/vendor/symfony/polyfill-apcu/bootstrap80.php +++ /dev/null @@ -1,75 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -use Symfony\Polyfill\Apcu as p; - -if (extension_loaded('Zend Data Cache')) { - if (!function_exists('apcu_add')) { - function apcu_add($key, mixed $value, ?int $ttl = 0): array|bool { return p\Apcu::apcu_add($key, $value, (int) $ttl); } - } - if (!function_exists('apcu_delete')) { - function apcu_delete($key): array|bool { return p\Apcu::apcu_delete($key); } - } - if (!function_exists('apcu_exists')) { - function apcu_exists($key): array|bool { return p\Apcu::apcu_exists($key); } - } - if (!function_exists('apcu_fetch')) { - function apcu_fetch($key, &$success = null): mixed { return p\Apcu::apcu_fetch($key, $success); } - } - if (!function_exists('apcu_store')) { - function apcu_store($key, mixed $value, ?int $ttl = 0): array|bool { return p\Apcu::apcu_store($key, $value, (int) $ttl); } - } -} else { - if (!function_exists('apcu_add')) { - function apcu_add($key, mixed $value, ?int $ttl = 0): array|bool { return apc_add($key, $value, (int) $ttl); } - } - if (!function_exists('apcu_delete')) { - function apcu_delete($key): array|bool { return apc_delete($key); } - } - if (!function_exists('apcu_exists')) { - function apcu_exists($key): array|bool { return apc_exists($key); } - } - if (!function_exists('apcu_fetch')) { - function apcu_fetch($key, &$success = null) { return apc_fetch($key, $success); } - } - if (!function_exists('apcu_store')) { - function apcu_store($key, mixed $value, ?int $ttl = 0): array|bool { return apc_store($key, $value, (int) $ttl); } - } -} - -if (!function_exists('apcu_cache_info')) { - function apcu_cache_info($limited = false) { return apc_cache_info('user', $limited); } -} -if (!function_exists('apcu_cas')) { - function apcu_cas($key, $old, $new) { return apc_cas($key, $old, $new); } -} -if (!function_exists('apcu_clear_cache')) { - function apcu_clear_cache() { return apc_clear_cache('user'); } -} -if (!function_exists('apcu_dec')) { - function apcu_dec($key, $step = 1, &$success = false) { return apc_dec($key, $step, $success); } -} -if (!function_exists('apcu_inc')) { - function apcu_inc($key, $step = 1, &$success = false) { return apc_inc($key, $step, $success); } -} -if (!function_exists('apcu_sma_info')) { - function apcu_sma_info($limited = false) { return apc_sma_info($limited); } -} - -if (!class_exists('APCuIterator', false) && class_exists('APCIterator', false)) { - class APCuIterator extends APCIterator - { - public function __construct($search = null, $format = APC_ITER_ALL, $chunk_size = 100, $list = APC_LIST_ACTIVE) - { - parent::__construct('user', $search, $format, $chunk_size, $list); - } - } -} diff --git a/advancedcontentfilter/vendor/symfony/polyfill-apcu/composer.json b/advancedcontentfilter/vendor/symfony/polyfill-apcu/composer.json deleted file mode 100644 index e92524f3..00000000 --- a/advancedcontentfilter/vendor/symfony/polyfill-apcu/composer.json +++ /dev/null @@ -1,35 +0,0 @@ -{ - "name": "symfony/polyfill-apcu", - "type": "library", - "description": "Symfony polyfill backporting apcu_* functions to lower PHP versions", - "keywords": ["polyfill", "shim", "compatibility", "portable", "apcu"], - "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\\Apcu\\": "" }, - "files": [ "bootstrap.php" ] - }, - "minimum-stability": "dev", - "extra": { - "branch-alias": { - "dev-main": "1.28-dev" - }, - "thanks": { - "name": "symfony/polyfill", - "url": "https://github.com/symfony/polyfill" - } - } -} From 7fcbd76c6b9a0d2b8a704fc5739c4f2d31f15c9f Mon Sep 17 00:00:00 2001 From: Michael Date: Wed, 20 Nov 2024 07:03:42 +0000 Subject: [PATCH 040/222] Bluesky: Improved handling of starter packs --- bluesky/bluesky.php | 30 +++++++++++++++++++++++++----- 1 file changed, 25 insertions(+), 5 deletions(-) diff --git a/bluesky/bluesky.php b/bluesky/bluesky.php index d719eecb..a78480b6 100644 --- a/bluesky/bluesky.php +++ b/bluesky/bluesky.php @@ -1481,11 +1481,7 @@ function bluesky_add_media(stdClass $embed, array $item, int $fetch_uid, int $le if (!empty($embed->record->record->$type)) { $embed_type = $embed->record->record->$type; if ($embed_type == 'app.bsky.graph.starterpack') { - Logger::debug('Starterpacks are not fetched like posts', ['original-uri' => $original_uri]); - if (empty($item['body'])) { - // @todo process starterpack - $item['body'] = '[url=' . $embed->record->record->list . ']' . $embed->record->record->name . '[/url]'; - } + bluesky_add_starterpack($item, $embed->record); break; } } @@ -1523,6 +1519,30 @@ function bluesky_add_media(stdClass $embed, array $item, int $fetch_uid, int $le return $item; } +function bluesky_add_starterpack(array $item, stdClass $record) +{ + Logger::debug('Received starterpack', ['uri-id' => $item['uri-id'], 'guid' => $item['guid'], 'uri' => $record->uri]); + if (!preg_match('#^at://(.+)/app.bsky.graph.starterpack/(.+)#', $record->uri, $matches)) { + return; + } + + $media = [ + 'uri-id' => $item['uri-id'], + 'type' => Post\Media::HTML, + 'url' => 'https://bsky.app/starter-pack/' . $matches[1] . '/' . $matches[2], + 'name' => $record->record->name, + 'description' => $record->record->description, + ]; + + Post\Media::insert($media); + + $fields = [ + 'name' => $record->record->name, + 'description' => $record->record->description, + ]; + Post\Media::update($fields, ['uri-id' => $media['uri-id'], 'url' => $media['url']]); +} + function bluesky_get_uri(stdClass $post): string { if (empty($post->cid)) { From f52bb75c97125045e6e5b2f9d1d743639120eb99 Mon Sep 17 00:00:00 2001 From: Michael Date: Wed, 20 Nov 2024 21:39:09 +0000 Subject: [PATCH 041/222] Blockbot: Drupal added --- blockbot/blockbot.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/blockbot/blockbot.php b/blockbot/blockbot.php index adf0a7c2..022f188d 100644 --- a/blockbot/blockbot.php +++ b/blockbot/blockbot.php @@ -461,7 +461,7 @@ function blockbot_is_social_media(array $parts): bool $agents = [ 'facebookexternalhit', 'twitterbot', 'mastodon', 'facebookexternalua', - 'friendica', 'diasporafederation', 'buzzrelay', 'activityrelay', + 'friendica', 'diasporafederation', 'buzzrelay', 'activityrelay', 'drupal', 'aoderelay', 'ap-relay', 'peertube', 'misskey', 'pleroma', 'foundkey', 'akkoma', 'lemmy', 'calckey', 'mobilizon', 'zot', 'camo-rs', 'gotosocial', 'pixelfed', 'pixelfedbot', 'app.wafrn.net', 'go-camo', 'http://a.gup.pe', 'iceshrimp', From 2ea40dc897c90d65c7be085fbd66fb5cc8d70c96 Mon Sep 17 00:00:00 2001 From: Artur Weigandt Date: Sat, 23 Nov 2024 22:28:59 +0100 Subject: [PATCH 042/222] Remove unused App paramter in securemail addon --- securemail/securemail.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/securemail/securemail.php b/securemail/securemail.php index 5390ebd1..61125587 100644 --- a/securemail/securemail.php +++ b/securemail/securemail.php @@ -82,7 +82,7 @@ function securemail_settings_post(array &$b) DI::pConfig()->set(DI::userSession()->getLocalUserId(), 'securemail', 'enable', $enable); if (!empty($_POST['securemail-test'])) { - $res = DI::emailer()->send(new SecureTestEmail(DI::app(), DI::config(), DI::pConfig(), DI::baseUrl())); + $res = DI::emailer()->send(new SecureTestEmail(DI::config(), DI::pConfig(), DI::baseUrl())); // revert to saved value DI::pConfig()->set(DI::userSession()->getLocalUserId(), 'securemail', 'enable', $enable); From ecf0edb520c50edca5512f0c450761c5d9d56121 Mon Sep 17 00:00:00 2001 From: Artur Weigandt Date: Sat, 23 Nov 2024 09:32:43 +0100 Subject: [PATCH 043/222] Remove unused parameter webdav_storage addon --- webdav_storage/webdav_storage.php | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/webdav_storage/webdav_storage.php b/webdav_storage/webdav_storage.php index adcbea29..fd2eb0d9 100644 --- a/webdav_storage/webdav_storage.php +++ b/webdav_storage/webdav_storage.php @@ -8,11 +8,10 @@ use Friendica\Addon\webdav_storage\src\WebDav; use Friendica\Addon\webdav_storage\src\WebDavConfig; -use Friendica\App; use Friendica\Core\Hook; use Friendica\DI; -function webdav_storage_install($a) +function webdav_storage_install() { Hook::register('storage_instance' , __FILE__, 'webdav_storage_instance'); Hook::register('storage_config' , __FILE__, 'webdav_storage_config'); From bf679262b0b238378a75ed0c7f7436cfe999ac7d Mon Sep 17 00:00:00 2001 From: Artur Weigandt Date: Sat, 23 Nov 2024 22:42:52 +0100 Subject: [PATCH 044/222] Remove unused parameter in saml addon --- saml/saml.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/saml/saml.php b/saml/saml.php index 56dd0f5d..9f065355 100755 --- a/saml/saml.php +++ b/saml/saml.php @@ -161,7 +161,7 @@ function saml_sso_reply() } if (!empty($user['uid'])) { - DI::auth()->setForUser(DI::app(), $user); + DI::auth()->setForUser($user); } if (isset($_POST['RelayState']) && Utils::getSelfURL() != $_POST['RelayState']) { From 348c44c972e54090f329511e992c7ea5618dd862 Mon Sep 17 00:00:00 2001 From: Art4 Date: Sun, 24 Nov 2024 15:36:37 +0000 Subject: [PATCH 045/222] inline slim routes and middlewares into advancedcontentfilter addon --- .../advancedcontentfilter.php | 25 +++++++++++-- advancedcontentfilter/src/middlewares.php | 32 ----------------- advancedcontentfilter/src/routes.php | 36 ------------------- 3 files changed, 23 insertions(+), 70 deletions(-) delete mode 100644 advancedcontentfilter/src/middlewares.php delete mode 100644 advancedcontentfilter/src/routes.php diff --git a/advancedcontentfilter/advancedcontentfilter.php b/advancedcontentfilter/advancedcontentfilter.php index 418b253e..84eb468c 100644 --- a/advancedcontentfilter/advancedcontentfilter.php +++ b/advancedcontentfilter/advancedcontentfilter.php @@ -192,9 +192,30 @@ function advancedcontentfilter_init() if (DI::args()->getArgc() > 1 && DI::args()->getArgv()[1] == 'api') { $slim = \Slim\Factory\AppFactory::create(); - require __DIR__ . '/src/middlewares.php'; + /** + * The routing middleware should be added before the ErrorMiddleware + * Otherwise exceptions thrown from it will not be handled + */ + $slim->addRoutingMiddleware(); + + $slim->addErrorMiddleware(true, true, true, DI::logger()); + + // register routes + $slim->group('/advancedcontentfilter/api', function (\Slim\Routing\RouteCollectorProxy $app) { + $app->group('/rules', function (\Slim\Routing\RouteCollectorProxy $app) { + $app->get('', 'advancedcontentfilter_get_rules'); + $app->post('', 'advancedcontentfilter_post_rules'); + + $app->get('/{id}', 'advancedcontentfilter_get_rules_id'); + $app->put('/{id}', 'advancedcontentfilter_put_rules_id'); + $app->delete('/{id}', 'advancedcontentfilter_delete_rules_id'); + }); + + $app->group('/variables', function (\Slim\Routing\RouteCollectorProxy $app) { + $app->get('/{guid}', 'advancedcontentfilter_get_variables_guid'); + }); + }); - require __DIR__ . '/src/routes.php'; $slim->run(); exit; diff --git a/advancedcontentfilter/src/middlewares.php b/advancedcontentfilter/src/middlewares.php deleted file mode 100644 index 2b831473..00000000 --- a/advancedcontentfilter/src/middlewares.php +++ /dev/null @@ -1,32 +0,0 @@ -. - * - */ - -use Friendica\DI; - -/** @var $slim \Slim\App */ - -/** - * The routing middleware should be added before the ErrorMiddleware - * Otherwise exceptions thrown from it will not be handled - */ -$slim->addRoutingMiddleware(); - -$errorMiddleware = $slim->addErrorMiddleware(true, true, true, DI::logger()); diff --git a/advancedcontentfilter/src/routes.php b/advancedcontentfilter/src/routes.php deleted file mode 100644 index a46f1b4b..00000000 --- a/advancedcontentfilter/src/routes.php +++ /dev/null @@ -1,36 +0,0 @@ -. - * - */ - -/* @var $slim Slim\App */ -$slim->group('/advancedcontentfilter/api', function (\Slim\Routing\RouteCollectorProxy $app) { - $app->group('/rules', function (\Slim\Routing\RouteCollectorProxy $app) { - $app->get('', 'advancedcontentfilter_get_rules'); - $app->post('', 'advancedcontentfilter_post_rules'); - - $app->get('/{id}', 'advancedcontentfilter_get_rules_id'); - $app->put('/{id}', 'advancedcontentfilter_put_rules_id'); - $app->delete('/{id}', 'advancedcontentfilter_delete_rules_id'); - }); - - $app->group('/variables', function (\Slim\Routing\RouteCollectorProxy $app) { - $app->get('/{guid}', 'advancedcontentfilter_get_variables_guid'); - }); -}); From e9d3afb483eff053d0e53d2f55d9d59cd6d7f29e Mon Sep 17 00:00:00 2001 From: Art4 Date: Sun, 24 Nov 2024 19:51:37 +0000 Subject: [PATCH 046/222] Fix errors in tictac addon --- tictac/tictac.php | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/tictac/tictac.php b/tictac/tictac.php index 0f9f4fb6..dc9f0348 100644 --- a/tictac/tictac.php +++ b/tictac/tictac.php @@ -70,6 +70,7 @@ class tictac { private $dimen; private $first_move = true; private $handicap = 0; + private $mefirst; private $yours; private $mine; private $winning_play; @@ -161,10 +162,10 @@ class tictac { ]; - function __construct($dimen,$handicap,$mefirst,$yours,$mine) { + function __construct($dimen, $handicap, $mefirst, $yours, $mine) { $this->dimen = 3; - $this->handicap = (($handicap) ? 1 : 0); - $this->mefirst = (($mefirst) ? 1 : 0); + $this->handicap = $handicap ? 1 : 0; + $this->mefirst = $mefirst ? 1 : 0; $this->yours = str_replace('XXX','',$yours); $this->mine = $mine; $this->you = $this->parse_moves('you'); @@ -175,6 +176,7 @@ class tictac { } function play() { + $o = ''; if($this->first_move) { if(rand(0,1) == 1) { From 6df91dd37bd96bac74a2e347640b0a81684c3028 Mon Sep 17 00:00:00 2001 From: Art4 Date: Sun, 24 Nov 2024 19:55:54 +0000 Subject: [PATCH 047/222] Fix errors in statusnet addon --- statusnet/library/codebirdsn.php | 7 +++---- tictac/tictac.php | 2 +- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/statusnet/library/codebirdsn.php b/statusnet/library/codebirdsn.php index 020c69c4..325bcb07 100644 --- a/statusnet/library/codebirdsn.php +++ b/statusnet/library/codebirdsn.php @@ -762,13 +762,13 @@ class CodebirdSN * @param string $method The API method to call * @param array $params The parameters to send along * - * @return void + * @return string */ protected function _buildMultipart($method, $params) { // well, files will only work in multipart methods if (! $this->_detectMultipart($method)) { - return; + return ''; } // only check specific parameters @@ -783,7 +783,7 @@ class CodebirdSN ); // method might have files? if (! in_array($method, array_keys($possible_files))) { - return; + return ''; } $possible_files = explode(' ', $possible_files[$method]); @@ -794,7 +794,6 @@ class CodebirdSN // is it an array? if (is_array($value)) { throw new \Exception('Using URL-encoded parameters is not supported for uploading media.'); - continue; } // check for filenames diff --git a/tictac/tictac.php b/tictac/tictac.php index dc9f0348..10103835 100644 --- a/tictac/tictac.php +++ b/tictac/tictac.php @@ -631,7 +631,7 @@ function winning_move() { function draw_board() { if(! strlen($this->yours)) $this->yours = 'XXX'; - $o .= "

handicap}/{$this->mefirst}/{$this->dimen}/{$this->yours}/{$this->mine}\" method=\"post\" />"; + $o = "handicap}/{$this->mefirst}/{$this->dimen}/{$this->yours}/{$this->mine}\" method=\"post\" />"; for($x = 0; $x < $this->dimen; $x ++) { $o .= ''; for($y = 0; $y < $this->dimen; $y ++) { From 422e4fd48f80487bf751acc3b19ebe6b5b1d8fc2 Mon Sep 17 00:00:00 2001 From: Michael Date: Sun, 24 Nov 2024 09:11:25 +0000 Subject: [PATCH 048/222] Bluesky: Fetch quoted post for "uid=0" --- bluesky/bluesky.php | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/bluesky/bluesky.php b/bluesky/bluesky.php index a78480b6..74d4fee8 100644 --- a/bluesky/bluesky.php +++ b/bluesky/bluesky.php @@ -1036,7 +1036,7 @@ function bluesky_complete_post(stdClass $post, int $uid, int $post_reason, int $ } if ($complete) { - $uri = bluesky_fetch_missing_post($post->uri, $uid, $uid, $post_reason, $causer, 0, $last_poll, '', true); + $uri = bluesky_fetch_missing_post(bluesky_get_uri($post), $uid, $uid, $post_reason, $causer, 0, $last_poll, '', true); $uri_id = bluesky_fetch_uri_id($uri, $uid); } else { $uri_id = bluesky_process_post($post, $uid, $uid, $post_reason, $causer, 0, $last_poll); @@ -1060,7 +1060,6 @@ function bluesky_process_reason(stdClass $reason, string $uri, int $uid) 'wall' => false, 'uri' => $reason->by->did . '/app.bsky.feed.repost/' . $reason->indexedAt, 'private' => Item::UNLISTED, - 'verb' => Activity::POST, 'contact-id' => $contact['id'], 'author-name' => $contact['name'], 'author-link' => $contact['url'], @@ -1485,7 +1484,12 @@ function bluesky_add_media(stdClass $embed, array $item, int $fetch_uid, int $le break; } } - $uri = bluesky_fetch_missing_post($uri, $item['uid'], $fetch_uid, Item::PR_FETCHED, $item['contact-id'], $level, $last_poll); + $fetched_uri = bluesky_fetch_post($uri, $item['uid']); + if (!$fetched_uri) { + $uri = bluesky_fetch_missing_post($uri, 0, $fetch_uid, Item::PR_FETCHED, $item['contact-id'], $level, $last_poll); + } else { + $uri = $fetched_uri; + } if ($uri) { $shared = Post::selectFirst(['uri-id'], ['uri' => $uri, 'uid' => [$item['uid'], 0]]); $uri_id = $shared['uri-id'] ?? 0; From d7d6a43655734a1ebeb0d70481452447baf5a80e Mon Sep 17 00:00:00 2001 From: Art4 Date: Tue, 26 Nov 2024 07:55:01 +0000 Subject: [PATCH 049/222] Add checks for CLD2Detector ans CLD2Encoding classes --- cld/cld.php | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/cld/cld.php b/cld/cld.php index 5ca4c932..83361e2b 100644 --- a/cld/cld.php +++ b/cld/cld.php @@ -22,6 +22,16 @@ function cld_detect_languages(array &$data) return; } + if (!class_exists('CLD2Detector')) { + Logger::warning('CLD2Detector class does not exist.'); + return; + } + + if (!class_exists('CLD2Encoding')) { + Logger::warning('CLD2Encoding class does not exist.'); + return; + } + $cld2 = new \CLD2Detector(); $cld2->setEncodingHint(CLD2Encoding::UTF8); // optional, hints about text encoding From fc0dda0cd9b607dc8d87f73644108f922f6bb1e1 Mon Sep 17 00:00:00 2001 From: Art4 Date: Tue, 26 Nov 2024 08:23:27 +0000 Subject: [PATCH 050/222] refactor convert addon, replace each() calls with foreach loop --- convert/convert.php | 20 ++++++++------------ 1 file changed, 8 insertions(+), 12 deletions(-) diff --git a/convert/convert.php b/convert/convert.php index 57ce6ea8..2c97e2aa 100644 --- a/convert/convert.php +++ b/convert/convert.php @@ -6,7 +6,6 @@ * Author: Mike Macgirvin */ -use Friendica\App; use Friendica\Core\Hook; function convert_install() { @@ -26,7 +25,7 @@ function convert_content() { // @TODO Let's one day rewrite this to a modern composer package include 'UnitConvertor.php'; - class TP_Converter extends UnitConvertor + $conv = new class('en') extends UnitConvertor { public function __construct(string $lang = 'en') { @@ -43,7 +42,7 @@ function convert_content() { private function findBaseUnit($from, $to) { - while (list($skey, $sval) = each($this->bases)) { + foreach ($this->bases as $skey => $sval) { if ($skey == $from || $to == $skey || in_array($to, $sval) || in_array($from, $sval)) { return $skey; } @@ -63,7 +62,7 @@ function convert_content() { $cells[] = $cell; // We now have the base unit and value now lets produce the table; - while (list($key, $val) = each($this->bases[$base_unit])) { + foreach ($this->bases[$base_unit] as $val) { $cell ['value'] = $this->convert($value, $from_unit, $val, $precision) . ' ' . $val; $cell ['class'] = ($val == $from_unit || $val == $to_unit) ? 'framedred' : ''; $cells[] = $cell; @@ -86,9 +85,7 @@ function convert_content() { return $string; } - } - - $conv = new TP_Converter('en'); + }; $conversions = [ 'Temperature' => ['base' => 'Celsius', @@ -176,10 +173,10 @@ function convert_content() { ] ]; - while (list($key, $val) = each($conversions)) { + foreach ($conversions as $key => $val) { $conv->addConversion($val['base'], $val['conv']); $list[$key][] = $val['base']; - while (list($ukey, $uval) = each($val['conv'])) { + foreach ($val['conv'] as $ukey => $uval) { $list[$key][] = $ukey; } } @@ -202,10 +199,9 @@ function convert_content() { $o .= ''; $o .= ''; $o .= '
- {{foreach $th_users as $k=>$th}} - {{if $k < 2 || $order_users == $th.1 || ($k==5 && !in_array($order_users,[$th_users.2.1, $th_users.3.1, $th_users.4.1])) }} + {{if $k < 2 || $order_users == $th.1 || ($k==4 && !in_array($order_users,[$th_users.2.1, $th_users.3.1, $th_users.5.1])) }} {{/if}} - {{if $order_users == $th_users.4.1}} - - {{/if}} - - {{if !in_array($order_users,[$th_users.2.1, $th_users.3.1, $th_users.4.1]) }} + {{if $order_users == $th_users.5.1}} From 46b38367209b8c5c6f084454d5a9ea9eb322a8d9 Mon Sep 17 00:00:00 2001 From: Matthew Exon Date: Sat, 11 Jan 2025 19:39:20 +0100 Subject: [PATCH 130/222] Ratioed: remove create user button --- ratioed/templates/ratioed.tpl | 3 --- 1 file changed, 3 deletions(-) diff --git a/ratioed/templates/ratioed.tpl b/ratioed/templates/ratioed.tpl index d634993e..c64cb1dc 100644 --- a/ratioed/templates/ratioed.tpl +++ b/ratioed/templates/ratioed.tpl @@ -6,9 +6,6 @@ {{$title}} - {{$page}} ({{$count}}) -

- {{$h_newuser}} -

+
@@ -323,7 +322,7 @@ $o .= <<< EOT - + @@ -345,13 +344,13 @@ $o .= <<< EOT - +
diff --git a/catavatar/catavatar.php b/catavatar/catavatar.php index 2116ac44..2bdf0cca 100644 --- a/catavatar/catavatar.php +++ b/catavatar/catavatar.php @@ -6,11 +6,9 @@ * Author: Fabio */ -use Friendica\App; use Friendica\Core\Hook; use Friendica\Core\Logger; use Friendica\Core\Renderer; -use Friendica\Core\Worker; use Friendica\Database\DBA; use Friendica\DI; use Friendica\Model\Contact; diff --git a/cookienotice/cookienotice.php b/cookienotice/cookienotice.php index 2bd6f9b1..bc9d2416 100644 --- a/cookienotice/cookienotice.php +++ b/cookienotice/cookienotice.php @@ -7,7 +7,6 @@ * Author: Peter Liebetrau */ -use Friendica\App; use Friendica\Core\Hook; use Friendica\Core\Renderer; use Friendica\DI; diff --git a/diaspora/diaspora.php b/diaspora/diaspora.php index 979204ba..d6c98e34 100644 --- a/diaspora/diaspora.php +++ b/diaspora/diaspora.php @@ -9,7 +9,6 @@ require_once 'addon/diaspora/Diaspora_Connection.php'; -use Friendica\App; use Friendica\Content\Text\BBCode; use Friendica\Core\Hook; use Friendica\Core\Logger; diff --git a/discourse/discourse.php b/discourse/discourse.php index 298b3f3e..e97a4fd8 100644 --- a/discourse/discourse.php +++ b/discourse/discourse.php @@ -8,7 +8,6 @@ * */ -use Friendica\App; use Friendica\Content\Text\Markdown; use Friendica\Core\Hook; use Friendica\Core\Logger; diff --git a/dwpost/dwpost.php b/dwpost/dwpost.php index 1ecd9764..7ce30086 100644 --- a/dwpost/dwpost.php +++ b/dwpost/dwpost.php @@ -8,7 +8,6 @@ * Author: Cat Gray */ -use Friendica\App; use Friendica\Content\Text\BBCode; use Friendica\Core\Hook; use Friendica\Core\Logger; diff --git a/fancybox/fancybox.php b/fancybox/fancybox.php index 73bbdab9..8608bcd7 100644 --- a/fancybox/fancybox.php +++ b/fancybox/fancybox.php @@ -7,7 +7,6 @@ * Status: Unsupported */ -use Friendica\App; use Friendica\Core\Hook; use Friendica\DI; diff --git a/fromapp/fromapp.php b/fromapp/fromapp.php index 0d5a5b16..8bd27606 100644 --- a/fromapp/fromapp.php +++ b/fromapp/fromapp.php @@ -7,7 +7,6 @@ * */ -use Friendica\App; use Friendica\Core\Hook; use Friendica\Core\Logger; use Friendica\Core\Renderer; @@ -76,6 +75,6 @@ function fromapp_post_hook(&$item) $apps = explode(',', $app); $item['app'] = trim($apps[mt_rand(0, count($apps)-1)]); - + return; } diff --git a/geocoordinates/geocoordinates.php b/geocoordinates/geocoordinates.php index 5cb90efd..eb56f093 100644 --- a/geocoordinates/geocoordinates.php +++ b/geocoordinates/geocoordinates.php @@ -6,7 +6,6 @@ * Author: Michael Vogel */ -use Friendica\App; use Friendica\Core\Hook; use Friendica\Core\Logger; use Friendica\Core\Renderer; diff --git a/geonames/geonames.php b/geonames/geonames.php index dcbd65f8..668eb0e7 100644 --- a/geonames/geonames.php +++ b/geonames/geonames.php @@ -6,7 +6,6 @@ * Author: Mike Macgirvin */ -use Friendica\App; use Friendica\Core\Hook; use Friendica\Core\Logger; use Friendica\Core\Renderer; diff --git a/gnot/gnot.php b/gnot/gnot.php index 15fb4da0..5d0919cb 100644 --- a/gnot/gnot.php +++ b/gnot/gnot.php @@ -4,11 +4,10 @@ * Description: Thread email comment notifications on Gmail and anonymise them * Version: 1.0 * Author: Mike Macgirvin - * + * * */ -use Friendica\App; use Friendica\Core\Hook; use Friendica\Core\Logger; use Friendica\Core\Renderer; @@ -38,7 +37,7 @@ function gnot_settings_post($post) { } /** - * Called from the Addon Setting form. + * Called from the Addon Setting form. * Add our own settings info to the page. */ function gnot_settings(array &$data) diff --git a/googlemaps/googlemaps.php b/googlemaps/googlemaps.php index 356ce68c..b83a9cf9 100644 --- a/googlemaps/googlemaps.php +++ b/googlemaps/googlemaps.php @@ -7,7 +7,6 @@ * */ -use Friendica\App; use Friendica\Core\Hook; use Friendica\Core\Logger; diff --git a/gravatar/gravatar.php b/gravatar/gravatar.php index 83a8fbb9..ca5eaaf0 100644 --- a/gravatar/gravatar.php +++ b/gravatar/gravatar.php @@ -6,15 +6,12 @@ * Author: Klaus Weidenbach */ -use Friendica\App; use Friendica\BaseModule; use Friendica\Core\Hook; use Friendica\Core\Logger; use Friendica\Core\Renderer; -use Friendica\Database\DBA; use Friendica\DI; use Friendica\Core\Config\Util\ConfigFileManager; -use Friendica\Util\Strings; /** * Installs the addon hook diff --git a/group_text/group_text.php b/group_text/group_text.php index 02e9fd0a..e5067fb5 100644 --- a/group_text/group_text.php +++ b/group_text/group_text.php @@ -8,9 +8,7 @@ * Note: Please use Circle Text instead */ -use Friendica\App; use Friendica\Core\Hook; -use Friendica\Core\Logger; use Friendica\Core\Renderer; use Friendica\DI; diff --git a/highlightjs/highlightjs.php b/highlightjs/highlightjs.php index 097d34c7..c1c2aac8 100644 --- a/highlightjs/highlightjs.php +++ b/highlightjs/highlightjs.php @@ -6,7 +6,6 @@ * Author: Hypolite Petovan */ -use Friendica\App; use Friendica\Core\Hook; use Friendica\DI; diff --git a/ifttt/ifttt.php b/ifttt/ifttt.php index 6d4f402c..51fa8db8 100644 --- a/ifttt/ifttt.php +++ b/ifttt/ifttt.php @@ -6,7 +6,6 @@ * Version: 0.1 * Author: Michael Vogel */ -use Friendica\App; use Friendica\Content\PageInfo; use Friendica\Core\Hook; use Friendica\Core\Logger; diff --git a/ijpost/ijpost.php b/ijpost/ijpost.php index f22dfff2..37c3cd45 100644 --- a/ijpost/ijpost.php +++ b/ijpost/ijpost.php @@ -8,7 +8,6 @@ * Author: Cat Gray */ -use Friendica\App; use Friendica\Content\Text\BBCode; use Friendica\Core\Hook; use Friendica\Core\Logger; diff --git a/impressum/impressum.php b/impressum/impressum.php index 754cb828..19ade933 100644 --- a/impressum/impressum.php +++ b/impressum/impressum.php @@ -7,7 +7,6 @@ * License: 3-clause BSD license */ -use Friendica\App; use Friendica\Content\Text\BBCode; use Friendica\Core\Hook; use Friendica\Core\Logger; diff --git a/infiniteimprobabilitydrive/infiniteimprobabilitydrive.php b/infiniteimprobabilitydrive/infiniteimprobabilitydrive.php index aff7aec0..9eb6ab36 100644 --- a/infiniteimprobabilitydrive/infiniteimprobabilitydrive.php +++ b/infiniteimprobabilitydrive/infiniteimprobabilitydrive.php @@ -6,7 +6,6 @@ * Author: Thomas Willingham */ -use Friendica\App; use Friendica\Core\Hook; use Friendica\DI; diff --git a/irc/irc.php b/irc/irc.php index d4435851..db808a99 100644 --- a/irc/irc.php +++ b/irc/irc.php @@ -7,7 +7,6 @@ * Author: Tobias Diekershoff */ -use Friendica\App; use Friendica\Core\Hook; use Friendica\Core\Renderer; use Friendica\DI; diff --git a/krynn/krynn.php b/krynn/krynn.php index f7e77c26..fa9db133 100644 --- a/krynn/krynn.php +++ b/krynn/krynn.php @@ -10,7 +10,6 @@ *"My body was my sacrifice... for my magic. This damage is permanent." - Raistlin Majere */ -use Friendica\App; use Friendica\Core\Hook; use Friendica\Core\Logger; use Friendica\Core\Renderer; diff --git a/ldapauth/ldapauth.php b/ldapauth/ldapauth.php index 38e2d6a1..14686e99 100644 --- a/ldapauth/ldapauth.php +++ b/ldapauth/ldapauth.php @@ -29,7 +29,6 @@ * The configuration options for this module are described in the config/ldapauth.config.php file */ -use Friendica\App; use Friendica\Core\Hook; use Friendica\Core\Logger; use Friendica\Database\DBA; diff --git a/libertree/libertree.php b/libertree/libertree.php index 1d997123..c138e597 100644 --- a/libertree/libertree.php +++ b/libertree/libertree.php @@ -6,7 +6,6 @@ * Author: Tony Baldwin */ -use Friendica\App; use Friendica\Content\Text\BBCode; use Friendica\Core\Hook; use Friendica\Core\Logger; diff --git a/libravatar/libravatar.php b/libravatar/libravatar.php index 54594b88..b0b2c214 100644 --- a/libravatar/libravatar.php +++ b/libravatar/libravatar.php @@ -6,7 +6,6 @@ * Author: Klaus Weidenbach */ -use Friendica\App; use Friendica\Core\Addon; use Friendica\Core\Hook; use Friendica\Core\Logger; diff --git a/markdown/markdown.php b/markdown/markdown.php index 6f459244..0822ac83 100644 --- a/markdown/markdown.php +++ b/markdown/markdown.php @@ -5,7 +5,6 @@ * Version: 0.1 * Author: Michael Vogel */ -use Friendica\App; use Friendica\Core\Hook; use Friendica\Content\Text\Markdown; use Friendica\Core\Renderer; diff --git a/mathjax/mathjax.php b/mathjax/mathjax.php index d0046cf7..e96aaddf 100644 --- a/mathjax/mathjax.php +++ b/mathjax/mathjax.php @@ -8,7 +8,6 @@ * License: 3-clause BSD license */ -use Friendica\App; use Friendica\Core\Hook; use Friendica\Core\Renderer; use Friendica\DI; diff --git a/morechoice/morechoice.php b/morechoice/morechoice.php index fe726d27..fbb88ce1 100644 --- a/morechoice/morechoice.php +++ b/morechoice/morechoice.php @@ -8,7 +8,6 @@ * Status: Deprecated */ -use Friendica\App; use Friendica\Core\Hook; use Friendica\DI; diff --git a/morepokes/morepokes.php b/morepokes/morepokes.php index abe59a6e..2ac09a73 100644 --- a/morepokes/morepokes.php +++ b/morepokes/morepokes.php @@ -7,7 +7,6 @@ * */ -use Friendica\App; use Friendica\Core\Hook; use Friendica\DI; diff --git a/newmemberwidget/newmemberwidget.php b/newmemberwidget/newmemberwidget.php index 01977d0c..d3b68807 100644 --- a/newmemberwidget/newmemberwidget.php +++ b/newmemberwidget/newmemberwidget.php @@ -6,7 +6,6 @@ * Author: Tobias Diekershoff ***/ -use Friendica\App; use Friendica\Content\Text\BBCode; use Friendica\Core\Hook; use Friendica\Core\Logger; diff --git a/nitter/nitter.php b/nitter/nitter.php index 946b18c0..adbfd6b0 100644 --- a/nitter/nitter.php +++ b/nitter/nitter.php @@ -25,7 +25,6 @@ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -use Friendica\App; use Friendica\Core\Hook; use Friendica\Core\Renderer; use Friendica\DI; diff --git a/nominatim/nominatim.php b/nominatim/nominatim.php index 6ad4a8a3..a3d14af5 100644 --- a/nominatim/nominatim.php +++ b/nominatim/nominatim.php @@ -6,7 +6,6 @@ * Author: Michael Vogel */ -use Friendica\App; use Friendica\Core\Hook; use Friendica\Core\Logger; use Friendica\Core\Renderer; diff --git a/notifyall/notifyall.php b/notifyall/notifyall.php index 966a9184..d37bac56 100644 --- a/notifyall/notifyall.php +++ b/notifyall/notifyall.php @@ -9,9 +9,7 @@ */ use Friendica\Addon\notifyall\NotifyAllEmail; -use Friendica\App; use Friendica\Database\DBA; -use Friendica\Core\Logger; use Friendica\Core\Renderer; use Friendica\DI; diff --git a/numfriends/numfriends.php b/numfriends/numfriends.php index 538a4a3e..66c9b74a 100644 --- a/numfriends/numfriends.php +++ b/numfriends/numfriends.php @@ -6,7 +6,6 @@ * Author: Mike Macgirvin */ -use Friendica\App; use Friendica\Core\Hook; use Friendica\Core\Logger; use Friendica\Core\Renderer; @@ -39,7 +38,7 @@ function numfriends_settings_post($post) { /** * - * Called from the Addon Setting form. + * Called from the Addon Setting form. * Add our own settings info to the page. * */ @@ -50,7 +49,7 @@ function numfriends_settings(array &$data) } $numfriends = DI::pConfig()->get(DI::userSession()->getLocalUserId(), 'system', 'display_friend_count', 24); - + $t = Renderer::getMarkupTemplate('settings.tpl', 'addon/numfriends/'); $html = Renderer::replaceMacros($t, [ '$numfriends' => ['numfriends', DI::l10n()->t('How many contacts to display on profile sidebar'), $numfriends], diff --git a/openstreetmap/openstreetmap.php b/openstreetmap/openstreetmap.php index ae22aff0..c520514c 100644 --- a/openstreetmap/openstreetmap.php +++ b/openstreetmap/openstreetmap.php @@ -9,7 +9,6 @@ * */ -use Friendica\App; use Friendica\Core\Cache\Enum\Duration; use Friendica\Core\Hook; use Friendica\Core\Logger; diff --git a/opmlexport/opmlexport.php b/opmlexport/opmlexport.php index fdfacc3e..3df71275 100644 --- a/opmlexport/opmlexport.php +++ b/opmlexport/opmlexport.php @@ -8,12 +8,8 @@ */ use Friendica\DI; -use Friendica\App; use Friendica\Core\Hook; use Friendica\Core\Logger; -use Friendica\Network\HTTPException; -use Friendica\Database\DBA; -use Friendica\Core\Renderer; use Friendica\Core\Protocol; use Friendica\Model\Contact; use Friendica\Model\User; diff --git a/pageheader/pageheader.php b/pageheader/pageheader.php index 057bb863..d729acc1 100644 --- a/pageheader/pageheader.php +++ b/pageheader/pageheader.php @@ -5,10 +5,9 @@ * Version: 1.1 * Author: Keith Fernie * Hauke Altmann - * + * */ -use Friendica\App; use Friendica\Core\Hook; use Friendica\Core\Renderer; use Friendica\DI; diff --git a/phpmailer/phpmailer.php b/phpmailer/phpmailer.php index 4c12709d..5e137b94 100644 --- a/phpmailer/phpmailer.php +++ b/phpmailer/phpmailer.php @@ -7,7 +7,6 @@ * Maintainer: Hypolite Petovan */ -use Friendica\App; use Friendica\Core\Hook; use Friendica\DI; use Friendica\Object\EMail\IEmail; diff --git a/piwik/piwik.php b/piwik/piwik.php index fd6d5fc9..b7b49bd4 100644 --- a/piwik/piwik.php +++ b/piwik/piwik.php @@ -35,7 +35,6 @@ * setting. */ -use Friendica\App; use Friendica\Core\Hook; use Friendica\Core\Logger; use Friendica\Core\Renderer; @@ -76,7 +75,7 @@ function piwik_analytics(string &$b) * Add the Piwik tracking code for the site. * If async is set to true use asynchronous tracking */ - + $scriptAsyncValue = $async ? 'true' : 'false'; $scriptPhpEndpoint = $shortendpoint ? 'js/' : 'piwik.php'; $scriptJsEndpoint = $shortendpoint ? 'js/' : 'piwik.js'; diff --git a/planets/planets.php b/planets/planets.php index 8a206fb5..d96e33a6 100644 --- a/planets/planets.php +++ b/planets/planets.php @@ -7,7 +7,6 @@ * Author: Tony Baldwin */ -use Friendica\App; use Friendica\Core\Hook; use Friendica\Core\Logger; use Friendica\Core\Renderer; diff --git a/public_server/public_server.php b/public_server/public_server.php index 7591c7d0..5834f42a 100644 --- a/public_server/public_server.php +++ b/public_server/public_server.php @@ -6,7 +6,6 @@ * Author: Keith Fernie */ -use Friendica\App; use Friendica\BaseModule; use Friendica\Core\Hook; use Friendica\Core\Logger; diff --git a/qcomment/qcomment.php b/qcomment/qcomment.php index 1b8bfcbf..f7126531 100644 --- a/qcomment/qcomment.php +++ b/qcomment/qcomment.php @@ -18,7 +18,6 @@ * */ -use Friendica\App; use Friendica\Core\Hook; use Friendica\Core\Renderer; use Friendica\DI; diff --git a/randplace/randplace.php b/randplace/randplace.php index 34f48c6c..5cb07597 100644 --- a/randplace/randplace.php +++ b/randplace/randplace.php @@ -19,7 +19,6 @@ * */ -use Friendica\App; use Friendica\Core\Hook; use Friendica\Core\Logger; use Friendica\Core\Renderer; diff --git a/rendertime/rendertime.php b/rendertime/rendertime.php index 731cf003..1cce5b1b 100644 --- a/rendertime/rendertime.php +++ b/rendertime/rendertime.php @@ -7,7 +7,6 @@ * */ -use Friendica\App; use Friendica\Core\Hook; use Friendica\Core\Renderer; use Friendica\DI; diff --git a/s3_storage/s3_storage.php b/s3_storage/s3_storage.php index 361577be..c08c3172 100644 --- a/s3_storage/s3_storage.php +++ b/s3_storage/s3_storage.php @@ -8,7 +8,6 @@ use Friendica\Addon\s3_storage\src\S3Client; use Friendica\Addon\s3_storage\src\S3Config; -use Friendica\App; use Friendica\Core\Hook; use Friendica\DI; diff --git a/securemail/SecureTestEmail.php b/securemail/SecureTestEmail.php index c614104f..32510091 100644 --- a/securemail/SecureTestEmail.php +++ b/securemail/SecureTestEmail.php @@ -21,7 +21,6 @@ namespace Friendica\Addon\securemail; -use Friendica\App; use Friendica\App\BaseURL; use Friendica\Core\Config\Capability\IManageConfigValues; use Friendica\Core\PConfig\Capability\IManagePersonalConfigValues; diff --git a/securemail/securemail.php b/securemail/securemail.php index 61125587..b56c0cbc 100644 --- a/securemail/securemail.php +++ b/securemail/securemail.php @@ -7,7 +7,6 @@ */ use Friendica\Addon\securemail\SecureTestEmail; -use Friendica\App; use Friendica\Core\Hook; use Friendica\Core\Logger; use Friendica\Core\Renderer; @@ -32,8 +31,6 @@ function securemail_install() * @link https://github.com/friendica/friendica/blob/develop/doc/Addons.md#addon_settings 'addon_settings' hook * * @param array $data - * - * @see App */ function securemail_settings(array &$data) { @@ -67,8 +64,6 @@ function securemail_settings(array &$data) * @link https://github.com/friendica/friendica/blob/develop/doc/Addons.md#addon_settings_post 'addon_settings_post' hook * * @param array $b hook data - * - * @see App */ function securemail_settings_post(array &$b) { @@ -102,8 +97,6 @@ function securemail_settings_post(array &$b) * @link https://github.com/friendica/friendica/blob/develop/doc/Addons.md#emailer_send_prepare 'emailer_send_prepare' hook * * @param IEmail $email Email - * - * @see App */ function securemail_emailer_send_prepare(IEmail &$email) { diff --git a/showmore_dyn/showmore_dyn.php b/showmore_dyn/showmore_dyn.php index 7cb64bcc..4c2e62f5 100644 --- a/showmore_dyn/showmore_dyn.php +++ b/showmore_dyn/showmore_dyn.php @@ -7,12 +7,8 @@ * */ -use Friendica\App; use Friendica\Core\Hook; -use Friendica\Core\L10n; -use Friendica\Core\Logger; use Friendica\Core\Renderer; -use Friendica\Database\DBA; use Friendica\DI; function showmore_dyn_install() diff --git a/smiley_pack/lang/smiley_pack_es/smiley_pack_es.php b/smiley_pack/lang/smiley_pack_es/smiley_pack_es.php index 38b208da..0f41101d 100644 --- a/smiley_pack/lang/smiley_pack_es/smiley_pack_es.php +++ b/smiley_pack/lang/smiley_pack_es/smiley_pack_es.php @@ -3,11 +3,10 @@ * Name: Smiley Pack (Español) * Description: Pack of smileys that make master too AOLish. * Version: 1.02 - * Author: Thomas Willingham (based on Mike Macgirvin's Adult Smile template) + * Author: Thomas Willingham (based on Mike Macgirvin's Adult Smile template) * All smileys from sites offering them as Public Domain */ -use Friendica\App; use Friendica\Core\Hook; use Friendica\DI; @@ -19,7 +18,7 @@ function smiley_pack_smilies_es(array &$b) { #Smileys are split into various directories by the intended range of emotions. This is in case we get too big and need to modularise things. We can then cut and paste the right lines, move the right directory, and just change the name of the addon to happy_smilies or whatever. -#Be careful with invocation strings. If you have a smiley called foo, and another called foobar, typing :foobar will call foo. Avoid this with clever naming, using ~ instead of : +#Be careful with invocation strings. If you have a smiley called foo, and another called foobar, typing :foobar will call foo. Avoid this with clever naming, using ~ instead of : #when all else fails. @@ -49,7 +48,7 @@ function smiley_pack_smilies_es(array &$b) { $b['texts'][] = ':vaca'; $b['icons'][] = '' . ':vaca' . ''; - + $b['texts'][] = ':cangrejo'; $b['icons'][] = '' . ':cangrejo' . ''; @@ -70,7 +69,7 @@ function smiley_pack_smilies_es(array &$b) { $b['texts'][] = ':caballo'; $b['icons'][] = '' . ':caballo' . ''; - + $b['texts'][] = ':loro'; $b['icons'][] = '' . ':loro' . ''; @@ -107,7 +106,7 @@ function smiley_pack_smilies_es(array &$b) { $b['texts'][] = ':cuna'; $b['icons'][] = '' . ':cuna' . ''; - + $b['texts'][] = ':embarazada'; $b['icons'][] = '' . ':embarazada' . ''; @@ -116,10 +115,10 @@ function smiley_pack_smilies_es(array &$b) { $b['icons'][] = '' . ':cigüeña' . ''; -#Confused Smileys +#Confused Smileys $b['texts'][] = ':confundido'; $b['icons'][] = '' . ':confundido' . ''; - + $b['texts'][] = ':encogehombros'; $b['icons'][] = '' . ':encogehombros' . ''; @@ -154,13 +153,13 @@ function smiley_pack_smilies_es(array &$b) { $b['texts'][] = ':diabólico'; $b['icons'][] = '' . ':diabólico' . ''; - + $b['texts'][] = ':adbalancín'; $b['icons'][] = '' . ':adbalancín' . ''; $b['texts'][] = ':vuelvedemonio'; $b['icons'][] = '' . ':vuelvedemonio' . ''; - + $b['texts'][] = ':santo'; $b['icons'][] = '' . ':santo' . ''; @@ -242,7 +241,7 @@ function smiley_pack_smilies_es(array &$b) { $b['texts'][] = ':billar'; $b['icons'][] = '' . ':billar' . ''; - + $b['texts'][] = ':tenis'; $b['icons'][] = '' . ':tenis' . ''; diff --git a/smiley_pack/lang/smiley_pack_fr/smiley_pack_fr.php b/smiley_pack/lang/smiley_pack_fr/smiley_pack_fr.php index 63cf613e..c5474e3c 100644 --- a/smiley_pack/lang/smiley_pack_fr/smiley_pack_fr.php +++ b/smiley_pack/lang/smiley_pack_fr/smiley_pack_fr.php @@ -9,7 +9,6 @@ * */ -use Friendica\App; use Friendica\Core\Hook; use Friendica\DI; @@ -23,7 +22,7 @@ function smiley_pack_fr_smilies(array &$b) #Smileys are split into various directories by the intended range of emotions. This is in case we get too big and need to modularise things. We can then cut and paste the right lines, move the right directory, and just change the name of the addon to happy_smilies or whatever. -#Be careful with invocation strings. If you have a smiley called foo, and another called foobar, typing :foobar will call foo. Avoid this with clever naming, using ~ instead of : +#Be careful with invocation strings. If you have a smiley called foo, and another called foobar, typing :foobar will call foo. Avoid this with clever naming, using ~ instead of : #when all else fails. @@ -56,7 +55,7 @@ function smiley_pack_fr_smilies(array &$b) $b['texts'][] = ':vache'; $b['icons'][] = '' . ':vache' . ''; - + $b['texts'][] = ':crabe'; $b['icons'][] = '' . ':crabe' . ''; @@ -74,7 +73,7 @@ function smiley_pack_fr_smilies(array &$b) $b['texts'][] = ':cheval'; $b['icons'][] = '' . ':cheval' . ''; - + $b['texts'][] = ':perroquet'; $b['icons'][] = '' . ':perroquet' . ''; @@ -108,7 +107,7 @@ function smiley_pack_fr_smilies(array &$b) $b['texts'][] = ':litbébé'; $b['icons'][] = '' . ':litbébé' . ''; - + $b['texts'][] = ':enceinte'; $b['icons'][] = '' . ':enceinte' . ''; @@ -117,10 +116,10 @@ function smiley_pack_fr_smilies(array &$b) $b['icons'][] = '' . ':cigogne' . ''; -#Confused Smileys +#Confused Smileys $b['texts'][] = ':paumé'; $b['icons'][] = '' . ':paumé' . ''; - + $b['texts'][] = ':hausseépaules'; $b['icons'][] = '' . ':hausseépaules' . ''; @@ -152,13 +151,13 @@ function smiley_pack_fr_smilies(array &$b) $b['texts'][] = ':démoniaque'; $b['icons'][] = '' . ':démoniaque' . ''; - + $b['texts'][] = ':bascule'; $b['icons'][] = '' . ':bascule' . ''; $b['texts'][] = ':possédé'; $b['icons'][] = '' . ':possédé' . ''; - + $b['texts'][] = ':tombe'; $b['icons'][] = '' . ':tombe' . ''; @@ -225,7 +224,7 @@ function smiley_pack_fr_smilies(array &$b) $b['texts'][] = ':billard'; $b['icons'][] = '' . ':billard' . ''; - + $b['texts'][] = ':équitation'; $b['icons'][] = '' . ':équitation' . ''; diff --git a/smileybutton/smileybutton.php b/smileybutton/smileybutton.php index 1df717b7..ae0e783b 100644 --- a/smileybutton/smileybutton.php +++ b/smileybutton/smileybutton.php @@ -7,7 +7,6 @@ * Maintainer: Hypolite Petovan */ -use Friendica\App; use Friendica\Core\Hook; use Friendica\DI; diff --git a/smilies_adult/smilies_adult.php b/smilies_adult/smilies_adult.php index e8af21e1..4a80168d 100644 --- a/smilies_adult/smilies_adult.php +++ b/smilies_adult/smilies_adult.php @@ -4,12 +4,11 @@ * Description: Smily icons that could or should not be included in core * Version: 1.0 * Author: Mike Macgirvin - * + * * This is a template for how to extend the "smily" code. - * + * */ -use Friendica\App; use Friendica\Core\Hook; use Friendica\DI; diff --git a/startpage/startpage.php b/startpage/startpage.php index e4d80c0c..558af473 100644 --- a/startpage/startpage.php +++ b/startpage/startpage.php @@ -7,7 +7,6 @@ * */ -use Friendica\App; use Friendica\Core\Hook; use Friendica\Core\Renderer; use Friendica\DI; diff --git a/statusnet/statusnet.php b/statusnet/statusnet.php index 48f9c254..bd115115 100644 --- a/statusnet/statusnet.php +++ b/statusnet/statusnet.php @@ -38,7 +38,6 @@ define('STATUSNET_DEFAULT_POLL_INTERVAL', 5); // given in minutes require_once __DIR__ . DIRECTORY_SEPARATOR . 'library' . DIRECTORY_SEPARATOR . 'statusnetoauth.php'; use CodebirdSN\CodebirdSN; -use Friendica\App; use Friendica\Content\Text\Plaintext; use Friendica\Core\Hook; use Friendica\Core\Logger; diff --git a/testdrive/testdrive.php b/testdrive/testdrive.php index 55645284..40f22e0a 100644 --- a/testdrive/testdrive.php +++ b/testdrive/testdrive.php @@ -6,7 +6,6 @@ * Author: Mike Macgirvin */ -use Friendica\App; use Friendica\Core\Hook; use Friendica\Core\Search; use Friendica\Database\DBA; diff --git a/unicode_smilies/unicode_smilies.php b/unicode_smilies/unicode_smilies.php index 22ee3439..b39c6f10 100644 --- a/unicode_smilies/unicode_smilies.php +++ b/unicode_smilies/unicode_smilies.php @@ -7,7 +7,6 @@ * Author: Matthias Ebers */ -use Friendica\App; use Friendica\Content\Smilies; use Friendica\Core\Hook; @@ -691,7 +690,7 @@ function unicode_smilies_smilies(array &$b) Smilies::add($b, ':custard:', '🍮'); Smilies::add($b, ':honey pot:', '🍯'); -// drink +// drink Smilies::add($b, ':baby bottle:', '🍼'); Smilies::add($b, ':glass of milk:', '🥛'); Smilies::add($b, ':hot beverage:', '☕'); @@ -1123,7 +1122,7 @@ function unicode_smilies_smilies(array &$b) Smilies::add($b, ':control knobs:', '🎛'); Smilies::add($b, ':microphone:', '🎤'); Smilies::add($b, ':headphone:', '🎧'); - Smilies::add($b, ':radio:', '📻'); + Smilies::add($b, ':radio:', '📻'); // musical-instrument Smilies::add($b, ':saxophone:', '🎷'); @@ -1529,7 +1528,7 @@ function unicode_smilies_smilies(array &$b) Smilies::add($b, ':O button (blood type):', '🅾'); Smilies::add($b, ':OK button:', '🆗'); Smilies::add($b, ':P button:', '🅿'); - Smilies::add($b, ':SOS button:', '🆘'); + Smilies::add($b, ':SOS button:', '🆘'); Smilies::add($b, ':UP! button:', '🆙'); Smilies::add($b, ':VS button:', '🆚'); Smilies::add($b, ':Japanese “here” button:', '🈁'); diff --git a/viewsrc/viewsrc.php b/viewsrc/viewsrc.php index c4d21ccb..bd07b541 100644 --- a/viewsrc/viewsrc.php +++ b/viewsrc/viewsrc.php @@ -7,7 +7,6 @@ * */ -use Friendica\App; use Friendica\Core\Hook; use Friendica\DI; diff --git a/webrtc/webrtc.php b/webrtc/webrtc.php index e142b374..e5d4ce6e 100644 --- a/webrtc/webrtc.php +++ b/webrtc/webrtc.php @@ -7,7 +7,6 @@ * Author: Tobias Diekershoff */ -use Friendica\App; use Friendica\Core\Hook; use Friendica\Core\Renderer; use Friendica\DI; From 84659fc1ad339b0f7cee0b8d11ede9ea9aafba07 Mon Sep 17 00:00:00 2001 From: Art4 Date: Wed, 11 Dec 2024 21:47:10 +0000 Subject: [PATCH 096/222] Replace DI::app() with DI::appHelper() --- advancedcontentfilter/advancedcontentfilter.php | 2 +- bluesky/bluesky.php | 2 +- fancybox/fancybox.php | 2 +- geonames/geonames.php | 2 +- gravatar/gravatar.php | 2 +- highlightjs/highlightjs.php | 2 +- impressum/impressum.php | 2 +- ldapauth/ldapauth.php | 2 +- libravatar/libravatar.php | 2 +- openstreetmap/openstreetmap.php | 2 +- phpmailer/phpmailer.php | 2 +- piwik/piwik.php | 2 +- pnut/pnut.php | 2 +- public_server/public_server.php | 2 +- pumpio/pumpio.php | 2 +- smileybutton/smileybutton.php | 6 +++--- testdrive/testdrive.php | 2 +- tumblr/tumblr.php | 2 +- twitter/twitter.php | 2 +- 19 files changed, 21 insertions(+), 21 deletions(-) diff --git a/advancedcontentfilter/advancedcontentfilter.php b/advancedcontentfilter/advancedcontentfilter.php index 329156f1..c03034cd 100644 --- a/advancedcontentfilter/advancedcontentfilter.php +++ b/advancedcontentfilter/advancedcontentfilter.php @@ -271,7 +271,7 @@ function advancedcontentfilter_content() 'rule_expression' => DI::l10n()->t('Rule Expression'), 'cancel' => DI::l10n()->t('Cancel'), ], - '$current_theme' => DI::app()->getCurrentTheme(), + '$current_theme' => DI::appHelper()->getCurrentTheme(), '$rules' => DBA::toArray(DBA::select('advancedcontentfilter_rules', [], ['uid' => DI::userSession()->getLocalUserId()])), '$form_security_token' => BaseModule::getFormSecurityToken() ]); diff --git a/bluesky/bluesky.php b/bluesky/bluesky.php index 91e524fe..aa4bc340 100644 --- a/bluesky/bluesky.php +++ b/bluesky/bluesky.php @@ -98,7 +98,7 @@ function bluesky_install() function bluesky_load_config(ConfigFileManager $loader) { - DI::app()->getConfigCache()->load($loader->loadAddonConfig('bluesky'), \Friendica\Core\Config\ValueObject\Cache::SOURCE_STATIC); + DI::appHelper()->getConfigCache()->load($loader->loadAddonConfig('bluesky'), \Friendica\Core\Config\ValueObject\Cache::SOURCE_STATIC); } function bluesky_check_item_notification(array &$notification_data) diff --git a/fancybox/fancybox.php b/fancybox/fancybox.php index 8608bcd7..b1a1ff35 100644 --- a/fancybox/fancybox.php +++ b/fancybox/fancybox.php @@ -39,7 +39,7 @@ function fancybox_render(array &$b){ function ($text) use ($gallery) { // This processes images inlined in posts // Frio / Vier hooks für lightbox are un-hooked in fancybox-config.js. So this works for them, too! - //if (!in_array(DI::app()->getCurrentTheme(),['vier','frio'])) + //if (!in_array(DI::appHelper()->getCurrentTheme(),['vier','frio'])) $text = preg_replace( '#]*href="([^"]*)"[^>]*>(]*src="[^"]*"[^>]*>)#', '$2', diff --git a/geonames/geonames.php b/geonames/geonames.php index 668eb0e7..d14b1e8f 100644 --- a/geonames/geonames.php +++ b/geonames/geonames.php @@ -34,7 +34,7 @@ function geonames_install() function geonames_load_config(ConfigFileManager $loader) { - DI::app()->getConfigCache()->load($loader->loadAddonConfig('geonames'), \Friendica\Core\Config\ValueObject\Cache::SOURCE_STATIC); + DI::appHelper()->getConfigCache()->load($loader->loadAddonConfig('geonames'), \Friendica\Core\Config\ValueObject\Cache::SOURCE_STATIC); } function geonames_post_hook(array &$item) diff --git a/gravatar/gravatar.php b/gravatar/gravatar.php index ca5eaaf0..6007c433 100644 --- a/gravatar/gravatar.php +++ b/gravatar/gravatar.php @@ -25,7 +25,7 @@ function gravatar_install() { function gravatar_load_config(ConfigFileManager $loader) { - DI::app()->getConfigCache()->load($loader->loadAddonConfig('gravatar'), \Friendica\Core\Config\ValueObject\Cache::SOURCE_STATIC); + DI::appHelper()->getConfigCache()->load($loader->loadAddonConfig('gravatar'), \Friendica\Core\Config\ValueObject\Cache::SOURCE_STATIC); } /** diff --git a/highlightjs/highlightjs.php b/highlightjs/highlightjs.php index c1c2aac8..762f4117 100644 --- a/highlightjs/highlightjs.php +++ b/highlightjs/highlightjs.php @@ -17,7 +17,7 @@ function highlightjs_install() function highlightjs_head(string &$str) { - if (DI::app()->getCurrentTheme() == 'frio') { + if (DI::appHelper()->getCurrentTheme() == 'frio') { $style = 'bootstrap'; } else { $style = 'default'; diff --git a/impressum/impressum.php b/impressum/impressum.php index 19ade933..f61d7182 100644 --- a/impressum/impressum.php +++ b/impressum/impressum.php @@ -55,7 +55,7 @@ function impressum_footer(string &$body) function impressum_load_config(ConfigFileManager $loader) { - DI::app()->getConfigCache()->load($loader->loadAddonConfig('impressum'), \Friendica\Core\Config\ValueObject\Cache::SOURCE_STATIC); + DI::appHelper()->getConfigCache()->load($loader->loadAddonConfig('impressum'), \Friendica\Core\Config\ValueObject\Cache::SOURCE_STATIC); } function impressum_show(string &$body) diff --git a/ldapauth/ldapauth.php b/ldapauth/ldapauth.php index 14686e99..f834b4d5 100644 --- a/ldapauth/ldapauth.php +++ b/ldapauth/ldapauth.php @@ -44,7 +44,7 @@ function ldapauth_install() function ldapauth_load_config(ConfigFileManager $loader) { - DI::app()->getConfigCache()->load($loader->loadAddonConfig('ldapauth'), \Friendica\Core\Config\ValueObject\Cache::SOURCE_STATIC); + DI::appHelper()->getConfigCache()->load($loader->loadAddonConfig('ldapauth'), \Friendica\Core\Config\ValueObject\Cache::SOURCE_STATIC); } function ldapauth_hook_authenticate(array &$b) diff --git a/libravatar/libravatar.php b/libravatar/libravatar.php index b0b2c214..4cd72c83 100644 --- a/libravatar/libravatar.php +++ b/libravatar/libravatar.php @@ -25,7 +25,7 @@ function libravatar_install() function libravatar_load_config(ConfigFileManager $loader) { - DI::app()->getConfigCache()->load($loader->loadAddonConfig('libravatar'), \Friendica\Core\Config\ValueObject\Cache::SOURCE_STATIC); + DI::appHelper()->getConfigCache()->load($loader->loadAddonConfig('libravatar'), \Friendica\Core\Config\ValueObject\Cache::SOURCE_STATIC); } /** diff --git a/openstreetmap/openstreetmap.php b/openstreetmap/openstreetmap.php index c520514c..fc5ebbbe 100644 --- a/openstreetmap/openstreetmap.php +++ b/openstreetmap/openstreetmap.php @@ -36,7 +36,7 @@ function openstreetmap_install() function openstreetmap_load_config(ConfigFileManager $loader) { - DI::app()->getConfigCache()->load($loader->loadAddonConfig('openstreetmap'), \Friendica\Core\Config\ValueObject\Cache::SOURCE_STATIC); + DI::appHelper()->getConfigCache()->load($loader->loadAddonConfig('openstreetmap'), \Friendica\Core\Config\ValueObject\Cache::SOURCE_STATIC); } function openstreetmap_alterheader(&$navHtml) diff --git a/phpmailer/phpmailer.php b/phpmailer/phpmailer.php index 5e137b94..f4bb7753 100644 --- a/phpmailer/phpmailer.php +++ b/phpmailer/phpmailer.php @@ -24,7 +24,7 @@ function phpmailer_install() function phpmailer_load_config(ConfigFileManager $loader) { - DI::app()->getConfigCache()->load($loader->loadAddonConfig('phpmailer'), \Friendica\Core\Config\ValueObject\Cache::SOURCE_STATIC); + DI::appHelper()->getConfigCache()->load($loader->loadAddonConfig('phpmailer'), \Friendica\Core\Config\ValueObject\Cache::SOURCE_STATIC); } /** diff --git a/piwik/piwik.php b/piwik/piwik.php index b7b49bd4..fc459a87 100644 --- a/piwik/piwik.php +++ b/piwik/piwik.php @@ -50,7 +50,7 @@ function piwik_install() { function piwik_load_config(ConfigFileManager $loader) { - DI::app()->getConfigCache()->load($loader->loadAddonConfig('piwik'), \Friendica\Core\Config\ValueObject\Cache::SOURCE_STATIC); + DI::appHelper()->getConfigCache()->load($loader->loadAddonConfig('piwik'), \Friendica\Core\Config\ValueObject\Cache::SOURCE_STATIC); } function piwik_analytics(string &$b) diff --git a/pnut/pnut.php b/pnut/pnut.php index 32f60f6d..f298997b 100644 --- a/pnut/pnut.php +++ b/pnut/pnut.php @@ -90,7 +90,7 @@ function pnut_connect() function pnut_load_config(ConfigFileManager $loader) { - DI::app()->getConfigCache()->load($loader->loadAddonConfig('pnut'), \Friendica\Core\Config\ValueObject\Cache::SOURCE_STATIC); + DI::appHelper()->getConfigCache()->load($loader->loadAddonConfig('pnut'), \Friendica\Core\Config\ValueObject\Cache::SOURCE_STATIC); } function pnut_addon_admin(string &$o) diff --git a/public_server/public_server.php b/public_server/public_server.php index 5834f42a..eb7af1e7 100644 --- a/public_server/public_server.php +++ b/public_server/public_server.php @@ -28,7 +28,7 @@ function public_server_install() function public_server_load_config(ConfigFileManager $loader) { - DI::app()->getConfigCache()->load($loader->loadAddonConfig('public_server'), \Friendica\Core\Config\ValueObject\Cache::SOURCE_STATIC); + DI::appHelper()->getConfigCache()->load($loader->loadAddonConfig('public_server'), \Friendica\Core\Config\ValueObject\Cache::SOURCE_STATIC); } function public_server_register_account($b) diff --git a/pumpio/pumpio.php b/pumpio/pumpio.php index d7c2ac32..ffe5f187 100644 --- a/pumpio/pumpio.php +++ b/pumpio/pumpio.php @@ -319,7 +319,7 @@ function pumpio_settings_post(array &$b) function pumpio_load_config(ConfigFileManager $loader) { - DI::app()->getConfigCache()->load($loader->loadAddonConfig('pumpio'), \Friendica\Core\Config\ValueObject\Cache::SOURCE_STATIC); + DI::appHelper()->getConfigCache()->load($loader->loadAddonConfig('pumpio'), \Friendica\Core\Config\ValueObject\Cache::SOURCE_STATIC); } function pumpio_hook_fork(array &$b) diff --git a/smileybutton/smileybutton.php b/smileybutton/smileybutton.php index ae0e783b..4d0a8d42 100644 --- a/smileybutton/smileybutton.php +++ b/smileybutton/smileybutton.php @@ -19,7 +19,7 @@ function smileybutton_install() function smileybutton_jot_tool(string &$body) { // Disable if theme is quattro - if (DI::app()->getCurrentTheme() == 'quattro') { + if (DI::appHelper()->getCurrentTheme() == 'quattro') { return; } @@ -96,7 +96,7 @@ function smileybutton_jot_tool(string &$body) $s .= '
'; //Add css to header - $css_file = __DIR__ . '/view/' . DI::app()->getCurrentTheme() . '.css'; + $css_file = __DIR__ . '/view/' . DI::appHelper()->getCurrentTheme() . '.css'; if (!file_exists($css_file)) { $css_file = __DIR__ . '/view/default.css'; } @@ -104,7 +104,7 @@ function smileybutton_jot_tool(string &$body) DI::page()->registerStylesheet($css_file); //Get the correct image for the theme - $image = 'addon/smileybutton/view/' . DI::app()->getCurrentTheme() . '.png'; + $image = 'addon/smileybutton/view/' . DI::appHelper()->getCurrentTheme() . '.png'; if (!file_exists($image)) { $image = 'addon/smileybutton/view/default.png'; } diff --git a/testdrive/testdrive.php b/testdrive/testdrive.php index 40f22e0a..90fb5918 100644 --- a/testdrive/testdrive.php +++ b/testdrive/testdrive.php @@ -26,7 +26,7 @@ function testdrive_install() function testdrive_load_config(ConfigFileManager $loader) { - DI::app()->getConfigCache()->load($loader->loadAddonConfig('testdrive'), \Friendica\Core\Config\ValueObject\Cache::SOURCE_STATIC); + DI::appHelper()->getConfigCache()->load($loader->loadAddonConfig('testdrive'), \Friendica\Core\Config\ValueObject\Cache::SOURCE_STATIC); } function testdrive_globaldir_update(array &$b) diff --git a/tumblr/tumblr.php b/tumblr/tumblr.php index 1e9f5c7f..580d73e6 100644 --- a/tumblr/tumblr.php +++ b/tumblr/tumblr.php @@ -65,7 +65,7 @@ function tumblr_install() function tumblr_load_config(ConfigFileManager $loader) { - DI::app()->getConfigCache()->load($loader->loadAddonConfig('tumblr'), \Friendica\Core\Config\ValueObject\Cache::SOURCE_STATIC); + DI::appHelper()->getConfigCache()->load($loader->loadAddonConfig('tumblr'), \Friendica\Core\Config\ValueObject\Cache::SOURCE_STATIC); } function tumblr_check_item_notification(array &$notification_data) diff --git a/twitter/twitter.php b/twitter/twitter.php index 10f8a2fb..ea4ae356 100644 --- a/twitter/twitter.php +++ b/twitter/twitter.php @@ -67,7 +67,7 @@ function twitter_install() function twitter_load_config(ConfigFileManager $loader) { - DI::app()->getConfigCache()->load($loader->loadAddonConfig('twitter'), \Friendica\Core\Config\ValueObject\Cache::SOURCE_STATIC); + DI::appHelper()->getConfigCache()->load($loader->loadAddonConfig('twitter'), \Friendica\Core\Config\ValueObject\Cache::SOURCE_STATIC); } function twitter_jot_nets(array &$jotnets_fields) From 31198294c787497d0c5cb4bcf081e5a15db084e5 Mon Sep 17 00:00:00 2001 From: Art4 Date: Fri, 29 Nov 2024 22:36:05 +0000 Subject: [PATCH 097/222] Fix error in bluesky addon --- bluesky/bluesky.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bluesky/bluesky.php b/bluesky/bluesky.php index 38934feb..8e2c1ca0 100644 --- a/bluesky/bluesky.php +++ b/bluesky/bluesky.php @@ -1563,7 +1563,7 @@ function bluesky_get_uri_class(string $uri): ?stdClass } $elements = explode(':', $uri); - if (empty($elements) || ($elements[0] != 'at')) { + if ($elements[0] !== 'at') { $post = Post::selectFirstPost(['extid'], ['uri' => $uri]); return bluesky_get_uri_class($post['extid'] ?? ''); } From cf8a7870f3765db549ec961cf28f7fc7b8e466ad Mon Sep 17 00:00:00 2001 From: Art4 Date: Sat, 30 Nov 2024 19:27:45 +0000 Subject: [PATCH 098/222] Fix errors in bluesky addon --- bluesky/bluesky.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/bluesky/bluesky.php b/bluesky/bluesky.php index 8e2c1ca0..91e524fe 100644 --- a/bluesky/bluesky.php +++ b/bluesky/bluesky.php @@ -683,6 +683,8 @@ function bluesky_create_activity(array $item, stdClass $parent = null) return; } + $post = []; + if ($item['verb'] == Activity::LIKE) { $record = [ 'subject' => $parent, From 1860e732aee24ee9b1f6677e7b8f5c503f226db6 Mon Sep 17 00:00:00 2001 From: Art4 Date: Sat, 30 Nov 2024 19:28:38 +0000 Subject: [PATCH 099/222] Fix errors in convert addon --- convert/convert.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/convert/convert.php b/convert/convert.php index 2c97e2aa..2545974c 100644 --- a/convert/convert.php +++ b/convert/convert.php @@ -181,7 +181,7 @@ function convert_content() { } } - $o .= '

Unit Conversions

'; + $o = '

Unit Conversions

'; if (isset($_POST['from_unit']) && isset($_POST['value'])) { $o .= ($conv->getTable(intval($_POST['value']), $_POST['from_unit'], $_POST['to_unit'], 5)) . '

'; From 81f232d57e8991ca342751d0db2d2680ec7bc7c8 Mon Sep 17 00:00:00 2001 From: Art4 Date: Sat, 30 Nov 2024 19:30:39 +0000 Subject: [PATCH 100/222] Fix errors in js_upload addon --- .../file-uploader/tests/action-acceptance.php | 16 ++++++++-------- .../tests/action-handler-queue-test.php | 8 ++++---- .../file-uploader/tests/action-handler-test.php | 8 ++++---- 3 files changed, 16 insertions(+), 16 deletions(-) diff --git a/js_upload/file-uploader/tests/action-acceptance.php b/js_upload/file-uploader/tests/action-acceptance.php index fc9583f2..172b8857 100644 --- a/js_upload/file-uploader/tests/action-acceptance.php +++ b/js_upload/file-uploader/tests/action-acceptance.php @@ -2,12 +2,12 @@ usleep(100000); -$fileName; -$fileSize; +$fileName = ''; +$fileSize = 0;; if (isset($_GET['qqfile'])){ $fileName = $_GET['qqfile']; - + // xhr request $headers = apache_request_headers(); $fileSize = (int)$headers['Content-Length']; @@ -34,13 +34,13 @@ if ($fileSize > 9 * 1024){ die ('{error: "server-error file size is bigger than 9kB"}'); } -if (count($_GET)){ +if (count($_GET)){ array_merge($_GET, array('fileName'=>$fileName)); - + $response = array_merge($_GET, array('success'=>true, 'fileName'=>$fileName)); - - // to pass data through iframe you will need to encode all html tags - echo htmlspecialchars(json_encode($response), ENT_NOQUOTES); + + // to pass data through iframe you will need to encode all html tags + echo htmlspecialchars(json_encode($response), ENT_NOQUOTES); } else { die ('{error: "server-error query params not passed"}'); } diff --git a/js_upload/file-uploader/tests/action-handler-queue-test.php b/js_upload/file-uploader/tests/action-handler-queue-test.php index ff13576d..78760d64 100644 --- a/js_upload/file-uploader/tests/action-handler-queue-test.php +++ b/js_upload/file-uploader/tests/action-handler-queue-test.php @@ -2,11 +2,11 @@ sleep(4); -$fileName; +$fileName = ''; if (isset($_GET['qqfile'])){ $fileName = $_GET['qqfile']; - + // xhr request $headers = apache_request_headers(); if ((int)$headers['Content-Length'] == 0){ @@ -14,7 +14,7 @@ if (isset($_GET['qqfile'])){ } } elseif (isset($_FILES['qqfile'])){ $fileName = basename($_FILES['qqfile']['name']); - + // form request if ($_FILES['qqfile']['size'] == 0){ die ('{error: "file size is zero"}'); @@ -25,7 +25,7 @@ if (isset($_GET['qqfile'])){ if (count($_GET)){ $_GET['success'] = true; - echo json_encode(array_merge($_GET)); + echo json_encode(array_merge($_GET)); } else { die ('{error: "query params not passed"}'); } diff --git a/js_upload/file-uploader/tests/action-handler-test.php b/js_upload/file-uploader/tests/action-handler-test.php index 24466b12..9fa72023 100644 --- a/js_upload/file-uploader/tests/action-handler-test.php +++ b/js_upload/file-uploader/tests/action-handler-test.php @@ -2,11 +2,11 @@ usleep(300); -$fileName; +$fileName = ''; if (isset($_GET['qqfile'])){ $fileName = $_GET['qqfile']; - + // xhr request $headers = apache_request_headers(); if ((int)$headers['Content-Length'] == 0){ @@ -14,7 +14,7 @@ if (isset($_GET['qqfile'])){ } } elseif (isset($_FILES['qqfile'])){ $fileName = basename($_FILES['qqfile']['name']); - + // form request if ($_FILES['qqfile']['size'] == 0){ die ('{error: "file size is zero"}'); @@ -25,7 +25,7 @@ if (isset($_GET['qqfile'])){ if (count($_GET)){ //return query params - echo json_encode(array_merge($_GET, array('fileName'=>$fileName))); + echo json_encode(array_merge($_GET, array('fileName'=>$fileName))); } else { die ('{error: "query params not passed"}'); } From 3cf53a334d3d04df83b35423f31a916eea0ab492 Mon Sep 17 00:00:00 2001 From: Art4 Date: Sat, 30 Nov 2024 19:32:07 +0000 Subject: [PATCH 101/222] Fix errors in keycloakpassword addon --- keycloakpassword/keycloakpassword.php | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/keycloakpassword/keycloakpassword.php b/keycloakpassword/keycloakpassword.php index bfff4ea4..e9809f86 100644 --- a/keycloakpassword/keycloakpassword.php +++ b/keycloakpassword/keycloakpassword.php @@ -6,7 +6,6 @@ * Author: Ryan */ -use Friendica\App; use Friendica\Core\Hook; use Friendica\Core\Logger; use Friendica\Core\Renderer; @@ -92,7 +91,7 @@ function keycloakpassword_authenticate(array &$b) $client_id, $secret, $endpoint . '/logout', - [ 'refresh_token' => res['refresh_token'] ] + [ 'refresh_token' => $res['refresh_token'] ] ); } } From a53d5ae29b1ec11d4063d636ec6c27074855576b Mon Sep 17 00:00:00 2001 From: Art4 Date: Sat, 30 Nov 2024 19:35:19 +0000 Subject: [PATCH 102/222] Fix errors in langfilter addon --- langfilter/langfilter.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/langfilter/langfilter.php b/langfilter/langfilter.php index e5efa8fb..2bf986f0 100644 --- a/langfilter/langfilter.php +++ b/langfilter/langfilter.php @@ -7,7 +7,6 @@ * License: MIT */ -use Friendica\App; use Friendica\Content\Text\BBCode; use Friendica\Core\Hook; use Friendica\Core\Renderer; @@ -148,6 +147,8 @@ function langfilter_prepare_body_content_filter(&$hook_data) $iso639 = new Matriphe\ISO639\ISO639; + $confidence = null; + // Extract the language of the post if (!empty($hook_data['item']['language'])) { $languages = json_decode($hook_data['item']['language'], true); From ee1a917612fb1c014eecce9d37b7dbcfa166aaa9 Mon Sep 17 00:00:00 2001 From: Art4 Date: Sat, 30 Nov 2024 19:37:58 +0000 Subject: [PATCH 103/222] Fix errors in leistungsschutzrecht addon --- leistungsschutzrecht/leistungsschutzrecht.php | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/leistungsschutzrecht/leistungsschutzrecht.php b/leistungsschutzrecht/leistungsschutzrecht.php index f6c65399..ec8091ac 100644 --- a/leistungsschutzrecht/leistungsschutzrecht.php +++ b/leistungsschutzrecht/leistungsschutzrecht.php @@ -6,7 +6,6 @@ * Author: Michael Vogel */ -use Friendica\App; use Friendica\Core\Hook; use Friendica\Core\Logger; use Friendica\DI; @@ -149,7 +148,7 @@ function leistungsschutzrecht_is_member_site(string $url): bool $cleanedurlpart = explode('%', $urldata['host']); $hostname = explode('.', $cleanedurlpart[0]); - if (empty($hostname)) { + if ($hostname === false || $hostname === '') { return false; } From d08a280ba6d51ea1671b62a65ee72f221f83106c Mon Sep 17 00:00:00 2001 From: Art4 Date: Sat, 30 Nov 2024 19:41:11 +0000 Subject: [PATCH 104/222] Fix errors in libravatar addon --- libravatar/Services/Libravatar.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libravatar/Services/Libravatar.php b/libravatar/Services/Libravatar.php index 70fcfe39..e51ef070 100644 --- a/libravatar/Services/Libravatar.php +++ b/libravatar/Services/Libravatar.php @@ -401,9 +401,8 @@ class Services_Libravatar */ protected function srvGet($domain, $https = false) { - // Are we going secure? Set up a fallback too. - if (isset($https) && $https === true) { + if ($https === true) { $subdomain = '_avatars-sec._tcp.'; $fallback = 'seccdn.'; } else { @@ -426,6 +425,7 @@ class Services_Libravatar $top = $srv[0]; $sum = 0; + $pri = []; // Try to adhere to RFC2782's weighting algorithm, page 3 // "arrange all SRV RRs (that have not been ordered yet) in any order, From 984e7c5e5d133ab4305c766a924d2517a03bbd2c Mon Sep 17 00:00:00 2001 From: Art4 Date: Sat, 30 Nov 2024 19:42:40 +0000 Subject: [PATCH 105/222] Fix errors in ljpost addon --- ljpost/ljpost.php | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/ljpost/ljpost.php b/ljpost/ljpost.php index 7acc6589..b416c605 100644 --- a/ljpost/ljpost.php +++ b/ljpost/ljpost.php @@ -8,7 +8,6 @@ * Author: Cat Gray */ -use Friendica\App; use Friendica\Content\Text\BBCode; use Friendica\Core\Hook; use Friendica\Core\Logger; @@ -203,10 +202,12 @@ EOT; Logger::debug('ljpost: data: ' . $xml); + $x = ''; + if ($lj_blog !== 'test') { $x = DI::httpClient()->post($lj_blog, $xml, ['Content-Type' => 'text/xml'])->getBodyString(); } - Logger::info('posted to livejournal: ' . ($x) ? $x : ''); + Logger::info('posted to livejournal: ' . $x); } } From 6b1b043dd8fc48511f9288249cd18322b8a709b4 Mon Sep 17 00:00:00 2001 From: Art4 Date: Sat, 30 Nov 2024 19:48:49 +0000 Subject: [PATCH 106/222] fix errors in mailstream addon --- mailstream/phpmailer/class.phpmailer.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mailstream/phpmailer/class.phpmailer.php b/mailstream/phpmailer/class.phpmailer.php index ff3d81e3..dcf02361 100644 --- a/mailstream/phpmailer/class.phpmailer.php +++ b/mailstream/phpmailer/class.phpmailer.php @@ -3287,7 +3287,7 @@ class PHPMailer $result = 'localhost.localdomain'; if (!empty($this->Hostname)) { $result = $this->Hostname; - } elseif (isset($_SERVER) and array_key_exists('SERVER_NAME', $_SERVER) and !empty($_SERVER['SERVER_NAME'])) { + } elseif (array_key_exists('SERVER_NAME', $_SERVER) and !empty($_SERVER['SERVER_NAME'])) { $result = $_SERVER['SERVER_NAME']; } elseif (function_exists('gethostname') && gethostname() !== false) { $result = gethostname(); From c0971779c6091f0d3621c38df30d77f4f1b7e021 Mon Sep 17 00:00:00 2001 From: Art4 Date: Sat, 30 Nov 2024 19:50:06 +0000 Subject: [PATCH 107/222] Fix errors in nsfw addon --- nsfw/nsfw.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/nsfw/nsfw.php b/nsfw/nsfw.php index 4a54d899..674fc201 100644 --- a/nsfw/nsfw.php +++ b/nsfw/nsfw.php @@ -8,7 +8,6 @@ * */ -use Friendica\App; use Friendica\Core\Hook; use Friendica\Core\Renderer; use Friendica\DI; @@ -119,7 +118,9 @@ function nsfw_prepare_body_content_filter(&$hook_data) $word_list = ['nsfw']; } - $found = false; + $found = false; + $tag_search = false; + if (count($word_list)) { $body = $hook_data['item']['title'] . "\n" . nsfw_extract_photos($hook_data['item']['body']); @@ -129,7 +130,6 @@ function nsfw_prepare_body_content_filter(&$hook_data) continue; } - $tag_search = false; switch ($word[0]) { case '/'; // Regular expression $found = @preg_match($word, $body); From 7fa2dfc608d9ac30253ac257c020dfda3061ec8b Mon Sep 17 00:00:00 2001 From: Art4 Date: Sat, 30 Nov 2024 19:51:18 +0000 Subject: [PATCH 108/222] Fix errors in pnut addon --- pnut/lib/phpnut.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/pnut/lib/phpnut.php b/pnut/lib/phpnut.php index 5794d795..89d5e5f8 100644 --- a/pnut/lib/phpnut.php +++ b/pnut/lib/phpnut.php @@ -1339,6 +1339,8 @@ class phpnut */ protected function updateUserImage(string $image, string $which='avatar') { + $mimeType = ''; + $test = @getimagesize($image); if ($test && array_key_exists('mime', $test)) { $mimeType = $test['mime']; From bda683c56b1800d1c2b3847e44074d554ac34c4b Mon Sep 17 00:00:00 2001 From: Art4 Date: Sat, 30 Nov 2024 20:12:23 +0000 Subject: [PATCH 109/222] fix errors in pumpio addon --- pumpio/pumpio.php | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/pumpio/pumpio.php b/pumpio/pumpio.php index 5e053d7c..d7c2ac32 100644 --- a/pumpio/pumpio.php +++ b/pumpio/pumpio.php @@ -6,7 +6,6 @@ * Author: Michael Vogel */ -use Friendica\App; use Friendica\Content\Text\BBCode; use Friendica\Content\Text\HTML; use Friendica\Core\Addon; @@ -582,6 +581,8 @@ function pumpio_action(int $uid, string $uri, string $action, string $content = $uri = $orig_post['uri']; } + $objectType = ''; + if (($orig_post['object-type'] != '') && (strstr($orig_post['object-type'], ActivityNamespace::ACTIVITY_SCHEMA))) { $objectType = str_replace(ActivityNamespace::ACTIVITY_SCHEMA, '', $orig_post['object-type']); } elseif (strstr($uri, '/api/comment/')) { @@ -827,6 +828,7 @@ function pumpio_dounlike(int $uid, array $self, $post, string $own_id) } $contactid = 0; + $contact = []; if (Strings::compareLink($post->actor->url, $own_id)) { $contactid = $self['id']; @@ -1430,6 +1432,8 @@ function pumpio_fetchallcomments($uid, $id) Logger::notice('pumpio_fetchallcomments: fetching comment for user ' . $uid . ', URL ' . $url); + $item = new \stdClass(); + if (pumpio_reachable($url)) { $success = $client->CallAPI($url, 'GET', [], ['FailOnAccessError' => true], $item); } else { From 5b623c83686b1ac4ac72d15f2072cb380b872ee2 Mon Sep 17 00:00:00 2001 From: Art4 Date: Sat, 30 Nov 2024 20:13:41 +0000 Subject: [PATCH 110/222] fix errors in ratioed addon --- ratioed/RatioedPanel.php | 1 + 1 file changed, 1 insertion(+) diff --git a/ratioed/RatioedPanel.php b/ratioed/RatioedPanel.php index e25c7f34..bd9b44dc 100644 --- a/ratioed/RatioedPanel.php +++ b/ratioed/RatioedPanel.php @@ -26,6 +26,7 @@ class RatioedPanel extends Active $action = $this->parameters['action'] ?? ''; $uid = $this->parameters['uid'] ?? 0; + $user = []; if ($uid) { $user = User::getById($uid, ['username', 'blocked']); From 8e778593ca014916297ad234587f5cbfb426f4f2 Mon Sep 17 00:00:00 2001 From: Art4 Date: Sat, 30 Nov 2024 20:27:57 +0000 Subject: [PATCH 111/222] fix errors in statusnet addon --- statusnet/library/codebirdsn.php | 13 +++++++------ statusnet/statusnet.php | 2 ++ 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/statusnet/library/codebirdsn.php b/statusnet/library/codebirdsn.php index 325bcb07..91e256be 100644 --- a/statusnet/library/codebirdsn.php +++ b/statusnet/library/codebirdsn.php @@ -31,11 +31,10 @@ use Friendica\Core\System; /** * Define constants */ -$constants = explode(' ', 'OBJECT ARRAY JSON'); -foreach ($constants as $i => $id) { - $id = 'CODEBIRD_RETURNFORMAT_' . $id; - defined($id) or define($id, $i); -} +defined('CODEBIRD_RETURNFORMAT_ARRAY') or define('CODEBIRD_RETURNFORMAT_ARRAY', 0); +defined('CODEBIRD_RETURNFORMAT_JSON') or define('CODEBIRD_RETURNFORMAT_JSON', 1); +defined('CODEBIRD_RETURNFORMAT_OBJECT') or define('CODEBIRD_RETURNFORMAT_OBJECT', 2); + $constants = array( 'CURLE_SSL_CERTPROBLEM' => 58, 'CURLE_SSL_CACERT' => 60, @@ -788,6 +787,8 @@ class CodebirdSN $possible_files = explode(' ', $possible_files[$method]); + $data = ''; + $multipart_border = '--------------------' . $this->_nonce(); $multipart_request = ''; foreach ($params as $key => $value) { @@ -917,7 +918,7 @@ class CodebirdSN $authorization = 'Authorization: Bearer ' . self::$_oauth_bearer_token; } $request_headers = array(); - if (isset($authorization)) { + if ($authorization !== '') { $request_headers[] = $authorization; $request_headers[] = 'Expect:'; } diff --git a/statusnet/statusnet.php b/statusnet/statusnet.php index 4bc32050..48f9c254 100644 --- a/statusnet/statusnet.php +++ b/statusnet/statusnet.php @@ -366,6 +366,8 @@ function statusnet_post_hook(array &$b) $otoken = DI::pConfig()->get($b['uid'], 'statusnet', 'oauthtoken'); $osecret = DI::pConfig()->get($b['uid'], 'statusnet', 'oauthsecret'); + $iscomment = null; + if ($ckey && $csecret && $otoken && $osecret) { $dent = new StatusNetOAuth($api, $ckey, $csecret, $otoken, $osecret); $max_char = $dent->get_maxlength(); // max. length for a dent From 2f89827deaa09de0cf8bf2a803645441f424cd9a Mon Sep 17 00:00:00 2001 From: Art4 Date: Sat, 30 Nov 2024 20:36:07 +0000 Subject: [PATCH 112/222] fix errors in tictac addon --- tictac/tictac.php | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/tictac/tictac.php b/tictac/tictac.php index 10103835..082b58c1 100644 --- a/tictac/tictac.php +++ b/tictac/tictac.php @@ -7,7 +7,6 @@ * Status: unsupported */ -use Friendica\App; use Friendica\Core\Hook; use Friendica\DI; @@ -30,7 +29,12 @@ function tictac_module() {} function tictac_content() { - $o = ''; + $o = ''; + $dimen = 3; + $handicap = 0; + $mefirst = 0; + $yours = ''; + $mine = ''; if($_POST['move']) { $handicap = DI::args()->get(1); @@ -45,9 +49,6 @@ function tictac_content() { $handicap = DI::args()->get(1); $dimen = 3; } - else { - $dimen = 3; - } $o .= '

' . DI::l10n()->t('3D Tic-Tac-Toe') . '


'; @@ -163,7 +164,7 @@ class tictac { ]; function __construct($dimen, $handicap, $mefirst, $yours, $mine) { - $this->dimen = 3; + $this->dimen = $dimen; $this->handicap = $handicap ? 1 : 0; $this->mefirst = $mefirst ? 1 : 0; $this->yours = str_replace('XXX','',$yours); @@ -228,6 +229,8 @@ class tictac { } function parse_moves($player) { + $str = ''; + if($player == 'me') $str = $this->mine; if($player == 'you') From a71db771d9473852786cc7435e9b1178b842880f Mon Sep 17 00:00:00 2001 From: Art4 Date: Sat, 30 Nov 2024 20:36:58 +0000 Subject: [PATCH 113/222] Fix errors in wppost addon --- wppost/wppost.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/wppost/wppost.php b/wppost/wppost.php index dba738de..f2ee5d21 100644 --- a/wppost/wppost.php +++ b/wppost/wppost.php @@ -259,9 +259,11 @@ EOT; Logger::debug('wppost: data: ' . $xml); + $x = ''; + if ($wp_blog !== 'test') { $x = DI::httpClient()->post($wp_blog, $xml)->getBodyString(); } - Logger::info('posted to wordpress: ' . (($x) ? $x : '')); + Logger::info('posted to wordpress: ' . $x); } } From 729b6e52107dd1f3ce870b2fa45b7a8e1f60cc4d Mon Sep 17 00:00:00 2001 From: Artur Weigandt Date: Thu, 5 Dec 2024 18:23:51 +0100 Subject: [PATCH 114/222] Update mailstream/phpmailer/class.phpmailer.php Co-authored-by: Hypolite Petovan --- mailstream/phpmailer/class.phpmailer.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mailstream/phpmailer/class.phpmailer.php b/mailstream/phpmailer/class.phpmailer.php index dcf02361..1d9df9af 100644 --- a/mailstream/phpmailer/class.phpmailer.php +++ b/mailstream/phpmailer/class.phpmailer.php @@ -3287,7 +3287,7 @@ class PHPMailer $result = 'localhost.localdomain'; if (!empty($this->Hostname)) { $result = $this->Hostname; - } elseif (array_key_exists('SERVER_NAME', $_SERVER) and !empty($_SERVER['SERVER_NAME'])) { + } elseif (!empty($_SERVER['SERVER_NAME'])) { $result = $_SERVER['SERVER_NAME']; } elseif (function_exists('gethostname') && gethostname() !== false) { $result = gethostname(); From 3719d1eee5d67424e9bb144a47fe06ba5e87d2a0 Mon Sep 17 00:00:00 2001 From: Michael Date: Fri, 6 Dec 2024 06:46:36 +0000 Subject: [PATCH 115/222] Set extid via guid, nit via id --- bluesky/bluesky.php | 4 ++-- tumblr/tumblr.php | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/bluesky/bluesky.php b/bluesky/bluesky.php index dfd7fe06..26ecb967 100644 --- a/bluesky/bluesky.php +++ b/bluesky/bluesky.php @@ -715,7 +715,7 @@ function bluesky_create_activity(array $item, stdClass $parent = null) } Logger::debug('Activity done', ['return' => $activity]); $uri = bluesky_get_uri($activity); - Item::update(['extid' => $uri], ['id' => $item['id']]); + Item::update(['extid' => $uri], ['guid' => $item['guid']]); Logger::debug('Set extid', ['id' => $item['id'], 'extid' => $activity]); } @@ -806,7 +806,7 @@ function bluesky_create_post(array $item, stdClass $root = null, stdClass $paren } if (($key == 0) && ($item['gravity'] != Item::GRAVITY_PARENT)) { $uri = bluesky_get_uri($parent); - Item::update(['extid' => $uri], ['id' => $item['id']]); + Item::update(['extid' => $uri], ['guid' => $item['guid']]); Logger::debug('Set extid', ['id' => $item['id'], 'extid' => $uri]); } } diff --git a/tumblr/tumblr.php b/tumblr/tumblr.php index 1e9f5c7f..ecd6f862 100644 --- a/tumblr/tumblr.php +++ b/tumblr/tumblr.php @@ -564,7 +564,7 @@ function tumblr_send(array &$b) if ($result->meta->status < 400) { Logger::info('Successfully performed activity', ['verb' => $b['verb'], 'deleted' => $b['deleted'], 'meta' => $result->meta, 'response' => $result->response]); if (!$b['deleted'] && !empty($result->response->id_string)) { - Item::update(['extid' => 'tumblr::' . $result->response->id_string], ['id' => $b['id']]); + Item::update(['extid' => 'tumblr::' . $result->response->id_string], ['guid' => $b['guid']]); } } else { Logger::notice('Error while performing activity', ['verb' => $b['verb'], 'deleted' => $b['deleted'], 'meta' => $result->meta, 'response' => $result->response, 'errors' => $result->errors, 'params' => $params]); From f29908464b87916948ce3e6763c01195290b624f Mon Sep 17 00:00:00 2001 From: Michael Date: Thu, 12 Dec 2024 20:20:44 +0000 Subject: [PATCH 116/222] Bluesky: Fix token problems --- bluesky/bluesky.php | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/bluesky/bluesky.php b/bluesky/bluesky.php index 26ecb967..6451f3fa 100644 --- a/bluesky/bluesky.php +++ b/bluesky/bluesky.php @@ -416,7 +416,7 @@ function bluesky_get_status(string $handle = null, string $did = null, string $p switch ($status) { case BLUEKSY_STATUS_TOKEN_OK: - return DI::l10n()->t("You are authenticated to Bluesky. For security reasons the password isn't stored."); + return DI::l10n()->t("You are authenticated to Bluesky."); case BLUEKSY_STATUS_SUCCESS: return DI::l10n()->t('The communication with the personal data server service (PDS) is established.'); case BLUEKSY_STATUS_API_FAIL; @@ -447,6 +447,7 @@ function bluesky_settings_post(array &$b) DI::pConfig()->set(DI::userSession()->getLocalUserId(), 'bluesky', 'post', intval($_POST['bluesky'])); DI::pConfig()->set(DI::userSession()->getLocalUserId(), 'bluesky', 'post_by_default', intval($_POST['bluesky_bydefault'])); DI::pConfig()->set(DI::userSession()->getLocalUserId(), 'bluesky', 'handle', $handle); + DI::pConfig()->set(DI::userSession()->getLocalUserId(), 'bluesky', 'password', $_POST['bluesky_password']); DI::pConfig()->set(DI::userSession()->getLocalUserId(), 'bluesky', 'import', intval($_POST['bluesky_import'])); DI::pConfig()->set(DI::userSession()->getLocalUserId(), 'bluesky', 'import_feeds', intval($_POST['bluesky_import_feeds'])); DI::pConfig()->set(DI::userSession()->getLocalUserId(), 'bluesky', 'complete_threads', intval($_POST['bluesky_complete_threads'])); @@ -466,6 +467,7 @@ function bluesky_settings_post(array &$b) } else { DI::pConfig()->delete(DI::userSession()->getLocalUserId(), 'bluesky', 'did'); DI::pConfig()->delete(DI::userSession()->getLocalUserId(), 'bluesky', 'pds'); + DI::pConfig()->delete(DI::userSession()->getLocalUserId(), 'bluesky', 'password'); DI::pConfig()->delete(DI::userSession()->getLocalUserId(), 'bluesky', 'access_token'); DI::pConfig()->delete(DI::userSession()->getLocalUserId(), 'bluesky', 'refresh_token'); DI::pConfig()->delete(DI::userSession()->getLocalUserId(), 'bluesky', 'token_created'); @@ -2108,6 +2110,11 @@ function bluesky_refresh_token(int $uid): string $data = bluesky_post($uid, '/xrpc/com.atproto.server.refreshSession', '', ['Authorization' => ['Bearer ' . $token]]); if (empty($data) || empty($data->accessJwt)) { + Logger::debug('Refresh failed', ['return' => $data]); + $password = DI::pConfig()->get($uid, 'bluesky', 'password'); + if (!empty($password)) { + return bluesky_create_token($uid, $password); + } DI::pConfig()->set($uid, 'bluesky', 'status', BLUEKSY_STATUS_TOKEN_FAIL); return ''; } @@ -2174,7 +2181,11 @@ function bluesky_post(int $uid, string $url, string $params, array $headers): ?s $data->code = $curlResult->getReturnCode(); } - DI::pConfig()->set($uid, 'bluesky', 'status', BLUEKSY_STATUS_SUCCESS); + if (!empty($data->code) && ($data->code >= 200) && ($data->code < 400)) { + DI::pConfig()->set($uid, 'bluesky', 'status', BLUEKSY_STATUS_SUCCESS); + } else { + DI::pConfig()->set($uid, 'bluesky', 'status', BLUEKSY_STATUS_API_FAIL); + } return $data; } @@ -2197,7 +2208,9 @@ function bluesky_xrpc_get(int $uid, string $url, array $parameters = []): ?stdCl } $data = bluesky_get($pds . '/xrpc/' . $url, HttpClientAccept::JSON, [HttpClientOptions::HEADERS => $headers]); - DI::pConfig()->set($uid, 'bluesky', 'status', is_null($data) ? BLUEKSY_STATUS_API_FAIL : BLUEKSY_STATUS_SUCCESS); + if ($uid != 0) { + DI::pConfig()->set($uid, 'bluesky', 'status', is_null($data) ? BLUEKSY_STATUS_API_FAIL : BLUEKSY_STATUS_SUCCESS); + } return $data; } From 52b18c7d9a7df1dcd6adb1f1d4d25fa0653c76cc Mon Sep 17 00:00:00 2001 From: Michael Date: Sat, 14 Dec 2024 19:03:15 +0000 Subject: [PATCH 117/222] Bluesky: Functionality moved to the core --- bluesky/bluesky.php | 1267 ++++--------------------------------------- 1 file changed, 91 insertions(+), 1176 deletions(-) diff --git a/bluesky/bluesky.php b/bluesky/bluesky.php index 6451f3fa..c9c7dc67 100644 --- a/bluesky/bluesky.php +++ b/bluesky/bluesky.php @@ -26,7 +26,6 @@ */ use Friendica\Content\Text\BBCode; -use Friendica\Content\Text\HTML; use Friendica\Content\Text\Plaintext; use Friendica\Core\Cache\Enum\Duration; use Friendica\Core\Config\Util\ConfigFileManager; @@ -39,42 +38,20 @@ use Friendica\Database\DBA; use Friendica\DI; use Friendica\Model\Contact; use Friendica\Model\Conversation; -use Friendica\Model\GServer; use Friendica\Model\Item; -use Friendica\Model\ItemURI; use Friendica\Model\Photo; use Friendica\Model\Post; -use Friendica\Model\Tag; use Friendica\Model\User; -use Friendica\Network\HTTPClient\Client\HttpClientAccept; -use Friendica\Network\HTTPClient\Client\HttpClientOptions; -use Friendica\Network\HTTPClient\Client\HttpClientRequest; use Friendica\Object\Image; use Friendica\Protocol\Activity; +use Friendica\Protocol\ATProtocol; use Friendica\Protocol\Relay; use Friendica\Util\DateTimeFormat; -use Friendica\Util\Network; use Friendica\Util\Strings; const BLUESKY_DEFAULT_POLL_INTERVAL = 10; // given in minutes const BLUESKY_IMAGE_SIZE = [1000000, 500000, 100000, 50000]; -const BLUEKSY_STATUS_UNKNOWN = 0; -const BLUEKSY_STATUS_TOKEN_OK = 1; -const BLUEKSY_STATUS_SUCCESS = 2; -const BLUEKSY_STATUS_API_FAIL = 10; -const BLUEKSY_STATUS_DID_FAIL = 11; -const BLUEKSY_STATUS_PDS_FAIL = 12; -const BLUEKSY_STATUS_TOKEN_FAIL = 13; - -/* - * (Currently) hard wired paths for Bluesky services - */ -const BLUESKY_APPVIEW_API = 'https://public.api.bsky.app'; // Path to the public Bluesky AppView API. -const BLUESKY_DIRECTORY = 'https://plc.directory'; // Path to the directory server service to fetch the PDS of a given DID -const BLUESKY_WEB = 'https://bsky.app'; // Path to the web interface with the user profile and posts -const BLUESKY_HOSTNAME = 'bsky.social'; // Host name to be added to the handle if incomplete - function bluesky_install() { Hook::register('load_config', __FILE__, 'bluesky_load_config'); @@ -86,13 +63,11 @@ function bluesky_install() Hook::register('connector_settings_post', __FILE__, 'bluesky_settings_post'); Hook::register('cron', __FILE__, 'bluesky_cron'); Hook::register('support_follow', __FILE__, 'bluesky_support_follow'); - Hook::register('support_probe', __FILE__, 'bluesky_support_probe'); Hook::register('follow', __FILE__, 'bluesky_follow'); Hook::register('unfollow', __FILE__, 'bluesky_unfollow'); Hook::register('block', __FILE__, 'bluesky_block'); Hook::register('unblock', __FILE__, 'bluesky_unblock'); Hook::register('check_item_notification', __FILE__, 'bluesky_check_item_notification'); - Hook::register('probe_detect', __FILE__, 'bluesky_probe_detect'); Hook::register('item_by_link', __FILE__, 'bluesky_item_by_link'); } @@ -107,7 +82,7 @@ function bluesky_check_item_notification(array &$notification_data) return; } - $did = bluesky_get_user_did($notification_data['uid']); + $did = DI::atProtocol()->getUserDid($notification_data['uid']); if (empty($did)) { return; } @@ -115,61 +90,6 @@ function bluesky_check_item_notification(array &$notification_data) $notification_data['profiles'][] = $did; } -function bluesky_probe_detect(array &$hookData) -{ - // Don't overwrite an existing result - if (isset($hookData['result'])) { - return; - } - - // Avoid a lookup for the wrong network - if (!in_array($hookData['network'], ['', Protocol::BLUESKY])) { - return; - } - - $pconfig = DBA::selectFirst('pconfig', ['uid'], ["`cat` = ? AND `k` = ? AND `v` != ?", 'bluesky', 'access_token', '']); - if (empty($pconfig['uid'])) { - return; - } - - if (parse_url($hookData['uri'], PHP_URL_SCHEME) == 'did') { - $did = $hookData['uri']; - } elseif (parse_url($hookData['uri'], PHP_URL_PATH) == $hookData['uri'] && strpos($hookData['uri'], '@') === false) { - $did = bluesky_get_did($hookData['uri'], $pconfig['uid']); - if (empty($did)) { - return; - } - } elseif (Network::isValidHttpUrl($hookData['uri'])) { - $did = bluesky_get_did_by_profile($hookData['uri'], $pconfig['uid']); - if (empty($did)) { - return; - } - } else { - return; - } - - $token = bluesky_get_token($pconfig['uid']); - if (empty($token)) { - return; - } - - $data = bluesky_xrpc_get($pconfig['uid'], 'app.bsky.actor.getProfile', ['actor' => $did]); - if (empty($data) || empty($data->did)) { - return; - } - - $hookData['result'] = bluesky_get_contact_fields($data, 0, $pconfig['uid'], true); - - // Preparing probe data. This differs slightly from the contact array - $hookData['result']['photo'] = $data->avatar ?? ''; - $hookData['result']['batch'] = ''; - $hookData['result']['notify'] = ''; - $hookData['result']['poll'] = ''; - $hookData['result']['poco'] = ''; - $hookData['result']['priority'] = 0; - $hookData['result']['guid'] = ''; -} - function bluesky_item_by_link(array &$hookData) { // Don't overwrite an existing result @@ -177,16 +97,17 @@ function bluesky_item_by_link(array &$hookData) return; } - $token = bluesky_get_token($hookData['uid']); + $token = DI::atProtocol()->getUserToken($hookData['uid']); if (empty($token)) { return; } - if (!preg_match('#^' . BLUESKY_WEB . '/profile/(.+)/post/(.+)#', $hookData['uri'], $matches)) { + // @todo also support the URI format (at://did/app.bsky.feed.post/cid) + if (!preg_match('#^' . ATProtocol::WEB . '/profile/(.+)/post/(.+)#', $hookData['uri'], $matches)) { return; } - $did = bluesky_get_did($matches[1], $hookData['uid']); + $did = DI::atProtocol()->getDid($matches[1]); if (empty($did)) { return; } @@ -195,7 +116,7 @@ function bluesky_item_by_link(array &$hookData) $uri = 'at://' . $did . '/app.bsky.feed.post/' . $matches[2]; - $uri = bluesky_fetch_missing_post($uri, $hookData['uid'], $hookData['uid'], Item::PR_FETCHED, 0, 0, 0); + $uri = DI::atpProcessor()->fetchMissingPost($uri, $hookData['uid'], Item::PR_FETCHED, 0, 0); Logger::debug('Got post', ['did' => $did, 'cid' => $matches[2], 'result' => $uri]); if (!empty($uri)) { $item = Post::selectFirst(['id'], ['uri' => $uri, 'uid' => $hookData['uid']]); @@ -212,16 +133,9 @@ function bluesky_support_follow(array &$data) } } -function bluesky_support_probe(array &$data) -{ - if ($data['protocol'] == Protocol::BLUESKY) { - $data['result'] = true; - } -} - function bluesky_follow(array &$hook_data) { - $token = bluesky_get_token($hook_data['uid']); + $token = DI::atProtocol()->getUserToken($hook_data['uid']); if (empty($token)) { return; } @@ -240,11 +154,11 @@ function bluesky_follow(array &$hook_data) $post = [ 'collection' => 'app.bsky.graph.follow', - 'repo' => bluesky_get_user_did($hook_data['uid']), + 'repo' => DI::atProtocol()->getUserDid($hook_data['uid']), 'record' => $record ]; - $activity = bluesky_xrpc_post($hook_data['uid'], 'com.atproto.repo.createRecord', $post); + $activity = DI::atProtocol()->XRPCPost($hook_data['uid'], 'com.atproto.repo.createRecord', $post); if (!empty($activity->uri)) { $hook_data['contact'] = $contact; Logger::debug('Successfully start following', ['url' => $contact['url'], 'uri' => $activity->uri]); @@ -253,7 +167,7 @@ function bluesky_follow(array &$hook_data) function bluesky_unfollow(array &$hook_data) { - $token = bluesky_get_token($hook_data['uid']); + $token = DI::atProtocol()->getUserToken($hook_data['uid']); if (empty($token)) { return; } @@ -262,7 +176,7 @@ function bluesky_unfollow(array &$hook_data) return; } - $data = bluesky_xrpc_get($hook_data['uid'], 'app.bsky.actor.getProfile', ['actor' => $hook_data['contact']['url']]); + $data = DI::atProtocol()->XRPCGet('app.bsky.actor.getProfile', ['actor' => $hook_data['contact']['url']], $hook_data['uid']); if (empty($data->viewer) || empty($data->viewer->following)) { return; } @@ -274,7 +188,7 @@ function bluesky_unfollow(array &$hook_data) function bluesky_block(array &$hook_data) { - $token = bluesky_get_token($hook_data['uid']); + $token = DI::atProtocol()->getUserToken($hook_data['uid']); if (empty($token)) { return; } @@ -291,11 +205,11 @@ function bluesky_block(array &$hook_data) $post = [ 'collection' => 'app.bsky.graph.block', - 'repo' => bluesky_get_user_did($hook_data['uid']), + 'repo' => DI::atProtocol()->getUserDid($hook_data['uid']), 'record' => $record ]; - $activity = bluesky_xrpc_post($hook_data['uid'], 'com.atproto.repo.createRecord', $post); + $activity = DI::atProtocol()->XRPCPost($hook_data['uid'], 'com.atproto.repo.createRecord', $post); if (!empty($activity->uri)) { $ucid = Contact::getUserContactId($hook_data['contact']['id'], $hook_data['uid']); if ($ucid) { @@ -307,7 +221,7 @@ function bluesky_block(array &$hook_data) function bluesky_unblock(array &$hook_data) { - $token = bluesky_get_token($hook_data['uid']); + $token = DI::atProtocol()->getUserToken($hook_data['uid']); if (empty($token)) { return; } @@ -316,7 +230,7 @@ function bluesky_unblock(array &$hook_data) return; } - $data = bluesky_xrpc_get($hook_data['uid'], 'app.bsky.actor.getProfile', ['actor' => $hook_data['contact']['url']]); + $data = DI::atProtocol()->XRPCGet('app.bsky.actor.getProfile', ['actor' => $hook_data['contact']['url']], $hook_data['uid']); if (empty($data->viewer) || empty($data->viewer->blocking)) { return; } @@ -351,7 +265,7 @@ function bluesky_settings(array &$data) $def_enabled = DI::pConfig()->get(DI::userSession()->getLocalUserId(), 'bluesky', 'post_by_default') ?? false; $pds = DI::pConfig()->get(DI::userSession()->getLocalUserId(), 'bluesky', 'pds'); $handle = DI::pConfig()->get(DI::userSession()->getLocalUserId(), 'bluesky', 'handle'); - $did = bluesky_get_user_did(DI::userSession()->getLocalUserId()); + $did = DI::atProtocol()->getUserDid(DI::userSession()->getLocalUserId()); $token = DI::pConfig()->get(DI::userSession()->getLocalUserId(), 'bluesky', 'access_token'); $import = DI::pConfig()->get(DI::userSession()->getLocalUserId(), 'bluesky', 'import') ?? false; $import_feeds = DI::pConfig()->get(DI::userSession()->getLocalUserId(), 'bluesky', 'import_feeds') ?? false; @@ -399,33 +313,33 @@ function bluesky_get_status(string $handle = null, string $did = null, string $p return DI::l10n()->t('You are not authenticated. Please enter your handle and the app password.'); } - $status = DI::pConfig()->get(DI::userSession()->getLocalUserId(), 'bluesky', 'status') ?? BLUEKSY_STATUS_UNKNOWN; + $status = DI::pConfig()->get(DI::userSession()->getLocalUserId(), 'bluesky', 'status') ?? ATProtocol::STATUS_UNKNOWN; // Fallback mechanism for connection that had been established before the introduction of the status - if ($status == BLUEKSY_STATUS_UNKNOWN) { + if ($status == ATProtocol::STATUS_UNKNOWN) { if (empty($did)) { - $status = BLUEKSY_STATUS_DID_FAIL; + $status = ATProtocol::STATUS_DID_FAIL; } elseif (empty($pds)) { - $status = BLUEKSY_STATUS_PDS_FAIL; + $status = ATProtocol::STATUS_PDS_FAIL; } elseif (!empty($token)) { - $status = BLUEKSY_STATUS_TOKEN_OK; + $status = ATProtocol::STATUS_TOKEN_OK; } else { - $status = BLUEKSY_STATUS_TOKEN_FAIL; + $status = ATProtocol::STATUS_TOKEN_FAIL; } } switch ($status) { - case BLUEKSY_STATUS_TOKEN_OK: + case ATProtocol::STATUS_TOKEN_OK: return DI::l10n()->t("You are authenticated to Bluesky."); - case BLUEKSY_STATUS_SUCCESS: + case ATProtocol::STATUS_SUCCESS: return DI::l10n()->t('The communication with the personal data server service (PDS) is established.'); - case BLUEKSY_STATUS_API_FAIL; + case ATProtocol::STATUS_API_FAIL; return DI::l10n()->t('Communication issues with the personal data server service (PDS).'); - case BLUEKSY_STATUS_DID_FAIL: + case ATProtocol::STATUS_DID_FAIL: return DI::l10n()->t('The DID for the provided handle could not be detected. Please check if you entered the correct handle.'); - case BLUEKSY_STATUS_PDS_FAIL: + case ATProtocol::STATUS_PDS_FAIL: return DI::l10n()->t('The personal data server service (PDS) could not be detected.'); - case BLUEKSY_STATUS_TOKEN_FAIL: + case ATProtocol::STATUS_TOKEN_FAIL: return DI::l10n()->t('The authentication with the provided handle and password failed. Please check if you entered the correct password.'); default: return ''; @@ -454,11 +368,11 @@ function bluesky_settings_post(array &$b) DI::pConfig()->set(DI::userSession()->getLocalUserId(), 'bluesky', 'friendica_handle', intval($_POST['bluesky_friendica_handle'] ?? false)); if (!empty($handle)) { - $did = bluesky_get_user_did(DI::userSession()->getLocalUserId(), empty($old_did) || $old_handle != $handle); + $did = DI::atProtocol()->getUserDid(DI::userSession()->getLocalUserId(), empty($old_did) || $old_handle != $handle); if (!empty($did) && (empty($old_pds) || $old_handle != $handle)) { - $pds = bluesky_get_pds($did); + $pds = DI::atProtocol()->getPdsOfDid($did); if (empty($pds)) { - DI::pConfig()->set(DI::userSession()->getLocalUserId(), 'bluesky', 'status', BLUEKSY_STATUS_PDS_FAIL); + DI::pConfig()->set(DI::userSession()->getLocalUserId(), 'bluesky', 'status', ATProtocol::STATUS_PDS_FAIL); } DI::pConfig()->set(DI::userSession()->getLocalUserId(), 'bluesky', 'pds', $pds); } else { @@ -475,7 +389,7 @@ function bluesky_settings_post(array &$b) } if (!empty($did) && !empty($pds) && !empty($_POST['bluesky_password'])) { - bluesky_create_token(DI::userSession()->getLocalUserId(), $_POST['bluesky_password']); + DI::atProtocol()->createUserToken(DI::userSession()->getLocalUserId(), $_POST['bluesky_password']); } } @@ -524,7 +438,7 @@ function bluesky_cron() $pconfigs = DBA::selectToArray('pconfig', [], ["`cat` = ? AND `k` IN (?, ?) AND `v`", 'bluesky', 'import', 'import_feeds']); foreach ($pconfigs as $pconfig) { - if (empty(bluesky_get_user_did($pconfig['uid']))) { + if (empty(DI::atProtocol()->getUserDid($pconfig['uid']))) { Logger::debug('User has got no valid DID', ['uid' => $pconfig['uid']]); continue; } @@ -538,7 +452,13 @@ function bluesky_cron() // Refresh the token now, so that it doesn't need to be refreshed in parallel by the following workers Logger::debug('Refresh the token', ['uid' => $pconfig['uid']]); - bluesky_get_token($pconfig['uid']); + DI::atProtocol()->getUserToken($pconfig['uid']); + + $last_sync = DI::pConfig()->get($pconfig['uid'], 'bluesky', 'last_contact_sync'); + if ($last_sync < (time() - 86400)) { + DI::atpActor()->syncContacts($pconfig['uid']); + DI::pConfig()->set($pconfig['uid'], 'bluesky', 'last_contact_sync', time()); + } Worker::add(['priority' => Worker::PRIORITY_MEDIUM, 'force_priority' => true], 'addon/bluesky/bluesky_notifications.php', $pconfig['uid']); if (DI::pConfig()->get($pconfig['uid'], 'bluesky', 'import')) { @@ -640,7 +560,7 @@ function bluesky_send(array &$b) Logger::debug('Got comment', ['item' => $b]); if ($b['deleted']) { - $uri = bluesky_get_uri_class($b['uri']); + $uri = DI::atpProcessor()->getUriClass($b['uri']); if (empty($uri)) { Logger::debug('Not a bluesky post', ['uri' => $b['uri']]); return; @@ -649,8 +569,8 @@ function bluesky_send(array &$b) return; } - $root = bluesky_get_uri_class($b['parent-uri']); - $parent = bluesky_get_uri_class($b['thr-parent']); + $root = DI::atpProcessor()->getUriClass($b['parent-uri']); + $parent = DI::atpProcessor()->getUriClass($b['thr-parent']); if (empty($root) || empty($parent)) { Logger::debug('No bluesky post', ['parent' => $b['parent'], 'thr-parent' => $b['thr-parent']]); @@ -675,12 +595,12 @@ function bluesky_send(array &$b) function bluesky_create_activity(array $item, stdClass $parent = null) { $uid = $item['uid']; - $token = bluesky_get_token($uid); + $token = DI::atProtocol()->getUserToken($uid); if (empty($token)) { return; } - $did = bluesky_get_user_did($uid); + $did = DI::atProtocol()->getUserDid($uid); if (empty($did)) { return; } @@ -711,12 +631,12 @@ function bluesky_create_activity(array $item, stdClass $parent = null) ]; } - $activity = bluesky_xrpc_post($uid, 'com.atproto.repo.createRecord', $post); + $activity = DI::atProtocol()->XRPCPost($uid, 'com.atproto.repo.createRecord', $post); if (empty($activity->uri)) { return; } Logger::debug('Activity done', ['return' => $activity]); - $uri = bluesky_get_uri($activity); + $uri = DI::atpProcessor()->getUri($activity); Item::update(['extid' => $uri], ['guid' => $item['guid']]); Logger::debug('Set extid', ['id' => $item['id'], 'extid' => $activity]); } @@ -724,7 +644,7 @@ function bluesky_create_activity(array $item, stdClass $parent = null) function bluesky_create_post(array $item, stdClass $root = null, stdClass $parent = null) { $uid = $item['uid']; - $token = bluesky_get_token($uid); + $token = DI::atProtocol()->getUserToken($uid); if (empty($token)) { return; } @@ -791,11 +711,11 @@ function bluesky_create_post(array $item, stdClass $root = null, stdClass $paren $post = [ 'collection' => 'app.bsky.feed.post', - 'repo' => bluesky_get_user_did($uid), + 'repo' => DI::atProtocol()->getUserDid($uid), 'record' => $record ]; - $parent = bluesky_xrpc_post($uid, 'com.atproto.repo.createRecord', $post); + $parent = DI::atProtocol()->XRPCPost($uid, 'com.atproto.repo.createRecord', $post); if (empty($parent->uri)) { if ($part == 0) { Worker::defer(); @@ -807,7 +727,7 @@ function bluesky_create_post(array $item, stdClass $root = null, stdClass $paren $root = $parent; } if (($key == 0) && ($item['gravity'] != Item::GRAVITY_PARENT)) { - $uri = bluesky_get_uri($parent); + $uri = DI::atpProcessor()->getUri($parent); Item::update(['extid' => $uri], ['guid' => $item['guid']]); Logger::debug('Set extid', ['id' => $item['id'], 'extid' => $uri]); } @@ -973,7 +893,7 @@ function bluesky_upload_blob(int $uid, array $photo): ?stdClass Logger::info('Uploading', ['uid' => $uid, 'retrial' => $retrial, 'height' => $new_height, 'width' => $new_width, 'size' => $new_size, 'orig-height' => $height, 'orig-width' => $width, 'orig-size' => $size]); - $data = bluesky_post($uid, '/xrpc/com.atproto.repo.uploadBlob', $content, ['Content-type' => $photo['type'], 'Authorization' => ['Bearer ' . bluesky_get_token($uid)]]); + $data = DI::atProtocol()->post($uid, '/xrpc/com.atproto.repo.uploadBlob', $content, ['Content-type' => $photo['type'], 'Authorization' => ['Bearer ' . DI::atProtocol()->getUserToken($uid)]]); if (empty($data) || empty($data->blob)) { Logger::info('Uploading failed', ['uid' => $uid, 'retrial' => $retrial, 'height' => $new_height, 'width' => $new_width, 'size' => $new_size, 'orig-height' => $height, 'orig-width' => $width, 'orig-size' => $size]); return null; @@ -986,18 +906,18 @@ function bluesky_upload_blob(int $uid, array $photo): ?stdClass function bluesky_delete_post(string $uri, int $uid) { - $parts = bluesky_get_uri_parts($uri); + $parts = DI::atpProcessor()->getUriParts($uri); if (empty($parts)) { Logger::debug('No uri delected', ['uri' => $uri]); return; } - bluesky_xrpc_post($uid, 'com.atproto.repo.deleteRecord', $parts); + DI::atProtocol()->XRPCPost($uid, 'com.atproto.repo.deleteRecord', $parts); Logger::debug('Deleted', ['parts' => $parts]); } function bluesky_fetch_timeline(int $uid) { - $data = bluesky_xrpc_get($uid, 'app.bsky.feed.getTimeline'); + $data = DI::atProtocol()->XRPCGet('app.bsky.feed.getTimeline', [], $uid); if (empty($data)) { return; } @@ -1006,42 +926,39 @@ function bluesky_fetch_timeline(int $uid) return; } - $last_post = DBA::selectFirst('post-thread-user', ['received'], ['network' => Protocol::BLUESKY, 'uid' => $uid], ['order' => ['received' => true]]); - $last_poll = !empty($last_post['received']) ? strtotime($last_post['received']) : 0; - foreach (array_reverse($data->feed) as $entry) { - $causer = bluesky_get_contact($entry->post->author, 0, $uid); + $causer = DI::atpActor()->getContactByDID($entry->post->author->did, $uid, 0, true); if (!empty($entry->reply)) { if (!empty($entry->reply->root)) { - bluesky_complete_post($entry->reply->root, $uid, Item::PR_COMMENT, $causer['id'], $last_poll, Conversation::PARCEL_CONNECTOR); + bluesky_complete_post($entry->reply->root, $uid, Item::PR_COMMENT, $causer['id'], Conversation::PARCEL_CONNECTOR); } if (!empty($entry->reply->parent)) { - bluesky_complete_post($entry->reply->parent, $uid, Item::PR_COMMENT, $causer['id'], $last_poll, Conversation::PARCEL_CONNECTOR); + bluesky_complete_post($entry->reply->parent, $uid, Item::PR_COMMENT, $causer['id'], Conversation::PARCEL_CONNECTOR); } } - bluesky_process_post($entry->post, $uid, $uid, Item::PR_NONE, 0, 0, $last_poll, Conversation::PARCEL_CONNECTOR); + DI::atpProcessor()->processPost($entry->post, $uid, Item::PR_NONE, 0, 0, Conversation::PARCEL_CONNECTOR); if (!empty($entry->reason)) { - bluesky_process_reason($entry->reason, bluesky_get_uri($entry->post), $uid); + bluesky_process_reason($entry->reason, DI::atpProcessor()->getUri($entry->post), $uid); } } } -function bluesky_complete_post(stdClass $post, int $uid, int $post_reason, int $causer, int $last_poll, int $protocol): int +function bluesky_complete_post(stdClass $post, int $uid, int $post_reason, int $causer, int $protocol): int { $complete = DI::pConfig()->get($uid, 'bluesky', 'complete_threads'); - $existing_uri = bluesky_fetch_post(bluesky_get_uri($post), $uid); + $existing_uri = DI::atpProcessor()->getPostUri(DI::atpProcessor()->getUri($post), $uid); if (!empty($existing_uri)) { $comments = Post::countPosts(['thr-parent' => $existing_uri, 'gravity' => Item::GRAVITY_COMMENT]); if (($post->replyCount <= $comments) || !$complete) { - return bluesky_fetch_uri_id($existing_uri, $uid); + return DI::atpProcessor()->fetchUriId($existing_uri, $uid); } } if ($complete) { - $uri = bluesky_fetch_missing_post(bluesky_get_uri($post), $uid, $uid, $post_reason, $causer, 0, $last_poll, '', true); - $uri_id = bluesky_fetch_uri_id($uri, $uid); + $uri = DI::atpProcessor()->fetchMissingPost(DI::atpProcessor()->getUri($post), $uid, $post_reason, $causer, 0, '', true); + $uri_id = DI::atpProcessor()->fetchUriId($uri, $uid); } else { - $uri_id = bluesky_process_post($post, $uid, $uid, $post_reason, $causer, 0, $last_poll, $protocol); + $uri_id = DI::atpProcessor()->processPost($post, $uid, $post_reason, $causer, 0, $protocol); } return $uri_id; } @@ -1053,7 +970,7 @@ function bluesky_process_reason(stdClass $reason, string $uri, int $uid) return; } - $contact = bluesky_get_contact($reason->by, $uid, $uid); + $contact = DI::atpActor()->getContactByDID($reason->by->did, $uid, 0); $item = [ 'network' => Protocol::BLUESKY, @@ -1089,16 +1006,13 @@ function bluesky_process_reason(stdClass $reason, string $uri, int $uid) function bluesky_fetch_notifications(int $uid) { - $data = bluesky_xrpc_get($uid, 'app.bsky.notification.listNotifications'); + $data = DI::atProtocol()->XRPCGet('app.bsky.notification.listNotifications', [], $uid); if (empty($data->notifications)) { return; } - $last_post = DBA::selectFirst('post-thread-user', ['received'], ['network' => Protocol::BLUESKY, 'uid' => $uid], ['order' => ['received' => true]]); - $last_poll = !empty($last_post['received']) ? strtotime($last_post['received']) : 0; - foreach ($data->notifications as $notification) { - $uri = bluesky_get_uri($notification); + $uri = DI::atpProcessor()->getUri($notification); if (Post::exists(['uri' => $uri, 'uid' => $uid]) || Post::exists(['extid' => $uri, 'uid' => $uid])) { Logger::debug('Notification already processed', ['uid' => $uid, 'reason' => $notification->reason, 'uri' => $uri, 'indexedAt' => $notification->indexedAt]); continue; @@ -1106,11 +1020,11 @@ function bluesky_fetch_notifications(int $uid) Logger::debug('Process notification', ['uid' => $uid, 'reason' => $notification->reason, 'uri' => $uri, 'indexedAt' => $notification->indexedAt]); switch ($notification->reason) { case 'like': - $item = bluesky_get_header($notification, $uri, $uid, $uid, $last_poll, Conversation::PARCEL_CONNECTOR); + $item = DI::atpProcessor()->getHeaderFromPost($notification, $uri, $uid, Conversation::PARCEL_CONNECTOR); $item['gravity'] = Item::GRAVITY_ACTIVITY; $item['body'] = $item['verb'] = Activity::LIKE; - $item['thr-parent'] = bluesky_get_uri($notification->record->subject); - $item['thr-parent'] = bluesky_fetch_missing_post($item['thr-parent'], $uid, $uid, Item::PR_FETCHED, $item['contact-id'], 0, $last_poll); + $item['thr-parent'] = DI::atpProcessor()->getUri($notification->record->subject); + $item['thr-parent'] = DI::atpProcessor()->fetchMissingPost($item['thr-parent'], $uid, Item::PR_FETCHED, $item['contact-id'], 0); if (!empty($item['thr-parent'])) { $data = Item::insert($item); Logger::debug('Got like', ['uid' => $uid, 'result' => $data, 'uri' => $uri]); @@ -1120,11 +1034,11 @@ function bluesky_fetch_notifications(int $uid) break; case 'repost': - $item = bluesky_get_header($notification, $uri, $uid, $uid, $last_poll, Conversation::PARCEL_CONNECTOR); + $item = DI::atpProcessor()->getHeaderFromPost($notification, $uri, $uid, Conversation::PARCEL_CONNECTOR); $item['gravity'] = Item::GRAVITY_ACTIVITY; $item['body'] = $item['verb'] = Activity::ANNOUNCE; - $item['thr-parent'] = bluesky_get_uri($notification->record->subject); - $item['thr-parent'] = bluesky_fetch_missing_post($item['thr-parent'], $uid, $uid, Item::PR_FETCHED, $item['contact-id'], 0, $last_poll); + $item['thr-parent'] = DI::atpProcessor()->getUri($notification->record->subject); + $item['thr-parent'] = DI::atpProcessor()->fetchMissingPost($item['thr-parent'], $uid, Item::PR_FETCHED, $item['contact-id'], 0); if (!empty($item['thr-parent'])) { $data = Item::insert($item); Logger::debug('Got repost', ['uid' => $uid, 'result' => $data, 'uri' => $uri]); @@ -1134,25 +1048,25 @@ function bluesky_fetch_notifications(int $uid) break; case 'follow': - $contact = bluesky_get_contact($notification->author, $uid, $uid); + $contact = DI::atpActor()->getContactByDID($notification->author->did, $uid, $uid); Logger::debug('New follower', ['uid' => $uid, 'nick' => $contact['nick'], 'uri' => $uri]); break; case 'mention': - $contact = bluesky_get_contact($notification->author, 0, $uid); - $result = bluesky_fetch_missing_post($uri, $uid, $uid, Item::PR_TO, $contact['id'], 0, $last_poll); + $contact = DI::atpActor()->getContactByDID($notification->author->did, $uid, 0); + $result = DI::atpProcessor()->fetchMissingPost($uri, $uid, Item::PR_TO, $contact['id'], 0); Logger::debug('Got mention', ['uid' => $uid, 'nick' => $contact['nick'], 'result' => $result, 'uri' => $uri]); break; case 'reply': - $contact = bluesky_get_contact($notification->author, 0, $uid); - $result = bluesky_fetch_missing_post($uri, $uid, $uid, Item::PR_COMMENT, $contact['id'], 0, $last_poll); + $contact = DI::atpActor()->getContactByDID($notification->author->did, $uid, 0); + $result = DI::atpProcessor()->fetchMissingPost($uri, $uid, Item::PR_COMMENT, $contact['id'], 0); Logger::debug('Got reply', ['uid' => $uid, 'nick' => $contact['nick'], 'result' => $result, 'uri' => $uri]); break; case 'quote': - $contact = bluesky_get_contact($notification->author, 0, $uid); - $result = bluesky_fetch_missing_post($uri, $uid, $uid, Item::PR_PUSHED, $contact['id'], 0, $last_poll); + $contact = DI::atpActor()->getContactByDID($notification->author->did, $uid, 0); + $result = DI::atpProcessor()->fetchMissingPost($uri, $uid, Item::PR_PUSHED, $contact['id'], 0); Logger::debug('Got quote', ['uid' => $uid, 'nick' => $contact['nick'], 'result' => $result, 'uri' => $uri]); break; @@ -1165,7 +1079,7 @@ function bluesky_fetch_notifications(int $uid) function bluesky_fetch_feed(int $uid, string $feed) { - $data = bluesky_xrpc_get($uid, 'app.bsky.feed.getFeed', ['feed' => $feed]); + $data = DI::atProtocol()->XRPCGet('app.bsky.feed.getFeed', ['feed' => $feed], $uid); if (empty($data)) { return; } @@ -1174,10 +1088,7 @@ function bluesky_fetch_feed(int $uid, string $feed) return; } - $last_post = DBA::selectFirst('post-thread-user', ['received'], ['network' => Protocol::BLUESKY, 'uid' => $uid], ['order' => ['received' => true]]); - $last_poll = !empty($last_post['received']) ? strtotime($last_post['received']) : 0; - - $feeddata = bluesky_xrpc_get($uid, 'app.bsky.feed.getFeedGenerator', ['feed' => $feed]); + $feeddata = DI::atProtocol()->XRPCGet('app.bsky.feed.getFeedGenerator', ['feed' => $feed], $uid); if (!empty($feeddata) && !empty($feeddata->view)) { $feedurl = $feeddata->view->uri; $feedname = $feeddata->view->displayName; @@ -1187,15 +1098,15 @@ function bluesky_fetch_feed(int $uid, string $feed) } foreach (array_reverse($data->feed) as $entry) { - $contact = bluesky_get_contact($entry->post->author, 0, $uid); + $contact = DI::atpActor()->getContactByDID($entry->post->author->did, $uid, 0); $languages = $entry->post->record->langs ?? []; if (!Relay::isWantedLanguage($entry->post->record->text, 0, $contact['id'] ?? 0, $languages)) { Logger::debug('Unwanted language detected', ['languages' => $languages, 'text' => $entry->post->record->text]); continue; } - $causer = bluesky_get_contact($entry->post->author, 0, $uid); - $uri_id = bluesky_complete_post($entry->post, $uid, Item::PR_TAG, $causer['id'], $last_poll, Conversation::PARCEL_CONNECTOR); + $causer = DI::atpActor()->getContactByDID($entry->post->author->did, $uid, 0); + $uri_id = bluesky_complete_post($entry->post, $uid, Item::PR_TAG, $causer['id'], Conversation::PARCEL_CONNECTOR); if (!empty($uri_id)) { $stored = Post\Category::storeFileByURIId($uri_id, $uid, Post\Category::SUBCRIPTION, $feedname, $feedurl); Logger::debug('Stored tag subscription for user', ['uri-id' => $uri_id, 'uid' => $uid, 'name' => $feedname, 'url' => $feedurl, 'stored' => $stored]); @@ -1203,641 +1114,11 @@ function bluesky_fetch_feed(int $uid, string $feed) Logger::notice('Post not found', ['entry' => $entry]); } if (!empty($entry->reason)) { - bluesky_process_reason($entry->reason, bluesky_get_uri($entry->post), $uid); + bluesky_process_reason($entry->reason, DI::atpProcessor()->getUri($entry->post), $uid); } } } -function bluesky_process_post(stdClass $post, int $uid, int $fetch_uid, int $post_reason, int $causer, int $level, int $last_poll, int $protocol): int -{ - $uri = bluesky_get_uri($post); - - if ($uri_id = bluesky_fetch_uri_id($uri, $uid)) { - return $uri_id; - } - - if (empty($post->record)) { - Logger::debug('Invalid post', ['uri' => $uri]); - return 0; - } - - Logger::debug('Importing post', ['uid' => $uid, 'indexedAt' => $post->indexedAt, 'uri' => $post->uri, 'cid' => $post->cid, 'root' => $post->record->reply->root ?? '']); - - $item = bluesky_get_header($post, $uri, $uid, $fetch_uid, $last_poll, $protocol); - $item = bluesky_get_content($item, $post->record, $uri, $uid, $fetch_uid, $level, $last_poll); - if (empty($item)) { - return 0; - } - - if (!empty($post->embed)) { - $item = bluesky_add_media($post->embed, $item, $uid, $level, $last_poll); - } - - $item['restrictions'] = bluesky_get_restrictions_for_user($post, $item, $post_reason); - - if (empty($item['post-reason'])) { - $item['post-reason'] = $post_reason; - } - - if ($causer != 0) { - $item['causer-id'] = $causer; - } - - Item::insert($item); - return bluesky_fetch_uri_id($uri, $uid); -} - -function bluesky_get_header(stdClass $post, string $uri, int $uid, int $fetch_uid, int $last_poll, int $protocol): array -{ - $parts = bluesky_get_uri_parts($uri); - if (empty($post->author) || empty($post->cid) || empty($parts->rkey)) { - return []; - } - $contact = bluesky_get_contact($post->author, $uid, $fetch_uid); - $item = [ - 'network' => Protocol::BLUESKY, - 'protocol' => $protocol, - 'uid' => $uid, - 'wall' => false, - 'uri' => $uri, - 'guid' => $post->cid, - 'received' => DateTimeFormat::utc($post->indexedAt, DateTimeFormat::MYSQL), - 'private' => Item::UNLISTED, - 'verb' => Activity::POST, - 'contact-id' => $contact['id'], - 'author-name' => $contact['name'], - 'author-link' => $contact['url'], - 'author-avatar' => $contact['avatar'], - 'plink' => $contact['alias'] . '/post/' . $parts->rkey, - 'source' => json_encode($post), - ]; - - if (($last_poll != 0) && strtotime($item['received']) < $last_poll) { - unset($item['received']); - } - - $account = Contact::selectFirstAccountUser(['pid'], ['id' => $contact['id']]); - - $item['author-id'] = $account['pid']; - $item['uri-id'] = ItemURI::getIdByURI($uri); - $item['owner-id'] = $item['author-id']; - $item['owner-name'] = $item['author-name']; - $item['owner-link'] = $item['author-link']; - $item['owner-avatar'] = $item['author-avatar']; - - if (in_array($contact['rel'], [Contact::SHARING, Contact::FRIEND])) { - $item['post-reason'] = Item::PR_FOLLOWER; - } - - if (!empty($post->labels)) { - foreach ($post->labels as $label) { - // Only flag posts as sensitive based on labels that had been provided by the author. - // When "ver" is set to "1" it was flagged by some automated process. - if (empty($label->ver)) { - $item['sensitive'] = true; - $item['content-warning'] = $label->val ?? ''; - Logger::debug('Sensitive content', ['uri-id' => $item['uri-id'], 'label' => $label]); - } - } - } - - return $item; -} - -function bluesky_get_restrictions_for_user(stdClass $post, array $item, int $post_reason): ?int -{ - if (!empty($post->viewer->replyDisabled)) { - return Item::CANT_REPLY; - } - - if (empty($post->threadgate)) { - return null; - } - - if (!isset($post->threadgate->record->allow)) { - return null; - } - - if ($item['uid'] == 0) { - return Item::CANT_REPLY; - } - - $restrict = true; - $type = '$type'; - foreach ($post->threadgate->record->allow as $allow) { - switch ($allow->$type) { - case 'app.bsky.feed.threadgate#followingRule': - // Only followers can reply. - if (Contact::isFollower($item['author-id'], $item['uid'])) { - $restrict = false; - } - break; - case 'app.bsky.feed.threadgate#mentionRule': - // Only mentioned accounts can reply. - if ($post_reason == Item::PR_TO) { - $restrict = false; - } - break; - case 'app.bsky.feed.threadgate#listRule'; - // Only accounts in the provided list can reply. We don't support this at the moment. - break; - } - } - - return $restrict ? Item::CANT_REPLY : null; -} - -function bluesky_get_content(array $item, stdClass $record, string $uri, int $uid, int $fetch_uid, int $level, int $last_poll): array -{ - if (empty($item)) { - return []; - } - - if (!empty($record->reply)) { - $item['parent-uri'] = bluesky_get_uri($record->reply->root); - if ($item['parent-uri'] != $uri) { - $item['parent-uri'] = bluesky_fetch_missing_post($item['parent-uri'], $uid, $fetch_uid, Item::PR_FETCHED, $item['contact-id'], $level, $last_poll); - if (empty($item['parent-uri'])) { - return []; - } - } - - $item['thr-parent'] = bluesky_get_uri($record->reply->parent); - if (!in_array($item['thr-parent'], [$uri, $item['parent-uri']])) { - $item['thr-parent'] = bluesky_fetch_missing_post($item['thr-parent'], $uid, $fetch_uid, Item::PR_FETCHED, $item['contact-id'], $level, $last_poll, $item['parent-uri']); - if (empty($item['thr-parent'])) { - return []; - } - } - } - - $item['body'] = bluesky_get_text($record, $item['uri-id']); - $item['created'] = DateTimeFormat::utc($record->createdAt, DateTimeFormat::MYSQL); - $item['transmitted-languages'] = $record->langs ?? []; - - return $item; -} - -function bluesky_get_text(stdClass $record, int $uri_id): string -{ - $text = $record->text ?? ''; - - if (empty($record->facets)) { - return $text; - } - - $facets = []; - foreach ($record->facets as $facet) { - $facets[$facet->index->byteStart] = $facet; - } - krsort($facets); - - foreach ($facets as $facet) { - $prefix = substr($text, 0, $facet->index->byteStart); - $linktext = substr($text, $facet->index->byteStart, $facet->index->byteEnd - $facet->index->byteStart); - $suffix = substr($text, $facet->index->byteEnd); - - $url = ''; - $type = '$type'; - foreach ($facet->features as $feature) { - - switch ($feature->$type) { - case 'app.bsky.richtext.facet#link': - $url = $feature->uri; - break; - - case 'app.bsky.richtext.facet#mention': - $contact = Contact::getByURL($feature->did, null, ['id']); - if (!empty($contact['id'])) { - $url = DI::baseUrl() . '/contact/' . $contact['id']; - if (substr($linktext, 0, 1) == '@') { - $prefix .= '@'; - $linktext = substr($linktext, 1); - } - } - break; - - case 'app.bsky.richtext.facet#tag'; - Tag::store($uri_id, Tag::HASHTAG, $feature->tag); - $url = DI::baseUrl() . '/search?tag=' . urlencode($feature->tag); - $linktext = '#' . $feature->tag; - break; - - default: - Logger::notice('Unhandled feature type', ['type' => $feature->$type, 'feature' => $feature, 'record' => $record]); - break; - } - } - if (!empty($url)) { - $text = $prefix . '[url=' . $url . ']' . $linktext . '[/url]' . $suffix; - } - } - return $text; -} - -function bluesky_add_media(stdClass $embed, array $item, int $fetch_uid, int $level, int $last_poll): array -{ - $type = '$type'; - switch ($embed->$type) { - case 'app.bsky.embed.images#view': - foreach ($embed->images as $image) { - $media = [ - 'uri-id' => $item['uri-id'], - 'type' => Post\Media::IMAGE, - 'url' => $image->fullsize, - 'preview' => $image->thumb, - 'description' => $image->alt, - ]; - Post\Media::insert($media); - } - break; - - case 'app.bsky.embed.video#view': - $media = [ - 'uri-id' => $item['uri-id'], - 'type' => Post\Media::HLS, - 'url' => $embed->playlist, - 'preview' => $embed->thumbnail, - 'description' => $embed->alt ?? '', - 'height' => $embed->aspectRatio->height ?? null, - 'width' => $embed->aspectRatio->width ?? null, - ]; - Post\Media::insert($media); - break; - - case 'app.bsky.embed.external#view': - $media = [ - 'uri-id' => $item['uri-id'], - 'type' => Post\Media::HTML, - 'url' => $embed->external->uri, - 'name' => $embed->external->title, - 'description' => $embed->external->description, - ]; - Post\Media::insert($media); - break; - - case 'app.bsky.embed.record#view': - $original_uri = $uri = bluesky_get_uri($embed->record); - $type = '$type'; - if (!empty($embed->record->record->$type)) { - $embed_type = $embed->record->record->$type; - if ($embed_type == 'app.bsky.graph.starterpack') { - bluesky_add_starterpack($item, $embed->record); - break; - } - } - $fetched_uri = bluesky_fetch_post($uri, $item['uid']); - if (!$fetched_uri) { - $uri = bluesky_fetch_missing_post($uri, 0, $fetch_uid, Item::PR_FETCHED, $item['contact-id'], $level, $last_poll); - } else { - $uri = $fetched_uri; - } - if ($uri) { - $shared = Post::selectFirst(['uri-id'], ['uri' => $uri, 'uid' => [$item['uid'], 0]]); - $uri_id = $shared['uri-id'] ?? 0; - } - if (!empty($uri_id)) { - $item['quote-uri-id'] = $uri_id; - } else { - Logger::debug('Quoted post could not be fetched', ['original-uri' => $original_uri, 'uri' => $uri]); - } - break; - - case 'app.bsky.embed.recordWithMedia#view': - bluesky_add_media($embed->media, $item, $fetch_uid, $level, $last_poll); - $original_uri = $uri = bluesky_get_uri($embed->record->record); - $uri = bluesky_fetch_missing_post($uri, $item['uid'], $fetch_uid, Item::PR_FETCHED, $item['contact-id'], $level, $last_poll); - if ($uri) { - $shared = Post::selectFirst(['uri-id'], ['uri' => $uri, 'uid' => [$item['uid'], 0]]); - $uri_id = $shared['uri-id'] ?? 0; - } - if (!empty($uri_id)) { - $item['quote-uri-id'] = $uri_id; - } else { - Logger::debug('Quoted post could not be fetched', ['original-uri' => $original_uri, 'uri' => $uri]); - } - break; - - default: - Logger::notice('Unhandled embed type', ['uri-id' => $item['uri-id'], 'type' => $embed->$type, 'embed' => $embed]); - break; - } - return $item; -} - -function bluesky_add_starterpack(array $item, stdClass $record) -{ - Logger::debug('Received starterpack', ['uri-id' => $item['uri-id'], 'guid' => $item['guid'], 'uri' => $record->uri]); - if (!preg_match('#^at://(.+)/app.bsky.graph.starterpack/(.+)#', $record->uri, $matches)) { - return; - } - - $media = [ - 'uri-id' => $item['uri-id'], - 'type' => Post\Media::HTML, - 'url' => 'https://bsky.app/starter-pack/' . $matches[1] . '/' . $matches[2], - 'name' => $record->record->name, - 'description' => $record->record->description, - ]; - - Post\Media::insert($media); - - $fields = [ - 'name' => $record->record->name, - 'description' => $record->record->description, - ]; - Post\Media::update($fields, ['uri-id' => $media['uri-id'], 'url' => $media['url']]); -} - -function bluesky_get_uri(stdClass $post): string -{ - if (empty($post->cid)) { - Logger::info('Invalid URI', ['post' => $post]); - return ''; - } - return $post->uri . ':' . $post->cid; -} - -function bluesky_get_uri_class(string $uri): ?stdClass -{ - if (empty($uri)) { - return null; - } - - $elements = explode(':', $uri); - if (empty($elements) || ($elements[0] != 'at')) { - $post = Post::selectFirstPost(['extid'], ['uri' => $uri]); - return bluesky_get_uri_class($post['extid'] ?? ''); - } - - $class = new stdClass; - - $class->cid = array_pop($elements); - $class->uri = implode(':', $elements); - - if ((substr_count($class->uri, '/') == 2) && (substr_count($class->cid, '/') == 2)) { - $class->uri .= ':' . $class->cid; - $class->cid = ''; - } - - return $class; -} - -function bluesky_get_uri_parts(string $uri): ?stdClass -{ - $class = bluesky_get_uri_class($uri); - if (empty($class)) { - return null; - } - - $parts = explode('/', substr($class->uri, 5)); - - $class = new stdClass; - - $class->repo = $parts[0]; - $class->collection = $parts[1]; - $class->rkey = $parts[2]; - - return $class; -} - -function bluesky_fetch_missing_post(string $uri, int $uid, int $fetch_uid, int $post_reason, int $causer, int $level, int $last_poll, string $fallback = '', bool $always_fetch = false, int $Protocol = Conversation::PARCEL_CONNECTOR): string -{ - $fetched_uri = bluesky_fetch_post($uri, $uid); - if (!$always_fetch && !empty($fetched_uri)) { - return $fetched_uri; - } - - if (++$level > 100) { - Logger::info('Recursion level too deep', ['level' => $level, 'uid' => $uid, 'uri' => $uri, 'fallback' => $fallback]); - // When the level is too deep we will fallback to the parent uri. - // Allthough the threading won't be correct, we at least had stored all posts and won't try again - return $fallback; - } - - $class = bluesky_get_uri_class($uri); - if (empty($class)) { - return $fallback; - } - - $fetch_uri = $class->uri; - - Logger::debug('Fetch missing post', ['level' => $level, 'uid' => $uid, 'uri' => $uri]); - $data = bluesky_xrpc_get($fetch_uid, 'app.bsky.feed.getPostThread', ['uri' => $fetch_uri]); - if (empty($data) || empty($data->thread)) { - Logger::info('Thread was not fetched', ['level' => $level, 'uid' => $uid, 'uri' => $uri, 'fallback' => $fallback]); - return $fallback; - } - - Logger::debug('Reply count', ['level' => $level, 'uid' => $uid, 'uri' => $uri]); - - if ($causer != 0) { - $causer = Contact::getPublicContactId($causer, $uid); - } - - if (!empty($data->thread->parent)) { - $parents = bluesky_fetch_parents($data->thread->parent, $uid); - - foreach ($parents as $parent) { - $uri_id = bluesky_process_post($parent, $uid, $fetch_uid, Item::PR_FETCHED, $causer, $level, $last_poll, $Protocol); - Logger::debug('Parent created', ['uri-id' => $uri_id]); - } - } - - return bluesky_process_thread($data->thread, $uid, $fetch_uid, $post_reason, $causer, $level, $last_poll, $Protocol); -} - -function bluesky_fetch_parents(stdClass $parent, int $uid, array $parents = []): array -{ - if (!empty($parent->parent)) { - $parents = bluesky_fetch_parents($parent->parent, $uid, $parents); - } - - if (!empty($parent->post) && empty(bluesky_fetch_post(bluesky_get_uri($parent->post), $uid))) { - $parents[] = $parent->post; - } - - return $parents; -} - -function bluesky_fetch_post(string $uri, int $uid): string -{ - if (Post::exists(['uri' => $uri, 'uid' => [$uid, 0]])) { - Logger::debug('Post exists', ['uri' => $uri]); - return $uri; - } - - $reply = Post::selectFirst(['uri'], ['extid' => $uri, 'uid' => [$uid, 0]]); - if (!empty($reply['uri'])) { - Logger::debug('Post with extid exists', ['uri' => $uri]); - return $reply['uri']; - } - return ''; -} - -function bluesky_fetch_uri_id(string $uri, int $uid): string -{ - $reply = Post::selectFirst(['uri-id'], ['uri' => $uri, 'uid' => [$uid, 0]]); - if (!empty($reply['uri-id'])) { - Logger::debug('Post with extid exists', ['uri' => $uri]); - return $reply['uri-id']; - } - $reply = Post::selectFirst(['uri-id'], ['extid' => $uri, 'uid' => [$uid, 0]]); - if (!empty($reply['uri-id'])) { - Logger::debug('Post with extid exists', ['uri' => $uri]); - return $reply['uri-id']; - } - return 0; -} - -function bluesky_process_thread(stdClass $thread, int $uid, int $fetch_uid, int $post_reason, int $causer, int $level, int $last_poll, int $protocol): string -{ - if (empty($thread->post)) { - Logger::info('Invalid post', ['post' => $thread]); - return ''; - } - $uri = bluesky_get_uri($thread->post); - - $fetched_uri = bluesky_fetch_post($uri, $uid); - if (empty($fetched_uri)) { - $uri_id = bluesky_process_post($thread->post, $uid, $fetch_uid, $post_reason, $causer, $level, $last_poll, $protocol); - if ($uri_id) { - Logger::debug('Post has been processed and stored', ['uri-id' => $uri_id, 'uri' => $uri]); - return $uri; - } else { - Logger::info('Post has not not been stored', ['uri' => $uri]); - return ''; - } - } else { - Logger::debug('Post exists', ['uri' => $uri]); - $uri = $fetched_uri; - } - - foreach ($thread->replies ?? [] as $reply) { - $reply_uri = bluesky_process_thread($reply, $uid, $fetch_uid, Item::PR_FETCHED, $causer, $level, $last_poll, $protocol); - Logger::debug('Reply has been processed', ['uri' => $uri, 'reply' => $reply_uri]); - } - - return $uri; -} - -function bluesky_get_contact(stdClass $author, int $uid, int $fetch_uid): array -{ - $condition = ['network' => Protocol::BLUESKY, 'uid' => 0, 'nurl' => $author->did]; - $contact = Contact::selectFirst(['id', 'updated'], $condition); - - $update = empty($contact) || $contact['updated'] < DateTimeFormat::utc('now -24 hours'); - - $public_fields = $fields = bluesky_get_contact_fields($author, $uid, $fetch_uid, $update); - - $public_fields['uid'] = 0; - $public_fields['rel'] = Contact::NOTHING; - - if (empty($contact)) { - $cid = Contact::insert($public_fields); - } else { - $cid = $contact['id']; - Logger::debug('Update contact', ['fields' => $public_fields, 'id' => $cid]); - Contact::update($public_fields, ['id' => $cid], true); - } - - if ($uid != 0) { - $condition = ['network' => Protocol::BLUESKY, 'uid' => $uid, 'nurl' => $author->did]; - - $contact = Contact::selectFirst(['id', 'rel', 'uid'], $condition); - if (!isset($fields['rel']) && isset($contact['rel'])) { - $fields['rel'] = $contact['rel']; - } elseif (!isset($fields['rel'])) { - $fields['rel'] = Contact::NOTHING; - } - } - - if (($uid != 0) && ($fields['rel'] != Contact::NOTHING)) { - if (empty($contact)) { - $cid = Contact::insert($fields); - } else { - $cid = $contact['id']; - Logger::debug('Update contact', ['fields' => $fields, 'id' => $cid]); - Contact::update($fields, ['id' => $cid], true); - } - Logger::debug('Get user contact', ['id' => $cid, 'uid' => $uid, 'update' => $update]); - } else { - Logger::debug('Get public contact', ['id' => $cid, 'uid' => $uid, 'update' => $update]); - } - if (!empty($author->avatar)) { - Contact::updateAvatar($cid, $author->avatar); - } - - return Contact::getById($cid); -} - -function bluesky_get_contact_fields(stdClass $author, int $uid, int $fetch_uid, bool $update): array -{ - $nick = $author->handle ?? $author->did; - $name = $author->displayName ?? $nick; - $fields = [ - 'uid' => $uid, - 'network' => Protocol::BLUESKY, - 'priority' => 1, - 'writable' => true, - 'blocked' => false, - 'readonly' => false, - 'pending' => false, - 'url' => $author->did, - 'nurl' => $author->did, - 'alias' => BLUESKY_WEB . '/profile/' . $nick, - 'name' => $name ?: $nick, - 'nick' => $nick, - 'addr' => $nick, - ]; - - if (!$update) { - Logger::debug('Got contact fields', ['uid' => $uid, 'url' => $fields['url'], 'fields' => $fields]); - return $fields; - } - - $data = bluesky_get(BLUESKY_DIRECTORY . '/' . $author->did); - if (!empty($data)) { - $fields['baseurl'] = bluesky_get_pds('', $data); - if (!empty($fields['baseurl'])) { - GServer::check($fields['baseurl'], Protocol::BLUESKY); - $fields['gsid'] = GServer::getID($fields['baseurl'], true); - } - $fields['pubkey'] = bluesky_get_public_key('', $data); - } - - $data = bluesky_xrpc_get($fetch_uid, 'app.bsky.actor.getProfile', ['actor' => $author->did]); - if (empty($data)) { - Logger::debug('Error fetching contact fields', ['uid' => $uid, 'url' => $fields['url']]); - return $fields; - } - - $fields['updated'] = DateTimeFormat::utcNow(DateTimeFormat::MYSQL); - - if (!empty($data->description)) { - $fields['about'] = HTML::toBBCode($data->description); - } - - if (!empty($data->banner)) { - $fields['header'] = $data->banner; - } - - if (!empty($data->viewer)) { - if (!empty($data->viewer->following) && !empty($data->viewer->followedBy)) { - $fields['rel'] = Contact::FRIEND; - } elseif (!empty($data->viewer->following) && empty($data->viewer->followedBy)) { - $fields['rel'] = Contact::SHARING; - } elseif (empty($data->viewer->following) && !empty($data->viewer->followedBy)) { - $fields['rel'] = Contact::FOLLOWER; - } else { - $fields['rel'] = Contact::NOTHING; - } - } - - Logger::debug('Got updated contact fields', ['uid' => $uid, 'url' => $fields['url']]); - return $fields; -} - function bluesky_get_feeds(int $uid): array { $type = '$type'; @@ -1861,7 +1142,7 @@ function bluesky_get_preferences(int $uid): ?stdClass return $data; } - $data = bluesky_xrpc_get($uid, 'app.bsky.actor.getPreferences'); + $data = DI::atProtocol()->XRPCGet('app.bsky.actor.getPreferences', [], $uid); if (empty($data)) { return null; } @@ -1869,369 +1150,3 @@ function bluesky_get_preferences(int $uid): ?stdClass DI::cache()->set($cachekey, $data, Duration::HOUR); return $data; } - -function bluesky_get_did_by_profile(string $url, int $uid): string -{ - if (preg_match('#^' . BLUESKY_WEB . '/profile/(.+)#', $url, $matches)) { - $did = bluesky_get_did($matches[1], $uid); - if (!empty($did)) { - return $did; - } - } - try { - $curlResult = DI::httpClient()->get($url, HttpClientAccept::HTML, [HttpClientOptions::REQUEST => HttpClientRequest::CONTACTINFO]); - } catch (\Throwable $th) { - return ''; - } - if (!$curlResult->isSuccess()) { - return ''; - } - $profile = $curlResult->getBodyString(); - if (empty($profile)) { - return ''; - } - - $doc = new DOMDocument(); - try { - @$doc->loadHTML($profile); - } catch (\Throwable $th) { - return ''; - } - $xpath = new DOMXPath($doc); - $list = $xpath->query('//p[@id]'); - foreach ($list as $node) { - foreach ($node->attributes as $attribute) { - if ($attribute->name == 'id') { - $ids[$attribute->value] = $node->textContent; - } - } - } - - if (empty($ids['bsky_handle']) || empty($ids['bsky_did'])) { - return ''; - } - - if (!bluesky_valid_did($ids['bsky_did'], $ids['bsky_handle'])) { - Logger::notice('Invalid DID', ['handle' => $ids['bsky_handle'], 'did' => $ids['bsky_did']]); - return ''; - } - - return $ids['bsky_did']; -} - -function bluesky_get_did_by_wellknown(string $handle): string -{ - $curlResult = DI::httpClient()->get('http://' . $handle . '/.well-known/atproto-did'); - if ($curlResult->isSuccess() && substr($curlResult->getBodyString(), 0, 4) == 'did:') { - $did = $curlResult->getBodyString(); - if (!bluesky_valid_did($did, $handle)) { - Logger::notice('Invalid DID', ['handle' => $handle, 'did' => $did]); - return ''; - } - return $did; - } - return ''; -} - -function bluesky_get_did_by_dns(string $handle): string -{ - $records = @dns_get_record('_atproto.' . $handle . '.', DNS_TXT); - if (empty($records)) { - return ''; - } - foreach ($records as $record) { - if (!empty($record['txt']) && substr($record['txt'], 0, 4) == 'did=') { - $did = substr($record['txt'], 4); - if (!bluesky_valid_did($did, $handle)) { - Logger::notice('Invalid DID', ['handle' => $handle, 'did' => $did]); - return ''; - } - return $did; - } - } - return ''; -} - -function bluesky_get_did(string $handle, int $uid): string -{ - if ($handle == '') { - return ''; - } - - if (strpos($handle, '.') === false) { - $handle .= '.' . BLUESKY_HOSTNAME; - } - - // At first we use the user PDS. That should cover most cases. - $pds = DI::pConfig()->get($uid, 'bluesky', 'pds'); - if (!empty($pds)) { - $data = bluesky_get($pds . '/xrpc/com.atproto.identity.resolveHandle?handle=' . urlencode($handle)); - if (!empty($data) && !empty($data->did)) { - Logger::debug('Got DID by user PDS call', ['handle' => $handle, 'did' => $data->did]); - return $data->did; - } - } - - // Then we query the DNS, which is used for third party handles (DNS should be faster than wellknown) - $did = bluesky_get_did_by_dns($handle); - if ($did != '') { - Logger::debug('Got DID by DNS', ['handle' => $handle, 'did' => $did]); - return $did; - } - - // Then we query wellknown, which should mostly cover the rest. - $did = bluesky_get_did_by_wellknown($handle); - if ($did != '') { - Logger::debug('Got DID by wellknown', ['handle' => $handle, 'did' => $did]); - return $did; - } - - // And finally we use the AppView API. - $data = bluesky_get(BLUESKY_APPVIEW_API . '/xrpc/com.atproto.identity.resolveHandle?handle=' . urlencode($handle)); - if (!empty($data) && !empty($data->did)) { - Logger::debug('Got DID by system PDS call', ['handle' => $handle, 'did' => $data->did]); - return $data->did; - } - - Logger::notice('No DID detected', ['handle' => $handle]); - return ''; -} - -function bluesky_get_user_did(int $uid, bool $refresh = false): ?string -{ - if (!$refresh) { - $did = DI::pConfig()->get($uid, 'bluesky', 'did'); - if (!empty($did)) { - return $did; - } - } - - $handle = DI::pConfig()->get($uid, 'bluesky', 'handle'); - if (empty($handle)) { - return null; - } - - $did = bluesky_get_did($handle, $uid); - if (empty($did)) { - return null; - } - - Logger::debug('Got DID for user', ['uid' => $uid, 'handle' => $handle, 'did' => $did]); - DI::pConfig()->set($uid, 'bluesky', 'did', $did); - return $did; -} - -function bluesky_get_user_pds(int $uid): ?string -{ - if ($uid == 0) { - return BLUESKY_APPVIEW_API; - } - - $pds = DI::pConfig()->get($uid, 'bluesky', 'pds'); - if (!empty($pds)) { - return $pds; - } - - $did = bluesky_get_user_did($uid); - if (empty($did)) { - return null; - } - - $pds = bluesky_get_pds($did); - if (empty($pds)) { - return null; - } - - DI::pConfig()->set($uid, 'bluesky', 'pds', $pds); - return $pds; -} - -function bluesky_get_pds(string $did, stdClass $data = null): ?string -{ - if (empty($data)) { - $data = bluesky_get(BLUESKY_DIRECTORY . '/' . $did); - } - if (empty($data) || empty($data->service)) { - return null; - } - - foreach ($data->service as $service) { - if (($service->id == '#atproto_pds') && ($service->type == 'AtprotoPersonalDataServer') && !empty($service->serviceEndpoint)) { - return $service->serviceEndpoint; - } - } - - return null; -} - -function bluesky_get_public_key(string $did, stdClass $data = null): ?string -{ - if (empty($data)) { - $data = bluesky_get(BLUESKY_DIRECTORY . '/' . $did); - } - if (empty($data) || empty($data->verificationMethod)) { - return null; - } - foreach ($data->verificationMethod as $method) { - if (!empty($method->publicKeyMultibase)) { - return $method->publicKeyMultibase; - } - } - return null; -} - -function bluesky_valid_did(string $did, string $handle): bool -{ - $data = bluesky_get(BLUESKY_DIRECTORY . '/' . $did); - if (empty($data) || empty($data->alsoKnownAs)) { - return false; - } - - return in_array('at://' . $handle, $data->alsoKnownAs); -} - -function bluesky_get_token(int $uid): string -{ - $token = DI::pConfig()->get($uid, 'bluesky', 'access_token'); - $created = DI::pConfig()->get($uid, 'bluesky', 'token_created'); - if (empty($token)) { - return ''; - } - - if ($created + 300 < time()) { - return bluesky_refresh_token($uid); - } - return $token; -} - -function bluesky_refresh_token(int $uid): string -{ - $token = DI::pConfig()->get($uid, 'bluesky', 'refresh_token'); - - $data = bluesky_post($uid, '/xrpc/com.atproto.server.refreshSession', '', ['Authorization' => ['Bearer ' . $token]]); - if (empty($data) || empty($data->accessJwt)) { - Logger::debug('Refresh failed', ['return' => $data]); - $password = DI::pConfig()->get($uid, 'bluesky', 'password'); - if (!empty($password)) { - return bluesky_create_token($uid, $password); - } - DI::pConfig()->set($uid, 'bluesky', 'status', BLUEKSY_STATUS_TOKEN_FAIL); - return ''; - } - - Logger::debug('Refreshed token', ['return' => $data]); - DI::pConfig()->set($uid, 'bluesky', 'access_token', $data->accessJwt); - DI::pConfig()->set($uid, 'bluesky', 'refresh_token', $data->refreshJwt); - DI::pConfig()->set($uid, 'bluesky', 'token_created', time()); - return $data->accessJwt; -} - -function bluesky_create_token(int $uid, string $password): string -{ - $did = bluesky_get_user_did($uid); - if (empty($did)) { - return ''; - } - - $data = bluesky_post($uid, '/xrpc/com.atproto.server.createSession', json_encode(['identifier' => $did, 'password' => $password]), ['Content-type' => 'application/json']); - if (empty($data) || empty($data->accessJwt)) { - DI::pConfig()->set($uid, 'bluesky', 'status', BLUEKSY_STATUS_TOKEN_FAIL); - return ''; - } - - Logger::debug('Created token', ['return' => $data]); - DI::pConfig()->set($uid, 'bluesky', 'access_token', $data->accessJwt); - DI::pConfig()->set($uid, 'bluesky', 'refresh_token', $data->refreshJwt); - DI::pConfig()->set($uid, 'bluesky', 'token_created', time()); - DI::pConfig()->set($uid, 'bluesky', 'status', BLUEKSY_STATUS_TOKEN_OK); - return $data->accessJwt; -} - -function bluesky_xrpc_post(int $uid, string $url, $parameters): ?stdClass -{ - $data = bluesky_post($uid, '/xrpc/' . $url, json_encode($parameters), ['Content-type' => 'application/json', 'Authorization' => ['Bearer ' . bluesky_get_token($uid)]]); - if (!empty($data)) { - Item::incrementOutbound(Protocol::BLUESKY); - } - return $data; -} - -function bluesky_post(int $uid, string $url, string $params, array $headers): ?stdClass -{ - $pds = bluesky_get_user_pds($uid); - if (empty($pds)) { - return null; - } - - try { - $curlResult = DI::httpClient()->post($pds . $url, $params, $headers); - } catch (\Exception $e) { - Logger::notice('Exception on post', ['exception' => $e]); - DI::pConfig()->set($uid, 'bluesky', 'status', BLUEKSY_STATUS_API_FAIL); - return null; - } - - $data = json_decode($curlResult->getBodyString()); - if (!$curlResult->isSuccess()) { - Logger::notice('API Error', ['url' => $url, 'code' => $curlResult->getReturnCode(), 'error' => $data ?: $curlResult->getBodyString()]); - if (!$data) { - DI::pConfig()->set($uid, 'bluesky', 'status', BLUEKSY_STATUS_API_FAIL); - return null; - } - $data->code = $curlResult->getReturnCode(); - } - - if (!empty($data->code) && ($data->code >= 200) && ($data->code < 400)) { - DI::pConfig()->set($uid, 'bluesky', 'status', BLUEKSY_STATUS_SUCCESS); - } else { - DI::pConfig()->set($uid, 'bluesky', 'status', BLUEKSY_STATUS_API_FAIL); - } - return $data; -} - -function bluesky_xrpc_get(int $uid, string $url, array $parameters = []): ?stdClass -{ - if (!empty($parameters)) { - $url .= '?' . http_build_query($parameters); - } - - $pds = bluesky_get_user_pds($uid); - if (empty($pds)) { - return null; - } - - $headers = ['Authorization' => ['Bearer ' . bluesky_get_token($uid)]]; - - $languages = User::getWantedLanguages($uid); - if (!empty($languages)) { - $headers['Accept-Language'] = implode(',', $languages); - } - - $data = bluesky_get($pds . '/xrpc/' . $url, HttpClientAccept::JSON, [HttpClientOptions::HEADERS => $headers]); - if ($uid != 0) { - DI::pConfig()->set($uid, 'bluesky', 'status', is_null($data) ? BLUEKSY_STATUS_API_FAIL : BLUEKSY_STATUS_SUCCESS); - } - return $data; -} - -function bluesky_get(string $url, string $accept_content = HttpClientAccept::DEFAULT, array $opts = []): ?stdClass -{ - try { - $curlResult = DI::httpClient()->get($url, $accept_content, $opts); - } catch (\Exception $e) { - Logger::notice('Exception on get', ['url' => $url, 'exception' => $e]); - return null; - } - - $data = json_decode($curlResult->getBodyString()); - if (!$curlResult->isSuccess()) { - Logger::notice('API Error', ['url' => $url, 'code' => $curlResult->getReturnCode(), 'error' => $data ?: $curlResult->getBodyString()]); - if (!$data) { - return null; - } - $data->code = $curlResult->getReturnCode(); - } - - Item::incrementInbound(Protocol::BLUESKY); - return $data; -} From 01ec6ecb8ea98555d744949305a60e12e2fdb76c Mon Sep 17 00:00:00 2001 From: Michael Date: Tue, 17 Dec 2024 04:50:54 +0000 Subject: [PATCH 118/222] Bluesky: Handle problems when uploading pictures --- bluesky/bluesky.php | 28 ++++++++++++++++++++-------- 1 file changed, 20 insertions(+), 8 deletions(-) diff --git a/bluesky/bluesky.php b/bluesky/bluesky.php index c9c7dc67..d6b7624b 100644 --- a/bluesky/bluesky.php +++ b/bluesky/bluesky.php @@ -313,7 +313,8 @@ function bluesky_get_status(string $handle = null, string $did = null, string $p return DI::l10n()->t('You are not authenticated. Please enter your handle and the app password.'); } - $status = DI::pConfig()->get(DI::userSession()->getLocalUserId(), 'bluesky', 'status') ?? ATProtocol::STATUS_UNKNOWN; + $status = DI::pConfig()->get(DI::userSession()->getLocalUserId(), 'bluesky', 'status') ?? ATProtocol::STATUS_UNKNOWN; + $message = DI::pConfig()->get(DI::userSession()->getLocalUserId(), 'bluesky', 'status-message') ?? ''; // Fallback mechanism for connection that had been established before the introduction of the status if ($status == ATProtocol::STATUS_UNKNOWN) { @@ -330,11 +331,11 @@ function bluesky_get_status(string $handle = null, string $did = null, string $p switch ($status) { case ATProtocol::STATUS_TOKEN_OK: - return DI::l10n()->t("You are authenticated to Bluesky."); + return DI::l10n()->t("You are authenticated to Bluesky. For security reasons the password isn't stored."); case ATProtocol::STATUS_SUCCESS: return DI::l10n()->t('The communication with the personal data server service (PDS) is established.'); case ATProtocol::STATUS_API_FAIL; - return DI::l10n()->t('Communication issues with the personal data server service (PDS).'); + return DI::l10n()->t('Communication issues with the personal data server service (PDS): %s', $message); case ATProtocol::STATUS_DID_FAIL: return DI::l10n()->t('The DID for the provided handle could not be detected. Please check if you entered the correct handle.'); case ATProtocol::STATUS_PDS_FAIL: @@ -361,7 +362,6 @@ function bluesky_settings_post(array &$b) DI::pConfig()->set(DI::userSession()->getLocalUserId(), 'bluesky', 'post', intval($_POST['bluesky'])); DI::pConfig()->set(DI::userSession()->getLocalUserId(), 'bluesky', 'post_by_default', intval($_POST['bluesky_bydefault'])); DI::pConfig()->set(DI::userSession()->getLocalUserId(), 'bluesky', 'handle', $handle); - DI::pConfig()->set(DI::userSession()->getLocalUserId(), 'bluesky', 'password', $_POST['bluesky_password']); DI::pConfig()->set(DI::userSession()->getLocalUserId(), 'bluesky', 'import', intval($_POST['bluesky_import'])); DI::pConfig()->set(DI::userSession()->getLocalUserId(), 'bluesky', 'import_feeds', intval($_POST['bluesky_import_feeds'])); DI::pConfig()->set(DI::userSession()->getLocalUserId(), 'bluesky', 'complete_threads', intval($_POST['bluesky_complete_threads'])); @@ -850,7 +850,14 @@ function bluesky_add_embed(int $uid, array $msg, array $record): array if (empty($blob)) { return []; } - $images[] = ['alt' => $image['description'] ?? '', 'image' => $blob]; + $images[] = [ + 'alt' => $image['description'] ?? '', + 'image' => $blob, + 'aspectRatio' => [ + 'width' => $photo['width'], + 'height' => $photo['height'], + ] + ]; } if (!empty($images)) { $record['embed'] = ['$type' => 'app.bsky.embed.images', 'images' => $images]; @@ -888,10 +895,15 @@ function bluesky_upload_blob(int $uid, array $photo): ?stdClass $picture = Photo::resizeToFileSize($picture, BLUESKY_IMAGE_SIZE[$retrial]); $new_height = $picture->getHeight(); $new_width = $picture->getWidth(); - $content = $picture->asString(); + $content = (string)$picture->asString(); $new_size = strlen($content); - Logger::info('Uploading', ['uid' => $uid, 'retrial' => $retrial, 'height' => $new_height, 'width' => $new_width, 'size' => $new_size, 'orig-height' => $height, 'orig-width' => $width, 'orig-size' => $size]); + if (($size != 0) && ($new_size == 0) && ($retrial == 0)) { + Logger::warning('Size is empty after resize, uploading original file', ['uid' => $uid, 'retrial' => $retrial, 'height' => $new_height, 'width' => $new_width, 'size' => $new_size, 'orig-height' => $height, 'orig-width' => $width, 'orig-size' => $size]); + $content = Photo::getImageForPhoto($photo); + } else { + Logger::info('Uploading', ['uid' => $uid, 'retrial' => $retrial, 'height' => $new_height, 'width' => $new_width, 'size' => $new_size, 'orig-height' => $height, 'orig-width' => $width, 'orig-size' => $size]); + } $data = DI::atProtocol()->post($uid, '/xrpc/com.atproto.repo.uploadBlob', $content, ['Content-type' => $photo['type'], 'Authorization' => ['Bearer ' . DI::atProtocol()->getUserToken($uid)]]); if (empty($data) || empty($data->blob)) { @@ -955,7 +967,7 @@ function bluesky_complete_post(stdClass $post, int $uid, int $post_reason, int $ } if ($complete) { - $uri = DI::atpProcessor()->fetchMissingPost(DI::atpProcessor()->getUri($post), $uid, $post_reason, $causer, 0, '', true); + $uri = DI::atpProcessor()->fetchMissingPost(DI::atpProcessor()->getUri($post), $uid, $post_reason, $causer, 0, '', true, $protocol); $uri_id = DI::atpProcessor()->fetchUriId($uri, $uid); } else { $uri_id = DI::atpProcessor()->processPost($post, $uid, $post_reason, $causer, 0, $protocol); From 16e06f9b2b85dba28a109ec85aaccc75509f2209 Mon Sep 17 00:00:00 2001 From: loma-one Date: Sun, 17 Nov 2024 08:20:49 +0100 Subject: [PATCH 119/222] Small bug fix MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Close the Uni-Code Smilies link with a ’;’ --- unicode_smilies/unicode_smilies.php | 3099 +++++++++++++-------------- 1 file changed, 1548 insertions(+), 1551 deletions(-) diff --git a/unicode_smilies/unicode_smilies.php b/unicode_smilies/unicode_smilies.php index 22ee3439..8d55c4be 100644 --- a/unicode_smilies/unicode_smilies.php +++ b/unicode_smilies/unicode_smilies.php @@ -2,7 +2,7 @@ /* * Name: Unicode Smilies * Description: Smilies based on the unicode emojis - On Linux use https://github.com/eosrei/emojione-color-font to see them in color and http://www.unicode.org/emoji/charts/full-emoji-list.html - * Version: 1.1.2 + * Version: 1.1.3 * Author: Michael Vogel * Author: Matthias Ebers */ @@ -25,7 +25,7 @@ function unicode_smilies_smilies(array &$b) Smilies::add($b, ':-D', '😁'); Smilies::add($b, ':D', '😁'); Smilies::add($b, ';-)', '😉'); - // Smilies::add($b, ';)', '😉'); // Deactivated since this leads to disturbed html entities +// Smilies::add($b, ';)', '😉'); // Deactivated since this leads to disturbed html entities Smilies::add($b, ':-P', '😛'); Smilies::add($b, ':-p', '😛'); Smilies::add($b, ':P', '😛'); @@ -54,353 +54,350 @@ function unicode_smilies_smilies(array &$b) // Smilies::add($b, 'O_o', '&#x;'); // face-smiling - Smilies::add($b, ':grinning face:', '😀'); - Smilies::add($b, ':grinning face with big eyes:', '😃'); - Smilies::add($b, ':grinning face with smiling eyes:', '😄'); - Smilies::add($b, ':beaming face with smiling eyes:', '😁'); - Smilies::add($b, ':grinning squinting face:', '😆'); - Smilies::add($b, ':laughing:', '😆'); - Smilies::add($b, ':grinning face with sweat:', '😅'); - Smilies::add($b, ':rolling on the floor laughing:', '🤣'); + Smilies::add($b, ':grinning face:', '😀'); + Smilies::add($b, ':grinning face with big eyes:', '😃'); + Smilies::add($b, ':grinning face with smiling eyes:', '😄'); + Smilies::add($b, ':beaming face with smiling eyes:', '😁'); + Smilies::add($b, ':grinning squinting face:', '😆'); + Smilies::add($b, ':laughing:', '😆'); + Smilies::add($b, ':grinning face with sweat:', '😅'); + Smilies::add($b, ':rolling on the floor laughing:', '🤣'); Smilies::add($b, ':rofl:', '🤣'); - Smilies::add($b, ':face with tears of joy:', '😂'); + Smilies::add($b, ':face with tears of joy:', '😂'); Smilies::add($b, ':tearsofjoy:', '😂'); - Smilies::add($b, ':slightly smiling face:', '🙂'); - Smilies::add($b, ':upside-down face:', '🙃'); - Smilies::add($b, ':winking face:', '😉'); - Smilies::add($b, ':smiling face with smiling eyes:', '😊'); - Smilies::add($b, ':smiling face with halo:', '😇'); + Smilies::add($b, ':slightly smiling face:', '🙂'); + Smilies::add($b, ':upside-down face:', '🙃'); + Smilies::add($b, ':winking face:', '😉'); + Smilies::add($b, ':smiling face with smiling eyes:', '😊'); + Smilies::add($b, ':smiling face with halo:', '😇'); // face-affection - Smilies::add($b, ':smiling face with hearts:', '🥰'); - Smilies::add($b, ':smiling face with heart-eyes:', '😍'); - Smilies::add($b, ':star-struck:', '🤩'); - Smilies::add($b, ':face blowing a kiss:', '😘'); - Smilies::add($b, ':kissing face:', '😗'); - Smilies::add($b, ':smiling face:', '☺'); - Smilies::add($b, ':kissing face with closed eyes:', '😚'); - Smilies::add($b, ':kissing face with smiling eyes:', '😙'); + Smilies::add($b, ':smiling face with hearts:', '🥰'); + Smilies::add($b, ':smiling face with heart-eyes:', '😍'); + Smilies::add($b, ':star-struck:', '🤩'); + Smilies::add($b, ':face blowing a kiss:', '😘'); + Smilies::add($b, ':kissing face:', '😗'); + Smilies::add($b, ':smiling face:', '☺'); + Smilies::add($b, ':kissing face with closed eyes:', '😚'); + Smilies::add($b, ':kissing face with smiling eyes:', '😙'); // face-tongue - Smilies::add($b, ':face savoring food:', '😋'); - Smilies::add($b, ':face with tongue:', '😛'); - Smilies::add($b, ':winking face with tongue:', '😜'); - Smilies::add($b, ':zany face:', '🤪'); - Smilies::add($b, ':squinting face with tongue:', '😝'); - Smilies::add($b, ':money-mouth face:', '🤑'); + Smilies::add($b, ':face savoring food:', '😋'); + Smilies::add($b, ':face with tongue:', '😛'); + Smilies::add($b, ':winking face with tongue:', '😜'); + Smilies::add($b, ':zany face:', '🤪'); + Smilies::add($b, ':squinting face with tongue:', '😝'); + Smilies::add($b, ':money-mouth face:', '🤑'); // face-hand - Smilies::add($b, ':hugging face:', '🤗'); - Smilies::add($b, ':face with hand over mouth:', '🤭'); - Smilies::add($b, ':shushing face:', '🤫'); - Smilies::add($b, ':thinking face:', '🤔'); + Smilies::add($b, ':hugging face:', '🤗'); + Smilies::add($b, ':face with hand over mouth:', '🤭'); + Smilies::add($b, ':shushing face:', '🤫'); + Smilies::add($b, ':thinking face:', '🤔'); // face-neutral-skeptical - Smilies::add($b, ':zipper-mouth face:', '🤐'); - Smilies::add($b, ':face with raised eyebrow:', '🤨'); - Smilies::add($b, ':neutral face:', '😐'); - Smilies::add($b, ':expressionless face:', '😑'); - Smilies::add($b, ':face without mouth:', '😶'); - Smilies::add($b, ':smirking face:', '😏'); - Smilies::add($b, ':unamused face:', '😒'); - Smilies::add($b, ':face with rolling eyes:', '🙄'); - Smilies::add($b, ':grimacing face:', '😬'); - Smilies::add($b, ':lying face:', '🤥'); + Smilies::add($b, ':zipper-mouth face:', '🤐'); + Smilies::add($b, ':face with raised eyebrow:', '🤨'); + Smilies::add($b, ':neutral face:', '😐'); + Smilies::add($b, ':expressionless face:', '😑'); + Smilies::add($b, ':face without mouth:', '😶'); + Smilies::add($b, ':smirking face:', '😏'); + Smilies::add($b, ':unamused face:', '😒'); + Smilies::add($b, ':face with rolling eyes:', '🙄'); + Smilies::add($b, ':grimacing face:', '😬'); + Smilies::add($b, ':lying face:', '🤥'); // face-sleepy - Smilies::add($b, ':relieved face:', '😌'); - Smilies::add($b, ':pensive face:', '😔'); - Smilies::add($b, ':sleepy face:', '😪'); - Smilies::add($b, ':drooling face:', '🤤'); + Smilies::add($b, ':relieved face:', '😌'); + Smilies::add($b, ':pensive face:', '😔'); + Smilies::add($b, ':sleepy face:', '😪'); + Smilies::add($b, ':drooling face:', '🤤'); Smilies::add($b, ':drool:', '🤤'); - Smilies::add($b, ':sleeping face:', '😴'); + Smilies::add($b, ':sleeping face:', '😴'); // face-unwell - Smilies::add($b, ':face with medical mask:', '😷'); - Smilies::add($b, ':face with thermometer:', '🤒'); - Smilies::add($b, ':face with head-bandage:', '🤕'); - Smilies::add($b, ':nauseated face:', '🤢'); - Smilies::add($b, ':face vomiting:', '🤮'); + Smilies::add($b, ':face with medical mask:', '😷'); + Smilies::add($b, ':face with thermometer:', '🤒'); + Smilies::add($b, ':face with head-bandage:', '🤕'); + Smilies::add($b, ':nauseated face:', '🤢'); + Smilies::add($b, ':face vomiting:', '🤮'); Smilies::add($b, ':vomit:', '🤮'); - Smilies::add($b, ':sneezing face:', '🤧'); - Smilies::add($b, ':hot face:', '🥵'); - Smilies::add($b, ':cold face:', '🥶'); - Smilies::add($b, ':woozy face:', '🥴'); - Smilies::add($b, ':dizzy face:', '😵'); + Smilies::add($b, ':sneezing face:', '🤧'); + Smilies::add($b, ':hot face:', '🥵'); + Smilies::add($b, ':cold face:', '🥶'); + Smilies::add($b, ':woozy face:', '🥴'); + Smilies::add($b, ':dizzy face:', '😵'); Smilies::add($b, ':dead:', '😵'); - Smilies::add($b, ':exploding head:', '🤯'); + Smilies::add($b, ':exploding head:', '🤯'); // face-hat - Smilies::add($b, ':cowboy hat face:', '🤠'); - Smilies::add($b, ':partying face:', '🥳'); + Smilies::add($b, ':cowboy hat face:', '🤠'); + Smilies::add($b, ':partying face:', '🥳'); // face-glasses - Smilies::add($b, ':smiling face with sunglasses:', '😎'); - Smilies::add($b, ':nerd face:', '🤓'); - Smilies::add($b, ':face with monocle:', '🧐'); + Smilies::add($b, ':smiling face with sunglasses:', '😎'); + Smilies::add($b, ':nerd face:', '🤓'); + Smilies::add($b, ':face with monocle:', '🧐'); // face-concerned - Smilies::add($b, ':confused face:', '😕'); - Smilies::add($b, ':worried face:', '😟'); - Smilies::add($b, ':slightly frowning face:', '🙁'); - Smilies::add($b, ':frowning face:', '☹'); - Smilies::add($b, ':face with open mouth:', '😮'); - Smilies::add($b, ':hushed face:', '😯'); - Smilies::add($b, ':astonished face:', '😲'); - Smilies::add($b, ':flushed face:', '😳'); + Smilies::add($b, ':confused face:', '😕'); + Smilies::add($b, ':worried face:', '😟'); + Smilies::add($b, ':slightly frowning face:', '🙁'); + Smilies::add($b, ':frowning face:', '☹'); + Smilies::add($b, ':face with open mouth:', '😮'); + Smilies::add($b, ':hushed face:', '😯'); + Smilies::add($b, ':astonished face:', '😲'); + Smilies::add($b, ':flushed face:', '😳'); Smilies::add($b, ':dazed:', '😳'); - Smilies::add($b, ':pleading face:', '🥺'); - Smilies::add($b, ':frowning face with open mouth:', '😦'); - Smilies::add($b, ':anguished face:', '😧'); - Smilies::add($b, ':fearful face:', '😨'); - Smilies::add($b, ':anxious face with sweat:', '😰'); - Smilies::add($b, ':sad but relieved face:', '😥'); - Smilies::add($b, ':crying face:', '😢'); - Smilies::add($b, ':loudly crying face:', '😭'); - Smilies::add($b, ':face screaming in fear:', '😱'); - Smilies::add($b, ':confounded face:', '😖'); - Smilies::add($b, ':persevering face:', '😣'); - Smilies::add($b, ':disappointed face:', '😞'); + Smilies::add($b, ':pleading face:', '🥺'); + Smilies::add($b, ':frowning face with open mouth:', '😦'); + Smilies::add($b, ':anguished face:', '😧'); + Smilies::add($b, ':fearful face:', '😨'); + Smilies::add($b, ':anxious face with sweat:', '😰'); + Smilies::add($b, ':sad but relieved face:', '😥'); + Smilies::add($b, ':crying face:', '😢'); + Smilies::add($b, ':loudly crying face:', '😭'); + Smilies::add($b, ':face screaming in fear:', '😱'); + Smilies::add($b, ':confounded face:', '😖'); + Smilies::add($b, ':persevering face:', '😣'); + Smilies::add($b, ':disappointed face:', '😞'); // face-negative - Smilies::add($b, ':face with steam from nose:', '😤'); - Smilies::add($b, ':pouting face:', '😡'); - Smilies::add($b, ':angry face:', '😠'); - Smilies::add($b, ':face with symbols on mouth:', '🤬'); - Smilies::add($b, ':smiling face with horns:', '😈'); - Smilies::add($b, ':angry face with horns:', '👿'); - Smilies::add($b, ':skull:', '💀'); - Smilies::add($b, ':skull and crossbones:', '☠'); + Smilies::add($b, ':face with steam from nose:', '😤'); + Smilies::add($b, ':pouting face:', '😡'); + Smilies::add($b, ':angry face:', '😠'); + Smilies::add($b, ':face with symbols on mouth:', '🤬'); + Smilies::add($b, ':smiling face with horns:', '😈'); + Smilies::add($b, ':angry face with horns:', '👿'); + Smilies::add($b, ':skull:', '💀'); + Smilies::add($b, ':skull and crossbones:', '☠'); // face-costume - Smilies::add($b, ':pile of poo:', '💩'); - Smilies::add($b, ':clown face:', '🤡'); - Smilies::add($b, ':ogre:', '👹'); - Smilies::add($b, ':goblin:', '👺'); - Smilies::add($b, ':ghost:', '👻'); - Smilies::add($b, ':alien:', '👽'); - Smilies::add($b, ':alien monster:', '👾'); - Smilies::add($b, ':robot:', '🤖'); + Smilies::add($b, ':pile of poo:', '💩'); + Smilies::add($b, ':clown face:', '🤡'); + Smilies::add($b, ':ogre:', '👹'); + Smilies::add($b, ':goblin:', '👺'); + Smilies::add($b, ':ghost:', '👻'); + Smilies::add($b, ':alien:', '👽'); + Smilies::add($b, ':alien monster:', '👾'); + Smilies::add($b, ':robot:', '🤖'); // cat-face - Smilies::add($b, ':grinning cat:', '😺'); - Smilies::add($b, ':grinning cat with smiling eyes:', '😸'); - Smilies::add($b, ':cat with tears of joy:', '😹'); - Smilies::add($b, ':smiling cat with heart-eyes:', '😻'); - Smilies::add($b, ':cat with wry smile:', '😼'); - Smilies::add($b, ':kissing cat:', '😽'); - Smilies::add($b, ':weary cat:', '🙀'); - Smilies::add($b, ':crying cat:', '😿'); - Smilies::add($b, ':pouting cat:', '😾'); + Smilies::add($b, ':grinning cat:', '😺'); + Smilies::add($b, ':grinning cat with smiling eyes:', '😸'); + Smilies::add($b, ':cat with tears of joy:', '😹'); + Smilies::add($b, ':smiling cat with heart-eyes:', '😻'); + Smilies::add($b, ':cat with wry smile:', '😼'); + Smilies::add($b, ':kissing cat:', '😽'); + Smilies::add($b, ':weary cat:', '🙀'); + Smilies::add($b, ':crying cat:', '😿'); + Smilies::add($b, ':pouting cat:', '😾'); // monkey-face - Smilies::add($b, ':see-no-evil monkey:', '🙈'); - Smilies::add($b, ':hear-no-evil monkey:', '🙉'); - Smilies::add($b, ':speak-no-evil monkey:', '🙊'); + Smilies::add($b, ':see-no-evil monkey:', '🙈'); + Smilies::add($b, ':hear-no-evil monkey:', '🙉'); + Smilies::add($b, ':speak-no-evil monkey:', '🙊'); //emotion - Smilies::add($b, ':kiss mark:', '💋'); - Smilies::add($b, ':love letter:', '💌'); - Smilies::add($b, ':heart with arrow:', '💘'); - Smilies::add($b, ':heart with ribbon:', '💝'); - Smilies::add($b, ':sparkling heart:', '💖'); - Smilies::add($b, ':loveheart:', '💖'); - Smilies::add($b, ':growing heart:', '💗'); - Smilies::add($b, ':beating heart:', '💓'); - Smilies::add($b, ':revolving hearts:', '💞'); - Smilies::add($b, ':two hearts:', '💕'); - Smilies::add($b, ':heart decoration:', '💟'); - Smilies::add($b, ':heart exclamation:', '❣'); - Smilies::add($b, ':broken heart:', '💔'); - Smilies::add($b, ':red heart:', '❤'); - Smilies::add($b, ':orange heart:', '🧡'); - Smilies::add($b, ':yellow heart:', '💛'); - Smilies::add($b, ':green heart:', '💚'); - Smilies::add($b, ':blue heart:', '💙'); - Smilies::add($b, ':purple heart:', '💜'); - Smilies::add($b, ':brown heart:', '🤎'); - Smilies::add($b, ':black heart:', '🖤'); - Smilies::add($b, ':white heart:', '🤍'); - Smilies::add($b, ':hundred points:', '💯'); - Smilies::add($b, ':anger symbol:', '💢'); - Smilies::add($b, ':collision:', '💥'); - Smilies::add($b, ':dizzy:', '💫'); - Smilies::add($b, ':sweat droplets:', '💦'); - Smilies::add($b, ':dashing away:', '💨'); - Smilies::add($b, ':hole:', '🕳'); - Smilies::add($b, ':bomb:', '💣'); - Smilies::add($b, ':speech balloon:', '💬'); - Smilies::add($b, ':left speech bubble:', '🗨'); - Smilies::add($b, ':right anger bubble:', '🗯'); - Smilies::add($b, ':thought balloon:', '💭'); - Smilies::add($b, ':zzz:', '💤'); + Smilies::add($b, ':kiss mark:', '💋'); + Smilies::add($b, ':love letter:', '💌'); + Smilies::add($b, ':heart with arrow:', '💘'); + Smilies::add($b, ':heart with ribbon:', '💝'); + Smilies::add($b, ':sparkling heart:', '💖'); + Smilies::add($b, ':loveheart:', '💖'); + Smilies::add($b, ':growing heart:', '💗'); + Smilies::add($b, ':beating heart:', '💓'); + Smilies::add($b, ':revolving hearts:', '💞'); + Smilies::add($b, ':two hearts:', '💕'); + Smilies::add($b, ':heart decoration:', '💟'); + Smilies::add($b, ':heart exclamation:', '❣'); + Smilies::add($b, ':broken heart:', '💔'); + Smilies::add($b, ':red heart:', '❤'); + Smilies::add($b, ':orange heart:', '🧡'); + Smilies::add($b, ':yellow heart:', '💛'); + Smilies::add($b, ':green heart:', '💚'); + Smilies::add($b, ':blue heart:', '💙'); + Smilies::add($b, ':purple heart:', '💜'); + Smilies::add($b, ':brown heart:', '🤎'); + Smilies::add($b, ':black heart:', '🖤'); + Smilies::add($b, ':white heart:', '🤍'); + Smilies::add($b, ':hundred points:', '💯'); + Smilies::add($b, ':anger symbol:', '💢'); + Smilies::add($b, ':collision:', '💥'); + Smilies::add($b, ':dizzy:', '💫'); + Smilies::add($b, ':sweat droplets:', '💦'); + Smilies::add($b, ':dashing away:', '💨'); + Smilies::add($b, ':hole:', '🕳'); + Smilies::add($b, ':bomb:', '💣'); + Smilies::add($b, ':speech balloon:', '💬'); + Smilies::add($b, ':left speech bubble:', '🗨'); + Smilies::add($b, ':right anger bubble:', '🗯'); + Smilies::add($b, ':thought balloon:', '💭'); + Smilies::add($b, ':zzz:', '💤'); // People & Body // hand-fingers-open - Smilies::add($b, ':waving hand:', '👋'); - Smilies::add($b, ':raised back of hand:', '🤚'); - Smilies::add($b, ':hand with fingers splayed:', '🖐'); - Smilies::add($b, ':raised hand:', '✋'); - Smilies::add($b, ':vulcan salute:', '🖖'); + Smilies::add($b, ':waving hand:', '👋'); + Smilies::add($b, ':raised back of hand:', '🤚'); + Smilies::add($b, ':hand with fingers splayed:', '🖐'); + Smilies::add($b, ':raised hand:', '✋'); + Smilies::add($b, ':vulcan salute:', '🖖'); // hand-fingers-partial - Smilies::add($b, ':OK hand:', '👌'); -// Smilies::add($b, ':pinching hand:', '🤏'); - Smilies::add($b, ':victory hand:', '✌'); - Smilies::add($b, ':crossed fingers:', '🤞'); - Smilies::add($b, ':love-you gesture:', '🤟'); - Smilies::add($b, ':sign of the horns:', '🤘'); - Smilies::add($b, ':call me hand:', '🤙'); + Smilies::add($b, ':OK hand:', '👌'); + Smilies::add($b, ':victory hand:', '✌'); + Smilies::add($b, ':crossed fingers:', '🤞'); + Smilies::add($b, ':love-you gesture:', '🤟'); + Smilies::add($b, ':sign of the horns:', '🤘'); + Smilies::add($b, ':call me hand:', '🤙'); // hand-single-finger - Smilies::add($b, ':backhand index pointing left:', '👈'); - Smilies::add($b, ':backhand index pointing right:', '👉'); - Smilies::add($b, ':backhand index pointing up:', '👆'); - Smilies::add($b, ':middle finger:', '🖕'); - Smilies::add($b, ':backhand index pointing down:', '👇'); - Smilies::add($b, ':index pointing up:', '☝'); + Smilies::add($b, ':backhand index pointing left:', '👈'); + Smilies::add($b, ':backhand index pointing right:', '👉'); + Smilies::add($b, ':backhand index pointing up:', '👆'); + Smilies::add($b, ':middle finger:', '🖕'); + Smilies::add($b, ':backhand index pointing down:', '👇'); + Smilies::add($b, ':index pointing up:', '☝'); // hand-fingers-closed - Smilies::add($b, ':thumbs up:', '👍'); + Smilies::add($b, ':thumbs up:', '👍'); Smilies::add($b, ':like:', '👍'); Smilies::add($b, '\\o/', '👍'); - Smilies::add($b, ':thumbs down:', '👎'); + Smilies::add($b, ':thumbs down:', '👎'); Smilies::add($b, ':dislike:', '👎'); - Smilies::add($b, ':raised fist:', '✊'); - Smilies::add($b, ':oncoming fist:', '👊'); - Smilies::add($b, ':left-facing fist:', '🤛'); - Smilies::add($b, ':right-facing fist:', '🤜'); + Smilies::add($b, ':raised fist:', '✊'); + Smilies::add($b, ':oncoming fist:', '👊'); + Smilies::add($b, ':left-facing fist:', '🤛'); + Smilies::add($b, ':right-facing fist:', '🤜'); // hands - Smilies::add($b, ':clapping hands:', '👏'); - Smilies::add($b, ':raising hands:', '🙌'); - Smilies::add($b, ':open hands:', '👐'); - Smilies::add($b, ':palms up together:', '🤲'); - Smilies::add($b, ':handshake:', '🤝'); - Smilies::add($b, ':folded hands:', '🙏'); + Smilies::add($b, ':clapping hands:', '👏'); + Smilies::add($b, ':raising hands:', '🙌'); + Smilies::add($b, ':open hands:', '👐'); + Smilies::add($b, ':palms up together:', '🤲'); + Smilies::add($b, ':handshake:', '🤝'); + Smilies::add($b, ':folded hands:', '🙏'); // hand-prop - Smilies::add($b, ':writing hand:', '✍'); - Smilies::add($b, ':nail polish:', '💅'); - Smilies::add($b, ':selfie:', '🤳'); + Smilies::add($b, ':writing hand:', '✍'); + Smilies::add($b, ':nail polish:', '💅'); + Smilies::add($b, ':selfie:', '🤳'); // body-parts - Smilies::add($b, ':flexed biceps:', '💪'); - Smilies::add($b, ':mechanical arm:', '🦾'); - Smilies::add($b, ':mechanical leg:', '🦿'); - Smilies::add($b, ':leg:', '🦵'); - Smilies::add($b, ':foot:', '🦶'); - Smilies::add($b, ':ear:', '👂'); -// Smilies::add($b, ':ear with hearing aid:', '🦻'); - Smilies::add($b, ':nose:', '👃'); - Smilies::add($b, ':brain:', '🧠'); - Smilies::add($b, ':tooth:', '🦷'); - Smilies::add($b, ':bone:', '🦴'); - Smilies::add($b, ':eyes:', '👀'); - Smilies::add($b, ':eye:', '👁'); - Smilies::add($b, ':tongue:', '👅'); - Smilies::add($b, ':mouth:', '👄'); + Smilies::add($b, ':flexed biceps:', '💪'); + Smilies::add($b, ':mechanical arm:', '🦾'); + Smilies::add($b, ':mechanical leg:', '🦿'); + Smilies::add($b, ':leg:', '🦵'); + Smilies::add($b, ':foot:', '🦶'); + Smilies::add($b, ':ear:', '👂'); + Smilies::add($b, ':brain:', '🧠'); + Smilies::add($b, ':tooth:', '🦷'); + Smilies::add($b, ':bone:', '🦴'); + Smilies::add($b, ':eyes:', '👀'); + Smilies::add($b, ':eye:', '👁'); + Smilies::add($b, ':tongue:', '👅'); + Smilies::add($b, ':mouth:', '👄'); // person - Smilies::add($b, ':baby:', '👶'); - Smilies::add($b, ':child:', '🧒'); - Smilies::add($b, ':boy:', '👦'); - Smilies::add($b, ':girl:', '👧'); - Smilies::add($b, ':person:', '🧑'); - Smilies::add($b, ':person: blond hair:', '👱'); - Smilies::add($b, ':man:', '👨'); - Smilies::add($b, ':man: beard:', '🧔'); + Smilies::add($b, ':baby:', '👶'); + Smilies::add($b, ':child:', '🧒'); + Smilies::add($b, ':boy:', '👦'); + Smilies::add($b, ':girl:', '👧'); + Smilies::add($b, ':person:', '🧑'); + Smilies::add($b, ':person: blond hair:', '👱'); + Smilies::add($b, ':man:', '👨'); + Smilies::add($b, ':man: beard:', '🧔'); Smilies::add($b, ':beard:', '🧔'); - Smilies::add($b, ':man: red hair:', '👨‍🦰'); - Smilies::add($b, ':man: curly hair:', '👨‍🦱'); - Smilies::add($b, ':man: white hair:', '👨‍🦳'); - Smilies::add($b, ':man: bald:', '👨‍🦲'); - Smilies::add($b, ':woman:', '👩'); - Smilies::add($b, ':woman: red hair:', '👩‍🦰'); - Smilies::add($b, ':person: red hair:', '🧑‍🦰'); - Smilies::add($b, ':woman: curly hair:', '👩‍🦱'); - Smilies::add($b, ':person: curly hair:', '🧑‍🦱'); - Smilies::add($b, ':woman: white hair:', '👩‍🦳'); - Smilies::add($b, ':person: white hair:', '🧑‍🦳'); - Smilies::add($b, ':woman: bald:', '👩‍🦲'); - Smilies::add($b, ':bald::', '🧑‍🦲'); - Smilies::add($b, ':woman: blond hair:', '👱‍♀️'); - Smilies::add($b, ':man: blond hair:', '👱‍♂️'); - Smilies::add($b, ':older person:', '🧓'); - Smilies::add($b, ':old man:', '👴'); - Smilies::add($b, ':old woman:', '👵'); + Smilies::add($b, ':man: red hair:', '👨‍🦰'); + Smilies::add($b, ':man: curly hair:', '👨‍🦱'); + Smilies::add($b, ':man: white hair:', '👨‍🦳'); + Smilies::add($b, ':man: bald:', '👨‍🦲'); + Smilies::add($b, ':woman:', '👩'); + Smilies::add($b, ':woman: red hair:', '👩‍🦰'); + Smilies::add($b, ':person: red hair:', '🧑‍🦰'); + Smilies::add($b, ':woman: curly hair:', '👩‍🦱'); + Smilies::add($b, ':person: curly hair:', '🧑‍🦱'); + Smilies::add($b, ':woman: white hair:', '👩‍🦳'); + Smilies::add($b, ':person: white hair:', '🧑‍🦳'); + Smilies::add($b, ':woman: bald:', '👩‍🦲'); + Smilies::add($b, ':bald::', '🧑‍🦲'); + Smilies::add($b, ':woman: blond hair:', '👱‍♀️'); + Smilies::add($b, ':man: blond hair:', '👱‍♂️'); + Smilies::add($b, ':older person:', '🧓'); + Smilies::add($b, ':old man:', '👴'); + Smilies::add($b, ':old woman:', '👵'); Smilies::add($b, ':pregnant:', '🤰'); // person-gesture - Smilies::add($b, ':person frowning:', '🙍'); - Smilies::add($b, ':man frowning:', '🙍‍♂️'); - Smilies::add($b, ':woman frowning:', '🙍‍♀️'); - Smilies::add($b, ':person pouting:', '🙎'); - Smilies::add($b, ':man pouting:', '🙎‍♂️'); - Smilies::add($b, ':woman pouting:', '🙎‍♀️'); - Smilies::add($b, ':person gesturing NO:', '🙅'); - Smilies::add($b, ':man gesturing NO:', '🙅‍♂️'); - Smilies::add($b, ':woman gesturing NO:', '🙅‍♀️'); - Smilies::add($b, ':person gesturing OK:', '🙆'); - Smilies::add($b, ':man gesturing OK:', '🙆‍♂️'); - Smilies::add($b, ':woman gesturing OK:', '🙆‍♀️'); - Smilies::add($b, ':person tipping hand:', '💁'); - Smilies::add($b, ':man tipping hand:', '💁‍♂️'); - Smilies::add($b, ':woman tipping hand:', '💁‍♀️'); - Smilies::add($b, ':person raising hand:', '🙋'); - Smilies::add($b, ':man raising hand:', '🙋‍♂️'); - Smilies::add($b, ':woman raising hand', '🙋‍♀️'); -// Smilies::add($b, ':deaf person:', '🧏'); -// Smilies::add($b, ':deaf man:', '🧏‍♂️'); -// Smilies::add($b, ':deaf woman:', '🧏‍♀️'); - Smilies::add($b, ':person bowing:', '🙇'); + Smilies::add($b, ':person frowning:', '🙍'); + Smilies::add($b, ':man frowning:', '🙍‍♂️'); + Smilies::add($b, ':woman frowning:', '🙍‍♀️'); + Smilies::add($b, ':person pouting:', '🙎'); + Smilies::add($b, ':man pouting:', '🙎‍♂️'); + Smilies::add($b, ':woman pouting:', '🙎‍♀️'); + Smilies::add($b, ':person gesturing NO:', '🙅'); + Smilies::add($b, ':man gesturing NO:', '🙅‍♂️'); + Smilies::add($b, ':woman gesturing NO:', '🙅‍♀️'); + Smilies::add($b, ':person gesturing OK:', '🙆'); + Smilies::add($b, ':man gesturing OK:', '🙆‍♂️'); + Smilies::add($b, ':woman gesturing OK:', '🙆‍♀️'); + Smilies::add($b, ':person tipping hand:', '💁'); + Smilies::add($b, ':man tipping hand:', '💁‍♂️'); + Smilies::add($b, ':woman tipping hand:', '💁‍♀️'); + Smilies::add($b, ':person raising hand:', '🙋'); + Smilies::add($b, ':man raising hand:', '🙋‍♂️'); + Smilies::add($b, ':woman raising hand', '🙋‍♀️'); +// Smilies::add($b, ':deaf person:', '🧏'); +// Smilies::add($b, ':deaf man:', '🧏‍♂️'); +// Smilies::add($b, ':deaf woman:', '🧏‍♀️'); + Smilies::add($b, ':person bowing:', '🙇'); Smilies::add($b, ':bow:', '🙇'); - Smilies::add($b, ':man bowing:', '🙇‍♂️'); - Smilies::add($b, ':woman bowing:', '🙇‍♀️'); - Smilies::add($b, ':person facepalming:', '🤦'); + Smilies::add($b, ':man bowing:', '🙇‍♂️'); + Smilies::add($b, ':woman bowing:', '🙇‍♀️'); + Smilies::add($b, ':person facepalming:', '🤦'); Smilies::add($b, ':facepalm:', '🤦'); - Smilies::add($b, ':man facepalming:', '🤦‍♂️'); - Smilies::add($b, ':woman facepalming:', '🤦‍♀️'); - Smilies::add($b, ':person shrugging:', '🤷'); + Smilies::add($b, ':man facepalming:', '🤦‍♂️'); + Smilies::add($b, ':woman facepalming:', '🤦‍♀️'); + Smilies::add($b, ':person shrugging:', '🤷'); Smilies::add($b, ':shrug:', '🤷'); - Smilies::add($b, ':man shrugging:', '🤷‍♂️'); - Smilies::add($b, ':woman shrugging:', '🤷‍♀️'); + Smilies::add($b, ':man shrugging:', '🤷‍♂️'); + Smilies::add($b, ':woman shrugging:', '🤷‍♀️'); // person-role // person-fantasy - Smilies::add($b, ':baby angel:', '👼'); + Smilies::add($b, ':baby angel:', '👼'); Smilies::add($b, ':angel:', '👼'); Smilies::add($b, ':cherub:', '👼'); - Smilies::add($b, ':Santa Claus:', '🎅'); - Smilies::add($b, ':Mrs. Claus:', '🤶'); - Smilies::add($b, ':superhero:', '🦸'); - Smilies::add($b, ':man superhero:', '🦸‍♂️'); - Smilies::add($b, ':woman superhero:', '🦸‍♀️'); - Smilies::add($b, ':supervillain:', '🦹'); - Smilies::add($b, ':man supervillain:', '🦹‍♂️'); - Smilies::add($b, ':woman supervillain:', '🦹‍♀️'); - Smilies::add($b, ':mage:', '🧙'); - Smilies::add($b, ':man mage:', '🧙‍♂️'); - Smilies::add($b, ':woman mage:', '🧙‍♀️'); - Smilies::add($b, ':fairy:', '🧚'); - Smilies::add($b, ':man fairy:', '🧚‍♂️'); - Smilies::add($b, ':woman fairy:', '🧚‍♀️'); - Smilies::add($b, ':vampire:', '🧛'); - Smilies::add($b, ':man vampire:', '🧛‍♂️'); - Smilies::add($b, ':woman vampire:', '🧛‍♀️'); - Smilies::add($b, ':merperson:', '🧜'); - Smilies::add($b, ':merman:', '🧜‍♂️'); - Smilies::add($b, ':mermaid:', '🧜‍♀️'); - Smilies::add($b, ':elf:', '🧝'); - Smilies::add($b, ':man elf:', '🧝‍♂️'); - Smilies::add($b, ':woman elf:', '🧝‍♀️'); - Smilies::add($b, ':genie:', '🧞'); - Smilies::add($b, ':man genie:', '🧞‍♂️'); - Smilies::add($b, ':woman genie:', '🧞‍♀️'); - Smilies::add($b, ':zombie:', '🧟'); - Smilies::add($b, ':man zombie:', '🧟‍♂️'); - Smilies::add($b, ':woman zombie:', '🧟‍♀️'); + Smilies::add($b, ':Santa Claus:', '🎅'); + Smilies::add($b, ':Mrs. Claus:', '🤶'); + Smilies::add($b, ':superhero:', '🦸'); + Smilies::add($b, ':man superhero:', '🦸‍♂️'); + Smilies::add($b, ':woman superhero:', '🦸‍♀️'); + Smilies::add($b, ':supervillain:', '🦹'); + Smilies::add($b, ':man supervillain:', '🦹‍♂️'); + Smilies::add($b, ':woman supervillain:', '🦹‍♀️'); + Smilies::add($b, ':mage:', '🧙'); + Smilies::add($b, ':man mage:', '🧙‍♂️'); + Smilies::add($b, ':woman mage:', '🧙‍♀️'); + Smilies::add($b, ':fairy:', '🧚'); + Smilies::add($b, ':man fairy:', '🧚‍♂️'); + Smilies::add($b, ':woman fairy:', '🧚‍♀️'); + Smilies::add($b, ':vampire:', '🧛'); + Smilies::add($b, ':man vampire:', '🧛‍♂️'); + Smilies::add($b, ':woman vampire:', '🧛‍♀️'); + Smilies::add($b, ':merperson:', '🧜'); + Smilies::add($b, ':merman:', '🧜‍♂️'); + Smilies::add($b, ':mermaid:', '🧜‍♀️'); + Smilies::add($b, ':elf:', '🧝'); + Smilies::add($b, ':man elf:', '🧝‍♂️'); + Smilies::add($b, ':woman elf:', '🧝‍♀️'); + Smilies::add($b, ':genie:', '🧞'); + Smilies::add($b, ':man genie:', '🧞‍♂️'); + Smilies::add($b, ':woman genie:', '🧞‍♀️'); + Smilies::add($b, ':zombie:', '🧟'); + Smilies::add($b, ':man zombie:', '🧟‍♂️'); + Smilies::add($b, ':woman zombie:', '🧟‍♀️'); // person-activity @@ -411,83 +408,83 @@ function unicode_smilies_smilies(array &$b) // person-resting // family - Smilies::add($b, ':people holding hands:', '🧑‍🤝‍🧑'); - Smilies::add($b, ':women holding hands:', '👭'); - Smilies::add($b, ':woman and man holding hands:', '👫'); - Smilies::add($b, ':men holding hands:', '👬'); - Smilies::add($b, ':kiss:', '💏'); - Smilies::add($b, ':couple with heart:', '💑'); - Smilies::add($b, ':family:', '👪'); + Smilies::add($b, ':people holding hands:', '🧑‍🤝‍🧑'); + Smilies::add($b, ':women holding hands:', '👭'); + Smilies::add($b, ':woman and man holding hands:', '👫'); + Smilies::add($b, ':men holding hands:', '👬'); + Smilies::add($b, ':kiss:', '💏'); + Smilies::add($b, ':couple with heart:', '💑'); + Smilies::add($b, ':family:', '👪'); // person-symbol - Smilies::add($b, ':speaking head:', '🗣'); - Smilies::add($b, ':bust in silhouette:', '👤'); - Smilies::add($b, ':busts in silhouette:', '👥'); - Smilies::add($b, ':footprints:', '👣'); + Smilies::add($b, ':speaking head:', '🗣'); + Smilies::add($b, ':bust in silhouette:', '👤'); + Smilies::add($b, ':busts in silhouette:', '👥'); + Smilies::add($b, ':footprints:', '👣'); // Component // hair-style // Animals & Nature // animal-mammal - Smilies::add($b, ':monkey face:', '🐵'); - Smilies::add($b, ':monkey:', '🐒'); - Smilies::add($b, ':gorilla:', '🦍'); - Smilies::add($b, ':orangutan:', '🦧'); - Smilies::add($b, ':dog face:', '🐶'); - Smilies::add($b, ':dog:', '🐕'); - Smilies::add($b, ':guide dog:', '🦮'); - Smilies::add($b, ':poodle:', '🐩'); - Smilies::add($b, ':wolf:', '🐺'); - Smilies::add($b, ':fox:', '🦊'); - Smilies::add($b, ':raccoon:', '🦝'); - Smilies::add($b, ':cat face:', '🐱'); - Smilies::add($b, ':cat:', '🐈'); - Smilies::add($b, ':lion:', '🦁'); - Smilies::add($b, ':tiger face:', '🐯'); - Smilies::add($b, ':tiger:', '🐅'); - Smilies::add($b, ':leopard:', '🐆'); - Smilies::add($b, ':horse face:', '🐴'); - Smilies::add($b, ':horse:', '🐎'); - Smilies::add($b, ':unicorn:', '🦄'); - Smilies::add($b, ':zebra:', '🦓'); - Smilies::add($b, ':deer:', '🦌'); - Smilies::add($b, ':cow face:', '🐮'); - Smilies::add($b, ':ox:', '🐂'); - Smilies::add($b, ':water buffalo:', '🐃'); - Smilies::add($b, ':cow:', '🐄'); - Smilies::add($b, ':pig face:', '🐷'); - Smilies::add($b, ':pig:', '🐖'); + Smilies::add($b, ':monkey face:', '🐵'); + Smilies::add($b, ':monkey:', '🐒'); + Smilies::add($b, ':gorilla:', '🦍'); + Smilies::add($b, ':orangutan:', '🦧'); + Smilies::add($b, ':dog face:', '🐶'); + Smilies::add($b, ':dog:', '🐕'); + Smilies::add($b, ':guide dog:', '🦮'); + Smilies::add($b, ':poodle:', '🐩'); + Smilies::add($b, ':wolf:', '🐺'); + Smilies::add($b, ':fox:', '🦊'); + Smilies::add($b, ':raccoon:', '🦝'); + Smilies::add($b, ':cat face:', '🐱'); + Smilies::add($b, ':cat:', '🐈'); + Smilies::add($b, ':lion:', '🦁'); + Smilies::add($b, ':tiger face:', '🐯'); + Smilies::add($b, ':tiger:', '🐅'); + Smilies::add($b, ':leopard:', '🐆'); + Smilies::add($b, ':horse face:', '🐴'); + Smilies::add($b, ':horse:', '🐎'); + Smilies::add($b, ':unicorn:', '🦄'); + Smilies::add($b, ':zebra:', '🦓'); + Smilies::add($b, ':deer:', '🦌'); + Smilies::add($b, ':cow face:', '🐮'); + Smilies::add($b, ':ox:', '🐂'); + Smilies::add($b, ':water buffalo:', '🐃'); + Smilies::add($b, ':cow:', '🐄'); + Smilies::add($b, ':pig face:', '🐷'); + Smilies::add($b, ':pig:', '🐖'); Smilies::add($b, ':boar:', '🐗'); - Smilies::add($b, ':pig nose:', '🐽'); - Smilies::add($b, ':ram:', '🐏'); - Smilies::add($b, ':sheep:', '🐑'); - Smilies::add($b, ':goat:', '🐐'); + Smilies::add($b, ':pig nose:', '🐽'); + Smilies::add($b, ':ram:', '🐏'); + Smilies::add($b, ':sheep:', '🐑'); + Smilies::add($b, ':goat:', '🐐'); Smilies::add($b, ':camel:', '🐪'); - Smilies::add($b, ':two-hump camel:', '🐫'); - Smilies::add($b, ':llama:', '🦙'); - Smilies::add($b, ':giraffe:', '🦒'); - Smilies::add($b, ':elephant:', '🐘'); - Smilies::add($b, ':rhinoceros:', '🦏'); - Smilies::add($b, ':hippopotamus:', '🦛'); - Smilies::add($b, ':mouse face:', '🐭'); - Smilies::add($b, ':mouse:', '🐁'); - Smilies::add($b, ':rat:', '🐀'); - Smilies::add($b, ':hamster:', '🐹'); - Smilies::add($b, ':rabbit face:', '🐰'); - Smilies::add($b, ':rabbit:', '🐇'); - Smilies::add($b, ':chipmunk:', '🐿'); - Smilies::add($b, ':hedgehog:', '🦔'); - Smilies::add($b, ':bat:', '🦇'); - Smilies::add($b, ':bear:', '🐻'); - Smilies::add($b, ':koala:', '🐨'); - Smilies::add($b, ':panda:', '🐼'); - Smilies::add($b, ':sloth:', '🦥'); - Smilies::add($b, ':otter:', '🦦'); - Smilies::add($b, ':skunk:', '🦨'); - Smilies::add($b, ':kangaroo:', '🦘'); - Smilies::add($b, ':badger:', '🦡'); - Smilies::add($b, ':paw prints:', '🐾'); + Smilies::add($b, ':two-hump camel:', '🐫'); + Smilies::add($b, ':llama:', '🦙'); + Smilies::add($b, ':giraffe:', '🦒'); + Smilies::add($b, ':elephant:', '🐘'); + Smilies::add($b, ':rhinoceros:', '🦏'); + Smilies::add($b, ':hippopotamus:', '🦛'); + Smilies::add($b, ':mouse face:', '🐭'); + Smilies::add($b, ':mouse:', '🐁'); + Smilies::add($b, ':rat:', '🐀'); + Smilies::add($b, ':hamster:', '🐹'); + Smilies::add($b, ':rabbit face:', '🐰'); + Smilies::add($b, ':rabbit:', '🐇'); + Smilies::add($b, ':chipmunk:', '🐿'); + Smilies::add($b, ':hedgehog:', '🦔'); + Smilies::add($b, ':bat:', '🦇'); + Smilies::add($b, ':bear:', '🐻'); + Smilies::add($b, ':koala:', '🐨'); + Smilies::add($b, ':panda:', '🐼'); + Smilies::add($b, ':sloth:', '🦥'); + Smilies::add($b, ':otter:', '🦦'); + Smilies::add($b, ':skunk:', '🦨'); + Smilies::add($b, ':kangaroo:', '🦘'); + Smilies::add($b, ':badger:', '🦡'); + Smilies::add($b, ':paw prints:', '🐾'); // Smilies::add($b, ':bunnyflowers:', '&#x;'); Smilies::add($b, ':chick:', '🐤'); Smilies::add($b, ':ladybird:', '🐞'); @@ -495,959 +492,958 @@ function unicode_smilies_smilies(array &$b) // Smilies::add($b, ':dragonfly:', '&#x;'); // animal-bird - Smilies::add($b, ':turkey:', '🦃'); - Smilies::add($b, ':chicken:', '🐔'); - Smilies::add($b, ':rooster:', '🐓'); - Smilies::add($b, ':hatching chick:', '🐣'); - Smilies::add($b, ':baby chick:', '🐤'); - Smilies::add($b, ':front-facing baby chick:', '🐥'); - Smilies::add($b, ':bird:', '🐦'); - Smilies::add($b, ':tux:', '🐧'); - Smilies::add($b, ':dove:', '🕊'); - Smilies::add($b, ':eagle:', '🦅'); - Smilies::add($b, ':duck:', '🦆'); - Smilies::add($b, ':swan:', '🦢'); - Smilies::add($b, ':owl:', '🦉'); - Smilies::add($b, ':flamingo:', '🦩'); - Smilies::add($b, ':peacock:', '🦚'); - Smilies::add($b, ':parrot:', '🦜'); + Smilies::add($b, ':turkey:', '🦃'); + Smilies::add($b, ':chicken:', '🐔'); + Smilies::add($b, ':rooster:', '🐓'); + Smilies::add($b, ':hatching chick:', '🐣'); + Smilies::add($b, ':baby chick:', '🐤'); + Smilies::add($b, ':front-facing baby chick:', '🐥'); + Smilies::add($b, ':bird:', '🐦'); + Smilies::add($b, ':tux:', '🐧'); + Smilies::add($b, ':dove:', '🕊'); + Smilies::add($b, ':eagle:', '🦅'); + Smilies::add($b, ':duck:', '🦆'); + Smilies::add($b, ':swan:', '🦢'); + Smilies::add($b, ':owl:', '🦉'); + Smilies::add($b, ':flamingo:', '🦩'); + Smilies::add($b, ':peacock:', '🦚'); + Smilies::add($b, ':parrot:', '🦜'); // animal-amphibian - Smilies::add($b, ':frog:', '🐸'); + Smilies::add($b, ':frog:', '🐸'); // animal-reptile - Smilies::add($b, ':crocodile:', '🐊'); - Smilies::add($b, ':turtle:', '🐢'); - Smilies::add($b, ':lizard:', '🦎'); - Smilies::add($b, ':snake:', '🐍'); - Smilies::add($b, ':dragon face:', '🐲'); - Smilies::add($b, ':dragon:', '🐉'); + Smilies::add($b, ':crocodile:', '🐊'); + Smilies::add($b, ':turtle:', '🐢'); + Smilies::add($b, ':lizard:', '🦎'); + Smilies::add($b, ':snake:', '🐍'); + Smilies::add($b, ':dragon face:', '🐲'); + Smilies::add($b, ':dragon:', '🐉'); Smilies::add($b, ':draco:', '🐉'); - Smilies::add($b, ':sauropod:', '🦕'); - Smilies::add($b, ':T-Rex:', '🦖'); + Smilies::add($b, ':sauropod:', '🦕'); + Smilies::add($b, ':T-Rex:', '🦖'); // animal-marine - Smilies::add($b, ':spouting whale:', '🐳'); - Smilies::add($b, ':whale:', '🐋'); - Smilies::add($b, ':dolphin:', '🐬'); - Smilies::add($b, ':fish:', '🐟'); - Smilies::add($b, ':tropical fish:', '🐠'); - Smilies::add($b, ':blowfish:', '🐡'); - Smilies::add($b, ':shark:', '🦈'); - Smilies::add($b, ':octopus:', '🐙'); - Smilies::add($b, ':spiral shell:', '🐚'); + Smilies::add($b, ':spouting whale:', '🐳'); + Smilies::add($b, ':whale:', '🐋'); + Smilies::add($b, ':dolphin:', '🐬'); + Smilies::add($b, ':fish:', '🐟'); + Smilies::add($b, ':tropical fish:', '🐠'); + Smilies::add($b, ':blowfish:', '🐡'); + Smilies::add($b, ':shark:', '🦈'); + Smilies::add($b, ':octopus:', '🐙'); + Smilies::add($b, ':spiral shell:', '🐚'); // animal-bug - Smilies::add($b, ':snail:', '🐌'); - Smilies::add($b, ':butterfly:', '🦋'); - Smilies::add($b, ':bug:', '🐛'); - Smilies::add($b, ':ant:', '🐜'); - Smilies::add($b, ':honeybee:', '🐝'); - Smilies::add($b, ':lady beetle:', '🐞'); - Smilies::add($b, ':cricket:', '🦗'); - Smilies::add($b, ':spider:', '🕷'); - Smilies::add($b, ':spider web:', '🕸'); - Smilies::add($b, ':scorpion:', '🦂'); - Smilies::add($b, ':mosquito:', '🦟'); - Smilies::add($b, ':microbe:', '🦠'); + Smilies::add($b, ':snail:', '🐌'); + Smilies::add($b, ':butterfly:', '🦋'); + Smilies::add($b, ':bug:', '🐛'); + Smilies::add($b, ':ant:', '🐜'); + Smilies::add($b, ':honeybee:', '🐝'); + Smilies::add($b, ':lady beetle:', '🐞'); + Smilies::add($b, ':cricket:', '🦗'); + Smilies::add($b, ':spider:', '🕷'); + Smilies::add($b, ':spider web:', '🕸'); + Smilies::add($b, ':scorpion:', '🦂'); + Smilies::add($b, ':mosquito:', '🦟'); + Smilies::add($b, ':microbe:', '🦠'); // plant-flower - Smilies::add($b, ':bouquet:', '💐'); - Smilies::add($b, ':cherry blossom:', '🌸'); - Smilies::add($b, ':white flower:', '💮'); - Smilies::add($b, ':rosette:', '🏵'); - Smilies::add($b, ':rose:', '🌹'); - Smilies::add($b, ':wilted flower:', '🥀'); - Smilies::add($b, ':hibiscus:', '🌺'); - Smilies::add($b, ':sunflower:', '🌻'); - Smilies::add($b, ':blossom:', '🌼'); - Smilies::add($b, ':tulip:', '🌷'); + Smilies::add($b, ':bouquet:', '💐'); + Smilies::add($b, ':cherry blossom:', '🌸'); + Smilies::add($b, ':white flower:', '💮'); + Smilies::add($b, ':rosette:', '🏵'); + Smilies::add($b, ':rose:', '🌹'); + Smilies::add($b, ':wilted flower:', '🥀'); + Smilies::add($b, ':hibiscus:', '🌺'); + Smilies::add($b, ':sunflower:', '🌻'); + Smilies::add($b, ':blossom:', '🌼'); + Smilies::add($b, ':tulip:', '🌷'); // plant-other - Smilies::add($b, ':seedling:', '🌱'); - Smilies::add($b, ':evergreen tree:', '🌲'); - Smilies::add($b, ':deciduous tree:', '🌳'); - Smilies::add($b, ':palm tree:', '🌴'); - Smilies::add($b, ':cactus:', '🌵'); - Smilies::add($b, ':sheaf of rice:', '🌾'); - Smilies::add($b, ':herb:', '🌿'); - Smilies::add($b, ':shamrock:', '☘'); - Smilies::add($b, ':four leaf clover:', '🍀'); - Smilies::add($b, ':maple leaf:', '🍁'); - Smilies::add($b, ':fallen leaf:', '🍂'); - Smilies::add($b, ':leaf fluttering in wind:', '🍃'); + Smilies::add($b, ':seedling:', '🌱'); + Smilies::add($b, ':evergreen tree:', '🌲'); + Smilies::add($b, ':deciduous tree:', '🌳'); + Smilies::add($b, ':palm tree:', '🌴'); + Smilies::add($b, ':cactus:', '🌵'); + Smilies::add($b, ':sheaf of rice:', '🌾'); + Smilies::add($b, ':herb:', '🌿'); + Smilies::add($b, ':shamrock:', '☘'); + Smilies::add($b, ':four leaf clover:', '🍀'); + Smilies::add($b, ':maple leaf:', '🍁'); + Smilies::add($b, ':fallen leaf:', '🍂'); + Smilies::add($b, ':leaf fluttering in wind:', '🍃'); // Food & Drink // food-fruit - Smilies::add($b, ':grapes:', '🍇'); - Smilies::add($b, ':melon:', '🍈'); - Smilies::add($b, ':watermelon:', '🍉'); - Smilies::add($b, ':tangerine:', '🍊'); - Smilies::add($b, ':lemon:', '🍋'); - Smilies::add($b, ':banana:', '🍌'); - Smilies::add($b, ':pineapple:', '🍍'); - Smilies::add($b, ':mango:', '🥭'); - Smilies::add($b, ':red apple:', '🍎'); + Smilies::add($b, ':grapes:', '🍇'); + Smilies::add($b, ':melon:', '🍈'); + Smilies::add($b, ':watermelon:', '🍉'); + Smilies::add($b, ':tangerine:', '🍊'); + Smilies::add($b, ':lemon:', '🍋'); + Smilies::add($b, ':banana:', '🍌'); + Smilies::add($b, ':pineapple:', '🍍'); + Smilies::add($b, ':mango:', '🥭'); + Smilies::add($b, ':red apple:', '🍎'); Smilies::add($b, ':apple:', '🍎'); - Smilies::add($b, ':green apple:', '🍏'); - Smilies::add($b, ':pear:', '🍐'); - Smilies::add($b, ':peach:', '🍑'); - Smilies::add($b, ':cherries:', '🍒'); - Smilies::add($b, ':strawberry:', '🍓'); - Smilies::add($b, ':kiwi fruit:', '🥝'); - Smilies::add($b, ':tomato:', '🍅'); - Smilies::add($b, ':coconut:', '🥥'); + Smilies::add($b, ':green apple:', '🍏'); + Smilies::add($b, ':pear:', '🍐'); + Smilies::add($b, ':peach:', '🍑'); + Smilies::add($b, ':cherries:', '🍒'); + Smilies::add($b, ':strawberry:', '🍓'); + Smilies::add($b, ':kiwi fruit:', '🥝'); + Smilies::add($b, ':tomato:', '🍅'); + Smilies::add($b, ':coconut:', '🥥'); // food-vegetable - Smilies::add($b, ':avocado:', '🥑'); - Smilies::add($b, ':eggplant:', '🍆'); - Smilies::add($b, ':potato:', '🥔'); - Smilies::add($b, ':carrot:', '🥕'); - Smilies::add($b, ':ear of corn:', '🌽'); - Smilies::add($b, ':hot pepper:', '🌶'); - Smilies::add($b, ':cucumber:', '🥒'); - Smilies::add($b, ':leafy green:', '🥬'); - Smilies::add($b, ':broccoli:', '🥦'); - Smilies::add($b, ':garlic:', '🧄'); - Smilies::add($b, ':onion:', '🧅'); - Smilies::add($b, ':mushroom:', '🍄'); - Smilies::add($b, ':peanuts:', '🥜'); - Smilies::add($b, ':chestnut:', '🌰'); + Smilies::add($b, ':avocado:', '🥑'); + Smilies::add($b, ':eggplant:', '🍆'); + Smilies::add($b, ':potato:', '🥔'); + Smilies::add($b, ':carrot:', '🥕'); + Smilies::add($b, ':ear of corn:', '🌽'); + Smilies::add($b, ':hot pepper:', '🌶'); + Smilies::add($b, ':cucumber:', '🥒'); + Smilies::add($b, ':leafy green:', '🥬'); + Smilies::add($b, ':broccoli:', '🥦'); + Smilies::add($b, ':garlic:', '🧄'); + Smilies::add($b, ':onion:', '🧅'); + Smilies::add($b, ':mushroom:', '🍄'); + Smilies::add($b, ':peanuts:', '🥜'); + Smilies::add($b, ':chestnut:', '🌰'); // food-prepared - Smilies::add($b, ':bread:', '🍞'); - Smilies::add($b, ':croissant:', '🥐'); - Smilies::add($b, ':baguette bread:', '🥖'); - Smilies::add($b, ':pretzel:', '🥨'); - Smilies::add($b, ':bagel:', '🥯'); - Smilies::add($b, ':pancakes:', '🥞'); - Smilies::add($b, ':waffle:', '🧇'); - Smilies::add($b, ':cheese wedge:', '🧀'); - Smilies::add($b, ':meat on bone:', '🍖'); - Smilies::add($b, ':poultry leg:', '🍗'); - Smilies::add($b, ':cut of meat:', '🥩'); - Smilies::add($b, ':bacon:', '🥓'); - Smilies::add($b, ':hamburger:', '🍔'); - Smilies::add($b, ':french fries:', '🍟'); - Smilies::add($b, ':pizza:', '🍕'); - Smilies::add($b, ':hot dog:', '🌭'); - Smilies::add($b, ':sandwich:', '🥪'); - Smilies::add($b, ':taco:', '🌮'); - Smilies::add($b, ':burrito:', '🌯'); - Smilies::add($b, ':stuffed flatbread:', '🥙'); - Smilies::add($b, ':falafel:', '🧆'); - Smilies::add($b, ':egg:', '🥚'); - Smilies::add($b, ':cooking:', '🍳'); + Smilies::add($b, ':bread:', '🍞'); + Smilies::add($b, ':croissant:', '🥐'); + Smilies::add($b, ':baguette bread:', '🥖'); + Smilies::add($b, ':pretzel:', '🥨'); + Smilies::add($b, ':bagel:', '🥯'); + Smilies::add($b, ':pancakes:', '🥞'); + Smilies::add($b, ':waffle:', '🧇'); + Smilies::add($b, ':cheese wedge:', '🧀'); + Smilies::add($b, ':meat on bone:', '🍖'); + Smilies::add($b, ':poultry leg:', '🍗'); + Smilies::add($b, ':cut of meat:', '🥩'); + Smilies::add($b, ':bacon:', '🥓'); + Smilies::add($b, ':hamburger:', '🍔'); + Smilies::add($b, ':french fries:', '🍟'); + Smilies::add($b, ':pizza:', '🍕'); + Smilies::add($b, ':hot dog:', '🌭'); + Smilies::add($b, ':sandwich:', '🥪'); + Smilies::add($b, ':taco:', '🌮'); + Smilies::add($b, ':burrito:', '🌯'); + Smilies::add($b, ':stuffed flatbread:', '🥙'); + Smilies::add($b, ':falafel:', '🧆'); + Smilies::add($b, ':egg:', '🥚'); + Smilies::add($b, ':cooking:', '🍳'); Smilies::add($b, ':fryegg:', '🍳'); - Smilies::add($b, ':shallow pan of food:', '🥘'); - Smilies::add($b, ':pot of food:', '🍲'); - Smilies::add($b, ':bowl with spoon:', '🥣'); - Smilies::add($b, ':green salad:', '🥗'); - Smilies::add($b, ':popcorn:', '🍿'); - Smilies::add($b, ':butter:', '🧈'); - Smilies::add($b, ':salt:', '🧂'); - Smilies::add($b, ':canned food:', '🥫'); + Smilies::add($b, ':shallow pan of food:', '🥘'); + Smilies::add($b, ':pot of food:', '🍲'); + Smilies::add($b, ':bowl with spoon:', '🥣'); + Smilies::add($b, ':green salad:', '🥗'); + Smilies::add($b, ':popcorn:', '🍿'); + Smilies::add($b, ':butter:', '🧈'); + Smilies::add($b, ':salt:', '🧂'); + Smilies::add($b, ':canned food:', '🥫'); // food-asian - Smilies::add($b, ':bento box:', '🍱'); - Smilies::add($b, ':rice cracker:', '🍘'); - Smilies::add($b, ':rice ball:', '🍙'); - Smilies::add($b, ':cooked rice:', '🍚'); - Smilies::add($b, ':curry rice:', '🍛'); - Smilies::add($b, ':steaming bowl:', '🍜'); - Smilies::add($b, ':spaghetti:', '🍝'); - Smilies::add($b, ':roasted sweet potato:', '🍠'); - Smilies::add($b, ':oden:', '🍢'); - Smilies::add($b, ':sushi:', '🍣'); - Smilies::add($b, ':fried shrimp:', '🍤'); - Smilies::add($b, ':fish cake with swirl:', '🍥'); - Smilies::add($b, ':moon cake:', '🥮'); - Smilies::add($b, ':dango:', '🍡'); - Smilies::add($b, ':dumpling:', '🥟'); - Smilies::add($b, ':fortune cookie:', '🥠'); - Smilies::add($b, ':takeout box:', '🥡'); + Smilies::add($b, ':bento box:', '🍱'); + Smilies::add($b, ':rice cracker:', '🍘'); + Smilies::add($b, ':rice ball:', '🍙'); + Smilies::add($b, ':cooked rice:', '🍚'); + Smilies::add($b, ':curry rice:', '🍛'); + Smilies::add($b, ':steaming bowl:', '🍜'); + Smilies::add($b, ':spaghetti:', '🍝'); + Smilies::add($b, ':roasted sweet potato:', '🍠'); + Smilies::add($b, ':oden:', '🍢'); + Smilies::add($b, ':sushi:', '🍣'); + Smilies::add($b, ':fried shrimp:', '🍤'); + Smilies::add($b, ':fish cake with swirl:', '🍥'); + Smilies::add($b, ':moon cake:', '🥮'); + Smilies::add($b, ':dango:', '🍡'); + Smilies::add($b, ':dumpling:', '🥟'); + Smilies::add($b, ':fortune cookie:', '🥠'); + Smilies::add($b, ':takeout box:', '🥡'); // food-marine - Smilies::add($b, ':crab:', '🦀'); - Smilies::add($b, ':lobster:', '🦞'); - Smilies::add($b, ':shrimp:', '🦐'); - Smilies::add($b, ':squid:', '🦑'); -// Smilies::add($b, ':oyster:', '🦪'); + Smilies::add($b, ':crab:', '🦀'); + Smilies::add($b, ':lobster:', '🦞'); + Smilies::add($b, ':shrimp:', '🦐'); + Smilies::add($b, ':squid:', '🦑'); +// Smilies::add($b, ':oyster:', '🦪'); // food-sweet - Smilies::add($b, ':soft ice cream:', '🍦'); - Smilies::add($b, ':shaved ice:', '🍧'); - Smilies::add($b, ':ice cream:', '🍨'); - Smilies::add($b, ':doughnut:', '🍩'); - Smilies::add($b, ':cookie:', '🍪'); - Smilies::add($b, ':birthday cake:', '🎂'); - Smilies::add($b, ':shortcake:', '🍰'); + Smilies::add($b, ':soft ice cream:', '🍦'); + Smilies::add($b, ':shaved ice:', '🍧'); + Smilies::add($b, ':ice cream:', '🍨'); + Smilies::add($b, ':doughnut:', '🍩'); + Smilies::add($b, ':cookie:', '🍪'); + Smilies::add($b, ':birthday cake:', '🎂'); + Smilies::add($b, ':shortcake:', '🍰'); Smilies::add($b, ':cake:', '🍰'); - Smilies::add($b, ':cupcake:', '🧁'); - Smilies::add($b, ':pie:', '🥧'); - Smilies::add($b, ':chocolate bar:', '🍫'); - Smilies::add($b, ':candy:', '🍬'); - Smilies::add($b, ':lollipop:', '🍭'); - Smilies::add($b, ':custard:', '🍮'); - Smilies::add($b, ':honey pot:', '🍯'); + Smilies::add($b, ':cupcake:', '🧁'); + Smilies::add($b, ':pie:', '🥧'); + Smilies::add($b, ':chocolate bar:', '🍫'); + Smilies::add($b, ':candy:', '🍬'); + Smilies::add($b, ':lollipop:', '🍭'); + Smilies::add($b, ':custard:', '🍮'); + Smilies::add($b, ':honey pot:', '🍯'); -// drink - Smilies::add($b, ':baby bottle:', '🍼'); - Smilies::add($b, ':glass of milk:', '🥛'); - Smilies::add($b, ':hot beverage:', '☕'); +// drink + Smilies::add($b, ':baby bottle:', '🍼'); + Smilies::add($b, ':glass of milk:', '🥛'); + Smilies::add($b, ':hot beverage:', '☕'); Smilies::add($b, ':coffee:', '☕'); Smilies::add($b, ':tea:', '☕'); Smilies::add($b, ':tee:', '☕'); - Smilies::add($b, ':teacup without handle:', '🍵'); - Smilies::add($b, ':sake:', '🍶'); - Smilies::add($b, ':bottle with popping cork:', '🍾'); - Smilies::add($b, ':wine glass:', '🍷'); - Smilies::add($b, ':cocktail glass:', '🍸'); - Smilies::add($b, ':tropical drink:', '🍹'); - Smilies::add($b, ':beer mug:', '🍺'); + Smilies::add($b, ':teacup without handle:', '🍵'); + Smilies::add($b, ':sake:', '🍶'); + Smilies::add($b, ':bottle with popping cork:', '🍾'); + Smilies::add($b, ':wine glass:', '🍷'); + Smilies::add($b, ':cocktail glass:', '🍸'); + Smilies::add($b, ':tropical drink:', '🍹'); + Smilies::add($b, ':beer mug:', '🍺'); Smilies::add($b, ':beer:', '🍺'); Smilies::add($b, ':homebrew:', '🍺'); - Smilies::add($b, ':clinking beer mugs:', '🍻'); - Smilies::add($b, ':clinking glasses:', '🥂'); - Smilies::add($b, ':tumbler glass:', '🥃'); - Smilies::add($b, ':cup with straw:', '🥤'); -// Smilies::add($b, ':beverage box:', '🧃'); - Smilies::add($b, ':mate:', '🧉'); - Smilies::add($b, ':ice:', '🧊'); + Smilies::add($b, ':clinking beer mugs:', '🍻'); + Smilies::add($b, ':clinking glasses:', '🥂'); + Smilies::add($b, ':tumbler glass:', '🥃'); + Smilies::add($b, ':cup with straw:', '🥤'); +// Smilies::add($b, ':beverage box:', '🧃'); + Smilies::add($b, ':mate:', '🧉'); + Smilies::add($b, ':ice:', '🧊'); // dishware - Smilies::add($b, ':chopsticks:', '🥢'); - Smilies::add($b, ':fork and knife with plate:', '🍽'); - Smilies::add($b, ':fork and knife:', '🍴'); - Smilies::add($b, ':spoon:', '🥄'); - Smilies::add($b, ':kitchen knife:', '🔪'); - Smilies::add($b, ':amphora:', '🏺'); + Smilies::add($b, ':chopsticks:', '🥢'); + Smilies::add($b, ':fork and knife with plate:', '🍽'); + Smilies::add($b, ':fork and knife:', '🍴'); + Smilies::add($b, ':spoon:', '🥄'); + Smilies::add($b, ':kitchen knife:', '🔪'); + Smilies::add($b, ':amphora:', '🏺'); // Travel & Places // place-map - Smilies::add($b, ':globe showing Europe-Africa:', '🌍'); - Smilies::add($b, ':globe showing Americas:', '🌎'); - Smilies::add($b, ':globe showing Asia-Australia:', '🌏'); - Smilies::add($b, ':globe with meridians:', '🌐'); - Smilies::add($b, ':world map:', '🗺'); - Smilies::add($b, ':map of Japan:', '🗾'); - Smilies::add($b, ':compass:', '🧭'); + Smilies::add($b, ':globe showing Europe-Africa:', '🌍'); + Smilies::add($b, ':globe showing Americas:', '🌎'); + Smilies::add($b, ':globe showing Asia-Australia:', '🌏'); + Smilies::add($b, ':globe with meridians:', '🌐'); + Smilies::add($b, ':world map:', '🗺'); + Smilies::add($b, ':map of Japan:', '🗾'); + Smilies::add($b, ':compass:', '🧭'); // place-geographic - Smilies::add($b, ':snow-capped mountain:', '🏔'); - Smilies::add($b, ':mountain:', '⛰'); - Smilies::add($b, ':volcano:', '🌋'); - Smilies::add($b, ':mount fuji:', '🗻'); - Smilies::add($b, ':camping:', '🏕'); - Smilies::add($b, ':beach with umbrella:', '🏖'); - Smilies::add($b, ':desert:', '🏜'); - Smilies::add($b, ':desert island:', '🏝'); - Smilies::add($b, ':national park:', '🏞'); + Smilies::add($b, ':snow-capped mountain:', '🏔'); + Smilies::add($b, ':mountain:', '⛰'); + Smilies::add($b, ':volcano:', '🌋'); + Smilies::add($b, ':mount fuji:', '🗻'); + Smilies::add($b, ':camping:', '🏕'); + Smilies::add($b, ':beach with umbrella:', '🏖'); + Smilies::add($b, ':desert:', '🏜'); + Smilies::add($b, ':desert island:', '🏝'); + Smilies::add($b, ':national park:', '🏞'); // place-building - Smilies::add($b, ':stadium:', '🏟'); - Smilies::add($b, ':classical building:', '🏛'); - Smilies::add($b, ':building construction:', '🏗'); - Smilies::add($b, ':brick:', '🧱'); - Smilies::add($b, ':houses:', '🏘'); - Smilies::add($b, ':derelict house:', '🏚'); - Smilies::add($b, ':house:', '🏠'); - Smilies::add($b, ':house with garden:', '🏡'); - Smilies::add($b, ':office building:', '🏢'); - Smilies::add($b, ':Japanese post office:', '🏣'); - Smilies::add($b, ':post office:', '🏤'); - Smilies::add($b, ':hospital:', '🏥'); - Smilies::add($b, ':bank:', '🏦'); - Smilies::add($b, ':hotel:', '🏨'); - Smilies::add($b, ':love hotel:', '🏩'); - Smilies::add($b, ':convenience store:', '🏪'); - Smilies::add($b, ':school:', '🏫'); - Smilies::add($b, ':department store:', '🏬'); - Smilies::add($b, ':factory:', '🏭'); - Smilies::add($b, ':Japanese castle:', '🏯'); - Smilies::add($b, ':castle:', '🏰'); - Smilies::add($b, ':wedding:', '💒'); - Smilies::add($b, ':Tokyo tower:', '🗼'); - Smilies::add($b, ':Statue of Liberty:', '🗽'); - + Smilies::add($b, ':stadium:', '🏟'); + Smilies::add($b, ':classical building:', '🏛'); + Smilies::add($b, ':building construction:', '🏗'); + Smilies::add($b, ':brick:', '🧱'); + Smilies::add($b, ':houses:', '🏘'); + Smilies::add($b, ':derelict house:', '🏚'); + Smilies::add($b, ':house:', '🏠'); + Smilies::add($b, ':house with garden:', '🏡'); + Smilies::add($b, ':office building:', '🏢'); + Smilies::add($b, ':Japanese post office:', '🏣'); + Smilies::add($b, ':post office:', '🏤'); + Smilies::add($b, ':hospital:', '🏥'); + Smilies::add($b, ':bank:', '🏦'); + Smilies::add($b, ':hotel:', '🏨'); + Smilies::add($b, ':love hotel:', '🏩'); + Smilies::add($b, ':convenience store:', '🏪'); + Smilies::add($b, ':school:', '🏫'); + Smilies::add($b, ':department store:', '🏬'); + Smilies::add($b, ':factory:', '🏭'); + Smilies::add($b, ':Japanese castle:', '🏯'); + Smilies::add($b, ':castle:', '🏰'); + Smilies::add($b, ':wedding:', '💒'); + Smilies::add($b, ':Tokyo tower:', '🗼'); + Smilies::add($b, ':Statue of Liberty:', '🗽'); // place-religious - Smilies::add($b, ':church:', '⛪'); - Smilies::add($b, ':mosque:', '🕌'); -// Smilies::add($b, ':hindu temple:', '🛕'); - Smilies::add($b, ':synagogue:', '🕍'); - Smilies::add($b, ':shinto shrine:', '⛩'); - Smilies::add($b, ':kaaba:', '🕋'); + Smilies::add($b, ':church:', '⛪'); + Smilies::add($b, ':mosque:', '🕌'); +// Smilies::add($b, ':hindu temple:', '🛕'); + Smilies::add($b, ':synagogue:', '🕍'); + Smilies::add($b, ':shinto shrine:', '⛩'); + Smilies::add($b, ':kaaba:', '🕋'); // place-other - Smilies::add($b, ':fountain:', '⛲'); - Smilies::add($b, ':tent:', '⛺'); - Smilies::add($b, ':foggy:', '🌁'); - Smilies::add($b, ':night with stars:', '🌃'); - Smilies::add($b, ':cityscape:', '🏙'); - Smilies::add($b, ':sunrise over mountains:', '🌄'); - Smilies::add($b, ':sunrise:', '🌅'); - Smilies::add($b, ':cityscape at dusk:', '🌆'); - Smilies::add($b, ':sunset:', '🌇'); - Smilies::add($b, ':bridge at night:', '🌉'); - Smilies::add($b, ':hot springs:', '♨'); - Smilies::add($b, ':carousel horse:', '🎠'); - Smilies::add($b, ':ferris wheel:', '🎡'); - Smilies::add($b, ':roller coaster:', '🎢'); - Smilies::add($b, ':barber pole:', '💈'); - Smilies::add($b, ':circus tent:', '🎪'); + Smilies::add($b, ':fountain:', '⛲'); + Smilies::add($b, ':tent:', '⛺'); + Smilies::add($b, ':foggy:', '🌁'); + Smilies::add($b, ':night with stars:', '🌃'); + Smilies::add($b, ':cityscape:', '🏙'); + Smilies::add($b, ':sunrise over mountains:', '🌄'); + Smilies::add($b, ':sunrise:', '🌅'); + Smilies::add($b, ':cityscape at dusk:', '🌆'); + Smilies::add($b, ':sunset:', '🌇'); + Smilies::add($b, ':bridge at night:', '🌉'); + Smilies::add($b, ':hot springs:', '♨'); + Smilies::add($b, ':carousel horse:', '🎠'); + Smilies::add($b, ':ferris wheel:', '🎡'); + Smilies::add($b, ':roller coaster:', '🎢'); + Smilies::add($b, ':barber pole:', '💈'); + Smilies::add($b, ':circus tent:', '🎪'); // transport-ground - Smilies::add($b, ':locomotive:', '🚂'); - Smilies::add($b, ':railway car:', '🚃'); - Smilies::add($b, ':high-speed train:', '🚄'); - Smilies::add($b, ':bullet train:', '🚅'); - Smilies::add($b, ':train:', '🚆'); - Smilies::add($b, ':metro:', '🚇'); - Smilies::add($b, ':light rail:', '🚈'); - Smilies::add($b, ':station:', '🚉'); - Smilies::add($b, ':tram:', '🚊'); - Smilies::add($b, ':monorail:', '🚝'); - Smilies::add($b, ':mountain railway:', '🚞'); - Smilies::add($b, ':tram car:', '🚋'); - Smilies::add($b, ':bus:', '🚌'); - Smilies::add($b, ':oncoming bus:', '🚍'); - Smilies::add($b, ':trolleybus:', '🚎'); - Smilies::add($b, ':minibus:', '🚐'); - Smilies::add($b, ':ambulance:', '🚑'); - Smilies::add($b, ':fire engine:', '🚒'); - Smilies::add($b, ':police car:', '🚓'); - Smilies::add($b, ':oncoming police car:', '🚔'); - Smilies::add($b, ':taxi:', '🚕'); - Smilies::add($b, ':oncoming taxi:', '🚖'); - Smilies::add($b, ':automobile:', '🚗'); - Smilies::add($b, ':oncoming automobile:', '🚘'); - Smilies::add($b, ':sport utility vehicle:', '🚙'); - Smilies::add($b, ':delivery truck:', '🚚'); - Smilies::add($b, ':articulated lorry:', '🚛'); - Smilies::add($b, ':tractor:', '🚜'); - Smilies::add($b, ':racing car:', '🏎'); - Smilies::add($b, ':motorcycle:', '🏍'); - Smilies::add($b, ':motor scooter:', '🛵'); -// Smilies::add($b, ':manual wheelchair:', '🦽'); -// Smilies::add($b, ':motorized wheelchair:', '🦼'); -// Smilies::add($b, ':auto rickshaw:', '🛺'); - Smilies::add($b, ':bicycle:', '🚲'); - Smilies::add($b, ':kick scooter:', '🛴'); - Smilies::add($b, ':skateboard:', '🛹'); - Smilies::add($b, ':bus stop:', '🚏'); - Smilies::add($b, ':motorway:', '🛣'); - Smilies::add($b, ':railway track:', '🛤'); - Smilies::add($b, ':oil drum:', '🛢'); - Smilies::add($b, ':fuel pump:', '⛽'); - Smilies::add($b, ':police car light:', '🚨'); - Smilies::add($b, ':horizontal traffic light:', '🚥'); - Smilies::add($b, ':vertical traffic light:', '🚦'); - Smilies::add($b, ':stop sign:', '🛑'); - Smilies::add($b, ':construction:', '🚧'); + Smilies::add($b, ':locomotive:', '🚂'); + Smilies::add($b, ':railway car:', '🚃'); + Smilies::add($b, ':high-speed train:', '🚄'); + Smilies::add($b, ':bullet train:', '🚅'); + Smilies::add($b, ':train:', '🚆'); + Smilies::add($b, ':metro:', '🚇'); + Smilies::add($b, ':light rail:', '🚈'); + Smilies::add($b, ':station:', '🚉'); + Smilies::add($b, ':tram:', '🚊'); + Smilies::add($b, ':monorail:', '🚝'); + Smilies::add($b, ':mountain railway:', '🚞'); + Smilies::add($b, ':tram car:', '🚋'); + Smilies::add($b, ':bus:', '🚌'); + Smilies::add($b, ':oncoming bus:', '🚍'); + Smilies::add($b, ':trolleybus:', '🚎'); + Smilies::add($b, ':minibus:', '🚐'); + Smilies::add($b, ':ambulance:', '🚑'); + Smilies::add($b, ':fire engine:', '🚒'); + Smilies::add($b, ':police car:', '🚓'); + Smilies::add($b, ':oncoming police car:', '🚔'); + Smilies::add($b, ':taxi:', '🚕'); + Smilies::add($b, ':oncoming taxi:', '🚖'); + Smilies::add($b, ':automobile:', '🚗'); + Smilies::add($b, ':oncoming automobile:', '🚘'); + Smilies::add($b, ':sport utility vehicle:', '🚙'); + Smilies::add($b, ':delivery truck:', '🚚'); + Smilies::add($b, ':articulated lorry:', '🚛'); + Smilies::add($b, ':tractor:', '🚜'); + Smilies::add($b, ':racing car:', '🏎'); + Smilies::add($b, ':motorcycle:', '🏍'); + Smilies::add($b, ':motor scooter:', '🛵'); +// Smilies::add($b, ':manual wheelchair:', '🦽'); +// Smilies::add($b, ':motorized wheelchair:', '🦼'); +// Smilies::add($b, ':auto rickshaw:', '🛺'); + Smilies::add($b, ':bicycle:', '🚲'); + Smilies::add($b, ':kick scooter:', '🛴'); + Smilies::add($b, ':skateboard:', '🛹'); + Smilies::add($b, ':bus stop:', '🚏'); + Smilies::add($b, ':motorway:', '🛣'); + Smilies::add($b, ':railway track:', '🛤'); + Smilies::add($b, ':oil drum:', '🛢'); + Smilies::add($b, ':fuel pump:', '⛽'); + Smilies::add($b, ':police car light:', '🚨'); + Smilies::add($b, ':horizontal traffic light:', '🚥'); + Smilies::add($b, ':vertical traffic light:', '🚦'); + Smilies::add($b, ':stop sign:', '🛑'); + Smilies::add($b, ':construction:', '🚧'); // transport-water - Smilies::add($b, ':anchor:', '⚓'); - Smilies::add($b, ':sailboat:', '⛵'); - Smilies::add($b, ':canoe:', '🛶'); - Smilies::add($b, ':speedboat:', '🚤'); - Smilies::add($b, ':passenger ship:', '🛳'); - Smilies::add($b, ':ferry:', '⛴'); - Smilies::add($b, ':motor boat:', '🛥'); - Smilies::add($b, ':ship:', '🚢'); + Smilies::add($b, ':anchor:', '⚓'); + Smilies::add($b, ':sailboat:', '⛵'); + Smilies::add($b, ':canoe:', '🛶'); + Smilies::add($b, ':speedboat:', '🚤'); + Smilies::add($b, ':passenger ship:', '🛳'); + Smilies::add($b, ':ferry:', '⛴'); + Smilies::add($b, ':motor boat:', '🛥'); + Smilies::add($b, ':ship:', '🚢'); // transport-air - Smilies::add($b, ':airplane:', '✈'); - Smilies::add($b, ':small airplane:', '🛩'); - Smilies::add($b, ':airplane departure:', '🛫'); - Smilies::add($b, ':airplane arrival:', '🛬'); - Smilies::add($b, ':parachute:', '🪂'); - Smilies::add($b, ':seat:', '💺'); - Smilies::add($b, ':helicopter:', '🚁'); - Smilies::add($b, ':suspension railway:', '🚟'); - Smilies::add($b, ':mountain cableway:', '🚠'); - Smilies::add($b, ':aerial tramway:', '🚡'); - Smilies::add($b, ':satellite:', '🛰'); - Smilies::add($b, ':rocket:', '🚀'); - Smilies::add($b, ':flying saucer:', '🛸'); + Smilies::add($b, ':airplane:', '✈'); + Smilies::add($b, ':small airplane:', '🛩'); + Smilies::add($b, ':airplane departure:', '🛫'); + Smilies::add($b, ':airplane arrival:', '🛬'); + Smilies::add($b, ':parachute:', '🪂'); + Smilies::add($b, ':seat:', '💺'); + Smilies::add($b, ':helicopter:', '🚁'); + Smilies::add($b, ':suspension railway:', '🚟'); + Smilies::add($b, ':mountain cableway:', '🚠'); + Smilies::add($b, ':aerial tramway:', '🚡'); + Smilies::add($b, ':satellite:', '🛰'); + Smilies::add($b, ':rocket:', '🚀'); + Smilies::add($b, ':flying saucer:', '🛸'); // hotel - Smilies::add($b, ':bellhop bell:', '🛎'); - Smilies::add($b, ':luggage:', '🧳'); + Smilies::add($b, ':bellhop bell:', '🛎'); + Smilies::add($b, ':luggage:', '🧳'); // time - Smilies::add($b, ':hourglass done:', '⌛'); - Smilies::add($b, ':hourglass not done:', '⏳'); - Smilies::add($b, ':watch:', '⌚'); - Smilies::add($b, ':alarm clock:', '⏰'); - Smilies::add($b, ':stopwatch:', '⏱'); - Smilies::add($b, ':timer clock:', '⏲'); - Smilies::add($b, ':mantelpiece clock:', '🕰'); - Smilies::add($b, ':twelve o’clock:', '🕛'); - Smilies::add($b, ':twelve-thirty:', '🕧'); - Smilies::add($b, ':one o’clock:', '🕐'); - Smilies::add($b, ':one-thirty:', '🕜'); - Smilies::add($b, ':two o’clock:', '🕑'); - Smilies::add($b, ':two-thirty:', '🕝'); - Smilies::add($b, ':three o’clock:', '🕒'); - Smilies::add($b, ':three-thirty:', '🕞'); - Smilies::add($b, ':four o’clock:', '🕓'); - Smilies::add($b, ':four-thirty:', '🕟'); - Smilies::add($b, ':five o’clock:', '🕔'); - Smilies::add($b, ':five-thirty:', '🕠'); - Smilies::add($b, ':six o’clock:', '🕕'); - Smilies::add($b, ':six-thirty:', '🕡'); - Smilies::add($b, ':seven o’clock:', '🕖'); - Smilies::add($b, ':seven-thirty:', '🕢'); - Smilies::add($b, ':eight o’clock:', '🕗'); - Smilies::add($b, ':eight-thirty:', '🕣'); - Smilies::add($b, ':nine o’clock:', '🕘'); - Smilies::add($b, ':nine-thirty:', '🕤'); - Smilies::add($b, ':ten o’clock:', '🕙'); - Smilies::add($b, ':ten-thirty:', '🕥'); - Smilies::add($b, ':eleven o’clock:', '🕚'); - Smilies::add($b, ':eleven-thirty:', '🕦'); + Smilies::add($b, ':hourglass done:', '⌛'); + Smilies::add($b, ':hourglass not done:', '⏳'); + Smilies::add($b, ':watch:', '⌚'); + Smilies::add($b, ':alarm clock:', '⏰'); + Smilies::add($b, ':stopwatch:', '⏱'); + Smilies::add($b, ':timer clock:', '⏲'); + Smilies::add($b, ':mantelpiece clock:', '🕰'); + Smilies::add($b, ':twelve o’clock:', '🕛'); + Smilies::add($b, ':twelve-thirty:', '🕧'); + Smilies::add($b, ':one o’clock:', '🕐'); + Smilies::add($b, ':one-thirty:', '🕜'); + Smilies::add($b, ':two o’clock:', '🕑'); + Smilies::add($b, ':two-thirty:', '🕝'); + Smilies::add($b, ':three o’clock:', '🕒'); + Smilies::add($b, ':three-thirty:', '🕞'); + Smilies::add($b, ':four o’clock:', '🕓'); + Smilies::add($b, ':four-thirty:', '🕟'); + Smilies::add($b, ':five o’clock:', '🕔'); + Smilies::add($b, ':five-thirty:', '🕠'); + Smilies::add($b, ':six o’clock:', '🕕'); + Smilies::add($b, ':six-thirty:', '🕡'); + Smilies::add($b, ':seven o’clock:', '🕖'); + Smilies::add($b, ':seven-thirty:', '🕢'); + Smilies::add($b, ':eight o’clock:', '🕗'); + Smilies::add($b, ':eight-thirty:', '🕣'); + Smilies::add($b, ':nine o’clock:', '🕘'); + Smilies::add($b, ':nine-thirty:', '🕤'); + Smilies::add($b, ':ten o’clock:', '🕙'); + Smilies::add($b, ':ten-thirty:', '🕥'); + Smilies::add($b, ':eleven o’clock:', '🕚'); + Smilies::add($b, ':eleven-thirty:', '🕦'); // sky & weather - Smilies::add($b, ':new moon:', '🌑'); - Smilies::add($b, ':waxing crescent moon:', '🌒'); - Smilies::add($b, ':first quarter moon:', '🌓'); - Smilies::add($b, ':waxing gibbous moon:', '🌔'); - Smilies::add($b, ':full moon:', '🌕'); - Smilies::add($b, ':waning gibbous moon:', '🌖'); - Smilies::add($b, ':last quarter moon:', '🌗'); - Smilies::add($b, ':waning crescent moon:', '🌘'); - Smilies::add($b, ':crescent moon:', '🌙'); - Smilies::add($b, ':new moon face:', '🌚'); - Smilies::add($b, ':first quarter moon face:', '🌛'); - Smilies::add($b, ':last quarter moon face:', '🌜'); - Smilies::add($b, ':thermometer:', '🌡'); - Smilies::add($b, ':sun:', '☀'); - Smilies::add($b, ':full moon face:', '🌝'); - Smilies::add($b, ':sun with face:', '🌞'); - Smilies::add($b, ':ringed planet:', '🪐'); - Smilies::add($b, ':star:', '⭐'); - Smilies::add($b, ':glowing star:', '🌟'); - Smilies::add($b, ':shooting star:', '🌠'); - Smilies::add($b, ':milky way:', '🌌'); - Smilies::add($b, ':cloud:', '☁'); - Smilies::add($b, ':sun behind cloud:', '⛅'); - Smilies::add($b, ':cloud with lightning and rain:', '⛈'); - Smilies::add($b, ':sun behind small cloud:', '🌤'); - Smilies::add($b, ':sun behind large cloud:', '🌥'); - Smilies::add($b, ':sun behind rain cloud:', '🌦'); - Smilies::add($b, ':cloud with rain:', '🌧'); - Smilies::add($b, ':cloud with snow:', '🌨'); - Smilies::add($b, ':cloud with lightning:', '🌩'); - Smilies::add($b, ':tornado:', '🌪'); - Smilies::add($b, ':fog:', '🌫'); - Smilies::add($b, ':wind face:', '🌬'); - Smilies::add($b, ':cyclone:', '🌀'); - Smilies::add($b, ':rainbow:', '🌈'); - Smilies::add($b, ':closed umbrella:', '🌂'); - Smilies::add($b, ':umbrella:', '☂'); - Smilies::add($b, ':umbrella with rain drops:', '☔'); - Smilies::add($b, ':umbrella on ground:', '⛱'); - Smilies::add($b, ':high voltage:', '⚡'); - Smilies::add($b, ':snowflake:', '❄'); - Smilies::add($b, ':snowman:', '☃'); - Smilies::add($b, ':snowman without snow:', '⛄'); - Smilies::add($b, ':comet:', '☄'); - Smilies::add($b, ':fire:', '🔥'); - Smilies::add($b, ':droplet:', '💧'); - Smilies::add($b, ':water wave:', '🌊'); + Smilies::add($b, ':new moon:', '🌑'); + Smilies::add($b, ':waxing crescent moon:', '🌒'); + Smilies::add($b, ':first quarter moon:', '🌓'); + Smilies::add($b, ':waxing gibbous moon:', '🌔'); + Smilies::add($b, ':full moon:', '🌕'); + Smilies::add($b, ':waning gibbous moon:', '🌖'); + Smilies::add($b, ':last quarter moon:', '🌗'); + Smilies::add($b, ':waning crescent moon:', '🌘'); + Smilies::add($b, ':crescent moon:', '🌙'); + Smilies::add($b, ':new moon face:', '🌚'); + Smilies::add($b, ':first quarter moon face:', '🌛'); + Smilies::add($b, ':last quarter moon face:', '🌜'); + Smilies::add($b, ':thermometer:', '🌡'); + Smilies::add($b, ':sun:', '☀'); + Smilies::add($b, ':full moon face:', '🌝'); + Smilies::add($b, ':sun with face:', '🌞'); + Smilies::add($b, ':ringed planet:', '🪐'); + Smilies::add($b, ':star:', '⭐'); + Smilies::add($b, ':glowing star:', '🌟'); + Smilies::add($b, ':shooting star:', '🌠'); + Smilies::add($b, ':milky way:', '🌌'); + Smilies::add($b, ':cloud:', '☁'); + Smilies::add($b, ':sun behind cloud:', '⛅'); + Smilies::add($b, ':cloud with lightning and rain:', '⛈'); + Smilies::add($b, ':sun behind small cloud:', '🌤'); + Smilies::add($b, ':sun behind large cloud:', '🌥'); + Smilies::add($b, ':sun behind rain cloud:', '🌦'); + Smilies::add($b, ':cloud with rain:', '🌧'); + Smilies::add($b, ':cloud with snow:', '🌨'); + Smilies::add($b, ':cloud with lightning:', '🌩'); + Smilies::add($b, ':tornado:', '🌪'); + Smilies::add($b, ':fog:', '🌫'); + Smilies::add($b, ':wind face:', '🌬'); + Smilies::add($b, ':cyclone:', '🌀'); + Smilies::add($b, ':rainbow:', '🌈'); + Smilies::add($b, ':closed umbrella:', '🌂'); + Smilies::add($b, ':umbrella:', '☂'); + Smilies::add($b, ':umbrella with rain drops:', '☔'); + Smilies::add($b, ':umbrella on ground:', '⛱'); + Smilies::add($b, ':high voltage:', '⚡'); + Smilies::add($b, ':snowflake:', '❄'); + Smilies::add($b, ':snowman:', '☃'); + Smilies::add($b, ':snowman without snow:', '⛄'); + Smilies::add($b, ':comet:', '☄'); + Smilies::add($b, ':fire:', '🔥'); + Smilies::add($b, ':droplet:', '💧'); + Smilies::add($b, ':water wave:', '🌊'); // Activities // event - Smilies::add($b, ':jack-o-lantern:', '🎃'); - Smilies::add($b, ':Christmas tree:', '🎄'); - Smilies::add($b, ':fireworks:', '🎆'); - Smilies::add($b, ':sparkler:', '🎇'); - Smilies::add($b, ':firecracker:', '🧨'); - Smilies::add($b, ':sparkles:', '✨'); - Smilies::add($b, ':balloon:', '🎈'); - Smilies::add($b, ':party popper:', '🎉'); - Smilies::add($b, ':confetti ball:', '🎊'); - Smilies::add($b, ':tanabata tree:', '🎋'); - Smilies::add($b, ':pine decoration:', '🎍'); - Smilies::add($b, ':Japanese dolls:', '🎎'); - Smilies::add($b, ':carp streamer:', '🎏'); - Smilies::add($b, ':wind chime:', '🎐'); - Smilies::add($b, ':moon viewing ceremony:', '🎑'); - Smilies::add($b, ':red envelope:', '🧧'); - Smilies::add($b, ':ribbon:', '🎀'); - Smilies::add($b, ':wrapped gift:', '🎁'); - Smilies::add($b, ':reminder ribbon:', '🎗'); - Smilies::add($b, ':admission tickets:', '🎟'); - Smilies::add($b, ':ticket:', '🎫'); + Smilies::add($b, ':jack-o-lantern:', '🎃'); + Smilies::add($b, ':Christmas tree:', '🎄'); + Smilies::add($b, ':fireworks:', '🎆'); + Smilies::add($b, ':sparkler:', '🎇'); + Smilies::add($b, ':firecracker:', '🧨'); + Smilies::add($b, ':sparkles:', '✨'); + Smilies::add($b, ':balloon:', '🎈'); + Smilies::add($b, ':party popper:', '🎉'); + Smilies::add($b, ':confetti ball:', '🎊'); + Smilies::add($b, ':tanabata tree:', '🎋'); + Smilies::add($b, ':pine decoration:', '🎍'); + Smilies::add($b, ':Japanese dolls:', '🎎'); + Smilies::add($b, ':carp streamer:', '🎏'); + Smilies::add($b, ':wind chime:', '🎐'); + Smilies::add($b, ':moon viewing ceremony:', '🎑'); + Smilies::add($b, ':red envelope:', '🧧'); + Smilies::add($b, ':ribbon:', '🎀'); + Smilies::add($b, ':wrapped gift:', '🎁'); + Smilies::add($b, ':reminder ribbon:', '🎗'); + Smilies::add($b, ':admission tickets:', '🎟'); + Smilies::add($b, ':ticket:', '🎫'); // award-medal - Smilies::add($b, ':military medal:', '🎖'); - Smilies::add($b, ':trophy:', '🏆'); - Smilies::add($b, ':sports medal:', '🏅'); - Smilies::add($b, ':1st place medal:', '🥇'); - Smilies::add($b, ':2nd place medal:', '🥈'); - Smilies::add($b, ':3rd place medal:', '🥉'); + Smilies::add($b, ':military medal:', '🎖'); + Smilies::add($b, ':trophy:', '🏆'); + Smilies::add($b, ':sports medal:', '🏅'); + Smilies::add($b, ':1st place medal:', '🥇'); + Smilies::add($b, ':2nd place medal:', '🥈'); + Smilies::add($b, ':3rd place medal:', '🥉'); // sport - Smilies::add($b, ':soccer ball:', '⚽'); - Smilies::add($b, ':baseball:', '⚾'); - Smilies::add($b, ':softball:', '🥎'); - Smilies::add($b, ':basketball:', '🏀'); - Smilies::add($b, ':volleyball:', '🏐'); - Smilies::add($b, ':american football:', '🏈'); + Smilies::add($b, ':soccer ball:', '⚽'); + Smilies::add($b, ':baseball:', '⚾'); + Smilies::add($b, ':softball:', '🥎'); + Smilies::add($b, ':basketball:', '🏀'); + Smilies::add($b, ':volleyball:', '🏐'); + Smilies::add($b, ':american football:', '🏈'); Smilies::add($b, ':football:', '🏈'); - Smilies::add($b, ':rugby football:', '🏉'); - Smilies::add($b, ':tennis:', '🎾'); - Smilies::add($b, ':flying disc:', '🥏'); - Smilies::add($b, ':bowling:', '🎳'); - Smilies::add($b, ':cricket game:', '🏏'); - Smilies::add($b, ':field hockey:', '🏑'); - Smilies::add($b, ':ice hockey:', '🏒'); - Smilies::add($b, ':lacrosse:', '🥍'); - Smilies::add($b, ':ping pong:', '🏓'); - Smilies::add($b, ':badminton:', '🏸'); - Smilies::add($b, ':boxing glove:', '🥊'); - Smilies::add($b, ':martial arts uniform:', '🥋'); - Smilies::add($b, ':goal net:', '🥅'); - Smilies::add($b, ':flag in hole:', '⛳'); - Smilies::add($b, ':ice skate:', '⛸'); - Smilies::add($b, ':fishing pole:', '🎣'); -// Smilies::add($b, ':diving mask:', '🤿'); - Smilies::add($b, ':running shirt:', '🎽'); - Smilies::add($b, ':skis:', '🎿'); - Smilies::add($b, ':sled:', '🛷'); - Smilies::add($b, ':curling stone:', '🥌'); + Smilies::add($b, ':rugby football:', '🏉'); + Smilies::add($b, ':tennis:', '🎾'); + Smilies::add($b, ':flying disc:', '🥏'); + Smilies::add($b, ':bowling:', '🎳'); + Smilies::add($b, ':cricket game:', '🏏'); + Smilies::add($b, ':field hockey:', '🏑'); + Smilies::add($b, ':ice hockey:', '🏒'); + Smilies::add($b, ':lacrosse:', '🥍'); + Smilies::add($b, ':ping pong:', '🏓'); + Smilies::add($b, ':badminton:', '🏸'); + Smilies::add($b, ':boxing glove:', '🥊'); + Smilies::add($b, ':martial arts uniform:', '🥋'); + Smilies::add($b, ':goal net:', '🥅'); + Smilies::add($b, ':flag in hole:', '⛳'); + Smilies::add($b, ':ice skate:', '⛸'); + Smilies::add($b, ':fishing pole:', '🎣'); +// Smilies::add($b, ':diving mask:', '🤿'); + Smilies::add($b, ':running shirt:', '🎽'); + Smilies::add($b, ':skis:', '🎿'); + Smilies::add($b, ':sled:', '🛷'); + Smilies::add($b, ':curling stone:', '🥌'); Smilies::add($b, ':cycling:', '🚴'); Smilies::add($b, ':darts:', '🎯'); Smilies::add($b, ':fencing:', '🤺'); Smilies::add($b, ':juggling:', '🤹'); -// Smilies::add($b, ':skipping:', '&#x;'); -// Smilies::add($b, ':archery:', '&#x;'); +// Smilies::add($b, ':skipping:', '&#x;'); +// Smilies::add($b, ':archery:', '&#x;'); Smilies::add($b, ':surfing:', '🏄'); Smilies::add($b, ':snooker:', '🎱'); Smilies::add($b, ':horseriding:', '🏇'); // game - Smilies::add($b, ':direct hit:', '🎯'); - Smilies::add($b, ':yo-yo:', '🪀'); - Smilies::add($b, ':kite:', '🪁'); - Smilies::add($b, ':pool 8 ball:', '🎱'); - Smilies::add($b, ':crystal ball:', '🔮'); - Smilies::add($b, ':nazar amulet:', '🧿'); - Smilies::add($b, ':video game:', '🎮'); - Smilies::add($b, ':joystick:', '🕹'); - Smilies::add($b, ':slot machine:', '🎰'); - Smilies::add($b, ':game die:', '🎲'); - Smilies::add($b, ':puzzle piece:', '🧩'); - Smilies::add($b, ':teddy bear:', '🧸'); - Smilies::add($b, ':spade suit:', '♠'); - Smilies::add($b, ':heart suit:', '♥'); - Smilies::add($b, ':diamond suit:', '♦'); - Smilies::add($b, ':club suit:', '♣'); - Smilies::add($b, ':chess pawn:', '♟'); - Smilies::add($b, ':joker:', '🃏'); - Smilies::add($b, ':mahjong red dragon:', '🀄'); - Smilies::add($b, ':flower playing cards:', '🎴'); + Smilies::add($b, ':direct hit:', '🎯'); + Smilies::add($b, ':yo-yo:', '🪀'); + Smilies::add($b, ':kite:', '🪁'); + Smilies::add($b, ':pool 8 ball:', '🎱'); + Smilies::add($b, ':crystal ball:', '🔮'); + Smilies::add($b, ':nazar amulet:', '🧿'); + Smilies::add($b, ':video game:', '🎮'); + Smilies::add($b, ':joystick:', '🕹'); + Smilies::add($b, ':slot machine:', '🎰'); + Smilies::add($b, ':game die:', '🎲'); + Smilies::add($b, ':puzzle piece:', '🧩'); + Smilies::add($b, ':teddy bear:', '🧸'); + Smilies::add($b, ':spade suit:', '♠'); + Smilies::add($b, ':heart suit:', '♥'); + Smilies::add($b, ':diamond suit:', '♦'); + Smilies::add($b, ':club suit:', '♣'); + Smilies::add($b, ':chess pawn:', '♟'); + Smilies::add($b, ':joker:', '🃏'); + Smilies::add($b, ':mahjong red dragon:', '🀄'); + Smilies::add($b, ':flower playing cards:', '🎴'); // arts & crafts - Smilies::add($b, ':performing arts:', '🎭'); - Smilies::add($b, ':framed picture:', '🖼'); - Smilies::add($b, ':artist palette:', '🎨'); - Smilies::add($b, ':thread:', '🧵'); - Smilies::add($b, ':yarn:', '🧶'); + Smilies::add($b, ':performing arts:', '🎭'); + Smilies::add($b, ':framed picture:', '🖼'); + Smilies::add($b, ':artist palette:', '🎨'); + Smilies::add($b, ':thread:', '🧵'); + Smilies::add($b, ':yarn:', '🧶'); // Objects // clothing - Smilies::add($b, ':glasses:', '👓'); - Smilies::add($b, ':sunglasses:', '🕶'); - Smilies::add($b, ':goggles:', '🥽'); - Smilies::add($b, ':lab coat:', '🥼'); - Smilies::add($b, ':safety vest:', '🦺'); - Smilies::add($b, ':necktie:', '👔'); - Smilies::add($b, ':t-shirt:', '👕'); - Smilies::add($b, ':jeans:', '👖'); - Smilies::add($b, ':scarf:', '🧣'); - Smilies::add($b, ':gloves:', '🧤'); - Smilies::add($b, ':coat:', '🧥'); - Smilies::add($b, ':socks:', '🧦'); - Smilies::add($b, ':dress:', '👗'); - Smilies::add($b, ':kimono:', '👘'); - Smilies::add($b, ':sari:', '🥻'); - Smilies::add($b, ':one-piece swimsuit:', '🩱'); - Smilies::add($b, ':briefs:', '🩲'); - Smilies::add($b, ':shorts:', '🩳'); - Smilies::add($b, ':bikini:', '👙'); - Smilies::add($b, ':woman’s clothes:', '👚'); - Smilies::add($b, ':purse:', '👛'); - Smilies::add($b, ':handbag:', '👜'); - Smilies::add($b, ':clutch bag:', '👝'); - Smilies::add($b, ':shopping bags:', '🛍'); - Smilies::add($b, ':backpack:', '🎒'); - Smilies::add($b, ':man’s shoe:', '👞'); - Smilies::add($b, ':running shoe:', '👟'); - Smilies::add($b, ':hiking boot:', '🥾'); - Smilies::add($b, ':flat shoe:', '🥿'); - Smilies::add($b, ':high-heeled shoe:', '👠'); - Smilies::add($b, ':woman’s sandal:', '👡'); -// Smilies::add($b, ':ballet shoes:', '🩰'); - Smilies::add($b, ':woman’s boot:', '👢'); - Smilies::add($b, ':crown:', '👑'); - Smilies::add($b, ':woman’s hat:', '👒'); - Smilies::add($b, ':top hat:', '🎩'); - Smilies::add($b, ':graduation cap:', '🎓'); - Smilies::add($b, ':billed cap:', '🧢'); - Smilies::add($b, ':rescue worker’s helmet:', '⛑'); - Smilies::add($b, ':prayer beads:', '📿'); - Smilies::add($b, ':lipstick:', '💄'); - Smilies::add($b, ':ring:', '💍'); - Smilies::add($b, ':gem stone:', '💎'); + Smilies::add($b, ':glasses:', '👓'); + Smilies::add($b, ':sunglasses:', '🕶'); + Smilies::add($b, ':goggles:', '🥽'); + Smilies::add($b, ':lab coat:', '🥼'); + Smilies::add($b, ':safety vest:', '🦺'); + Smilies::add($b, ':necktie:', '👔'); + Smilies::add($b, ':t-shirt:', '👕'); + Smilies::add($b, ':jeans:', '👖'); + Smilies::add($b, ':scarf:', '🧣'); + Smilies::add($b, ':gloves:', '🧤'); + Smilies::add($b, ':coat:', '🧥'); + Smilies::add($b, ':socks:', '🧦'); + Smilies::add($b, ':dress:', '👗'); + Smilies::add($b, ':kimono:', '👘'); + Smilies::add($b, ':sari:', '🥻'); + Smilies::add($b, ':one-piece swimsuit:', '🩱'); + Smilies::add($b, ':briefs:', '🩲'); + Smilies::add($b, ':shorts:', '🩳'); + Smilies::add($b, ':bikini:', '👙'); + Smilies::add($b, ':woman’s clothes:', '👚'); + Smilies::add($b, ':purse:', '👛'); + Smilies::add($b, ':handbag:', '👜'); + Smilies::add($b, ':clutch bag:', '👝'); + Smilies::add($b, ':shopping bags:', '🛍'); + Smilies::add($b, ':backpack:', '🎒'); + Smilies::add($b, ':man’s shoe:', '👞'); + Smilies::add($b, ':running shoe:', '👟'); + Smilies::add($b, ':hiking boot:', '🥾'); + Smilies::add($b, ':flat shoe:', '🥿'); + Smilies::add($b, ':high-heeled shoe:', '👠'); + Smilies::add($b, ':woman’s sandal:', '👡'); +// Smilies::add($b, ':ballet shoes:', '🩰'); + Smilies::add($b, ':woman’s boot:', '👢'); + Smilies::add($b, ':crown:', '👑'); + Smilies::add($b, ':woman’s hat:', '👒'); + Smilies::add($b, ':top hat:', '🎩'); + Smilies::add($b, ':graduation cap:', '🎓'); + Smilies::add($b, ':billed cap:', '🧢'); + Smilies::add($b, ':rescue worker’s helmet:', '⛑'); + Smilies::add($b, ':prayer beads:', '📿'); + Smilies::add($b, ':lipstick:', '💄'); + Smilies::add($b, ':ring:', '💍'); + Smilies::add($b, ':gem stone:', '💎'); // sound - Smilies::add($b, ':muted speaker:', '🔇'); - Smilies::add($b, ':speaker low volume:', '🔈'); - Smilies::add($b, ':speaker medium volume:', '🔉'); - Smilies::add($b, ':speaker high volume:', '🔊'); - Smilies::add($b, ':loudspeaker:', '📢'); - Smilies::add($b, ':megaphone:', '📣'); - Smilies::add($b, ':postal horn:', '📯'); - Smilies::add($b, ':bell:', '🔔'); - Smilies::add($b, ':bell with slash:', '🔕'); + Smilies::add($b, ':muted speaker:', '🔇'); + Smilies::add($b, ':speaker low volume:', '🔈'); + Smilies::add($b, ':speaker medium volume:', '🔉'); + Smilies::add($b, ':speaker high volume:', '🔊'); + Smilies::add($b, ':loudspeaker:', '📢'); + Smilies::add($b, ':megaphone:', '📣'); + Smilies::add($b, ':postal horn:', '📯'); + Smilies::add($b, ':bell:', '🔔'); + Smilies::add($b, ':bell with slash:', '🔕'); // musik - Smilies::add($b, ':musical score:', '🎼'); - Smilies::add($b, ':musical note:', '🎵'); - Smilies::add($b, ':musical notes:', '🎶'); - Smilies::add($b, ':studio microphone:', '🎙'); - Smilies::add($b, ':level slider:', '🎚'); - Smilies::add($b, ':control knobs:', '🎛'); - Smilies::add($b, ':microphone:', '🎤'); - Smilies::add($b, ':headphone:', '🎧'); - Smilies::add($b, ':radio:', '📻'); + Smilies::add($b, ':musical score:', '🎼'); + Smilies::add($b, ':musical note:', '🎵'); + Smilies::add($b, ':musical notes:', '🎶'); + Smilies::add($b, ':studio microphone:', '🎙'); + Smilies::add($b, ':level slider:', '🎚'); + Smilies::add($b, ':control knobs:', '🎛'); + Smilies::add($b, ':microphone:', '🎤'); + Smilies::add($b, ':headphone:', '🎧'); + Smilies::add($b, ':radio:', '📻'); // musical-instrument - Smilies::add($b, ':saxophone:', '🎷'); - Smilies::add($b, ':guitar:', '🎸'); - Smilies::add($b, ':musical keyboard:', '🎹'); - Smilies::add($b, ':trumpet:', '🎺'); - Smilies::add($b, ':violin:', '🎻'); -// Smilies::add($b, ':banjo:', '🪕'); - Smilies::add($b, ':drum:', '🥁'); + Smilies::add($b, ':saxophone:', '🎷'); + Smilies::add($b, ':guitar:', '🎸'); + Smilies::add($b, ':musical keyboard:', '🎹'); + Smilies::add($b, ':trumpet:', '🎺'); + Smilies::add($b, ':violin:', '🎻'); +// Smilies::add($b, ':banjo:', '🪕'); + Smilies::add($b, ':drum:', '🥁'); // phone - Smilies::add($b, ':mobile phone:', '📱'); - Smilies::add($b, ':mobile phone with arrow:', '📲'); - Smilies::add($b, ':telephone:', '☎'); - Smilies::add($b, ':telephone receiver:', '📞'); - Smilies::add($b, ':pager:', '📟'); - Smilies::add($b, ':fax machine:', '📠'); + Smilies::add($b, ':mobile phone:', '📱'); + Smilies::add($b, ':mobile phone with arrow:', '📲'); + Smilies::add($b, ':telephone:', '☎'); + Smilies::add($b, ':telephone receiver:', '📞'); + Smilies::add($b, ':pager:', '📟'); + Smilies::add($b, ':fax machine:', '📠'); // computer - Smilies::add($b, ':battery:', '🔋'); - Smilies::add($b, ':electric plug:', '🔌'); - Smilies::add($b, ':laptop:', '💻'); - Smilies::add($b, ':desktop computer:', '🖥'); - Smilies::add($b, ':printer:', '🖨'); - Smilies::add($b, ':keyboard:', '⌨'); - Smilies::add($b, ':computer mouse:', '🖱'); - Smilies::add($b, ':trackball:', '🖲'); - Smilies::add($b, ':computer disk:', '💽'); - Smilies::add($b, ':floppy disk:', '💾'); - Smilies::add($b, ':optical disk:', '💿'); - Smilies::add($b, ':dvd:', '📀'); - Smilies::add($b, ':abacus:', '🧮'); + Smilies::add($b, ':battery:', '🔋'); + Smilies::add($b, ':electric plug:', '🔌'); + Smilies::add($b, ':laptop:', '💻'); + Smilies::add($b, ':desktop computer:', '🖥'); + Smilies::add($b, ':printer:', '🖨'); + Smilies::add($b, ':keyboard:', '⌨'); + Smilies::add($b, ':computer mouse:', '🖱'); + Smilies::add($b, ':trackball:', '🖲'); + Smilies::add($b, ':computer disk:', '💽'); + Smilies::add($b, ':floppy disk:', '💾'); + Smilies::add($b, ':optical disk:', '💿'); + Smilies::add($b, ':dvd:', '📀'); + Smilies::add($b, ':abacus:', '🧮'); // light & video - Smilies::add($b, ':movie camera:', '🎥'); - Smilies::add($b, ':film frames:', '🎞'); - Smilies::add($b, ':film projector:', '📽'); - Smilies::add($b, ':clapper board:', '🎬'); - Smilies::add($b, ':television:', '📺'); - Smilies::add($b, ':camera:', '📷'); - Smilies::add($b, ':camera with flash:', '📸'); - Smilies::add($b, ':video camera:', '📹'); - Smilies::add($b, ':videocassette:', '📼'); - Smilies::add($b, ':magnifying glass tilted left:', '🔍'); - Smilies::add($b, ':magnifying glass tilted right:', '🔎'); - Smilies::add($b, ':candle:', '🕯'); - Smilies::add($b, ':light bulb:', '💡'); - Smilies::add($b, ':flashlight:', '🔦'); - Smilies::add($b, ':red paper lantern:', '🏮'); -// Smilies::add($b, ':diya lamp:', '🪔'); + Smilies::add($b, ':movie camera:', '🎥'); + Smilies::add($b, ':film frames:', '🎞'); + Smilies::add($b, ':film projector:', '📽'); + Smilies::add($b, ':clapper board:', '🎬'); + Smilies::add($b, ':television:', '📺'); + Smilies::add($b, ':camera:', '📷'); + Smilies::add($b, ':camera with flash:', '📸'); + Smilies::add($b, ':video camera:', '📹'); + Smilies::add($b, ':videocassette:', '📼'); + Smilies::add($b, ':magnifying glass tilted left:', '🔍'); + Smilies::add($b, ':magnifying glass tilted right:', '🔎'); + Smilies::add($b, ':candle:', '🕯'); + Smilies::add($b, ':light bulb:', '💡'); + Smilies::add($b, ':flashlight:', '🔦'); + Smilies::add($b, ':red paper lantern:', '🏮'); +// Smilies::add($b, ':diya lamp:', '🪔'); // book-paper - Smilies::add($b, ':notebook with decorative cover:', '📔'); - Smilies::add($b, ':closed book:', '📕'); - Smilies::add($b, ':open book:', '📖'); - Smilies::add($b, ':green book:', '📗'); - Smilies::add($b, ':blue book:', '📘'); - Smilies::add($b, ':orange book:', '📙'); - Smilies::add($b, ':books:', '📚'); - Smilies::add($b, ':notebook:', '📓'); - Smilies::add($b, ':ledger:', '📒'); - Smilies::add($b, ':page with curl:', '📃'); - Smilies::add($b, ':scroll:', '📜'); - Smilies::add($b, ':page facing up:', '📄'); - Smilies::add($b, ':newspaper:', '📰'); - Smilies::add($b, ':rolled-up newspaper:', '🗞'); - Smilies::add($b, ':bookmark tabs:', '📑'); - Smilies::add($b, ':bookmark:', '🔖'); - Smilies::add($b, ':label:', '🏷'); + Smilies::add($b, ':notebook with decorative cover:', '📔'); + Smilies::add($b, ':closed book:', '📕'); + Smilies::add($b, ':open book:', '📖'); + Smilies::add($b, ':green book:', '📗'); + Smilies::add($b, ':blue book:', '📘'); + Smilies::add($b, ':orange book:', '📙'); + Smilies::add($b, ':books:', '📚'); + Smilies::add($b, ':notebook:', '📓'); + Smilies::add($b, ':ledger:', '📒'); + Smilies::add($b, ':page with curl:', '📃'); + Smilies::add($b, ':scroll:', '📜'); + Smilies::add($b, ':page facing up:', '📄'); + Smilies::add($b, ':newspaper:', '📰'); + Smilies::add($b, ':rolled-up newspaper:', '🗞'); + Smilies::add($b, ':bookmark tabs:', '📑'); + Smilies::add($b, ':bookmark:', '🔖'); + Smilies::add($b, ':label:', '🏷'); // money - Smilies::add($b, ':money bag:', '💰'); - Smilies::add($b, ':yen banknote:', '💴'); - Smilies::add($b, ':dollar banknote:', '💵'); - Smilies::add($b, ':euro banknote:', '💶'); - Smilies::add($b, ':pound banknote:', '💷'); - Smilies::add($b, ':money with wings:', '💸'); - Smilies::add($b, ':credit card:', '💳'); - Smilies::add($b, ':receipt:', '🧾'); - Smilies::add($b, ':chart increasing with yen:', '💹'); + Smilies::add($b, ':money bag:', '💰'); + Smilies::add($b, ':yen banknote:', '💴'); + Smilies::add($b, ':dollar banknote:', '💵'); + Smilies::add($b, ':euro banknote:', '💶'); + Smilies::add($b, ':pound banknote:', '💷'); + Smilies::add($b, ':money with wings:', '💸'); + Smilies::add($b, ':credit card:', '💳'); + Smilies::add($b, ':receipt:', '🧾'); + Smilies::add($b, ':chart increasing with yen:', '💹'); // mail - Smilies::add($b, ':envelope:', '✉'); - Smilies::add($b, ':e-mail:', '📧'); - Smilies::add($b, ':incoming envelope:', '📨'); - Smilies::add($b, ':envelope with arrow:', '📩'); - Smilies::add($b, ':outbox tray:', '📤'); - Smilies::add($b, ':inbox tray:', '📥'); - Smilies::add($b, ':package:', '📦'); - Smilies::add($b, ':closed mailbox with raised flag:', '📫'); - Smilies::add($b, ':closed mailbox with lowered flag:', '📪'); - Smilies::add($b, ':open mailbox with raised flag:', '📬'); - Smilies::add($b, ':open mailbox with lowered flag:', '📭'); - Smilies::add($b, ':postbox:', '📮'); - Smilies::add($b, ':ballot box with ballot:', '🗳'); + Smilies::add($b, ':envelope:', '✉'); + Smilies::add($b, ':e-mail:', '📧'); + Smilies::add($b, ':incoming envelope:', '📨'); + Smilies::add($b, ':envelope with arrow:', '📩'); + Smilies::add($b, ':outbox tray:', '📤'); + Smilies::add($b, ':inbox tray:', '📥'); + Smilies::add($b, ':package:', '📦'); + Smilies::add($b, ':closed mailbox with raised flag:', '📫'); + Smilies::add($b, ':closed mailbox with lowered flag:', '📪'); + Smilies::add($b, ':open mailbox with raised flag:', '📬'); + Smilies::add($b, ':open mailbox with lowered flag:', '📭'); + Smilies::add($b, ':postbox:', '📮'); + Smilies::add($b, ':ballot box with ballot:', '🗳'); // writing - Smilies::add($b, ':pencil:', '✏'); - Smilies::add($b, ':black nib:', '✒'); - Smilies::add($b, ':fountain pen:', '🖋'); - Smilies::add($b, ':pen:', '🖊'); - Smilies::add($b, ':paintbrush:', '🖌'); - Smilies::add($b, ':crayon:', '🖍'); - Smilies::add($b, ':memo:', '📝'); + Smilies::add($b, ':pencil:', '✏'); + Smilies::add($b, ':black nib:', '✒'); + Smilies::add($b, ':fountain pen:', '🖋'); + Smilies::add($b, ':pen:', '🖊'); + Smilies::add($b, ':paintbrush:', '🖌'); + Smilies::add($b, ':crayon:', '🖍'); + Smilies::add($b, ':memo:', '📝'); // office - Smilies::add($b, ':briefcase:', '💼'); - Smilies::add($b, ':file folder:', '📁'); - Smilies::add($b, ':open file folder:', '📂'); - Smilies::add($b, ':card index dividers:', '🗂'); - Smilies::add($b, ':calendar:', '📅'); - Smilies::add($b, ':tear-off calendar:', '📆'); - Smilies::add($b, ':spiral notepad:', '🗒'); - Smilies::add($b, ':spiral calendar:', '🗓'); - Smilies::add($b, ':card index:', '📇'); - Smilies::add($b, ':chart increasing:', '📈'); - Smilies::add($b, ':chart decreasing:', '📉'); - Smilies::add($b, ':bar chart:', '📊'); - Smilies::add($b, ':clipboard:', '📋'); - Smilies::add($b, ':pushpin:', '📌'); - Smilies::add($b, ':round pushpin:', '📍'); - Smilies::add($b, ':paperclip:', '📎'); - Smilies::add($b, ':linked paperclips:', '🖇'); - Smilies::add($b, ':straight ruler:', '📏'); - Smilies::add($b, ':triangular ruler:', '📐'); - Smilies::add($b, ':scissors:', '✂'); - Smilies::add($b, ':card file box:', '🗃'); - Smilies::add($b, ':file cabinet:', '🗄'); - Smilies::add($b, ':wastebasket:', '🗑'); + Smilies::add($b, ':briefcase:', '💼'); + Smilies::add($b, ':file folder:', '📁'); + Smilies::add($b, ':open file folder:', '📂'); + Smilies::add($b, ':card index dividers:', '🗂'); + Smilies::add($b, ':calendar:', '📅'); + Smilies::add($b, ':tear-off calendar:', '📆'); + Smilies::add($b, ':spiral notepad:', '🗒'); + Smilies::add($b, ':spiral calendar:', '🗓'); + Smilies::add($b, ':card index:', '📇'); + Smilies::add($b, ':chart increasing:', '📈'); + Smilies::add($b, ':chart decreasing:', '📉'); + Smilies::add($b, ':bar chart:', '📊'); + Smilies::add($b, ':clipboard:', '📋'); + Smilies::add($b, ':pushpin:', '📌'); + Smilies::add($b, ':round pushpin:', '📍'); + Smilies::add($b, ':paperclip:', '📎'); + Smilies::add($b, ':linked paperclips:', '🖇'); + Smilies::add($b, ':straight ruler:', '📏'); + Smilies::add($b, ':triangular ruler:', '📐'); + Smilies::add($b, ':scissors:', '✂'); + Smilies::add($b, ':card file box:', '🗃'); + Smilies::add($b, ':file cabinet:', '🗄'); + Smilies::add($b, ':wastebasket:', '🗑'); // lock - Smilies::add($b, ':locked:', '🔒'); - Smilies::add($b, ':unlocked:', '🔓'); - Smilies::add($b, ':locked with pen:', '🔏'); - Smilies::add($b, ':locked with key:', '🔐'); - Smilies::add($b, ':key:', '🔑'); - Smilies::add($b, ':old key:', '🗝'); + Smilies::add($b, ':locked:', '🔒'); + Smilies::add($b, ':unlocked:', '🔓'); + Smilies::add($b, ':locked with pen:', '🔏'); + Smilies::add($b, ':locked with key:', '🔐'); + Smilies::add($b, ':key:', '🔑'); + Smilies::add($b, ':old key:', '🗝'); // tool - Smilies::add($b, ':hammer:', '🔨'); -// Smilies::add($b, ':axe:', '🪓'); - Smilies::add($b, ':pick:', '⛏'); - Smilies::add($b, ':hammer and pick:', '⚒'); - Smilies::add($b, ':hammer and wrench:', '🛠'); - Smilies::add($b, ':dagger:', '🗡'); + Smilies::add($b, ':hammer:', '🔨'); +// Smilies::add($b, ':axe:', '🪓'); + Smilies::add($b, ':pick:', '⛏'); + Smilies::add($b, ':hammer and pick:', '⚒'); + Smilies::add($b, ':hammer and wrench:', '🛠'); + Smilies::add($b, ':dagger:', '🗡'); Smilies::add($b, ':sabre:', '🗡'); - Smilies::add($b, ':crossed swords:', '⚔'); - Smilies::add($b, ':pistol:', '🔫'); - Smilies::add($b, ':bow and arrow:', '🏹'); - Smilies::add($b, ':shield:', '🛡'); - Smilies::add($b, ':wrench:', '🔧'); - Smilies::add($b, ':nut and bolt:', '🔩'); - Smilies::add($b, ':gear:', '⚙'); - Smilies::add($b, ':clamp:', '🗜'); - Smilies::add($b, ':balance scale:', '⚖'); - Smilies::add($b, ':white cane:', '🦯'); - Smilies::add($b, ':link:', '🔗'); - Smilies::add($b, ':chains:', '⛓'); - Smilies::add($b, ':toolbox:', '🧰'); - Smilies::add($b, ':magnet:', '🧲'); + Smilies::add($b, ':crossed swords:', '⚔'); + Smilies::add($b, ':pistol:', '🔫'); + Smilies::add($b, ':bow and arrow:', '🏹'); + Smilies::add($b, ':shield:', '🛡'); + Smilies::add($b, ':wrench:', '🔧'); + Smilies::add($b, ':nut and bolt:', '🔩'); + Smilies::add($b, ':gear:', '⚙'); + Smilies::add($b, ':clamp:', '🗜'); + Smilies::add($b, ':balance scale:', '⚖'); + Smilies::add($b, ':white cane:', '🦯'); + Smilies::add($b, ':link:', '🔗'); + Smilies::add($b, ':chains:', '⛓'); + Smilies::add($b, ':toolbox:', '🧰'); + Smilies::add($b, ':magnet:', '🧲'); // science - Smilies::add($b, ':alembic:', '⚗'); - Smilies::add($b, ':test tube:', '🧪'); - Smilies::add($b, ':petri dish:', '🧫'); - Smilies::add($b, ':dna:', '🧬'); - Smilies::add($b, ':microscope:', '🔬'); - Smilies::add($b, ':telescope:', '🔭'); - Smilies::add($b, ':satellite antenna:', '📡'); - Smilies::add($b, ':asterism:', '⁂'); - Smilies::add($b, ':outlines white star:', '⚝'); + Smilies::add($b, ':alembic:', '⚗'); + Smilies::add($b, ':test tube:', '🧪'); + Smilies::add($b, ':petri dish:', '🧫'); + Smilies::add($b, ':dna:', '🧬'); + Smilies::add($b, ':microscope:', '🔬'); + Smilies::add($b, ':telescope:', '🔭'); + Smilies::add($b, ':satellite antenna:', '📡'); + Smilies::add($b, ':asterism:', '⁂'); + Smilies::add($b, ':outlines white star:', '颅'); // medical - Smilies::add($b, ':syringe:', '💉'); - Smilies::add($b, ':drop of blood:', '🩸'); - Smilies::add($b, ':pill:', '💊'); - Smilies::add($b, ':adhesive bandage:', '🩹'); - Smilies::add($b, ':stethoscope:', '🩺'); + Smilies::add($b, ':syringe:', '💉'); + Smilies::add($b, ':drop of blood:', '🩸'); + Smilies::add($b, ':pill:', '💊'); + Smilies::add($b, ':adhesive bandage:', '🩹'); + Smilies::add($b, ':stethoscope:', '🩺'); // household - Smilies::add($b, ':door:', '🚪'); - Smilies::add($b, ':bed:', '🛏'); - Smilies::add($b, ':couch and lamp:', '🛋'); -// Smilies::add($b, ':chair:', '🪑'); - Smilies::add($b, ':toilet:', '🚽'); - Smilies::add($b, ':shower:', '🚿'); - Smilies::add($b, ':bathtub:', '🛁'); - Smilies::add($b, ':razor:', '🪒'); - Smilies::add($b, ':lotion bottle:', '🧴'); - Smilies::add($b, ':safety pin:', '🧷'); - Smilies::add($b, ':broom:', '🧹'); - Smilies::add($b, ':basket:', '🧺'); - Smilies::add($b, ':roll of paper:', '🧻'); - Smilies::add($b, ':soap:', '🧼'); - Smilies::add($b, ':sponge:', '🧽'); - Smilies::add($b, ':fire extinguisher:', '🧯'); - Smilies::add($b, ':shopping cart:', '🛒'); + Smilies::add($b, ':door:', '🚪'); + Smilies::add($b, ':bed:', '🛏'); + Smilies::add($b, ':couch and lamp:', '🛋'); +// Smilies::add($b, ':chair:', '🪑'); + Smilies::add($b, ':toilet:', '🚽'); + Smilies::add($b, ':shower:', '🚿'); + Smilies::add($b, ':bathtub:', '🛁'); + Smilies::add($b, ':razor:', '🪒'); + Smilies::add($b, ':lotion bottle:', '🧴'); + Smilies::add($b, ':safety pin:', '🧷'); + Smilies::add($b, ':broom:', '🧹'); + Smilies::add($b, ':basket:', '🧺'); + Smilies::add($b, ':roll of paper:', '🧻'); + Smilies::add($b, ':soap:', '🧼'); + Smilies::add($b, ':sponge:', '🧽'); + Smilies::add($b, ':fire extinguisher:', '🧯'); + Smilies::add($b, ':shopping cart:', '🛒'); // other-object - Smilies::add($b, ':cigarette:', '🚬'); - Smilies::add($b, ':coffin:', '⚰'); - Smilies::add($b, ':funeral urn:', '⚱'); - Smilies::add($b, ':moai:', '🗿'); + Smilies::add($b, ':cigarette:', '🚬'); + Smilies::add($b, ':coffin:', '⚰'); + Smilies::add($b, ':funeral urn:', '⚱'); + Smilies::add($b, ':moai:', '🗿'); // Symbols // transport-sign - Smilies::add($b, ':atm sign:', '🏧'); - Smilies::add($b, ':litter in bin sign:', '🚮'); - Smilies::add($b, ':potable water:', '🚰'); - Smilies::add($b, ':wheelchair symbol:', '♿'); - Smilies::add($b, ':men’s room:', '🚹'); - Smilies::add($b, ':women’s room:', '🚺'); - Smilies::add($b, ':restroom:', '🚻'); - Smilies::add($b, ':baby symbol:', '🚼'); - Smilies::add($b, ':water closet:', '🚾'); - Smilies::add($b, ':passport control:', '🛂'); - Smilies::add($b, ':customs:', '🛃'); - Smilies::add($b, ':baggage claim:', '🛄'); - Smilies::add($b, ':left luggage:', '🛅'); + Smilies::add($b, ':atm sign:', '🏧'); + Smilies::add($b, ':litter in bin sign:', '🚮'); + Smilies::add($b, ':potable water:', '🚰'); + Smilies::add($b, ':wheelchair symbol:', '♿'); + Smilies::add($b, ':men’s room:', '🚹'); + Smilies::add($b, ':women’s room:', '🚺'); + Smilies::add($b, ':restroom:', '🚻'); + Smilies::add($b, ':baby symbol:', '🚼'); + Smilies::add($b, ':water closet:', '🚾'); + Smilies::add($b, ':passport control:', '🛂'); + Smilies::add($b, ':customs:', '🛃'); + Smilies::add($b, ':baggage claim:', '🛄'); + Smilies::add($b, ':left luggage:', '🛅'); // warning - Smilies::add($b, ':warning:', '⚠'); - Smilies::add($b, ':children crossing:', '🚸'); - Smilies::add($b, ':no entry:', '⛔'); - Smilies::add($b, ':prohibited:', '🚫'); - Smilies::add($b, ':no bicycles:', '🚳'); - Smilies::add($b, ':no smoking:', '🚭'); - Smilies::add($b, ':no littering:', '🚯'); - Smilies::add($b, ':non-potable water:', '🚱'); - Smilies::add($b, ':no pedestrians:', '🚷'); - Smilies::add($b, ':no mobile phones:', '📵'); - Smilies::add($b, ':no one under eighteen:', '🔞'); - Smilies::add($b, ':radioactive:', '☢'); - Smilies::add($b, ':biohazard:', '☣'); + Smilies::add($b, ':warning:', '⚠'); + Smilies::add($b, ':children crossing:', '🚸'); + Smilies::add($b, ':no entry:', '⛔'); + Smilies::add($b, ':prohibited:', '🚫'); + Smilies::add($b, ':no bicycles:', '🚳'); + Smilies::add($b, ':no smoking:', '🚭'); + Smilies::add($b, ':no littering:', '🚯'); + Smilies::add($b, ':non-potable water:', '🚱'); + Smilies::add($b, ':no pedestrians:', '🚷'); + Smilies::add($b, ':no mobile phones:', '📵'); + Smilies::add($b, ':no one under eighteen:', '🔞'); + Smilies::add($b, ':radioactive:', '☢'); + Smilies::add($b, ':biohazard:', '☣'); Smilies::add($b, ':army:', '🪖'); // arrow - Smilies::add($b, ':up arrow:', '⬆'); - Smilies::add($b, ':up-right arrow:', '↗'); - Smilies::add($b, ':right arrow:', '➡'); - Smilies::add($b, ':down-right arrow:', '↘'); - Smilies::add($b, ':down arrow:', '⬇'); - Smilies::add($b, ':down-left arrow:', '↙'); - Smilies::add($b, ':left arrow:', '⬅'); - Smilies::add($b, ':up-left arrow:', '↖'); - Smilies::add($b, ':up-down arrow:', '↕'); - Smilies::add($b, ':left-right arrow:', '↔'); - Smilies::add($b, ':right arrow curving left:', '↩'); - Smilies::add($b, ':left arrow curving right:', '↪'); - Smilies::add($b, ':right arrow curving up:', '⤴'); - Smilies::add($b, ':right arrow curving down:', '⤵'); - Smilies::add($b, ':clockwise vertical arrows:', '🔃'); - Smilies::add($b, ':counterclockwise arrows button:', '🔄'); - Smilies::add($b, ':BACK arrow:', '🔙'); - Smilies::add($b, ':END arrow:', '🔚'); - Smilies::add($b, ':ON! arrow:', '🔛'); - Smilies::add($b, ':SOON arrow:', '🔜'); - Smilies::add($b, ':TOP arrow:', '🔝'); + Smilies::add($b, ':up arrow:', '⬆'); + Smilies::add($b, ':up-right arrow:', '↗'); + Smilies::add($b, ':right arrow:', '➡'); + Smilies::add($b, ':down-right arrow:', '↘'); + Smilies::add($b, ':down arrow:', '⬇'); + Smilies::add($b, ':down-left arrow:', '↙'); + Smilies::add($b, ':left arrow:', '⬅'); + Smilies::add($b, ':up-left arrow:', '↖'); + Smilies::add($b, ':up-down arrow:', '↕'); + Smilies::add($b, ':left-right arrow:', '↔'); + Smilies::add($b, ':right arrow curving left:', '↩'); + Smilies::add($b, ':left arrow curving right:', '↪'); + Smilies::add($b, ':right arrow curving up:', '⤴'); + Smilies::add($b, ':right arrow curving down:', '⤵'); + Smilies::add($b, ':clockwise vertical arrows:', '🔃'); + Smilies::add($b, ':counterclockwise arrows button:', '🔄'); + Smilies::add($b, ':BACK arrow:', '🔙'); + Smilies::add($b, ':END arrow:', '🔚'); + Smilies::add($b, ':ON! arrow:', '🔛'); + Smilies::add($b, ':SOON arrow:', '🔜'); + Smilies::add($b, ':TOP arrow:', '🔝'); // religion - Smilies::add($b, ':place of worship:', '🛐'); - Smilies::add($b, ':atom symbol:', '⚛'); - Smilies::add($b, ':om:', '🕉'); - Smilies::add($b, ':star of David:', '✡'); - Smilies::add($b, ':wheel of dharma:', '☸'); - Smilies::add($b, ':yin yang:', '☯'); - Smilies::add($b, ':latin cross:', '✝'); - Smilies::add($b, ':orthodox cross:', '☦'); - Smilies::add($b, ':star and crescent:', '☪'); - Smilies::add($b, ':peace symbol:', '☮'); - Smilies::add($b, ':menorah:', '🕎'); - Smilies::add($b, ':dotted six-pointed star:', '🔯'); + Smilies::add($b, ':place of worship:', '🛐'); + Smilies::add($b, ':atom symbol:', '⚛'); + Smilies::add($b, ':om:', '🕉'); + Smilies::add($b, ':star of David:', '✡'); + Smilies::add($b, ':wheel of dharma:', '☸'); + Smilies::add($b, ':yin yang:', '☯'); + Smilies::add($b, ':latin cross:', '✝'); + Smilies::add($b, ':orthodox cross:', '☦'); + Smilies::add($b, ':star and crescent:', '☪'); + Smilies::add($b, ':peace symbol:', '☮'); + Smilies::add($b, ':menorah:', '🕎'); + Smilies::add($b, ':dotted six-pointed star:', '🔯'); // zodiac - Smilies::add($b, ':Aries:', '♈'); - Smilies::add($b, ':Taurus:', '♉'); - Smilies::add($b, ':Gemini:', '♊'); - Smilies::add($b, ':Cancer:', '♋'); - Smilies::add($b, ':Leo:', '♌'); - Smilies::add($b, ':Virgo:', '♍'); - Smilies::add($b, ':Libra:', '♎'); - Smilies::add($b, ':Scorpio:', '♏'); - Smilies::add($b, ':Sagittarius:', '♐'); - Smilies::add($b, ':Capricorn:', '♑'); - Smilies::add($b, ':Aquarius:', '♒'); - Smilies::add($b, ':Pisces:', '♓'); - Smilies::add($b, ':Ophiuchus:', '⛎'); + Smilies::add($b, ':Aries:', '♈'); + Smilies::add($b, ':Taurus:', '♉'); + Smilies::add($b, ':Gemini:', '♊'); + Smilies::add($b, ':Cancer:', '♋'); + Smilies::add($b, ':Leo:', '♌'); + Smilies::add($b, ':Virgo:', '♍'); + Smilies::add($b, ':Libra:', '♎'); + Smilies::add($b, ':Scorpio:', '♏'); + Smilies::add($b, ':Sagittarius:', '♐'); + Smilies::add($b, ':Capricorn:', '♑'); + Smilies::add($b, ':Aquarius:', '♒'); + Smilies::add($b, ':Pisces:', '♓'); + Smilies::add($b, ':Ophiuchus:', '⛎'); // av-symbol - Smilies::add($b, ':shuffle tracks button:', '🔀'); - Smilies::add($b, ':repeat button:', '🔁'); - Smilies::add($b, ':repeat single button:', '🔂'); - Smilies::add($b, ':play button:', '▶'); - Smilies::add($b, ':fast-forward button:', '⏩'); - Smilies::add($b, ':next track button:', '⏭'); - Smilies::add($b, ':play or pause button:', '⏯'); - Smilies::add($b, ':reverse button:', '◀'); - Smilies::add($b, ':fast reverse button:', '⏪'); - Smilies::add($b, ':last track button:', '⏮'); - Smilies::add($b, ':upwards button:', '🔼'); - Smilies::add($b, ':fast up button:', '⏫'); - Smilies::add($b, ':downwards button:', '🔽'); - Smilies::add($b, ':fast down button:', '⏬'); - Smilies::add($b, ':pause button:', '⏸'); - Smilies::add($b, ':stop button:', '⏹'); - Smilies::add($b, ':record button:', '⏺'); - Smilies::add($b, ':eject button:', '⏏'); - Smilies::add($b, ':cinema:', '🎦'); - Smilies::add($b, ':dim button:', '🔅'); - Smilies::add($b, ':bright button:', '🔆'); - Smilies::add($b, ':antenna bars:', '📶'); - Smilies::add($b, ':vibration mode:', '📳'); - Smilies::add($b, ':mobile phone off:', '📴'); + Smilies::add($b, ':shuffle tracks button:', '🔀'); + Smilies::add($b, ':repeat button:', '🔁'); + Smilies::add($b, ':repeat single button:', '🔂'); + Smilies::add($b, ':play button:', '▶'); + Smilies::add($b, ':fast-forward button:', '⏩'); + Smilies::add($b, ':next track button:', '⏭'); + Smilies::add($b, ':play or pause button:', '⏯'); + Smilies::add($b, ':reverse button:', '◀'); + Smilies::add($b, ':fast reverse button:', '⏪'); + Smilies::add($b, ':last track button:', '⏮'); + Smilies::add($b, ':upwards button:', '🔼'); + Smilies::add($b, ':fast up button:', '⏫'); + Smilies::add($b, ':downwards button:', '🔽'); + Smilies::add($b, ':fast down button:', '⏬'); + Smilies::add($b, ':pause button:', '⏸'); + Smilies::add($b, ':stop button:', '⏹'); + Smilies::add($b, ':record button:', '⏺'); + Smilies::add($b, ':eject button:', '⏏'); + Smilies::add($b, ':cinema:', '🎦'); + Smilies::add($b, ':dim button:', '🔅'); + Smilies::add($b, ':bright button:', '🔆'); + Smilies::add($b, ':antenna bars:', '📶'); + Smilies::add($b, ':vibration mode:', '📳'); + Smilies::add($b, ':mobile phone off:', '📴'); // gender - Smilies::add($b, ':female sign:', '♀'); - Smilies::add($b, ':male sign:', '♂'); + Smilies::add($b, ':female sign:', '♀'); + Smilies::add($b, ':male sign:', '♂'); // math - Smilies::add($b, ':multiply:', '✖'); - Smilies::add($b, ':plus:', '➕'); - Smilies::add($b, ':minus:', '➖'); - Smilies::add($b, ':divide:', '➗'); - Smilies::add($b, ':infinity:', '♾'); + Smilies::add($b, ':multiply:', '✖'); + Smilies::add($b, ':plus:', '➕'); + Smilies::add($b, ':minus:', '➖'); + Smilies::add($b, ':divide:', '➗'); + Smilies::add($b, ':infinity:', '♾'); Smilies::add($b, ':kreisoperator:', '∘'); Smilies::add($b, ':leere menge:', '∅'); Smilies::add($b, ':rundung:', '≈'); @@ -1458,407 +1454,408 @@ function unicode_smilies_smilies(array &$b) Smilies::add($b, ':prozent:', '%'); // punctuation - Smilies::add($b, ':double exclamation mark:', '‼'); - Smilies::add($b, ':exclamation question mark:', '⁉'); - Smilies::add($b, ':question mark:', '❓'); - Smilies::add($b, ':white question mark:', '❔'); - Smilies::add($b, ':white exclamation mark:', '❕'); - Smilies::add($b, ':exclamation mark:', '❗'); - Smilies::add($b, ':wavy dash:', '〰'); + Smilies::add($b, ':double exclamation mark:', '‼'); + Smilies::add($b, ':exclamation question mark:', '⁉'); + Smilies::add($b, ':question mark:', '❓'); + Smilies::add($b, ':white question mark:', '❔'); + Smilies::add($b, ':white exclamation mark:', '❕'); + Smilies::add($b, ':exclamation mark:', '❗'); + Smilies::add($b, ':wavy dash:', '〰'); // currency - Smilies::add($b, ':currency exchange:', '💱'); - Smilies::add($b, ':heavy dollar sign:', '💲'); + Smilies::add($b, ':currency exchange:', '💱'); + Smilies::add($b, ':heavy dollar sign:', '💲'); // other-symbol - Smilies::add($b, ':medical symbol:', '⚕'); - Smilies::add($b, ':recycling symbol:', '♻'); - Smilies::add($b, ':fleur-de-lis:', '⚜'); - Smilies::add($b, ':trident emblem:', '🔱'); - Smilies::add($b, ':name badge:', '📛'); - Smilies::add($b, ':Japanese symbol for beginner:', '🔰'); - Smilies::add($b, ':hollow red circle:', '⭕'); - Smilies::add($b, ':check mark button:', '✅'); - Smilies::add($b, ':check box with check:', '☑'); - Smilies::add($b, ':check mark:', '✔'); - Smilies::add($b, ':cross mark:', '❌'); - Smilies::add($b, ':cross mark button:', '❎'); - Smilies::add($b, ':curly loop:', '➰'); - Smilies::add($b, ':double curly loop:', '➿'); - Smilies::add($b, ':part alternation mark:', '〽'); - Smilies::add($b, ':eight-spoked asterisk:', '✳'); - Smilies::add($b, ':eight-pointed star:', '✴'); - Smilies::add($b, ':sparkle:', '❇'); - Smilies::add($b, ':copyright:', '©'); - Smilies::add($b, ':registered:', '®'); - Smilies::add($b, ':trade mark:', '™'); + Smilies::add($b, ':medical symbol:', '⚕'); + Smilies::add($b, ':recycling symbol:', '♻'); + Smilies::add($b, ':fleur-de-lis:', '⚜'); + Smilies::add($b, ':trident emblem:', '🔱'); + Smilies::add($b, ':name badge:', '📛'); + Smilies::add($b, ':Japanese symbol for beginner:', '🔰'); + Smilies::add($b, ':hollow red circle:', '⭕'); + Smilies::add($b, ':check mark button:', '✅'); + Smilies::add($b, ':check box with check:', '☑'); + Smilies::add($b, ':check mark:', '✔'); + Smilies::add($b, ':cross mark:', '❌'); + Smilies::add($b, ':cross mark button:', '❎'); + Smilies::add($b, ':curly loop:', '➰'); + Smilies::add($b, ':double curly loop:', '➿'); + Smilies::add($b, ':part alternation mark:', '〽'); + Smilies::add($b, ':eight-spoked asterisk:', '✳'); + Smilies::add($b, ':eight-pointed star:', '✴'); + Smilies::add($b, ':sparkle:', '❇'); + Smilies::add($b, ':copyright:', '©'); + Smilies::add($b, ':registered:', '®'); + Smilies::add($b, ':trade mark:', '™'); // keycap - Smilies::add($b, ':keycap: #:', '#️⃣'); - Smilies::add($b, ':keycap: *:', '*️⃣'); - Smilies::add($b, ':keycap: 0:', '0️⃣'); - Smilies::add($b, ':keycap: 1:', '1️⃣'); - Smilies::add($b, ':keycap: 2:', '2️⃣'); - Smilies::add($b, ':keycap: 3:', '3️⃣'); - Smilies::add($b, ':keycap: 4:', '4️⃣'); - Smilies::add($b, ':keycap: 5:', '5️⃣'); - Smilies::add($b, ':keycap: 6:', '6️⃣'); - Smilies::add($b, ':keycap: 7:', '7️⃣'); - Smilies::add($b, ':keycap: 8:', '8️⃣'); - Smilies::add($b, ':keycap: 9:', '9️⃣'); - Smilies::add($b, ':keycap: 10:', '🔟'); + Smilies::add($b, ':keycap: #:', '#️⃣'); + Smilies::add($b, ':keycap: *:', '*️⃣'); + Smilies::add($b, ':keycap: 0:', '0️⃣'); + Smilies::add($b, ':keycap: 1:', '1️⃣'); + Smilies::add($b, ':keycap: 2:', '2️⃣'); + Smilies::add($b, ':keycap: 3:', '3️⃣'); + Smilies::add($b, ':keycap: 4:', '4️⃣'); + Smilies::add($b, ':keycap: 5:', '5️⃣'); + Smilies::add($b, ':keycap: 6:', '6️⃣'); + Smilies::add($b, ':keycap: 7:', '7️⃣'); + Smilies::add($b, ':keycap: 8:', '8️⃣'); + Smilies::add($b, ':keycap: 9:', '9️⃣'); + Smilies::add($b, ':keycap: 10:', '🔟'); // alphanum - Smilies::add($b, ':input latin uppercase:', '🔠'); - Smilies::add($b, ':input latin lowercase:', '🔡'); - Smilies::add($b, ':input numbers:', '🔢'); - Smilies::add($b, ':input symbols:', '🔣'); - Smilies::add($b, ':input latin letters:', '🔤'); - Smilies::add($b, ':A button (blood type):', '🅰'); - Smilies::add($b, ':AB button (blood type):', '🆎'); - Smilies::add($b, ':B button (blood type):', '🅱'); - Smilies::add($b, ':CL button:', '🆑'); - Smilies::add($b, ':COOL button:', '🆒'); + Smilies::add($b, ':input latin uppercase:', '🔠'); + Smilies::add($b, ':input latin lowercase:', '🔡'); + Smilies::add($b, ':input numbers:', '🔢'); + Smilies::add($b, ':input symbols:', '🔣'); + Smilies::add($b, ':input latin letters:', '🔤'); + Smilies::add($b, ':A button (blood type):', '🅰'); + Smilies::add($b, ':AB button (blood type):', '🆎'); + Smilies::add($b, ':B button (blood type):', '🅱'); + Smilies::add($b, ':CL button:', '🆑'); + Smilies::add($b, ':COOL button:', '🆒'); Smilies::add($b, ':cool:', '🆒'); - Smilies::add($b, ':FREE button:', '🆓'); - Smilies::add($b, ':information:', 'ℹ'); - Smilies::add($b, ':ID button:', '🆔'); - Smilies::add($b, ':circled M:', 'Ⓜ'); - Smilies::add($b, ':NEW button:', '🆕'); - Smilies::add($b, ':NG button:', '🆖'); - Smilies::add($b, ':O button (blood type):', '🅾'); - Smilies::add($b, ':OK button:', '🆗'); - Smilies::add($b, ':P button:', '🅿'); - Smilies::add($b, ':SOS button:', '🆘'); - Smilies::add($b, ':UP! button:', '🆙'); - Smilies::add($b, ':VS button:', '🆚'); - Smilies::add($b, ':Japanese “here” button:', '🈁'); - Smilies::add($b, ':Japanese “service charge” button:', '🈂'); - Smilies::add($b, ':Japanese “monthly amount” button:', '🈷'); - Smilies::add($b, ':Japanese “not free of charge” button:', '🈶'); - Smilies::add($b, ':Japanese “reserved” button:', '🈯'); - Smilies::add($b, ':Japanese “bargain” button:', '🉐'); - Smilies::add($b, ':Japanese “discount” button:', '🈹'); - Smilies::add($b, ':Japanese “free of charge” button:', '🈚'); - Smilies::add($b, ':Japanese “prohibited” button:', '🈲'); - Smilies::add($b, ':Japanese “acceptable” button:', '🉑'); - Smilies::add($b, ':Japanese “application” button:', '🈸'); - Smilies::add($b, ':Japanese “passing grade” button:', '🈴'); - Smilies::add($b, ':Japanese “vacancy” button:', '🈳'); - Smilies::add($b, ':Japanese “congratulations” button:', '㊗'); - Smilies::add($b, ':Japanese “secret” button:', '㊙'); - Smilies::add($b, ':Japanese “open for business” button:', '🈺'); - Smilies::add($b, ':Japanese “no vacancy” button:', '🈵'); + Smilies::add($b, ':FREE button:', '🆓'); + Smilies::add($b, ':information:', 'ℹ'); + Smilies::add($b, ':ID button:', '🆔'); + Smilies::add($b, ':circled M:', 'Ⓜ'); + Smilies::add($b, ':NEW button:', '🆕'); + Smilies::add($b, ':NG button:', '🆖'); + Smilies::add($b, ':O button (blood type):', '🅾'); + Smilies::add($b, ':OK button:', '🆗'); + Smilies::add($b, ':P button:', '🅿'); + Smilies::add($b, ':SOS button:', '🆘'); + Smilies::add($b, ':UP! button:', '🆙'); + Smilies::add($b, ':VS button:', '🆚'); + Smilies::add($b, ':Japanese “here” button:', '🈁'); + Smilies::add($b, ':Japanese “service charge” button:', '🈂'); + Smilies::add($b, ':Japanese “monthly amount” button:', '🈷'); + Smilies::add($b, ':Japanese “not free of charge” button:', '🈶'); + Smilies::add($b, ':Japanese “reserved” button:', '🈯'); + Smilies::add($b, ':Japanese “bargain” button:', '🉐'); + Smilies::add($b, ':Japanese “discount” button:', '🈹'); + Smilies::add($b, ':Japanese “free of charge” button:', '🈚'); + Smilies::add($b, ':Japanese “prohibited” button:', '🈲'); + Smilies::add($b, ':Japanese “acceptable” button:', '🉑'); + Smilies::add($b, ':Japanese “application” button:', '🈸'); + Smilies::add($b, ':Japanese “passing grade” button:', '🈴'); + Smilies::add($b, ':Japanese “vacancy” button:', '🈳'); + Smilies::add($b, ':Japanese “congratulations” button:', '㊗'); + Smilies::add($b, ':Japanese “secret” button:', '㊙'); + Smilies::add($b, ':Japanese “open for business” button:', '🈺'); + Smilies::add($b, ':Japanese “no vacancy” button:', '🈵'); // geometric - Smilies::add($b, ':red circle:', '🔴'); -// Smilies::add($b, ':orange circle:', '🟠'); -// Smilies::add($b, ':yellow circle:', '🟡'); -// Smilies::add($b, ':green circle:', '🟢'); - Smilies::add($b, ':blue circle:', '🔵'); -// Smilies::add($b, ':purple circle:', '🟣'); -// Smilies::add($b, ':brown circle:', '🟤'); - Smilies::add($b, ':black circle:', '⚫'); - Smilies::add($b, ':white circle:', '⚪'); -// Smilies::add($b, ':red square:', '🟥'); -// Smilies::add($b, ':orange square:', '🟧'); -// Smilies::add($b, ':yellow square:', '🟨'); -// Smilies::add($b, ':green square:', '🟩'); -// Smilies::add($b, ':blue square:', '🟦'); -// Smilies::add($b, ':purple square:', '🟪'); -// Smilies::add($b, ':brown square:', '🟫'); - Smilies::add($b, ':black large square:', '⬛'); - Smilies::add($b, ':white large square:', '⬜'); - Smilies::add($b, ':black medium square:', '◼'); - Smilies::add($b, ':white medium square:', '◻'); - Smilies::add($b, ':black medium-small square:', '◾'); - Smilies::add($b, ':white medium-small square:', '◽'); - Smilies::add($b, ':black small square:', '▪'); - Smilies::add($b, ':white small square:', '▫'); - Smilies::add($b, ':large orange diamond:', '🔶'); - Smilies::add($b, ':large blue diamond:', '🔷'); - Smilies::add($b, ':small orange diamond:', '🔸'); - Smilies::add($b, ':small blue diamond:', '🔹'); - Smilies::add($b, ':red triangle pointed up:', '🔺'); - Smilies::add($b, ':red triangle pointed down:', '🔻'); - Smilies::add($b, ':diamond with a dot:', '💠'); - Smilies::add($b, ':radio button:', '🔘'); - Smilies::add($b, ':white square button:', '🔳'); - Smilies::add($b, ':black square button:', '🔲'); + Smilies::add($b, ':red circle:', '🔴'); +// Smilies::add($b, ':orange circle:', '🟠'); +// Smilies::add($b, ':yellow circle:', '🟡'); +// Smilies::add($b, ':green circle:', '🟢'); + Smilies::add($b, ':blue circle:', '🔵'); +// Smilies::add($b, ':purple circle:', '🟣'); +// Smilies::add($b, ':brown circle:', '🟤'); + Smilies::add($b, ':black circle:', '⚫'); + Smilies::add($b, ':white circle:', '⚪'); +// Smilies::add($b, ':red square:', '🟥'); +// Smilies::add($b, ':orange square:', '🟧'); +// Smilies::add($b, ':yellow square:', '🟨'); +// Smilies::add($b, ':green square:', '🟩'); +// Smilies::add($b, ':blue square:', '🟦'); +// Smilies::add($b, ':purple square:', '🟪'); +// Smilies::add($b, ':brown square:', '🟫'); + Smilies::add($b, ':black large square:', '⬛'); + Smilies::add($b, ':white large square:', '⬜'); + Smilies::add($b, ':black medium square:', '◼'); + Smilies::add($b, ':white medium square:', '◻'); + Smilies::add($b, ':black medium-small square:', '◾'); + Smilies::add($b, ':white medium-small square:', '◽'); + Smilies::add($b, ':black small square:', '▪'); + Smilies::add($b, ':white small square:', '▫'); + Smilies::add($b, ':large orange diamond:', '🔶'); + Smilies::add($b, ':large blue diamond:', '🔷'); + Smilies::add($b, ':small orange diamond:', '🔸'); + Smilies::add($b, ':small blue diamond:', '🔹'); + Smilies::add($b, ':red triangle pointed up:', '🔺'); + Smilies::add($b, ':red triangle pointed down:', '🔻'); + Smilies::add($b, ':diamond with a dot:', '💠'); + Smilies::add($b, ':radio button:', '🔘'); + Smilies::add($b, ':white square button:', '🔳'); + Smilies::add($b, ':black square button:', '🔲'); // Flags // flag - Smilies::add($b, ':chequered flag:', '🏁'); - Smilies::add($b, ':triangular flag:', '🚩'); - Smilies::add($b, ':crossed flags:', '🎌'); - Smilies::add($b, ':black flag:', '🏴'); - Smilies::add($b, ':white flag:', '🏳'); - Smilies::add($b, ':rainbow flag:', '🏳️‍🌈'); - Smilies::add($b, ':pirate flag:', '🏴‍☠️'); + Smilies::add($b, ':chequered flag:', '🏁'); + Smilies::add($b, ':triangular flag:', '🚩'); + Smilies::add($b, ':crossed flags:', '🎌'); + Smilies::add($b, ':black flag:', '🏴'); + Smilies::add($b, ':white flag:', '🏳'); + Smilies::add($b, ':rainbow flag:', '🏳️‍🌈'); + Smilies::add($b, ':pirate flag:', '🏴‍☠️'); // country-flag - Smilies::add($b, ':ascension island:', '🇦🇨'); - Smilies::add($b, ':andorra:', '🇦🇩'); - Smilies::add($b, ':united arab emirates:', '🇦🇪'); - Smilies::add($b, ':afghanistan:', '🇦🇫'); - Smilies::add($b, ':antigua & barbuda:', '🇦🇬'); - Smilies::add($b, ':anguilla:', '🇦🇮'); - Smilies::add($b, ':albania:', '🇦🇱'); - Smilies::add($b, ':armenia:', '🇦🇲'); - Smilies::add($b, ':angola:', '🇦🇴'); - Smilies::add($b, ':antarctica:', '🇦🇶'); - Smilies::add($b, ':argentina:', '🇦🇷'); - Smilies::add($b, ':americansamoa:', '🇦🇸'); - Smilies::add($b, ':austria:', '🇦🇹'); - Smilies::add($b, ':australia:', '🇦🇺'); - Smilies::add($b, ':aruba:', '🇦🇼'); - Smilies::add($b, ':ålandislands:', '🇦🇽'); - Smilies::add($b, ':azerbaijan:', '🇦🇿'); - Smilies::add($b, ':bosnia&herzegovina:', '🇧🇦'); - Smilies::add($b, ':barbados:', '🇧🇧'); - Smilies::add($b, ':bangladesh:', '🇧🇩'); - Smilies::add($b, ':belgium:', '🇧🇪'); - Smilies::add($b, ':burkinafaso:', '🇧🇫'); - Smilies::add($b, ':bulgaria:', '🇧🇬'); - Smilies::add($b, ':bahrain:', '🇧🇭'); - Smilies::add($b, ':burundi:', '🇧🇮'); - Smilies::add($b, ':benin:', '🇧🇯'); - Smilies::add($b, ':st.barthélemy:', '🇧🇱'); - Smilies::add($b, ':bermuda:', '🇧🇲'); - Smilies::add($b, ':brunei:', '🇧🇳'); - Smilies::add($b, ':bolivia:', '🇧🇴'); - Smilies::add($b, ':caribbeannetherlands:', '🇧🇶'); - Smilies::add($b, ':brazil:', '🇧🇷'); - Smilies::add($b, ':bahamas:', '🇧🇸'); - Smilies::add($b, ':bhutan:', '🇧🇹'); - Smilies::add($b, ':bouvetisland:', '🇧🇻'); - Smilies::add($b, ':botswana:', '🇧🇼'); - Smilies::add($b, ':belarus:', '🇧🇾'); - Smilies::add($b, ':belize:', '🇧🇿'); - Smilies::add($b, ':canada:', '🇨🇦'); - Smilies::add($b, ':cocos(keeling)islands:', '🇨🇨'); - Smilies::add($b, ':congo-kinshasa:', '🇨🇩'); - Smilies::add($b, ':centralafricanrepublic:', '🇨🇫'); - Smilies::add($b, ':congo-brazzaville:', '🇨🇬'); - Smilies::add($b, ':switzerland:', '🇨🇭'); - Smilies::add($b, ':côted’ivoire:', '🇨🇮'); - Smilies::add($b, ':cookislands:', '🇨🇰'); - Smilies::add($b, ':chile:', '🇨🇱'); - Smilies::add($b, ':cameroon:', '🇨🇲'); - Smilies::add($b, ':china:', '🇨🇳'); - Smilies::add($b, ':colombia:', '🇨🇴'); - Smilies::add($b, ':clippertonisland:', '🇨🇵'); - Smilies::add($b, ':costarica:', '🇨🇷'); - Smilies::add($b, ':cuba:', '🇨🇺'); - Smilies::add($b, ':capeverde:', '🇨🇻'); - Smilies::add($b, ':curaçao:', '🇨🇼'); - Smilies::add($b, ':christmasisland:', '🇨🇽'); - Smilies::add($b, ':cyprus:', '🇨🇾'); - Smilies::add($b, ':czechia:', '🇨🇿'); - Smilies::add($b, ':germany:', '🇩🇪'); - Smilies::add($b, ':diegogarcia:', '🇩🇬'); - Smilies::add($b, ':djibouti:', '🇩🇯'); - Smilies::add($b, ':denmark:', '🇩🇰'); - Smilies::add($b, ':dominica:', '🇩🇲'); - Smilies::add($b, ':dominicanrepublic:', '🇩🇴'); - Smilies::add($b, ':algeria:', '🇩🇿'); - Smilies::add($b, ':ceuta&melilla:', '🇪🇦'); - Smilies::add($b, ':ecuador:', '🇪🇨'); - Smilies::add($b, ':estonia:', '🇪🇪'); - Smilies::add($b, ':egypt:', '🇪🇬'); - Smilies::add($b, ':westernsahara:', '🇪🇭'); - Smilies::add($b, ':eritrea:', '🇪🇷'); - Smilies::add($b, ':spain:', '🇪🇸'); - Smilies::add($b, ':ethiopia:', '🇪🇹'); - Smilies::add($b, ':europeanunion:', '🇪🇺'); - Smilies::add($b, ':finland:', '🇫🇮'); - Smilies::add($b, ':fiji:', '🇫🇯'); - Smilies::add($b, ':falklandislands:', '🇫🇰'); - Smilies::add($b, ':micronesia:', '🇫🇲'); - Smilies::add($b, ':faroeislands:', '🇫🇴'); - Smilies::add($b, ':france:', '🇫🇷'); - Smilies::add($b, ':gabon:', '🇬🇦'); - Smilies::add($b, ':unitedkingdom:', '🇬🇧'); - Smilies::add($b, ':grenada:', '🇬🇩'); - Smilies::add($b, ':georgia:', '🇬🇪'); - Smilies::add($b, ':frenchguiana:', '🇬🇫'); - Smilies::add($b, ':guernsey:', '🇬🇬'); - Smilies::add($b, ':ghana:', '🇬🇭'); - Smilies::add($b, ':gibraltar:', '🇬🇮'); - Smilies::add($b, ':greenland:', '🇬🇱'); - Smilies::add($b, ':gambia:', '🇬🇲'); - Smilies::add($b, ':guinea:', '🇬🇳'); - Smilies::add($b, ':guadeloupe:', '🇬🇵'); - Smilies::add($b, ':equatorialguinea:', '🇬🇶'); - Smilies::add($b, ':greece:', '🇬🇷'); - Smilies::add($b, ':southgeorgia&southsandwichislands:', '🇬🇸'); - Smilies::add($b, ':guatemala:', '🇬🇹'); - Smilies::add($b, ':guam:', '🇬🇺'); - Smilies::add($b, ':guinea-bissau:', '🇬🇼'); - Smilies::add($b, ':guyana:', '🇬🇾'); - Smilies::add($b, ':hongkongsarchina:', '🇭🇰'); - Smilies::add($b, ':heard&mcdonaldislands:', '🇭🇲'); - Smilies::add($b, ':honduras:', '🇭🇳'); - Smilies::add($b, ':croatia:', '🇭🇷'); - Smilies::add($b, ':haiti:', '🇭🇹'); - Smilies::add($b, ':hungary:', '🇭🇺'); - Smilies::add($b, ':canaryislands:', '🇮🇨'); - Smilies::add($b, ':indonesia:', '🇮🇩'); - Smilies::add($b, ':ireland:', '🇮🇪'); - Smilies::add($b, ':israel:', '🇮🇱'); - Smilies::add($b, ':isleofman:', '🇮🇲'); - Smilies::add($b, ':india:', '🇮🇳'); - Smilies::add($b, ':britishindianoceanterritory:', '🇮🇴'); - Smilies::add($b, ':iraq:', '🇮🇶'); - Smilies::add($b, ':iran:', '🇮🇷'); - Smilies::add($b, ':iceland:', '🇮🇸'); - Smilies::add($b, ':italy:', '🇮🇹'); - Smilies::add($b, ':jersey:', '🇯🇪'); - Smilies::add($b, ':jamaica:', '🇯🇲'); - Smilies::add($b, ':jordan:', '🇯🇴'); - Smilies::add($b, ':japan:', '🇯🇵'); - Smilies::add($b, ':kenya:', '🇰🇪'); - Smilies::add($b, ':kyrgyzstan:', '🇰🇬'); - Smilies::add($b, ':cambodia:', '🇰🇭'); - Smilies::add($b, ':kiribati:', '🇰🇮'); - Smilies::add($b, ':comoros:', '🇰🇲'); - Smilies::add($b, ':st.kitts&nevis:', '🇰🇳'); - Smilies::add($b, ':northkorea:', '🇰🇵'); - Smilies::add($b, ':southkorea:', '🇰🇷'); - Smilies::add($b, ':kuwait:', '🇰🇼'); - Smilies::add($b, ':caymanislands:', '🇰🇾'); - Smilies::add($b, ':kazakhstan:', '🇰🇿'); - Smilies::add($b, ':laos:', '🇱🇦'); - Smilies::add($b, ':lebanon:', '🇱🇧'); - Smilies::add($b, ':st.lucia:', '🇱🇨'); - Smilies::add($b, ':liechtenstein:', '🇱🇮'); - Smilies::add($b, ':srilanka:', '🇱🇰'); - Smilies::add($b, ':liberia:', '🇱🇷'); - Smilies::add($b, ':lesotho:', '🇱🇸'); - Smilies::add($b, ':lithuania:', '🇱🇹'); - Smilies::add($b, ':luxembourg:', '🇱🇺'); - Smilies::add($b, ':latvia:', '🇱🇻'); - Smilies::add($b, ':libya:', '🇱🇾'); - Smilies::add($b, ':morocco:', '🇲🇦'); - Smilies::add($b, ':monaco:', '🇲🇨'); - Smilies::add($b, ':moldova:', '🇲🇩'); - Smilies::add($b, ':montenegro:', '🇲🇪'); - Smilies::add($b, ':st.martin:', '🇲🇫'); - Smilies::add($b, ':madagascar:', '🇲🇬'); - Smilies::add($b, ':marshallislands:', '🇲🇭'); - Smilies::add($b, ':northmacedonia:', '🇲🇰'); - Smilies::add($b, ':mali:', '🇲🇱'); - Smilies::add($b, ':myanmar(burma):', '🇲🇲'); - Smilies::add($b, ':mongolia:', '🇲🇳'); - Smilies::add($b, ':macaosarchina:', '🇲🇴'); - Smilies::add($b, ':northernmarianaislands:', '🇲🇵'); - Smilies::add($b, ':martinique:', '🇲🇶'); - Smilies::add($b, ':mauritania:', '🇲🇷'); - Smilies::add($b, ':montserrat:', '🇲🇸'); - Smilies::add($b, ':malta:', '🇲🇹'); - Smilies::add($b, ':mauritius:', '🇲🇺'); - Smilies::add($b, ':maldives:', '🇲🇻'); - Smilies::add($b, ':malawi:', '🇲🇼'); - Smilies::add($b, ':mexico:', '🇲🇽'); - Smilies::add($b, ':malaysia:', '🇲🇾'); - Smilies::add($b, ':mozambique:', '🇲🇿'); - Smilies::add($b, ':namibia:', '🇳🇦'); - Smilies::add($b, ':newcaledonia:', '🇳🇨'); - Smilies::add($b, ':niger:', '🇳🇪'); - Smilies::add($b, ':norfolkisland:', '🇳🇫'); - Smilies::add($b, ':nigeria:', '🇳🇬'); - Smilies::add($b, ':nicaragua:', '🇳🇮'); - Smilies::add($b, ':netherlands:', '🇳🇱'); - Smilies::add($b, ':norway:', '🇳🇴'); - Smilies::add($b, ':nepal:', '🇳🇵'); - Smilies::add($b, ':nauru:', '🇳🇷'); - Smilies::add($b, ':niue:', '🇳🇺'); - Smilies::add($b, ':newzealand:', '🇳🇿'); - Smilies::add($b, ':oman:', '🇴🇲'); - Smilies::add($b, ':panama:', '🇵🇦'); - Smilies::add($b, ':peru:', '🇵🇪'); - Smilies::add($b, ':frenchpolynesia:', '🇵🇫'); - Smilies::add($b, ':papuanewguinea:', '🇵🇬'); - Smilies::add($b, ':philippines:', '🇵🇭'); - Smilies::add($b, ':pakistan:', '🇵🇰'); - Smilies::add($b, ':poland:', '🇵🇱'); - Smilies::add($b, ':st.pierre&miquelon:', '🇵🇲'); - Smilies::add($b, ':pitcairnislands:', '🇵🇳'); - Smilies::add($b, ':puertorico:', '🇵🇷'); - Smilies::add($b, ':palestinianterritories:', '🇵🇸'); - Smilies::add($b, ':portugal:', '🇵🇹'); - Smilies::add($b, ':palau:', '🇵🇼'); - Smilies::add($b, ':paraguay:', '🇵🇾'); - Smilies::add($b, ':qatar:', '🇶🇦'); - Smilies::add($b, ':réunion:', '🇷🇪'); - Smilies::add($b, ':romania:', '🇷🇴'); - Smilies::add($b, ':serbia:', '🇷🇸'); - Smilies::add($b, ':russia:', '🇷🇺'); - Smilies::add($b, ':rwanda:', '🇷🇼'); - Smilies::add($b, ':saudiarabia:', '🇸🇦'); - Smilies::add($b, ':solomonislands:', '🇸🇧'); - Smilies::add($b, ':seychelles:', '🇸🇨'); - Smilies::add($b, ':sudan:', '🇸🇩'); - Smilies::add($b, ':sweden:', '🇸🇪'); - Smilies::add($b, ':singapore:', '🇸🇬'); - Smilies::add($b, ':st.helena:', '🇸🇭'); - Smilies::add($b, ':slovenia:', '🇸🇮'); - Smilies::add($b, ':svalbard&janmayen:', '🇸🇯'); - Smilies::add($b, ':slovakia:', '🇸🇰'); - Smilies::add($b, ':sierraleone:', '🇸🇱'); - Smilies::add($b, ':sanmarino:', '🇸🇲'); - Smilies::add($b, ':senegal:', '🇸🇳'); - Smilies::add($b, ':somalia:', '🇸🇴'); - Smilies::add($b, ':suriname:', '🇸🇷'); - Smilies::add($b, ':southsudan:', '🇸🇸'); - Smilies::add($b, ':sãotomé&príncipe:', '🇸🇹'); - Smilies::add($b, ':elsalvador:', '🇸🇻'); - Smilies::add($b, ':sintmaarten:', '🇸🇽'); - Smilies::add($b, ':syria:', '🇸🇾'); - Smilies::add($b, ':eswatini:', '🇸🇿'); - Smilies::add($b, ':tristandacunha:', '🇹🇦'); - Smilies::add($b, ':turks&caicosislands:', '🇹🇨'); - Smilies::add($b, ':chad:', '🇹🇩'); - Smilies::add($b, ':frenchsouthernterritories:', '🇹🇫'); - Smilies::add($b, ':togo:', '🇹🇬'); - Smilies::add($b, ':thailand:', '🇹🇭'); - Smilies::add($b, ':tajikistan:', '🇹🇯'); - Smilies::add($b, ':tokelau:', '🇹🇰'); - Smilies::add($b, ':timor-leste:', '🇹🇱'); - Smilies::add($b, ':turkmenistan:', '🇹🇲'); - Smilies::add($b, ':tunisia:', '🇹🇳'); - Smilies::add($b, ':tonga:', '🇹🇴'); - Smilies::add($b, ':turkey:', '🇹🇷'); - Smilies::add($b, ':trinidad&tobago:', '🇹🇹'); - Smilies::add($b, ':tuvalu:', '🇹🇻'); - Smilies::add($b, ':taiwan:', '🇹🇼'); - Smilies::add($b, ':tanzania:', '🇹🇿'); - Smilies::add($b, ':ukraine:', '🇺🇦'); - Smilies::add($b, ':uganda:', '🇺🇬'); - Smilies::add($b, ':u.s.outlyingislands:', '🇺🇲'); - Smilies::add($b, ':unitednations:', '🇺🇳'); - Smilies::add($b, ':unitedstates:', '🇺🇸'); - Smilies::add($b, ':uruguay:', '🇺🇾'); - Smilies::add($b, ':uzbekistan:', '🇺🇿'); - Smilies::add($b, ':vaticancity:', '🇻🇦'); - Smilies::add($b, ':st.vincent&grenadines:', '🇻🇨'); - Smilies::add($b, ':venezuela:', '🇻🇪'); - Smilies::add($b, ':britishvirginislands:', '🇻🇬'); - Smilies::add($b, ':u.s.virginislands:', '🇻🇮'); - Smilies::add($b, ':vietnam:', '🇻🇳'); - Smilies::add($b, ':vanuatu:', '🇻🇺'); - Smilies::add($b, ':wallis&futuna:', '🇼🇫'); - Smilies::add($b, ':samoa:', '🇼🇸'); - Smilies::add($b, ':kosovo:', '🇽🇰'); - Smilies::add($b, ':yemen:', '🇾🇪'); - Smilies::add($b, ':mayotte:', '🇾🇹'); - Smilies::add($b, ':southafrica:', '🇿🇦'); - Smilies::add($b, ':zambia:', '🇿🇲'); - Smilies::add($b, ':zimbabwe:', '🇿🇼'); + Smilies::add($b, ':ascension island:', '🇦🇨'); + Smilies::add($b, ':andorra:', '🇦🇩'); + Smilies::add($b, ':united arab emirates:', '🇦🇪'); + Smilies::add($b, ':afghanistan:', '🇦🇫'); + Smilies::add($b, ':antigua & barbuda:', '🇦🇬'); + Smilies::add($b, ':anguilla:', '🇦🇮'); + Smilies::add($b, ':albania:', '🇦🇱'); + Smilies::add($b, ':armenia:', '🇦🇲'); + Smilies::add($b, ':angola:', '🇦🇴'); + Smilies::add($b, ':antarctica:', '🇦🇶'); + Smilies::add($b, ':argentina:', '🇦🇷'); + Smilies::add($b, ':americansamoa:', '🇦🇸'); + Smilies::add($b, ':austria:', '🇦🇹'); + Smilies::add($b, ':australia:', '🇦🇺'); + Smilies::add($b, ':aruba:', '🇦🇼'); + Smilies::add($b, ':ålandislands:', '🇦🇽'); + Smilies::add($b, ':azerbaijan:', '🇦🇿'); + Smilies::add($b, ':bosnia&herzegovina:', '🇧🇦'); + Smilies::add($b, ':barbados:', '🇧🇧'); + Smilies::add($b, ':bangladesh:', '🇧🇩'); + Smilies::add($b, ':belgium:', '🇧🇪'); + Smilies::add($b, ':burkinafaso:', '🇧🇫'); + Smilies::add($b, ':bulgaria:', '🇧🇬'); + Smilies::add($b, ':bahrain:', '🇧🇭'); + Smilies::add($b, ':burundi:', '🇧🇮'); + Smilies::add($b, ':benin:', '🇧🇯'); + Smilies::add($b, ':st.barthélemy:', '🇧🇱'); + Smilies::add($b, ':bermuda:', '🇧🇲'); + Smilies::add($b, ':brunei:', '🇧🇳'); + Smilies::add($b, ':bolivia:', '🇧🇴'); + Smilies::add($b, ':caribbeannetherlands:', '🇧🇶'); + Smilies::add($b, ':brazil:', '🇧🇷'); + Smilies::add($b, ':bahamas:', '🇧🇸'); + Smilies::add($b, ':bhutan:', '🇧🇹'); + Smilies::add($b, ':bouvetisland:', '🇧🇻'); + Smilies::add($b, ':botswana:', '🇧🇼'); + Smilies::add($b, ':belarus:', '🇧🇾'); + Smilies::add($b, ':belize:', '🇧🇿'); + Smilies::add($b, ':canada:', '🇨🇦'); + Smilies::add($b, ':cocos(keeling)islands:', '🇨🇨'); + Smilies::add($b, ':congo-kinshasa:', '🇨🇩'); + Smilies::add($b, ':centralafricanrepublic:', '🇨🇫'); + Smilies::add($b, ':congo-brazzaville:', '🇨🇬'); + Smilies::add($b, ':switzerland:', '🇨🇭'); + Smilies::add($b, ':côted’ivoire:', '🇨🇮'); + Smilies::add($b, ':cookislands:', '🇨🇰'); + Smilies::add($b, ':chile:', '🇨🇱'); + Smilies::add($b, ':cameroon:', '🇨🇲'); + Smilies::add($b, ':china:', '🇨🇳'); + Smilies::add($b, ':colombia:', '🇨🇴'); + Smilies::add($b, ':clippertonisland:', '🇨🇵'); + Smilies::add($b, ':costarica:', '🇨🇷'); + Smilies::add($b, ':cuba:', '🇨🇺'); + Smilies::add($b, ':capeverde:', '🇨🇻'); + Smilies::add($b, ':curaçao:', '🇨🇼'); + Smilies::add($b, ':christmasisland:', '🇨🇽'); + Smilies::add($b, ':cyprus:', '🇨🇾'); + Smilies::add($b, ':czechia:', '🇨🇿'); + Smilies::add($b, ':germany:', '🇩🇪'); + Smilies::add($b, ':diegogarcia:', '🇩🇬'); + Smilies::add($b, ':djibouti:', '🇩🇯'); + Smilies::add($b, ':denmark:', '🇩🇰'); + Smilies::add($b, ':dominica:', '🇩🇲'); + Smilies::add($b, ':dominicanrepublic:', '🇩🇴'); + Smilies::add($b, ':algeria:', '🇩🇿'); + Smilies::add($b, ':ceuta&melilla:', '🇪🇦'); + Smilies::add($b, ':ecuador:', '🇪🇨'); + Smilies::add($b, ':estonia:', '🇪🇪'); + Smilies::add($b, ':egypt:', '🇪🇬'); + Smilies::add($b, ':westernsahara:', '🇪🇭'); + Smilies::add($b, ':eritrea:', '🇪🇷'); + Smilies::add($b, ':spain:', '🇪🇸'); + Smilies::add($b, ':ethiopia:', '🇪🇹'); + Smilies::add($b, ':europeanunion:', '🇪🇺'); + Smilies::add($b, ':finland:', '🇫🇮'); + Smilies::add($b, ':fiji:', '🇫🇯'); + Smilies::add($b, ':falklandislands:', '🇫🇰'); + Smilies::add($b, ':micronesia:', '🇫🇲'); + Smilies::add($b, ':faroeislands:', '🇫🇴'); + Smilies::add($b, ':france:', '🇫🇷'); + Smilies::add($b, ':gabon:', '🇬🇦'); + Smilies::add($b, ':unitedkingdom:', '🇬🇧'); + Smilies::add($b, ':grenada:', '🇬🇩'); + Smilies::add($b, ':georgia:', '🇬🇪'); + Smilies::add($b, ':frenchguiana:', '🇬🇫'); + Smilies::add($b, ':guernsey:', '🇬🇬'); + Smilies::add($b, ':ghana:', '🇬🇭'); + Smilies::add($b, ':gibraltar:', '🇬🇮'); + Smilies::add($b, ':greenland:', '🇬🇱'); + Smilies::add($b, ':gambia:', '🇬🇲'); + Smilies::add($b, ':guinea:', '🇬🇳'); + Smilies::add($b, ':guadeloupe:', '🇬🇵'); + Smilies::add($b, ':equatorialguinea:', '🇬🇶'); + Smilies::add($b, ':greece:', '🇬,;🇷'); + Smilies::add($b, ':southgeorgia&southsandwichislands:', '🇬🇸'); + Smilies::add($b, ':guatemala:', '🇬🇹'); + Smilies::add($b, ':guam:', '🇬🇺'); + Smilies::add($b, ':guinea-bissau:', '🇬🇼'); + Smilies::add($b, ':guyana:', '🇬🇾'); + Smilies::add($b, ':hongkongsarchina:', '🇭🇰'); + Smilies::add($b, ':heard&mcdonaldislands:', '🇭🇲'); + Smilies::add($b, ':honduras:', '🇭🇳'); + Smilies::add($b, ':croatia:', '🇭🇷'); + Smilies::add($b, ':haiti:', '🇭🇹'); + Smilies::add($b, ':hungary:', '🇭🇺'); + Smilies::add($b, ':canaryislands:', '🇮🇨'); + Smilies::add($b, ':indonesia:', '🇮🇩'); + Smilies::add($b, ':ireland:', '🇮🇪'); + Smilies::add($b, ':israel:', '🇮🇱'); + Smilies::add($b, ':isleofman:', '🇮🇲'); + Smilies::add($b, ':india:', '🇮🇳'); + Smilies::add($b, ':britishindianoceanterritory:', '🇮🇴'); + Smilies::add($b, ':iraq:', '🇮🇶'); + Smilies::add($b, ':iran:', '🇮🇷'); + Smilies::add($b, ':iceland:', '🇮🇸'); + Smilies::add($b, ':italy:', '🇮🇹'); + Smilies::add($b, ':jersey:', '🇯🇪'); + Smilies::add($b, ':jamaica:', '🇯🇲'); + Smilies::add($b, ':jordan:', '🇯🇴'); + Smilies::add($b, ':japan:', '🇯🇵'); + Smilies::add($b, ':kenya:', '🇰🇪'); + Smilies::add($b, ':kyrgyzstan:', '🇰🇬'); + Smilies::add($b, ':cambodia:', '🇰🇭'); + Smilies::add($b, ':kiribati:', '🇰🇮'); + Smilies::add($b, ':comoros:', '🇰🇲'); + Smilies::add($b, ':st.kitts&nevis:', '🇰🇳'); + Smilies::add($b, ':northkorea:', '🇰🇵'); + Smilies::add($b, ':southkorea:', '🇰🇷'); + Smilies::add($b, ':kuwait:', '🇰🇼'); + Smilies::add($b, ':caymanislands:', '🇰🇾'); + Smilies::add($b, ':kazakhstan:', '🇰🇿'); + Smilies::add($b, ':laos:', '🇱🇦'); + Smilies::add($b, ':lebanon:', '🇱🇧'); + Smilies::add($b, ':st.lucia:', '🇱🇨'); + Smilies::add($b, ':liechtenstein:', '🇱🇮'); + Smilies::add($b, ':srilanka:', '🇱🇰'); + Smilies::add($b, ':liberia:', '🇱🇷'); + Smilies::add($b, ':lesotho:', '🇱🇸'); + Smilies::add($b, ':lithuania:', '🇱🇹'); + Smilies::add($b, ':luxembourg:', '🇱🇺'); + Smilies::add($b, ':latvia:', '🇱🇻'); + Smilies::add($b, ':libya:', '🇱🇾'); + Smilies::add($b, ':morocco:', '🇲🇦'); + Smilies::add($b, ':monaco:', '🇲🇨'); + Smilies::add($b, ':moldova:', '🇲🇩'); + Smilies::add($b, ':montenegro:', '🇲🇪'); + Smilies::add($b, ':st.martin:', '🇲🇫'); + Smilies::add($b, ':madagascar:', '🇲🇬'); + Smilies::add($b, ':marshallislands:', '🇲🇭'); + Smilies::add($b, ':northmacedonia:', '🇲🇰'); + Smilies::add($b, ':mali:', '🇲🇱'); + Smilies::add($b, ':myanmar(burma):', '🇲🇲'); + Smilies::add($b, ':mongolia:', '🇲🇳'); + Smilies::add($b, ':macaosarchina:', '🇲🇴'); + Smilies::add($b, ':northernmarianaislands:', '🇲🇵'); + Smilies::add($b, ':martinique:', '🇲🇶'); + Smilies::add($b, ':mauritania:', '🇲🇷'); + Smilies::add($b, ':montserrat:', '🇲🇸'); + Smilies::add($b, ':malta:', '🇲🇹'); + Smilies::add($b, ':mauritius:', '🇲🇺'); + Smilies::add($b, ':maldives:', '🇲🇻'); + Smilies::add($b, ':malawi:', '🇲🇼'); + Smilies::add($b, ':mexico:', '🇲🇽'); + Smilies::add($b, ':malaysia:', '🇲🇾'); + Smilies::add($b, ':mozambique:', '🇲🇿'); + Smilies::add($b, ':namibia:', '🇳🇦'); + Smilies::add($b, ':newcaledonia:', '🇳🇨'); + Smilies::add($b, ':niger:', '🇳🇪'); + Smilies::add($b, ':norfolkisland:', '🇳🇫'); + Smilies::add($b, ':nigeria:', '🇳🇬'); + Smilies::add($b, ':nicaragua:', '🇳🇮'); + Smilies::add($b, ':netherlands:', '🇳🇱'); + Smilies::add($b, ':norway:', '🇳🇴'); + Smilies::add($b, ':nepal:', '🇳🇵'); + Smilies::add($b, ':nauru:', '🇳🇷'); + Smilies::add($b, ':niue:', '🇳🇺'); + Smilies::add($b, ':newzealand:', '🇳🇿'); + Smilies::add($b, ':oman:', '🇴🇲'); + Smilies::add($b, ':panama:', '🇵🇦'); + Smilies::add($b, ':peru:', '🇵🇪'); + Smilies::add($b, ':frenchpolynesia:', '🇵🇫'); + Smilies::add($b, ':papuanewguinea:', '🇵🇬'); + Smilies::add($b, ':philippines:', '🇵🇭'); + Smilies::add($b, ':pakistan:', '🇵🇰'); + Smilies::add($b, ':poland:', '🇵🇱'); + Smilies::add($b, ':st.pierre&miquelon:', '🇵🇲'); + Smilies::add($b, ':pitcairnislands:', '🇵🇳'); + Smilies::add($b, ':puertorico:', '🇵🇷'); + Smilies::add($b, ':palestinianterritories:', '🇵🇸'); + Smilies::add($b, ':portugal:', '🇵🇹'); + Smilies::add($b, ':palau:', '🇵🇼'); + Smilies::add($b, ':paraguay:', '🇵🇾'); + Smilies::add($b, ':qatar:', '🇶🇦'); + Smilies::add($b, ':réunion:', '🇷🇪'); + Smilies::add($b, ':romania:', '🇷🇴'); + Smilies::add($b, ':serbia:', '🇷🇸'); + Smilies::add($b, ':russia:', '🇷🇺'); + Smilies::add($b, ':rwanda:', '🇷🇼'); + Smilies::add($b, ':saudiarabia:', '🇸🇦'); + Smilies::add($b, ':solomonislands:', '🇸🇧'); + Smilies::add($b, ':seychelles:', '🇸🇨'); + Smilies::add($b, ':sudan:', '🇸🇩'); + Smilies::add($b, ':sweden:', '🇸🇪'); + Smilies::add($b, ':singapore:', '🇸🇬'); + Smilies::add($b, ':st.helena:', '🇸🇭'); + Smilies::add($b, ':slovenia:', '🇸🇮'); + Smilies::add($b, ':svalbard&janmayen:', '🇸🇯'); + Smilies::add($b, ':slovakia:', '🇸🇰'); + Smilies::add($b, ':sierraleone:', '🇸🇱'); + Smilies::add($b, ':sanmarino:', '🇸🇲'); + Smilies::add($b, ':senegal:', '🇸🇳'); + Smilies::add($b, ':somalia:', '🇸🇴'); + Smilies::add($b, ':suriname:', '🇸🇷'); + Smilies::add($b, ':southsudan:', '🇸🇸'); + Smilies::add($b, ':sãotomé&príncipe:', '🇸🇹'); + Smilies::add($b, ':elsalvador:', '🇸🇻'); + Smilies::add($b, ':sintmaarten:', '🇸🇽'); + Smilies::add($b, ':syria:', '🇸🇾'); + Smilies::add($b, ':eswatini:', '🇸🇿'); + Smilies::add($b, ':tristandacunha:', '🇹🇦'); + Smilies::add($b, ':turks&caicosislands:', '🇹🇨'); + Smilies::add($b, ':chad:', '🇹🇩'); + Smilies::add($b, ':frenchsouthernterritories:', '🇹🇫'); + Smilies::add($b, ':togo:', '🇹🇬'); + Smilies::add($b, ':thailand:', '🇹🇭'); + Smilies::add($b, ':tajikistan:', '🇹🇯'); + Smilies::add($b, ':tokelau:', '🇹🇰'); + Smilies::add($b, ':timor-leste:', '🇹🇱'); + Smilies::add($b, ':turkmenistan:', '🇹🇲'); + Smilies::add($b, ':tunisia:', '🇹🇳'); + Smilies::add($b, ':tonga:', '🇹🇴'); + Smilies::add($b, ':turkey:', '🇹🇷'); + Smilies::add($b, ':trinidad&tobago:', '🇹🇹'); + Smilies::add($b, ':tuvalu:', '🇹🇻'); + Smilies::add($b, ':taiwan:', '🇹🇼'); + Smilies::add($b, ':tanzania:', '🇹🇿'); + Smilies::add($b, ':ukraine:', '🇺🇦'); + Smilies::add($b, ':uganda:', '🇺🇬'); + Smilies::add($b, ':u.s.outlyingislands:', '🇺🇲'); + Smilies::add($b, ':unitednations:', '🇺🇳'); + Smilies::add($b, ':unitedstates:', '🇺🇸'); + Smilies::add($b, ':uruguay:', '🇺🇾'); + Smilies::add($b, ':uzbekistan:', '🇺🇿'); + Smilies::add($b, ':vaticancity:', '🇻🇦'); + Smilies::add($b, ':st.vincent&grenadines:', '🇻🇨'); + Smilies::add($b, ':venezuela:', '🇻🇪'); + Smilies::add($b, ':britishvirginislands:', '🇻🇬'); + Smilies::add($b, ':u.s.virginislands:', '🇻🇮'); + Smilies::add($b, ':vietnam:', '🇻🇳'); + Smilies::add($b, ':vanuatu:', '🇻🇺'); + Smilies::add($b, ':wallis&futuna:', '🇼🇫'); + Smilies::add($b, ':samoa:', '🇼🇸'); + Smilies::add($b, ':kosovo:', '🇽🇰'); + Smilies::add($b, ':yemen:', '🇾🇪'); + Smilies::add($b, ':mayotte:', '🇾🇹'); + Smilies::add($b, ':southafrica:', '🇿🇦'); + Smilies::add($b, ':zambia:', '🇿🇲'); + Smilies::add($b, ':zimbabwe:', '🇿🇼'); // subdivision-flag - Smilies::add($b, ':england:', '🏴󠁧󠁢󠁥󠁮󠁧󠁿'); - Smilies::add($b, ':scotland:', '🏴󠁧󠁢󠁳󠁴󠁿'); - Smilies::add($b, ':wales:', '🏴󠁧󠁢󠁷󠁬󠁳󠁿'); + Smilies::add($b, ':england:', '🏴󠁧󠁢󠁥󠁮󠁧󠁿'); + Smilies::add($b, ':scotland:', '🏴󠁧󠁢󠁳󠁴󠁿'); + Smilies::add($b, ':wales:', '🏴󠁧󠁢󠁷󠁬󠁳󠁿'); } + From 0697f078f11af094ec8455d1ec9e59ec63cd66d0 Mon Sep 17 00:00:00 2001 From: Philipp Date: Sun, 22 Dec 2024 08:38:17 +0100 Subject: [PATCH 120/222] [CI] Fix codecov --- .woodpecker/.phpunit.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.woodpecker/.phpunit.yml b/.woodpecker/.phpunit.yml index 887e897e..3f713d19 100644 --- a/.woodpecker/.phpunit.yml +++ b/.woodpecker/.phpunit.yml @@ -98,9 +98,9 @@ pipeline: - friendica/friendica-addons commands: - codecov -R '.' -Z -f 'clover.xml' - secrets: - - source: codecov-token - target: codecov_token + environment: + codecov_token: + from_secret: codecov-token services: mariadb: From 5f50fd2498b58787f8671c3e6cff6658d9dd38dd Mon Sep 17 00:00:00 2001 From: Philipp Date: Sun, 22 Dec 2024 08:54:51 +0100 Subject: [PATCH 121/222] Fix codecov token env --- .woodpecker/.phpunit.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.woodpecker/.phpunit.yml b/.woodpecker/.phpunit.yml index 3f713d19..6acbf787 100644 --- a/.woodpecker/.phpunit.yml +++ b/.woodpecker/.phpunit.yml @@ -99,7 +99,7 @@ pipeline: commands: - codecov -R '.' -Z -f 'clover.xml' environment: - codecov_token: + CODECOV_TOKEN: from_secret: codecov-token services: From 9e1f7dc468b3e615e2345b691b89ecfc80364f87 Mon Sep 17 00:00:00 2001 From: Michael Date: Fri, 27 Dec 2024 10:26:20 +0000 Subject: [PATCH 122/222] Bluesky: Preparation to be able to fetch AT links --- bluesky/bluesky.php | 34 ++++++++++++++++------------------ 1 file changed, 16 insertions(+), 18 deletions(-) diff --git a/bluesky/bluesky.php b/bluesky/bluesky.php index d6b7624b..1355f000 100644 --- a/bluesky/bluesky.php +++ b/bluesky/bluesky.php @@ -97,27 +97,25 @@ function bluesky_item_by_link(array &$hookData) return; } - $token = DI::atProtocol()->getUserToken($hookData['uid']); - if (empty($token)) { - return; + if (substr($hookData['uri'], 0, 5) != 'at://') { + if (!preg_match('#^' . ATProtocol::WEB . '/profile/(.+)/post/(.+)#', $hookData['uri'], $matches)) { + return; + } + + $did = DI::atProtocol()->getDid($matches[1]); + if (empty($did)) { + return; + } + + Logger::debug('Found bluesky post', ['uri' => $hookData['uri'], 'did' => $did, 'cid' => $matches[2]]); + + $uri = 'at://' . $did . '/app.bsky.feed.post/' . $matches[2]; + } else { + $uri = $hookData['uri']; } - // @todo also support the URI format (at://did/app.bsky.feed.post/cid) - if (!preg_match('#^' . ATProtocol::WEB . '/profile/(.+)/post/(.+)#', $hookData['uri'], $matches)) { - return; - } - - $did = DI::atProtocol()->getDid($matches[1]); - if (empty($did)) { - return; - } - - Logger::debug('Found bluesky post', ['url' => $hookData['uri'], 'did' => $did, 'cid' => $matches[2]]); - - $uri = 'at://' . $did . '/app.bsky.feed.post/' . $matches[2]; - $uri = DI::atpProcessor()->fetchMissingPost($uri, $hookData['uid'], Item::PR_FETCHED, 0, 0); - Logger::debug('Got post', ['did' => $did, 'cid' => $matches[2], 'result' => $uri]); + Logger::debug('Got post', ['uri' => $uri]); if (!empty($uri)) { $item = Post::selectFirst(['id'], ['uri' => $uri, 'uid' => $hookData['uid']]); if (!empty($item['id'])) { From f0999a1e46e655a287cc4dbd68136dcc1dc6d3b1 Mon Sep 17 00:00:00 2001 From: Philipp Date: Wed, 1 Jan 2025 20:06:43 +0100 Subject: [PATCH 123/222] [CI] Fix releaser --- .woodpecker/.code_standards_check.yml | 2 +- .woodpecker/.continuous-deployment.yml | 2 +- .woodpecker/.messages.po_check.yml | 2 +- .woodpecker/.phpunit.yml | 2 +- .woodpecker/.releaser.yml | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/.woodpecker/.code_standards_check.yml b/.woodpecker/.code_standards_check.yml index fb5be33c..50872d4c 100644 --- a/.woodpecker/.code_standards_check.yml +++ b/.woodpecker/.code_standards_check.yml @@ -1,6 +1,6 @@ skip_clone: true -pipeline: +steps: clone_friendica_base: image: alpine/git commands: diff --git a/.woodpecker/.continuous-deployment.yml b/.woodpecker/.continuous-deployment.yml index 4d3bc5b7..6b41deae 100644 --- a/.woodpecker/.continuous-deployment.yml +++ b/.woodpecker/.continuous-deployment.yml @@ -5,7 +5,7 @@ labels: skip_clone: true -pipeline: +steps: clone_friendica_base: image: alpine/git commands: diff --git a/.woodpecker/.messages.po_check.yml b/.woodpecker/.messages.po_check.yml index aa40ab4e..e0239dcd 100644 --- a/.woodpecker/.messages.po_check.yml +++ b/.woodpecker/.messages.po_check.yml @@ -1,6 +1,6 @@ skip_clone: true -pipeline: +steps: clone_friendica_base: image: alpine/git commands: diff --git a/.woodpecker/.phpunit.yml b/.woodpecker/.phpunit.yml index 6acbf787..8b840f80 100644 --- a/.woodpecker/.phpunit.yml +++ b/.woodpecker/.phpunit.yml @@ -17,7 +17,7 @@ labels: skip_clone: true -pipeline: +steps: clone_friendica_base: image: alpine/git commands: diff --git a/.woodpecker/.releaser.yml b/.woodpecker/.releaser.yml index f12697b9..2d880a6b 100644 --- a/.woodpecker/.releaser.yml +++ b/.woodpecker/.releaser.yml @@ -5,7 +5,7 @@ labels: skip_clone: true -pipeline: +steps: clone_friendica_base: image: alpine/git commands: From 995e81e951a7525f4aa9bbceb661dd0fc8e548ae Mon Sep 17 00:00:00 2001 From: Philipp Date: Wed, 1 Jan 2025 20:06:43 +0100 Subject: [PATCH 124/222] [CI] Fix releaser --- .woodpecker/.code_standards_check.yml | 2 +- .woodpecker/.continuous-deployment.yml | 2 +- .woodpecker/.messages.po_check.yml | 2 +- .woodpecker/.phpunit.yml | 2 +- .woodpecker/.releaser.yml | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/.woodpecker/.code_standards_check.yml b/.woodpecker/.code_standards_check.yml index fb5be33c..50872d4c 100644 --- a/.woodpecker/.code_standards_check.yml +++ b/.woodpecker/.code_standards_check.yml @@ -1,6 +1,6 @@ skip_clone: true -pipeline: +steps: clone_friendica_base: image: alpine/git commands: diff --git a/.woodpecker/.continuous-deployment.yml b/.woodpecker/.continuous-deployment.yml index 4d3bc5b7..6b41deae 100644 --- a/.woodpecker/.continuous-deployment.yml +++ b/.woodpecker/.continuous-deployment.yml @@ -5,7 +5,7 @@ labels: skip_clone: true -pipeline: +steps: clone_friendica_base: image: alpine/git commands: diff --git a/.woodpecker/.messages.po_check.yml b/.woodpecker/.messages.po_check.yml index aa40ab4e..e0239dcd 100644 --- a/.woodpecker/.messages.po_check.yml +++ b/.woodpecker/.messages.po_check.yml @@ -1,6 +1,6 @@ skip_clone: true -pipeline: +steps: clone_friendica_base: image: alpine/git commands: diff --git a/.woodpecker/.phpunit.yml b/.woodpecker/.phpunit.yml index 6acbf787..8b840f80 100644 --- a/.woodpecker/.phpunit.yml +++ b/.woodpecker/.phpunit.yml @@ -17,7 +17,7 @@ labels: skip_clone: true -pipeline: +steps: clone_friendica_base: image: alpine/git commands: diff --git a/.woodpecker/.releaser.yml b/.woodpecker/.releaser.yml index f12697b9..2d880a6b 100644 --- a/.woodpecker/.releaser.yml +++ b/.woodpecker/.releaser.yml @@ -5,7 +5,7 @@ labels: skip_clone: true -pipeline: +steps: clone_friendica_base: image: alpine/git commands: From d034e311cbe5c45f808baf0c88efd88c484acd76 Mon Sep 17 00:00:00 2001 From: Matthew Exon Date: Sun, 5 Jan 2025 21:51:37 +0100 Subject: [PATCH 125/222] Ratioed: add help link --- ratioed/templates/ratioed.tpl | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/ratioed/templates/ratioed.tpl b/ratioed/templates/ratioed.tpl index 0d81b0d7..5d92bff2 100644 --- a/ratioed/templates/ratioed.tpl +++ b/ratioed/templates/ratioed.tpl @@ -2,7 +2,10 @@
-

{{$title}} - {{$page}} ({{$count}})

+

+ {{$title}} - {{$page}} ({{$count}}) + +

{{$h_newuser}}

From 8e65141cb5e04be141ee0489d28aa8be62155553 Mon Sep 17 00:00:00 2001 From: Matthew Exon Date: Sun, 5 Jan 2025 21:57:18 +0100 Subject: [PATCH 126/222] Ratioed: bump version number --- ratioed/ratioed.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ratioed/ratioed.php b/ratioed/ratioed.php index 8ae0d48c..581ef89b 100644 --- a/ratioed/ratioed.php +++ b/ratioed/ratioed.php @@ -2,7 +2,7 @@ /** * Name: Ratioed * Description: Additional moderation user table with statistics about user behaviour - * Version: 0.1 + * Version: 0.2 * Author: Matthew Exon */ From 2ef9cb8add8bc28a5d6dea9f40276abea2814d97 Mon Sep 17 00:00:00 2001 From: Matthew Exon Date: Sat, 11 Jan 2025 19:36:06 +0100 Subject: [PATCH 127/222] Ratioed: fill in zeroes for empty values --- ratioed/RatioedPanel.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/ratioed/RatioedPanel.php b/ratioed/RatioedPanel.php index bd9b44dc..dac71752 100644 --- a/ratioed/RatioedPanel.php +++ b/ratioed/RatioedPanel.php @@ -175,8 +175,10 @@ class RatioedPanel extends Active $user['ratioed'] = (float)($user['ratio']) >= 2.0; } else { + $user['reactions'] = 0; if ($user['comments'] == 0) { - $user['ratio'] = '0'; + $user['comments'] = 0; + $user['ratio'] = 0; $user['ratioed'] = false; } else { From d495810b2daf9e278cf317df9a12702b136d131c Mon Sep 17 00:00:00 2001 From: Matthew Exon Date: Sat, 11 Jan 2025 19:36:38 +0100 Subject: [PATCH 128/222] Ratioed: allow both sorting directions --- ratioed/RatioedPanel.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/ratioed/RatioedPanel.php b/ratioed/RatioedPanel.php index dac71752..08d94167 100644 --- a/ratioed/RatioedPanel.php +++ b/ratioed/RatioedPanel.php @@ -70,10 +70,10 @@ class RatioedPanel extends Active $order = 'last-item'; $order_direction = '-'; - if (!empty($request['o'])) { - $new_order = $request['o']; - if ($new_order[0] === '-') { - $order_direction = '-'; + if (!empty($_REQUEST['o'])) { + $new_order = $_REQUEST['o']; + if ($new_order[0] === '+') { + $order_direction = '+'; $new_order = substr($new_order, 1); } From 81639ff61574c38769c3693bec6054b1b27bfefc Mon Sep 17 00:00:00 2001 From: Matthew Exon Date: Sat, 11 Jan 2025 19:38:29 +0100 Subject: [PATCH 129/222] Ratioed: fix sorting by columns --- ratioed/templates/ratioed.tpl | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/ratioed/templates/ratioed.tpl b/ratioed/templates/ratioed.tpl index 5d92bff2..d634993e 100644 --- a/ratioed/templates/ratioed.tpl +++ b/ratioed/templates/ratioed.tpl @@ -22,9 +22,9 @@
- + {{if $order_users == $th.1}} {{if $order_direction_users == "+"}} ↓ @@ -66,11 +66,7 @@ {{$u.login_date}}{{$u.lastitem_date}}
From b360b553eddf3a7ad01c06f7b050b1a69734cdc7 Mon Sep 17 00:00:00 2001 From: Matthew Exon Date: Sat, 11 Jan 2025 20:07:18 +0100 Subject: [PATCH 131/222] Ratioed: remove actions --- ratioed/RatioedPanel.php | 30 ++++-------------------------- ratioed/templates/ratioed.tpl | 26 ++------------------------ 2 files changed, 6 insertions(+), 50 deletions(-) diff --git a/ratioed/RatioedPanel.php b/ratioed/RatioedPanel.php index 08d94167..19f6dd44 100644 --- a/ratioed/RatioedPanel.php +++ b/ratioed/RatioedPanel.php @@ -24,7 +24,6 @@ class RatioedPanel extends Active return Renderer::replaceMacros($template, array('$config' => DI::baseUrl() . '/settings/addon')); } - $action = $this->parameters['action'] ?? ''; $uid = $this->parameters['uid'] ?? 0; $user = []; @@ -32,31 +31,10 @@ class RatioedPanel extends Active $user = User::getById($uid, ['username', 'blocked']); if (!$user) { $this->systemMessages->addNotice($this->t('User not found')); - $this->baseUrl->redirect('moderation/users'); + $this->baseUrl->redirect('ratioed'); } } - switch ($action) { - case 'delete': - if ($this->session->getLocalUserId() != $uid) { - self::checkFormSecurityTokenRedirectOnError('moderation/users/active', 'moderation_users_active', 't'); - // delete user - User::remove($uid); - - $this->systemMessages->addNotice($this->t('User "%s" deleted', $user['username'])); - } else { - $this->systemMessages->addNotice($this->t('You can\'t remove yourself')); - } - - $this->baseUrl->redirect('moderation/users/active'); - break; - case 'block': - self::checkFormSecurityTokenRedirectOnError('moderation/users/active', 'moderation_users_active', 't'); - User::block($uid); - $this->systemMessages->addNotice($this->t('User "%s" blocked', $user['username'])); - $this->baseUrl->redirect('moderation/users/active'); - break; - } $pager = new Pager($this->l10n, $this->args->getQueryString(), 100); $valid_orders = [ @@ -69,11 +47,11 @@ class RatioedPanel extends Active ]; $order = 'last-item'; - $order_direction = '-'; + $order_direction = '+'; if (!empty($_REQUEST['o'])) { $new_order = $_REQUEST['o']; - if ($new_order[0] === '+') { - $order_direction = '+'; + if ($new_order[0] === '-') { + $order_direction = '-'; $new_order = substr($new_order, 1); } diff --git a/ratioed/templates/ratioed.tpl b/ratioed/templates/ratioed.tpl index c64cb1dc..24ae20b8 100644 --- a/ratioed/templates/ratioed.tpl +++ b/ratioed/templates/ratioed.tpl @@ -11,12 +11,7 @@
- + {{foreach $th_users as $k=>$th}} {{if $k < 2 || $order_users == $th.1 || ($k==4 && !in_array($order_users,[$th_users.2.1, $th_users.3.1, $th_users.5.1])) }} @@ -42,16 +37,7 @@ {{foreach $users as $u}} - + @@ -151,14 +137,6 @@ {{/foreach}}
-
- - -
-
- {{if $u.is_deletable}} -
- - -
- {{else}} -   - {{/if}} -
{{$u.name}} {{$u.email}}
- {{$pager nofilter}} From 3441c9bd0e7bcf713b5358a3d316c091af1c459a Mon Sep 17 00:00:00 2001 From: Matthew Exon Date: Sun, 5 Jan 2025 00:23:51 +0100 Subject: [PATCH 132/222] Ratioed: add statistics about reply likes and reply guy score --- ratioed/RatioedPanel.php | 137 ++++++++++++++++++++++++++++++++++ ratioed/templates/help.tpl | 57 +++++++++++++- ratioed/templates/ratioed.tpl | 2 +- 3 files changed, 192 insertions(+), 4 deletions(-) diff --git a/ratioed/RatioedPanel.php b/ratioed/RatioedPanel.php index 19f6dd44..33a009cd 100644 --- a/ratioed/RatioedPanel.php +++ b/ratioed/RatioedPanel.php @@ -8,7 +8,9 @@ use Friendica\Core\Renderer; use Friendica\Database\DBA; use Friendica\DI; use Friendica\Model\User; +use Friendica\Model\Verb; use Friendica\Module\Moderation\Users\Active; +use Friendica\Protocol\Activity; /** * This class implements the "Behaviour" panel in Moderation/Users @@ -75,6 +77,11 @@ class RatioedPanel extends Active $this->t('Comments last 24h'), $this->t('Reactions last 24h'), $this->t('Ratio last 24h'), + $this->t('Replies last month'), + $this->t('Reply likes'), + $this->t('Respondee likes'), + $this->t('OP likes'), + $this->t('Reply guy score'), ]; $field_names = [ 'name', @@ -87,6 +94,11 @@ class RatioedPanel extends Active 'comments', 'reactions', 'ratio', + 'reply_count', + 'reply_likes', + 'reply_respondee_likes', + 'reply_op_likes', + 'reply_guy_score', ]; $th_users = array_map(null, $header_titles, $valid_orders, $field_names); @@ -125,6 +137,129 @@ class RatioedPanel extends Active ]); } + protected function getReplyGuyRow($contact_uid) + { + $like_vid = Verb::getID(Activity::LIKE); + $post_vid = Verb::getID(Activity::POST); + + /* + * This is a complicated query. + * + * The innermost select retrieves a chain of four posts: an + * original post, a target comment (possibly deep down in the + * thread), a reply from our user, and a like for that reply. + * If there's no like, we still want to count the reply, so we + * use an outer join. + * + * The second select adds "points" for different kinds of + * likes. The outermost select then counts up these points, + * and the number of distinct replies. + */ + $reply_guy_result = DBA::p(' +SELECT + COUNT(distinct reply_id) AS replies_total, + SUM(like_point) AS like_total, + SUM(target_like_point) AS target_like_total, + SUM(original_like_point) AS original_like_total +FROM ( + SELECT + reply_id, + like_date, + like_date IS NOT NULL AS like_point, + like_author = target_author AS target_like_point, + like_author = original_author AS original_like_point + FROM ( + SELECT + original_post.`uri-id` AS original_id, + original_post.`author-id` AS original_author, + original_post.created AS original_date, + target_post.`uri-id` AS target_id, + target_post.`author-id` AS target_author, + target_post.created AS target_date, + reply_post.`uri-id` AS reply_id, + reply_post.`author-id` AS reply_author, + reply_post.created AS reply_date, + like_post.`uri-id` AS like_id, + like_post.`author-id` AS like_author, + like_post.created AS like_date + FROM + post AS original_post + JOIN + post AS target_post + ON + original_post.`uri-id` = target_post.`parent-uri-id` + JOIN + post AS reply_post + ON + target_post.`uri-id` = reply_post.`thr-parent-id` AND + reply_post.`author-id` = ? AND + reply_post.`author-id` != target_post.`author-id` AND + reply_post.`author-id` != original_post.`author-id` AND + reply_post.`uri-id` != reply_post.`thr-parent-id` AND + reply_post.vid = ? AND + reply_post.created > CURDATE() - INTERVAL 1 MONTH + LEFT OUTER JOIN + post AS like_post + ON + reply_post.`uri-id` = like_post.`thr-parent-id` AND + like_post.vid = ? AND + like_post.`author-id` != reply_post.`author-id` + ) AS post_meta +) AS reply_counts +', $contact_uid, $post_vid, $like_vid); + return $reply_guy_result; + } + + // https://stackoverflow.com/a/48283297/235936 + protected function sigFig($value, $digits) + { + if ($value == 0) { + $decimalPlaces = $digits - 1; + } elseif ($value < 0) { + $decimalPlaces = $digits - floor(log10($value * -1)) - 1; + } else { + $decimalPlaces = $digits - floor(log10($value)) - 1; + } + + $answer = ($decimalPlaces > 0) ? + number_format($value, $decimalPlaces) : round($value, $decimalPlaces); + return $answer; + } + + protected function fillReplyGuyData(&$user) { + $reply_guy_result = $this->getReplyGuyRow($user['user_contact_uid']); + if (DBA::isResult($reply_guy_result)) { + $reply_guy_result_row = DBA::fetch($reply_guy_result); + $user['reply_count'] = $reply_guy_result_row['replies_total'] ?? 0; + $user['reply_likes'] = $reply_guy_result_row['like_total'] ?? 0; + $user['reply_respondee_likes'] = $reply_guy_result_row['target_like_total'] ?? 0; + $user['reply_op_likes'] = $reply_guy_result_row['original_like_total'] ?? 0; + + $denominator = $user['reply_likes'] + $user['reply_respondee_likes'] + $user['reply_op_likes']; + if ($user['reply_count'] == 0) { + $user['reply_guy'] = false; + $user['reply_guy_score'] = 0; + } + elseif ($denominator == 0) { + $user['reply_guy'] = true; + $user['reply_guy_score'] = '∞'; + } + else { + $reply_guy_score = $user['reply_count'] / $denominator; + $user['reply_guy'] = $reply_guy_score >= 1.0; + $user['reply_guy_score'] = $this->sigFig($reply_guy_score, 2); + } + } + else { + $user['reply_count'] = "error"; + $user['reply_likes'] = "error"; + $user['reply_respondee_likes'] = "error"; + $user['reply_op_likes'] = "error"; + $user['reply_guy'] = false; + $user['reply_guy_score'] = 0; + } + } + protected function setupUserCallback(): \Closure { Logger::debug("ratioed: setupUserCallback"); @@ -179,6 +314,8 @@ class RatioedPanel extends Active $user['ratioed'] = false; } + $this->fillReplyGuyData($user); + $user = $parentCallback($user); Logger::debug("ratioed: setupUserCallback", [ 'uid' => $user['uid'], diff --git a/ratioed/templates/help.tpl b/ratioed/templates/help.tpl index fee47e34..db6480cf 100644 --- a/ratioed/templates/help.tpl +++ b/ratioed/templates/help.tpl @@ -2,7 +2,7 @@

Ratioed Plugin Help

- This plugin provides administrators with additional statistics about + This plugin provides moderators with additional statistics about the behaviour of users. These may be useful as early warning signs that warrant more carefully watching the behaviour of a user. They are not suitable as a trigger for instantly blocking, @@ -28,7 +28,7 @@

This plugin allows viewing of an actual ratio, calculated over the last 24 hours. This is a useful timeframe for sudden dogpiling - events that administrators might not otherwise notice. The plugin + events that moderators might not otherwise notice. The plugin also calculates other statistics.

Explanation of Statistics

@@ -68,10 +68,61 @@ 24h". It is intended to approximate the traditional ratio as understood on Twitter.

+

Replies last month

+

+ This is the number of times the user posted a reply to someone any time in the last month. +

+

Reply likes

+

+ This is the number of likes received by the user on their + replies to other people's posts in the last month. Replies that + receive likes can be assumed to be more of a valuable + contribution than replies that do not. +

+

Respondee likes

+

+ The number of times in the last month the user replied to + someone else's comment and that person then liked the reply. + Likes to replies are not necessarily a positive thing, but if + the person you're replying to approves the reply, that's a very + good sign. Of course it's also common in a debate for neither + side to like the other side's comments, but the debate still can + be valuable. +

+

OP likes

+

+ The number of times in the last month the user replied on a + thread and the original poster that started the thread liked the + reply. While there is no formal concept of "ownership" of a + thread, conventionally the original poster is assumed to have + started the thread for a reason, and making replies that do not + fulfil that purpose are bad etiquette. Getting approval from + the original poster therefore is a good sign that the user is + posting replies that are wanted. +

+

Reply guy score

+

+ A "reply + guy" is a common Internet phenomenon of people (disproportionately male) + posting unwanted comments on other (disproportionately female) + people's threads, derailing the + conversation. This score loosely approximates this phenomenon, + as the ratio betwen the number of replies and the sum of likes, + respondee likes, and OP likes. This formula gives extra weight + to particularly relevant likes: a reply to a top-level post that + is liked by the original poster scores the maximum of 3 + "points". A score above 1.0 might indicate cause for concern + for moderators. +

+

+ Since this is indicative of long-term behaviour, the score is + calculated over a month instead of 24 hours. +

+

Performance

The statistics are computed from scratch each time the page loads. - It's possible that this might put a heavy load on the database. and + It's possible that this might put a heavy load on the database, and the page may take a long time to load.

Extending

diff --git a/ratioed/templates/ratioed.tpl b/ratioed/templates/ratioed.tpl index 24ae20b8..6ee6b1d0 100644 --- a/ratioed/templates/ratioed.tpl +++ b/ratioed/templates/ratioed.tpl @@ -36,7 +36,7 @@ {{foreach $users as $u}} - + {{$u.name}} From 8ba4cd5f6140a1ad64ad5404e603ed76b8d535f3 Mon Sep 17 00:00:00 2001 From: Matthew Exon Date: Sat, 11 Jan 2025 19:42:03 +0100 Subject: [PATCH 133/222] Ratioed: bump version number --- ratioed/ratioed.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ratioed/ratioed.php b/ratioed/ratioed.php index 581ef89b..443fdaa9 100644 --- a/ratioed/ratioed.php +++ b/ratioed/ratioed.php @@ -2,7 +2,7 @@ /** * Name: Ratioed * Description: Additional moderation user table with statistics about user behaviour - * Version: 0.2 + * Version: 0.3 * Author: Matthew Exon */ From 807598dbd03b9dca3c3ac7d890fe0cb2f8a1bb9f Mon Sep 17 00:00:00 2001 From: Matthew Exon Date: Wed, 15 Jan 2025 19:32:55 +0100 Subject: [PATCH 134/222] Ratioed: wrap long lines --- ratioed/templates/help.tpl | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/ratioed/templates/help.tpl b/ratioed/templates/help.tpl index db6480cf..0d012ca7 100644 --- a/ratioed/templates/help.tpl +++ b/ratioed/templates/help.tpl @@ -70,7 +70,9 @@

Replies last month

- This is the number of times the user posted a reply to someone any time in the last month. + This is the number of times the user posted a reply to someone + else, on a thread the user did not start, any time in the last + month.

Reply likes

@@ -86,8 +88,8 @@ Likes to replies are not necessarily a positive thing, but if the person you're replying to approves the reply, that's a very good sign. Of course it's also common in a debate for neither - side to like the other side's comments, but the debate still can - be valuable. + side to like the other side's comments without that indicating + an unhealthy interaction, so interpret this statistic cautiously.

OP likes

@@ -103,10 +105,10 @@

Reply guy score

A "reply - guy" is a common Internet phenomenon of people (disproportionately male) - posting unwanted comments on other (disproportionately female) - people's threads, derailing the - conversation. This score loosely approximates this phenomenon, + guy" is a common Internet phenomenon of people + (disproportionately male) posting unwanted comments on other + (disproportionately female) people's threads, derailing the + conversation. This score loosely quantifies this phenomenon, as the ratio betwen the number of replies and the sum of likes, respondee likes, and OP likes. This formula gives extra weight to particularly relevant likes: a reply to a top-level post that From ee8c852d38cd74ca770a8d2445c4975607260bfc Mon Sep 17 00:00:00 2001 From: Matthew Exon Date: Wed, 15 Jan 2025 19:33:11 +0100 Subject: [PATCH 135/222] Ratioed: remove action buttons --- ratioed/templates/ratioed.tpl | 13 +------------ 1 file changed, 1 insertion(+), 12 deletions(-) diff --git a/ratioed/templates/ratioed.tpl b/ratioed/templates/ratioed.tpl index 6ee6b1d0..2413ed9d 100644 --- a/ratioed/templates/ratioed.tpl +++ b/ratioed/templates/ratioed.tpl @@ -121,18 +121,7 @@ {{/foreach}} - - {{if $u.is_deletable}} - - - - - - - {{else}} -   - {{/if}} - + {{/foreach}} From cb70a4eaffa1e603c5a910211118deab02e519e8 Mon Sep 17 00:00:00 2001 From: Michael Date: Sat, 18 Jan 2025 15:25:50 +0000 Subject: [PATCH 136/222] Fix codestyle --- ratioed/RatioedPanel.php | 111 ++++++++++++++++++--------------------- 1 file changed, 52 insertions(+), 59 deletions(-) diff --git a/ratioed/RatioedPanel.php b/ratioed/RatioedPanel.php index 33a009cd..d0fac8ad 100644 --- a/ratioed/RatioedPanel.php +++ b/ratioed/RatioedPanel.php @@ -163,47 +163,47 @@ SELECT SUM(original_like_point) AS original_like_total FROM ( SELECT - reply_id, - like_date, - like_date IS NOT NULL AS like_point, - like_author = target_author AS target_like_point, - like_author = original_author AS original_like_point + reply_id, + like_date, + like_date IS NOT NULL AS like_point, + like_author = target_author AS target_like_point, + like_author = original_author AS original_like_point FROM ( - SELECT - original_post.`uri-id` AS original_id, - original_post.`author-id` AS original_author, - original_post.created AS original_date, - target_post.`uri-id` AS target_id, - target_post.`author-id` AS target_author, - target_post.created AS target_date, - reply_post.`uri-id` AS reply_id, - reply_post.`author-id` AS reply_author, - reply_post.created AS reply_date, - like_post.`uri-id` AS like_id, - like_post.`author-id` AS like_author, - like_post.created AS like_date - FROM - post AS original_post - JOIN - post AS target_post - ON - original_post.`uri-id` = target_post.`parent-uri-id` - JOIN - post AS reply_post - ON - target_post.`uri-id` = reply_post.`thr-parent-id` AND - reply_post.`author-id` = ? AND - reply_post.`author-id` != target_post.`author-id` AND - reply_post.`author-id` != original_post.`author-id` AND - reply_post.`uri-id` != reply_post.`thr-parent-id` AND - reply_post.vid = ? AND - reply_post.created > CURDATE() - INTERVAL 1 MONTH - LEFT OUTER JOIN - post AS like_post - ON - reply_post.`uri-id` = like_post.`thr-parent-id` AND - like_post.vid = ? AND - like_post.`author-id` != reply_post.`author-id` + SELECT + original_post.`uri-id` AS original_id, + original_post.`author-id` AS original_author, + original_post.created AS original_date, + target_post.`uri-id` AS target_id, + target_post.`author-id` AS target_author, + target_post.created AS target_date, + reply_post.`uri-id` AS reply_id, + reply_post.`author-id` AS reply_author, + reply_post.created AS reply_date, + like_post.`uri-id` AS like_id, + like_post.`author-id` AS like_author, + like_post.created AS like_date + FROM + post AS original_post + JOIN + post AS target_post + ON + original_post.`uri-id` = target_post.`parent-uri-id` + JOIN + post AS reply_post + ON + target_post.`uri-id` = reply_post.`thr-parent-id` AND + reply_post.`author-id` = ? AND + reply_post.`author-id` != target_post.`author-id` AND + reply_post.`author-id` != original_post.`author-id` AND + reply_post.`uri-id` != reply_post.`thr-parent-id` AND + reply_post.vid = ? AND + reply_post.created > CURDATE() - INTERVAL 1 MONTH + LEFT OUTER JOIN + post AS like_post + ON + reply_post.`uri-id` = like_post.`thr-parent-id` AND + like_post.vid = ? AND + like_post.`author-id` != reply_post.`author-id` ) AS post_meta ) AS reply_counts ', $contact_uid, $post_vid, $like_vid); @@ -226,7 +226,8 @@ FROM ( return $answer; } - protected function fillReplyGuyData(&$user) { + protected function fillReplyGuyData(&$user) + { $reply_guy_result = $this->getReplyGuyRow($user['user_contact_uid']); if (DBA::isResult($reply_guy_result)) { $reply_guy_result_row = DBA::fetch($reply_guy_result); @@ -235,22 +236,19 @@ FROM ( $user['reply_respondee_likes'] = $reply_guy_result_row['target_like_total'] ?? 0; $user['reply_op_likes'] = $reply_guy_result_row['original_like_total'] ?? 0; - $denominator = $user['reply_likes'] + $user['reply_respondee_likes'] + $user['reply_op_likes']; + $denominator = (int)($user['reply_likes'] + $user['reply_respondee_likes'] + $user['reply_op_likes']); if ($user['reply_count'] == 0) { $user['reply_guy'] = false; $user['reply_guy_score'] = 0; - } - elseif ($denominator == 0) { + } elseif ($denominator == 0) { $user['reply_guy'] = true; $user['reply_guy_score'] = '∞'; - } - else { + } else { $reply_guy_score = $user['reply_count'] / $denominator; $user['reply_guy'] = $reply_guy_score >= 1.0; $user['reply_guy_score'] = $this->sigFig($reply_guy_score, 2); } - } - else { + } else { $user['reply_count'] = "error"; $user['reply_likes'] = "error"; $user['reply_respondee_likes'] = "error"; @@ -272,9 +270,8 @@ FROM ( if (DBA::isResult($self_contact_result)) { $self_contact_result_row = DBA::fetch($self_contact_result); $user['user_contact_uid'] = $self_contact_result_row['user_contact_uid']; - } - else { - $user['user_contact_uid'] = NULL; + } else { + $user['user_contact_uid'] = null; } if ($user['user_contact_uid']) { @@ -286,28 +283,24 @@ FROM ( if ($user['reactions'] > 0) { $user['ratio'] = number_format($user['comments'] / $user['reactions'], 1, '.', ''); $user['ratioed'] = (float)($user['ratio']) >= 2.0; - } - else { + } else { $user['reactions'] = 0; if ($user['comments'] == 0) { $user['comments'] = 0; $user['ratio'] = 0; $user['ratioed'] = false; - } - else { + } else { $user['ratio'] = '∞'; $user['ratioed'] = false; } } - } - else { + } else { $user['comments'] = 'error'; $user['reactions'] = 'error'; $user['ratio'] = 'error'; $user['ratioed'] = false; } - } - else { + } else { $user['comments'] = 'error'; $user['reactions'] = 'error'; $user['ratio'] = 'error'; From 0d0aae36cd1a5a646ddbad15e1a4f548d6f14073 Mon Sep 17 00:00:00 2001 From: Matthew Exon Date: Wed, 22 Jan 2025 08:30:30 +0100 Subject: [PATCH 137/222] Clean up phpstan warning --- ratioed/RatioedPanel.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ratioed/RatioedPanel.php b/ratioed/RatioedPanel.php index d0fac8ad..b611b256 100644 --- a/ratioed/RatioedPanel.php +++ b/ratioed/RatioedPanel.php @@ -236,7 +236,7 @@ FROM ( $user['reply_respondee_likes'] = $reply_guy_result_row['target_like_total'] ?? 0; $user['reply_op_likes'] = $reply_guy_result_row['original_like_total'] ?? 0; - $denominator = (int)($user['reply_likes'] + $user['reply_respondee_likes'] + $user['reply_op_likes']); + $denominator = intval($user['reply_likes']) + intval($user['reply_respondee_likes']) + intval($user['reply_op_likes']); if ($user['reply_count'] == 0) { $user['reply_guy'] = false; $user['reply_guy_score'] = 0; From 2741227bfa8bb174d29a69399403f72b94e00ba2 Mon Sep 17 00:00:00 2001 From: Art4 Date: Wed, 22 Jan 2025 08:42:18 +0000 Subject: [PATCH 138/222] Add phpstan in woodpacker --- .woodpecker/.code_standards_check.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.woodpecker/.code_standards_check.yml b/.woodpecker/.code_standards_check.yml index 50872d4c..60a1bd2a 100644 --- a/.woodpecker/.code_standards_check.yml +++ b/.woodpecker/.code_standards_check.yml @@ -56,6 +56,10 @@ steps: - /tmp/drone-cache:/tmp/cache when: event: pull_request + phpstan: + image: friendicaci/php8.3:php8.3.3 + commands: + - ./bin/composer.phar run phpstan; check: image: friendicaci/php-cs commands: From 7a7940a8eddcd39279afc953ea136ff78f854f8a Mon Sep 17 00:00:00 2001 From: Art4 Date: Wed, 22 Jan 2025 08:46:57 +0000 Subject: [PATCH 139/222] Fix PHPStan errors --- ratioed/RatioedPanel.php | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/ratioed/RatioedPanel.php b/ratioed/RatioedPanel.php index b611b256..91665640 100644 --- a/ratioed/RatioedPanel.php +++ b/ratioed/RatioedPanel.php @@ -231,13 +231,13 @@ FROM ( $reply_guy_result = $this->getReplyGuyRow($user['user_contact_uid']); if (DBA::isResult($reply_guy_result)) { $reply_guy_result_row = DBA::fetch($reply_guy_result); - $user['reply_count'] = $reply_guy_result_row['replies_total'] ?? 0; - $user['reply_likes'] = $reply_guy_result_row['like_total'] ?? 0; - $user['reply_respondee_likes'] = $reply_guy_result_row['target_like_total'] ?? 0; - $user['reply_op_likes'] = $reply_guy_result_row['original_like_total'] ?? 0; + $user['reply_count'] = (int) $reply_guy_result_row['replies_total'] ?? 0; + $user['reply_likes'] = (int) $reply_guy_result_row['like_total'] ?? 0; + $user['reply_respondee_likes'] = (int) $reply_guy_result_row['target_like_total'] ?? 0; + $user['reply_op_likes'] = (int) $reply_guy_result_row['original_like_total'] ?? 0; - $denominator = intval($user['reply_likes']) + intval($user['reply_respondee_likes']) + intval($user['reply_op_likes']); - if ($user['reply_count'] == 0) { + $denominator = $user['reply_likes'] + $user['reply_respondee_likes'] + $user['reply_op_likes']; + if ($user['reply_count'] === 0) { $user['reply_guy'] = false; $user['reply_guy_score'] = 0; } elseif ($denominator == 0) { From 2b5764c132bb02390d8a417bc80e0fb28f83df07 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakobus=20Sch=C3=BCrz?= Date: Wed, 15 Jan 2025 10:42:08 +0100 Subject: [PATCH 140/222] rework saml addon fix #1587 remove css-side hiding of elements, which was broken. remove them or make them readonly via javascript --- saml/saml.css | 1 - saml/saml.php | 9 ++++----- 2 files changed, 4 insertions(+), 6 deletions(-) delete mode 100644 saml/saml.css diff --git a/saml/saml.css b/saml/saml.css deleted file mode 100644 index 087633cd..00000000 --- a/saml/saml.css +++ /dev/null @@ -1 +0,0 @@ -#settings-form > div:first-of-type, #settings-form > h2:first-of-type, #wrapper_mpassword, #wrapper_email { display: none !important; } diff --git a/saml/saml.php b/saml/saml.php index 9f065355..f3dd1774 100755 --- a/saml/saml.php +++ b/saml/saml.php @@ -75,11 +75,6 @@ function saml_install() Hook::register('footer', __FILE__, 'saml_footer'); } -function saml_head(string &$body) -{ - DI::page()->registerStylesheet(__DIR__ . '/saml.css'); -} - function saml_footer(string &$body) { $fragment = addslashes(BBCode::convertForUriId(User::getSystemUriId(), DI::config()->get('saml', 'settings_statement'))); @@ -87,6 +82,10 @@ function saml_footer(string &$body) EOL; } From 792f50f835ebb9181f7d627282e582a153373a1b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakobus=20Sch=C3=BCrz?= Date: Thu, 16 Jan 2025 18:53:05 +0100 Subject: [PATCH 141/222] fix view in vier and frio --- saml/saml.php | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/saml/saml.php b/saml/saml.php index f3dd1774..7fdafc1e 100755 --- a/saml/saml.php +++ b/saml/saml.php @@ -83,9 +83,22 @@ function saml_footer(string &$body) var target=$("#settings-nickname-desc"); if (target.length) { target.append("

$fragment

"); } document.getElementById('id_email').setAttribute('readonly', 'readonly'); -document.getElementById('password-settings').remove(); -document.getElementById('password-settings-collapse').remove(); -document.getElementById('id_mpassword_wrapper').remove(); +if ( document.getElementById('password-settings') != null ) { + document.getElementById('password-settings').remove(); +} +if ( document.getElementById('password-settings-collapse') != null ) { + document.getElementById('password-settings-collapse').remove(); +} +if ( document.getElementById('id_mpassword_wrapper') != null ) { + document.getElementById('id_mpassword_wrapper').remove(); +} +if ( document.getElementById('wrapper_mpassword') != null ) { + document.getElementById('wrapper_mpassword').remove(); +} +if ( document.getElementById('wrapper_password') != null ) { + document.getElementById('wrapper_password').parentNode.parentNode.children[0].remove(); + document.getElementById('wrapper_password').parentNode.remove(); +} EOL; } From c50636727361a153b5ed5f445ab6afed9497e663 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakobus=20Sch=C3=BCrz?= Date: Fri, 17 Jan 2025 03:04:31 +0100 Subject: [PATCH 142/222] replace password-handling with hint also add hint to email-field --- saml/saml.php | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/saml/saml.php b/saml/saml.php index 7fdafc1e..81a6bfcc 100755 --- a/saml/saml.php +++ b/saml/saml.php @@ -78,26 +78,32 @@ function saml_install() function saml_footer(string &$body) { $fragment = addslashes(BBCode::convertForUriId(User::getSystemUriId(), DI::config()->get('saml', 'settings_statement'))); + $samlhint = DI::l10n()->t('managed via SAML authentication'); $body .= << var target=$("#settings-nickname-desc"); if (target.length) { target.append("

$fragment

"); } document.getElementById('id_email').setAttribute('readonly', 'readonly'); -if ( document.getElementById('password-settings') != null ) { - document.getElementById('password-settings').remove(); -} +var saml_hint = document.createElement("span"); +var saml_hint_text = document.createTextNode('$samlhint'); +saml_hint.appendChild(saml_hint_text); +document.getElementById('id_email').parentNode.insertBefore(saml_hint, document.getElementById('id_email').nextSibling); +// Frio theme if ( document.getElementById('password-settings-collapse') != null ) { - document.getElementById('password-settings-collapse').remove(); + document.getElementById('password-settings-collapse').replaceChildren(saml_hint.cloneNode(true)); } if ( document.getElementById('id_mpassword_wrapper') != null ) { + document.getElementById('id_mpassword_wrapper').parentNode.appendChild(saml_hint.cloneNode(true)); document.getElementById('id_mpassword_wrapper').remove(); + document.getElementById('id_email').nextElementSibling.classList.add('help-block'); } +// Vier theme if ( document.getElementById('wrapper_mpassword') != null ) { document.getElementById('wrapper_mpassword').remove(); + document.getElementById('id_email').nextElementSibling.classList.add('field_help'); } if ( document.getElementById('wrapper_password') != null ) { - document.getElementById('wrapper_password').parentNode.parentNode.children[0].remove(); - document.getElementById('wrapper_password').parentNode.remove(); + document.getElementById('wrapper_password').parentNode.replaceChildren(saml_hint.cloneNode(true)); } EOL; From 0b4aaac9fd16bc26511f226ed470fb4e18395e22 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakobus=20Sch=C3=BCrz?= Date: Fri, 17 Jan 2025 03:24:17 +0100 Subject: [PATCH 143/222] translation for saml-hint --- saml/lang/C/messages.po | 82 ++++++++++++++++++++--------------------- 1 file changed, 41 insertions(+), 41 deletions(-) diff --git a/saml/lang/C/messages.po b/saml/lang/C/messages.po index 05579568..b4a4c8ce 100644 --- a/saml/lang/C/messages.po +++ b/saml/lang/C/messages.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2021-05-18 07:23+0200\n" +"POT-Creation-Date: 2025-01-17 03:23+0100\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -17,82 +17,82 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -#: saml.php:231 +#: saml.php:81 +msgid "managed via SAML authentication" +msgstr "" + +#: saml.php:246 msgid "Settings statement" msgstr "" -#: saml.php:232 -msgid "" -"A statement on the settings page explaining where the user should go to " -"change their e-mail and password. BBCode allowed." -msgstr "" - -#: saml.php:237 -msgid "IdP ID" -msgstr "" - -#: saml.php:238 -msgid "" -"Identity provider (IdP) entity URI (e.g., https://example.com/auth/realms/" -"user)." -msgstr "" - -#: saml.php:242 -msgid "Client ID" -msgstr "" - -#: saml.php:243 -msgid "Identifier assigned to client by the identity provider (IdP)." -msgstr "" - #: saml.php:247 -msgid "IdP SSO URL" -msgstr "" - -#: saml.php:248 -msgid "The URL for your identity provider's SSO endpoint." +msgid "A statement on the settings page explaining where the user should go to change their e-mail and password. BBCode allowed." msgstr "" #: saml.php:252 -msgid "IdP SLO request URL" +msgid "IdP ID" msgstr "" #: saml.php:253 -msgid "The URL for your identity provider's SLO request endpoint." +msgid "Identity provider (IdP) entity URI (e.g., https://example.com/auth/realms/user)." msgstr "" #: saml.php:257 -msgid "IdP SLO response URL" +msgid "Client ID" msgstr "" #: saml.php:258 -msgid "The URL for your identity provider's SLO response endpoint." +msgid "Identifier assigned to client by the identity provider (IdP)." msgstr "" #: saml.php:262 -msgid "SP private key" +msgid "IdP SSO URL" msgstr "" #: saml.php:263 -msgid "The private key the addon should use to authenticate." +msgid "The URL for your identity provider's SSO endpoint." msgstr "" #: saml.php:267 -msgid "SP certificate" +msgid "IdP SLO request URL" msgstr "" #: saml.php:268 -msgid "The certficate for the addon's private key." +msgid "The URL for your identity provider's SLO request endpoint." msgstr "" #: saml.php:272 -msgid "IdP certificate" +msgid "IdP SLO response URL" msgstr "" #: saml.php:273 +msgid "The URL for your identity provider's SLO response endpoint." +msgstr "" + +#: saml.php:277 +msgid "SP private key" +msgstr "" + +#: saml.php:278 +msgid "The private key the addon should use to authenticate." +msgstr "" + +#: saml.php:282 +msgid "SP certificate" +msgstr "" + +#: saml.php:283 +msgid "The certficate for the addon's private key." +msgstr "" + +#: saml.php:287 +msgid "IdP certificate" +msgstr "" + +#: saml.php:288 msgid "The x509 certficate for your identity provider." msgstr "" -#: saml.php:276 +#: saml.php:291 msgid "Save Settings" msgstr "" From 4310c1355d42e7d0c9f071866c06624afd324f3a Mon Sep 17 00:00:00 2001 From: Art4 Date: Fri, 24 Jan 2025 10:53:01 +0000 Subject: [PATCH 144/222] Replace call for Logger with DI::logger() --- advancedcontentfilter/advancedcontentfilter.php | 3 +-- birdavatar/birdavatar.php | 3 +-- blackout/blackout.php | 3 +-- catavatar/catavatar.php | 3 +-- fromapp/fromapp.php | 3 +-- geonames/geonames.php | 3 +-- gnot/gnot.php | 3 +-- googlemaps/googlemaps.php | 3 +-- gravatar/gravatar.php | 3 +-- impressum/impressum.php | 3 +-- keycloakpassword/keycloakpassword.php | 3 +-- krynn/krynn.php | 3 +-- leistungsschutzrecht/leistungsschutzrecht.php | 3 +-- libravatar/libravatar.php | 3 +-- newmemberwidget/newmemberwidget.php | 3 +-- numfriends/numfriends.php | 3 +-- opmlexport/opmlexport.php | 3 +-- piwik/piwik.php | 3 +-- pumpio/pumpio_sync.php | 4 ++-- securemail/securemail.php | 3 +-- 20 files changed, 21 insertions(+), 40 deletions(-) diff --git a/advancedcontentfilter/advancedcontentfilter.php b/advancedcontentfilter/advancedcontentfilter.php index c03034cd..aeeff77c 100644 --- a/advancedcontentfilter/advancedcontentfilter.php +++ b/advancedcontentfilter/advancedcontentfilter.php @@ -36,7 +36,6 @@ use Friendica\BaseModule; use Friendica\Content\Text\Markdown; use Friendica\Core\Hook; -use Friendica\Core\Logger; use Friendica\Core\Renderer; use Friendica\Database\DBA; use Friendica\Database\DBStructure; @@ -62,7 +61,7 @@ function advancedcontentfilter_install() Hook::add('dbstructure_definition' , __FILE__, 'advancedcontentfilter_dbstructure_definition'); DBStructure::performUpdate(); - Logger::notice('installed advancedcontentfilter'); + DI::logger()->notice('installed advancedcontentfilter'); } /* diff --git a/birdavatar/birdavatar.php b/birdavatar/birdavatar.php index 9a9dce0a..cd49b183 100644 --- a/birdavatar/birdavatar.php +++ b/birdavatar/birdavatar.php @@ -7,7 +7,6 @@ */ use Friendica\Core\Hook; -use Friendica\Core\Logger; use Friendica\Core\Renderer; use Friendica\Database\DBA; use Friendica\DI; @@ -27,7 +26,7 @@ function birdavatar_install() Hook::register('addon_settings', __FILE__, 'birdavatar_addon_settings'); Hook::register('addon_settings_post', __FILE__, 'birdavatar_addon_settings_post'); - Logger::info('registered birdavatar'); + DI::logger()->info('registered birdavatar'); } /** diff --git a/blackout/blackout.php b/blackout/blackout.php index a3f806ff..ac1ee3e6 100644 --- a/blackout/blackout.php +++ b/blackout/blackout.php @@ -45,7 +45,6 @@ */ use Friendica\Core\Hook; -use Friendica\Core\Logger; use Friendica\Core\Renderer; use Friendica\Core\System; use Friendica\DI; @@ -77,7 +76,7 @@ function blackout_redirect ($b) } if (( $date1 <= $now ) && ( $now <= $date2 )) { - Logger::notice('redirecting user to blackout page'); + DI::logger()->notice('redirecting user to blackout page'); System::externalRedirect($myurl); } } diff --git a/catavatar/catavatar.php b/catavatar/catavatar.php index 2bdf0cca..7b5f05c0 100644 --- a/catavatar/catavatar.php +++ b/catavatar/catavatar.php @@ -7,7 +7,6 @@ */ use Friendica\Core\Hook; -use Friendica\Core\Logger; use Friendica\Core\Renderer; use Friendica\Database\DBA; use Friendica\DI; @@ -27,7 +26,7 @@ function catavatar_install() Hook::register('addon_settings', __FILE__, 'catavatar_addon_settings'); Hook::register('addon_settings_post', __FILE__, 'catavatar_addon_settings_post'); - Logger::notice('registered catavatar'); + DI::logger()->notice('registered catavatar'); } /** diff --git a/fromapp/fromapp.php b/fromapp/fromapp.php index 8bd27606..bb8a4fe6 100644 --- a/fromapp/fromapp.php +++ b/fromapp/fromapp.php @@ -8,7 +8,6 @@ */ use Friendica\Core\Hook; -use Friendica\Core\Logger; use Friendica\Core\Renderer; use Friendica\DI; @@ -17,7 +16,7 @@ function fromapp_install() Hook::register('post_local', 'addon/fromapp/fromapp.php', 'fromapp_post_hook'); Hook::register('addon_settings', 'addon/fromapp/fromapp.php', 'fromapp_settings'); Hook::register('addon_settings_post', 'addon/fromapp/fromapp.php', 'fromapp_settings_post'); - Logger::notice("installed fromapp"); + DI::logger()->notice("installed fromapp"); } function fromapp_settings_post($post) diff --git a/geonames/geonames.php b/geonames/geonames.php index d14b1e8f..4c5e54d8 100644 --- a/geonames/geonames.php +++ b/geonames/geonames.php @@ -7,7 +7,6 @@ */ use Friendica\Core\Hook; -use Friendica\Core\Logger; use Friendica\Core\Renderer; use Friendica\DI; use Friendica\Core\Config\Util\ConfigFileManager; @@ -45,7 +44,7 @@ function geonames_post_hook(array &$item) * - The profile owner must have allowed our addon */ - Logger::notice('geonames invoked'); + DI::logger()->notice('geonames invoked'); if (!DI::userSession()->getLocalUserId()) { /* non-zero if this is a logged in user of this system */ return; diff --git a/gnot/gnot.php b/gnot/gnot.php index 5d0919cb..3801a210 100644 --- a/gnot/gnot.php +++ b/gnot/gnot.php @@ -9,7 +9,6 @@ */ use Friendica\Core\Hook; -use Friendica\Core\Logger; use Friendica\Core\Renderer; use Friendica\DI; use Friendica\Model\Notification; @@ -20,7 +19,7 @@ function gnot_install() Hook::register('addon_settings_post', 'addon/gnot/gnot.php', 'gnot_settings_post'); Hook::register('enotify_mail', 'addon/gnot/gnot.php', 'gnot_enotify_mail'); - Logger::notice("installed gnot"); + DI::logger()->notice("installed gnot"); } /** diff --git a/googlemaps/googlemaps.php b/googlemaps/googlemaps.php index b83a9cf9..a0bba8ad 100644 --- a/googlemaps/googlemaps.php +++ b/googlemaps/googlemaps.php @@ -8,13 +8,12 @@ */ use Friendica\Core\Hook; -use Friendica\Core\Logger; function googlemaps_install() { Hook::register('render_location', 'addon/googlemaps/googlemaps.php', 'googlemaps_location'); - Logger::notice('installed googlemaps'); + DI::logger()->notice('installed googlemaps'); } function googlemaps_location(&$item) diff --git a/gravatar/gravatar.php b/gravatar/gravatar.php index 6007c433..7fe0d955 100644 --- a/gravatar/gravatar.php +++ b/gravatar/gravatar.php @@ -8,7 +8,6 @@ use Friendica\BaseModule; use Friendica\Core\Hook; -use Friendica\Core\Logger; use Friendica\Core\Renderer; use Friendica\DI; use Friendica\Core\Config\Util\ConfigFileManager; @@ -20,7 +19,7 @@ function gravatar_install() { Hook::register('load_config', 'addon/gravatar/gravatar.php', 'gravatar_load_config'); Hook::register('avatar_lookup', 'addon/gravatar/gravatar.php', 'gravatar_lookup'); - Logger::notice("registered gravatar in avatar_lookup hook"); + DI::logger()->notice("registered gravatar in avatar_lookup hook"); } function gravatar_load_config(ConfigFileManager $loader) diff --git a/impressum/impressum.php b/impressum/impressum.php index f61d7182..0ad34e40 100644 --- a/impressum/impressum.php +++ b/impressum/impressum.php @@ -9,7 +9,6 @@ use Friendica\Content\Text\BBCode; use Friendica\Core\Hook; -use Friendica\Core\Logger; use Friendica\Core\Renderer; use Friendica\DI; use Friendica\Core\Config\Util\ConfigFileManager; @@ -20,7 +19,7 @@ function impressum_install() Hook::register('load_config', 'addon/impressum/impressum.php', 'impressum_load_config'); Hook::register('about_hook', 'addon/impressum/impressum.php', 'impressum_show'); Hook::register('page_end', 'addon/impressum/impressum.php', 'impressum_footer'); - Logger::notice("installed impressum Addon"); + DI::logger()->notice("installed impressum Addon"); } /** diff --git a/keycloakpassword/keycloakpassword.php b/keycloakpassword/keycloakpassword.php index e9809f86..11034ffe 100644 --- a/keycloakpassword/keycloakpassword.php +++ b/keycloakpassword/keycloakpassword.php @@ -7,7 +7,6 @@ */ use Friendica\Core\Hook; -use Friendica\Core\Logger; use Friendica\Core\Renderer; use Friendica\Database\DBA; use Friendica\DI; @@ -37,7 +36,7 @@ function keycloakpassword_request($client_id, $secret, $url, $params = []) $res = curl_exec($ch); if (curl_errno($ch)) { - Logger::error(curl_error($ch)); + DI::logger()->error(curl_error($ch)); } curl_close($ch); diff --git a/krynn/krynn.php b/krynn/krynn.php index fa9db133..b57d827e 100644 --- a/krynn/krynn.php +++ b/krynn/krynn.php @@ -11,7 +11,6 @@ */ use Friendica\Core\Hook; -use Friendica\Core\Logger; use Friendica\Core\Renderer; use Friendica\DI; @@ -31,7 +30,7 @@ function krynn_install() Hook::register('addon_settings', 'addon/krynn/krynn.php', 'krynn_settings'); Hook::register('addon_settings_post', 'addon/krynn/krynn.php', 'krynn_settings_post'); - Logger::notice("installed krynn"); + DI::logger()->notice("installed krynn"); } function krynn_post_hook(&$item) diff --git a/leistungsschutzrecht/leistungsschutzrecht.php b/leistungsschutzrecht/leistungsschutzrecht.php index ec8091ac..891cb6ca 100644 --- a/leistungsschutzrecht/leistungsschutzrecht.php +++ b/leistungsschutzrecht/leistungsschutzrecht.php @@ -7,7 +7,6 @@ */ use Friendica\Core\Hook; -use Friendica\Core\Logger; use Friendica\DI; function leistungsschutzrecht_install() @@ -168,7 +167,7 @@ function leistungsschutzrecht_cron($b) if ($last) { $next = $last + 86400; if ($next > time()) { - Logger::notice('poll intervall not reached'); + DI::logger()->notice('poll intervall not reached'); return; } } diff --git a/libravatar/libravatar.php b/libravatar/libravatar.php index 4cd72c83..6cb35331 100644 --- a/libravatar/libravatar.php +++ b/libravatar/libravatar.php @@ -8,7 +8,6 @@ use Friendica\Core\Addon; use Friendica\Core\Hook; -use Friendica\Core\Logger; use Friendica\Core\Renderer; use Friendica\DI; use Friendica\Core\Config\Util\ConfigFileManager; @@ -20,7 +19,7 @@ function libravatar_install() { Hook::register('load_config', 'addon/libravatar/libravatar.php', 'libravatar_load_config'); Hook::register('avatar_lookup', 'addon/libravatar/libravatar.php', 'libravatar_lookup'); - Logger::notice("registered libravatar in avatar_lookup hook"); + DI::logger()->notice("registered libravatar in avatar_lookup hook"); } function libravatar_load_config(ConfigFileManager $loader) diff --git a/newmemberwidget/newmemberwidget.php b/newmemberwidget/newmemberwidget.php index d3b68807..ba7dfb39 100644 --- a/newmemberwidget/newmemberwidget.php +++ b/newmemberwidget/newmemberwidget.php @@ -8,7 +8,6 @@ use Friendica\Content\Text\BBCode; use Friendica\Core\Hook; -use Friendica\Core\Logger; use Friendica\Core\Renderer; use Friendica\DI; use Friendica\Model\User; @@ -16,7 +15,7 @@ use Friendica\Model\User; function newmemberwidget_install() { Hook::register( 'network_mod_init', 'addon/newmemberwidget/newmemberwidget.php', 'newmemberwidget_network_mod_init'); - Logger::notice('newmemberwidget installed'); + DI::logger()->notice('newmemberwidget installed'); } function newmemberwidget_network_mod_init ($b) diff --git a/numfriends/numfriends.php b/numfriends/numfriends.php index 66c9b74a..5652c8f0 100644 --- a/numfriends/numfriends.php +++ b/numfriends/numfriends.php @@ -7,7 +7,6 @@ */ use Friendica\Core\Hook; -use Friendica\Core\Logger; use Friendica\Core\Renderer; use Friendica\DI; @@ -16,7 +15,7 @@ function numfriends_install() { Hook::register('addon_settings', 'addon/numfriends/numfriends.php', 'numfriends_settings'); Hook::register('addon_settings_post', 'addon/numfriends/numfriends.php', 'numfriends_settings_post'); - Logger::notice("installed numfriends"); + DI::logger()->notice("installed numfriends"); } /** diff --git a/opmlexport/opmlexport.php b/opmlexport/opmlexport.php index 3df71275..be1d335c 100644 --- a/opmlexport/opmlexport.php +++ b/opmlexport/opmlexport.php @@ -9,7 +9,6 @@ use Friendica\DI; use Friendica\Core\Hook; -use Friendica\Core\Logger; use Friendica\Core\Protocol; use Friendica\Model\Contact; use Friendica\Model\User; @@ -18,7 +17,7 @@ function opmlexport_install() { Hook::register('addon_settings', __FILE__, 'opmlexport_addon_settings'); Hook::register('addon_settings_post', __FILE__, 'opmlexport_addon_settings_post'); - Logger::notice('installed opmlexport Addon'); + DI::logger()->notice('installed opmlexport Addon'); } diff --git a/piwik/piwik.php b/piwik/piwik.php index fc459a87..b7e9e71c 100644 --- a/piwik/piwik.php +++ b/piwik/piwik.php @@ -36,7 +36,6 @@ */ use Friendica\Core\Hook; -use Friendica\Core\Logger; use Friendica\Core\Renderer; use Friendica\DI; use Friendica\Core\Config\Util\ConfigFileManager; @@ -45,7 +44,7 @@ function piwik_install() { Hook::register('load_config', 'addon/piwik/piwik.php', 'piwik_load_config'); Hook::register('page_end', 'addon/piwik/piwik.php', 'piwik_analytics'); - Logger::notice("installed piwik addon"); + DI::logger()->notice("installed piwik addon"); } function piwik_load_config(ConfigFileManager $loader) diff --git a/pumpio/pumpio_sync.php b/pumpio/pumpio_sync.php index beaf6e81..09548c6d 100644 --- a/pumpio/pumpio_sync.php +++ b/pumpio/pumpio_sync.php @@ -1,5 +1,5 @@ DI::config()->get('system', 'maxloadavg', 50)) { - Logger::notice('system: load ' . $load[0] . ' too high. Pumpio sync deferred to next scheduled run.'); + DI::logger()->notice('system: load ' . $load[0] . ' too high. Pumpio sync deferred to next scheduled run.'); return; } } diff --git a/securemail/securemail.php b/securemail/securemail.php index b56c0cbc..7b412395 100644 --- a/securemail/securemail.php +++ b/securemail/securemail.php @@ -8,7 +8,6 @@ use Friendica\Addon\securemail\SecureTestEmail; use Friendica\Core\Hook; -use Friendica\Core\Logger; use Friendica\Core\Renderer; use Friendica\DI; use Friendica\Object\EMail\IEmail; @@ -22,7 +21,7 @@ function securemail_install() Hook::register('emailer_send_prepare', 'addon/securemail/securemail.php', 'securemail_emailer_send_prepare', 10); - Logger::notice('installed securemail'); + DI::logger()->notice('installed securemail'); } /** From 41f280f0c71f214e7d2c803363e83c4d5ca7dac6 Mon Sep 17 00:00:00 2001 From: Art4 Date: Fri, 24 Jan 2025 11:34:33 +0000 Subject: [PATCH 145/222] Replace call for Logger with DI::logger() in blockbot addon --- blockbot/blockbot.php | 41 ++++++++++++++++++++--------------------- 1 file changed, 20 insertions(+), 21 deletions(-) diff --git a/blockbot/blockbot.php b/blockbot/blockbot.php index 022f188d..163d0cbc 100644 --- a/blockbot/blockbot.php +++ b/blockbot/blockbot.php @@ -11,7 +11,6 @@ use Friendica\Core\Hook; use Friendica\DI; use Jaybizzle\CrawlerDetect\CrawlerDetect; -use Friendica\Core\Logger; use Friendica\Core\Renderer; use Friendica\Core\System; use Friendica\Network\HTTPException\ForbiddenException; @@ -70,7 +69,7 @@ function blockbot_init_1() } if (empty($parts)) { - Logger::debug('Known frontend found - accept', $logdata); + DI::logger()->debug('Known frontend found - accept', $logdata); if ($isCrawler) { blockbot_save('badly-parsed-agents', $_SERVER['HTTP_USER_AGENT']); } @@ -80,66 +79,66 @@ function blockbot_init_1() blockbot_log_activitypub($_SERVER['REQUEST_URI'], $_SERVER['HTTP_USER_AGENT']); if (blockbot_is_crawler($parts)) { - Logger::debug('Crawler found - reject', $logdata); + DI::logger()->debug('Crawler found - reject', $logdata); blockbot_reject(); } if (blockbot_is_searchbot($parts)) { - Logger::debug('Search bot found - reject', $logdata); + DI::logger()->debug('Search bot found - reject', $logdata); blockbot_reject(); } if (blockbot_is_unwanted($parts)) { - Logger::debug('Uncategorized unwanted agent found - reject', $logdata); + DI::logger()->debug('Uncategorized unwanted agent found - reject', $logdata); blockbot_reject(); } if (blockbot_is_security_checker($parts)) { if (!DI::config()->get('blockbot', 'security_checker')) { - Logger::debug('Security checker found - reject', $logdata); + DI::logger()->debug('Security checker found - reject', $logdata); blockbot_reject(); } - Logger::debug('Security checker found - accept', $logdata); + DI::logger()->debug('Security checker found - accept', $logdata); return; } if (blockbot_is_social_media($parts)) { - Logger::debug('Social media service found - accept', $logdata); + DI::logger()->debug('Social media service found - accept', $logdata); return; } if (blockbot_is_fediverse_client($parts)) { - Logger::debug('Fediverse client found - accept', $logdata); + DI::logger()->debug('Fediverse client found - accept', $logdata); return; } if (blockbot_is_feed_reader($parts)) { - Logger::debug('Feed reader found - accept', $logdata); + DI::logger()->debug('Feed reader found - accept', $logdata); return; } if (blockbot_is_fediverse_tool($parts)) { - Logger::debug('Fediverse tool found - accept', $logdata); + DI::logger()->debug('Fediverse tool found - accept', $logdata); return; } if (blockbot_is_service_agent($parts)) { - Logger::debug('Service agent found - accept', $logdata); + DI::logger()->debug('Service agent found - accept', $logdata); return; } if (blockbot_is_monitor($parts)) { - Logger::debug('Monitoring service found - accept', $logdata); + DI::logger()->debug('Monitoring service found - accept', $logdata); return; } if (blockbot_is_validator($parts)) { - Logger::debug('Validation service found - accept', $logdata); + DI::logger()->debug('Validation service found - accept', $logdata); return; } if (blockbot_is_good_tool($parts)) { - Logger::debug('Uncategorized helpful service found - accept', $logdata); + DI::logger()->debug('Uncategorized helpful service found - accept', $logdata); return; } @@ -147,10 +146,10 @@ function blockbot_init_1() if (blockbot_is_http_library($parts)) { blockbot_check_login_attempt($_SERVER['REQUEST_URI'], $logdata); if (!DI::config()->get('blockbot', 'http_libraries')) { - Logger::debug('HTTP Library found - reject', $logdata); + DI::logger()->debug('HTTP Library found - reject', $logdata); blockbot_reject(); } - Logger::debug('HTTP Library found - accept', $logdata); + DI::logger()->debug('HTTP Library found - accept', $logdata); return; } @@ -161,12 +160,12 @@ function blockbot_init_1() if (!$isCrawler) { blockbot_save('good-agents', $_SERVER['HTTP_USER_AGENT']); - Logger::debug('Non-bot user agent detected', $logdata); + DI::logger()->debug('Non-bot user agent detected', $logdata); return; } blockbot_save('bad-agents', $_SERVER['HTTP_USER_AGENT']); - Logger::notice('Possible bot found - reject', $logdata); + DI::logger()->notice('Possible bot found - reject', $logdata); blockbot_reject(); } @@ -217,7 +216,7 @@ function blockbot_log_activitypub(string $url, string $agent) function blockbot_check_login_attempt(string $url, array $logdata) { if (in_array(trim(parse_url($url, PHP_URL_PATH), '/'), ['login', 'lostpass', 'register'])) { - Logger::debug('Login attempt detected - reject', $logdata); + DI::logger()->debug('Login attempt detected - reject', $logdata); blockbot_reject(); } } @@ -443,7 +442,7 @@ function blockbot_is_monitor(array $parts): bool } /** - * Services in the centralized and decentralized social media environment + * Services in the centralized and decentralized social media environment * * @param array $parts * @return boolean From d78ea50516c67f871ddb49ca18328379a95b4d57 Mon Sep 17 00:00:00 2001 From: Art4 Date: Fri, 24 Jan 2025 11:36:23 +0000 Subject: [PATCH 146/222] Replace call for Logger with DI::logger() in bluesky addon --- bluesky/bluesky.php | 95 +++++++++++++++---------------- bluesky/bluesky_feed.php | 6 +- bluesky/bluesky_notifications.php | 6 +- bluesky/bluesky_timeline.php | 6 +- 4 files changed, 56 insertions(+), 57 deletions(-) diff --git a/bluesky/bluesky.php b/bluesky/bluesky.php index 5bf07afb..7f6bb9e7 100644 --- a/bluesky/bluesky.php +++ b/bluesky/bluesky.php @@ -30,7 +30,6 @@ use Friendica\Content\Text\Plaintext; use Friendica\Core\Cache\Enum\Duration; use Friendica\Core\Config\Util\ConfigFileManager; use Friendica\Core\Hook; -use Friendica\Core\Logger; use Friendica\Core\Protocol; use Friendica\Core\Renderer; use Friendica\Core\Worker; @@ -106,16 +105,16 @@ function bluesky_item_by_link(array &$hookData) if (empty($did)) { return; } - - Logger::debug('Found bluesky post', ['uri' => $hookData['uri'], 'did' => $did, 'cid' => $matches[2]]); - + + DI::logger()->debug('Found bluesky post', ['uri' => $hookData['uri'], 'did' => $did, 'cid' => $matches[2]]); + $uri = 'at://' . $did . '/app.bsky.feed.post/' . $matches[2]; } else { $uri = $hookData['uri']; } $uri = DI::atpProcessor()->fetchMissingPost($uri, $hookData['uid'], Item::PR_FETCHED, 0, 0); - Logger::debug('Got post', ['uri' => $uri]); + DI::logger()->debug('Got post', ['uri' => $uri]); if (!empty($uri)) { $item = Post::selectFirst(['id'], ['uri' => $uri, 'uid' => $hookData['uid']]); if (!empty($item['id'])) { @@ -138,7 +137,7 @@ function bluesky_follow(array &$hook_data) return; } - Logger::debug('Check if contact is bluesky', ['data' => $hook_data]); + DI::logger()->debug('Check if contact is bluesky', ['data' => $hook_data]); $contact = DBA::selectFirst('contact', [], ['network' => Protocol::BLUESKY, 'url' => $hook_data['url'], 'uid' => [0, $hook_data['uid']]]); if (empty($contact)) { return; @@ -159,7 +158,7 @@ function bluesky_follow(array &$hook_data) $activity = DI::atProtocol()->XRPCPost($hook_data['uid'], 'com.atproto.repo.createRecord', $post); if (!empty($activity->uri)) { $hook_data['contact'] = $contact; - Logger::debug('Successfully start following', ['url' => $contact['url'], 'uri' => $activity->uri]); + DI::logger()->debug('Successfully start following', ['url' => $contact['url'], 'uri' => $activity->uri]); } } @@ -213,7 +212,7 @@ function bluesky_block(array &$hook_data) if ($ucid) { Contact::remove($ucid); } - Logger::debug('Successfully blocked contact', ['url' => $hook_data['contact']['url'], 'uri' => $activity->uri]); + DI::logger()->debug('Successfully blocked contact', ['url' => $hook_data['contact']['url'], 'uri' => $activity->uri]); } } @@ -421,11 +420,11 @@ function bluesky_cron() if ($last) { $next = $last + ($poll_interval * 60); if ($next > time()) { - Logger::notice('poll interval not reached'); + DI::logger()->notice('poll interval not reached'); return; } } - Logger::notice('cron_start'); + DI::logger()->notice('cron_start'); $abandon_days = intval(DI::config()->get('system', 'account_abandon_days')); if ($abandon_days < 1) { @@ -437,19 +436,19 @@ function bluesky_cron() $pconfigs = DBA::selectToArray('pconfig', [], ["`cat` = ? AND `k` IN (?, ?) AND `v`", 'bluesky', 'import', 'import_feeds']); foreach ($pconfigs as $pconfig) { if (empty(DI::atProtocol()->getUserDid($pconfig['uid']))) { - Logger::debug('User has got no valid DID', ['uid' => $pconfig['uid']]); + DI::logger()->debug('User has got no valid DID', ['uid' => $pconfig['uid']]); continue; } if ($abandon_days != 0) { if (!DBA::exists('user', ["`uid` = ? AND `login_date` >= ?", $pconfig['uid'], $abandon_limit])) { - Logger::notice('abandoned account: timeline from user will not be imported', ['user' => $pconfig['uid']]); + DI::logger()->notice('abandoned account: timeline from user will not be imported', ['user' => $pconfig['uid']]); continue; } } // Refresh the token now, so that it doesn't need to be refreshed in parallel by the following workers - Logger::debug('Refresh the token', ['uid' => $pconfig['uid']]); + DI::logger()->debug('Refresh the token', ['uid' => $pconfig['uid']]); DI::atProtocol()->getUserToken($pconfig['uid']); $last_sync = DI::pConfig()->get($pconfig['uid'], 'bluesky', 'last_contact_sync'); @@ -463,32 +462,32 @@ function bluesky_cron() Worker::add(['priority' => Worker::PRIORITY_MEDIUM, 'force_priority' => true], 'addon/bluesky/bluesky_timeline.php', $pconfig['uid']); } if (DI::pConfig()->get($pconfig['uid'], 'bluesky', 'import_feeds')) { - Logger::debug('Fetch feeds for user', ['uid' => $pconfig['uid']]); + DI::logger()->debug('Fetch feeds for user', ['uid' => $pconfig['uid']]); $feeds = bluesky_get_feeds($pconfig['uid']); foreach ($feeds as $feed) { Worker::add(['priority' => Worker::PRIORITY_MEDIUM, 'force_priority' => true], 'addon/bluesky/bluesky_feed.php', $pconfig['uid'], $feed); } } - Logger::debug('Polling done for user', ['uid' => $pconfig['uid']]); + DI::logger()->debug('Polling done for user', ['uid' => $pconfig['uid']]); } - Logger::notice('Polling done for all users'); + DI::logger()->notice('Polling done for all users'); DI::keyValue()->set('bluesky_last_poll', time()); $last_clean = DI::keyValue()->get('bluesky_last_clean'); if (empty($last_clean) || ($last_clean + 86400 < time())) { - Logger::notice('Start contact cleanup'); + DI::logger()->notice('Start contact cleanup'); $contacts = DBA::select('account-user-view', ['id', 'pid'], ["`network` = ? AND `uid` != ? AND `rel` = ?", Protocol::BLUESKY, 0, Contact::NOTHING]); while ($contact = DBA::fetch($contacts)) { Worker::add(Worker::PRIORITY_LOW, 'MergeContact', $contact['pid'], $contact['id'], 0); } DBA::close($contacts); DI::keyValue()->set('bluesky_last_clean', time()); - Logger::notice('Contact cleanup done'); + DI::logger()->notice('Contact cleanup done'); } - Logger::notice('cron_end'); + DI::logger()->notice('cron_end'); } function bluesky_hook_fork(array &$b) @@ -508,7 +507,7 @@ function bluesky_hook_fork(array &$b) if (DI::pConfig()->get($post['uid'], 'bluesky', 'import')) { // Don't post if it isn't a reply to a bluesky post if (($post['gravity'] != Item::GRAVITY_PARENT) && !Post::exists(['id' => $post['parent'], 'network' => Protocol::BLUESKY])) { - Logger::notice('No bluesky parent found', ['item' => $post['id']]); + DI::logger()->notice('No bluesky parent found', ['item' => $post['id']]); $b['execute'] = false; return; } @@ -555,12 +554,12 @@ function bluesky_send(array &$b) } if ($b['gravity'] != Item::GRAVITY_PARENT) { - Logger::debug('Got comment', ['item' => $b]); + DI::logger()->debug('Got comment', ['item' => $b]); if ($b['deleted']) { $uri = DI::atpProcessor()->getUriClass($b['uri']); if (empty($uri)) { - Logger::debug('Not a bluesky post', ['uri' => $b['uri']]); + DI::logger()->debug('Not a bluesky post', ['uri' => $b['uri']]); return; } bluesky_delete_post($b['uri'], $b['uid']); @@ -571,12 +570,12 @@ function bluesky_send(array &$b) $parent = DI::atpProcessor()->getUriClass($b['thr-parent']); if (empty($root) || empty($parent)) { - Logger::debug('No bluesky post', ['parent' => $b['parent'], 'thr-parent' => $b['thr-parent']]); + DI::logger()->debug('No bluesky post', ['parent' => $b['parent'], 'thr-parent' => $b['thr-parent']]); return; } if ($b['gravity'] == Item::GRAVITY_COMMENT) { - Logger::debug('Posting comment', ['root' => $root, 'parent' => $parent]); + DI::logger()->debug('Posting comment', ['root' => $root, 'parent' => $parent]); bluesky_create_post($b, $root, $parent); return; } elseif (in_array($b['verb'], [Activity::LIKE, Activity::ANNOUNCE])) { @@ -635,10 +634,10 @@ function bluesky_create_activity(array $item, stdClass $parent = null) if (empty($activity->uri)) { return; } - Logger::debug('Activity done', ['return' => $activity]); + DI::logger()->debug('Activity done', ['return' => $activity]); $uri = DI::atpProcessor()->getUri($activity); Item::update(['extid' => $uri], ['guid' => $item['guid']]); - Logger::debug('Set extid', ['id' => $item['id'], 'extid' => $activity]); + DI::logger()->debug('Set extid', ['id' => $item['id'], 'extid' => $activity]); } function bluesky_create_post(array $item, stdClass $root = null, stdClass $parent = null) @@ -722,14 +721,14 @@ function bluesky_create_post(array $item, stdClass $root = null, stdClass $paren } return; } - Logger::debug('Posting done', ['return' => $parent]); + DI::logger()->debug('Posting done', ['return' => $parent]); if (empty($root)) { $root = $parent; } if (($key == 0) && ($item['gravity'] != Item::GRAVITY_PARENT)) { $uri = DI::atpProcessor()->getUri($parent); Item::update(['extid' => $uri], ['guid' => $item['guid']]); - Logger::debug('Set extid', ['id' => $item['id'], 'extid' => $uri]); + DI::logger()->debug('Set extid', ['id' => $item['id'], 'extid' => $uri]); } } } @@ -899,20 +898,20 @@ function bluesky_upload_blob(int $uid, array $photo): ?stdClass $new_size = strlen($content); if (($size != 0) && ($new_size == 0) && ($retrial == 0)) { - Logger::warning('Size is empty after resize, uploading original file', ['uid' => $uid, 'retrial' => $retrial, 'height' => $new_height, 'width' => $new_width, 'size' => $new_size, 'orig-height' => $height, 'orig-width' => $width, 'orig-size' => $size]); + DI::logger()->warning('Size is empty after resize, uploading original file', ['uid' => $uid, 'retrial' => $retrial, 'height' => $new_height, 'width' => $new_width, 'size' => $new_size, 'orig-height' => $height, 'orig-width' => $width, 'orig-size' => $size]); $content = Photo::getImageForPhoto($photo); } else { - Logger::info('Uploading', ['uid' => $uid, 'retrial' => $retrial, 'height' => $new_height, 'width' => $new_width, 'size' => $new_size, 'orig-height' => $height, 'orig-width' => $width, 'orig-size' => $size]); + DI::logger()->info('Uploading', ['uid' => $uid, 'retrial' => $retrial, 'height' => $new_height, 'width' => $new_width, 'size' => $new_size, 'orig-height' => $height, 'orig-width' => $width, 'orig-size' => $size]); } $data = DI::atProtocol()->post($uid, '/xrpc/com.atproto.repo.uploadBlob', $content, ['Content-type' => $photo['type'], 'Authorization' => ['Bearer ' . DI::atProtocol()->getUserToken($uid)]]); if (empty($data) || empty($data->blob)) { - Logger::info('Uploading failed', ['uid' => $uid, 'retrial' => $retrial, 'height' => $new_height, 'width' => $new_width, 'size' => $new_size, 'orig-height' => $height, 'orig-width' => $width, 'orig-size' => $size]); + DI::logger()->info('Uploading failed', ['uid' => $uid, 'retrial' => $retrial, 'height' => $new_height, 'width' => $new_width, 'size' => $new_size, 'orig-height' => $height, 'orig-width' => $width, 'orig-size' => $size]); return null; } Item::incrementOutbound(Protocol::BLUESKY); - Logger::debug('Uploaded blob', ['return' => $data, 'uid' => $uid, 'retrial' => $retrial, 'height' => $new_height, 'width' => $new_width, 'size' => $new_size, 'orig-height' => $height, 'orig-width' => $width, 'orig-size' => $size]); + DI::logger()->debug('Uploaded blob', ['return' => $data, 'uid' => $uid, 'retrial' => $retrial, 'height' => $new_height, 'width' => $new_width, 'size' => $new_size, 'orig-height' => $height, 'orig-width' => $width, 'orig-size' => $size]); return $data->blob; } @@ -920,11 +919,11 @@ function bluesky_delete_post(string $uri, int $uid) { $parts = DI::atpProcessor()->getUriParts($uri); if (empty($parts)) { - Logger::debug('No uri delected', ['uri' => $uri]); + DI::logger()->debug('No uri delected', ['uri' => $uri]); return; } DI::atProtocol()->XRPCPost($uid, 'com.atproto.repo.deleteRecord', $parts); - Logger::debug('Deleted', ['parts' => $parts]); + DI::logger()->debug('Deleted', ['parts' => $parts]); } function bluesky_fetch_timeline(int $uid) @@ -1026,10 +1025,10 @@ function bluesky_fetch_notifications(int $uid) foreach ($data->notifications as $notification) { $uri = DI::atpProcessor()->getUri($notification); if (Post::exists(['uri' => $uri, 'uid' => $uid]) || Post::exists(['extid' => $uri, 'uid' => $uid])) { - Logger::debug('Notification already processed', ['uid' => $uid, 'reason' => $notification->reason, 'uri' => $uri, 'indexedAt' => $notification->indexedAt]); + DI::logger()->debug('Notification already processed', ['uid' => $uid, 'reason' => $notification->reason, 'uri' => $uri, 'indexedAt' => $notification->indexedAt]); continue; } - Logger::debug('Process notification', ['uid' => $uid, 'reason' => $notification->reason, 'uri' => $uri, 'indexedAt' => $notification->indexedAt]); + DI::logger()->debug('Process notification', ['uid' => $uid, 'reason' => $notification->reason, 'uri' => $uri, 'indexedAt' => $notification->indexedAt]); switch ($notification->reason) { case 'like': $item = DI::atpProcessor()->getHeaderFromPost($notification, $uri, $uid, Conversation::PARCEL_CONNECTOR); @@ -1039,9 +1038,9 @@ function bluesky_fetch_notifications(int $uid) $item['thr-parent'] = DI::atpProcessor()->fetchMissingPost($item['thr-parent'], $uid, Item::PR_FETCHED, $item['contact-id'], 0); if (!empty($item['thr-parent'])) { $data = Item::insert($item); - Logger::debug('Got like', ['uid' => $uid, 'result' => $data, 'uri' => $uri]); + DI::logger()->debug('Got like', ['uid' => $uid, 'result' => $data, 'uri' => $uri]); } else { - Logger::info('Thread parent not found', ['uid' => $uid, 'parent' => $item['thr-parent'], 'uri' => $uri]); + DI::logger()->info('Thread parent not found', ['uid' => $uid, 'parent' => $item['thr-parent'], 'uri' => $uri]); } break; @@ -1053,37 +1052,37 @@ function bluesky_fetch_notifications(int $uid) $item['thr-parent'] = DI::atpProcessor()->fetchMissingPost($item['thr-parent'], $uid, Item::PR_FETCHED, $item['contact-id'], 0); if (!empty($item['thr-parent'])) { $data = Item::insert($item); - Logger::debug('Got repost', ['uid' => $uid, 'result' => $data, 'uri' => $uri]); + DI::logger()->debug('Got repost', ['uid' => $uid, 'result' => $data, 'uri' => $uri]); } else { - Logger::info('Thread parent not found', ['uid' => $uid, 'parent' => $item['thr-parent'], 'uri' => $uri]); + DI::logger()->info('Thread parent not found', ['uid' => $uid, 'parent' => $item['thr-parent'], 'uri' => $uri]); } break; case 'follow': $contact = DI::atpActor()->getContactByDID($notification->author->did, $uid, $uid); - Logger::debug('New follower', ['uid' => $uid, 'nick' => $contact['nick'], 'uri' => $uri]); + DI::logger()->debug('New follower', ['uid' => $uid, 'nick' => $contact['nick'], 'uri' => $uri]); break; case 'mention': $contact = DI::atpActor()->getContactByDID($notification->author->did, $uid, 0); $result = DI::atpProcessor()->fetchMissingPost($uri, $uid, Item::PR_TO, $contact['id'], 0); - Logger::debug('Got mention', ['uid' => $uid, 'nick' => $contact['nick'], 'result' => $result, 'uri' => $uri]); + DI::logger()->debug('Got mention', ['uid' => $uid, 'nick' => $contact['nick'], 'result' => $result, 'uri' => $uri]); break; case 'reply': $contact = DI::atpActor()->getContactByDID($notification->author->did, $uid, 0); $result = DI::atpProcessor()->fetchMissingPost($uri, $uid, Item::PR_COMMENT, $contact['id'], 0); - Logger::debug('Got reply', ['uid' => $uid, 'nick' => $contact['nick'], 'result' => $result, 'uri' => $uri]); + DI::logger()->debug('Got reply', ['uid' => $uid, 'nick' => $contact['nick'], 'result' => $result, 'uri' => $uri]); break; case 'quote': $contact = DI::atpActor()->getContactByDID($notification->author->did, $uid, 0); $result = DI::atpProcessor()->fetchMissingPost($uri, $uid, Item::PR_PUSHED, $contact['id'], 0); - Logger::debug('Got quote', ['uid' => $uid, 'nick' => $contact['nick'], 'result' => $result, 'uri' => $uri]); + DI::logger()->debug('Got quote', ['uid' => $uid, 'nick' => $contact['nick'], 'result' => $result, 'uri' => $uri]); break; default: - Logger::notice('Unhandled reason', ['reason' => $notification->reason, 'uri' => $uri]); + DI::logger()->notice('Unhandled reason', ['reason' => $notification->reason, 'uri' => $uri]); break; } } @@ -1114,16 +1113,16 @@ function bluesky_fetch_feed(int $uid, string $feed) $languages = $entry->post->record->langs ?? []; if (!Relay::isWantedLanguage($entry->post->record->text, 0, $contact['id'] ?? 0, $languages)) { - Logger::debug('Unwanted language detected', ['languages' => $languages, 'text' => $entry->post->record->text]); + DI::logger()->debug('Unwanted language detected', ['languages' => $languages, 'text' => $entry->post->record->text]); continue; } $causer = DI::atpActor()->getContactByDID($entry->post->author->did, $uid, 0); $uri_id = bluesky_complete_post($entry->post, $uid, Item::PR_TAG, $causer['id'], Conversation::PARCEL_CONNECTOR); if (!empty($uri_id)) { $stored = Post\Category::storeFileByURIId($uri_id, $uid, Post\Category::SUBCRIPTION, $feedname, $feedurl); - Logger::debug('Stored tag subscription for user', ['uri-id' => $uri_id, 'uid' => $uid, 'name' => $feedname, 'url' => $feedurl, 'stored' => $stored]); + DI::logger()->debug('Stored tag subscription for user', ['uri-id' => $uri_id, 'uid' => $uid, 'name' => $feedname, 'url' => $feedurl, 'stored' => $stored]); } else { - Logger::notice('Post not found', ['entry' => $entry]); + DI::logger()->notice('Post not found', ['entry' => $entry]); } if (!empty($entry->reason)) { bluesky_process_reason($entry->reason, DI::atpProcessor()->getUri($entry->post), $uid); diff --git a/bluesky/bluesky_feed.php b/bluesky/bluesky_feed.php index a20ef1b9..e4aa3fdc 100644 --- a/bluesky/bluesky_feed.php +++ b/bluesky/bluesky_feed.php @@ -1,6 +1,6 @@ $argv[1], 'feed' => $argv[2]]); + DI::logger()->debug('Importing feed - start', ['user' => $argv[1], 'feed' => $argv[2]]); bluesky_fetch_feed($argv[1], $argv[2]); - Logger::debug('Importing feed - done', ['user' => $argv[1], 'feed' => $argv[2]]); + DI::logger()->debug('Importing feed - done', ['user' => $argv[1], 'feed' => $argv[2]]); } diff --git a/bluesky/bluesky_notifications.php b/bluesky/bluesky_notifications.php index 1fbc8f67..e1bf2047 100644 --- a/bluesky/bluesky_notifications.php +++ b/bluesky/bluesky_notifications.php @@ -1,6 +1,6 @@ $argv[1]]); + DI::logger()->notice('importing notifications - start', ['user' => $argv[1]]); bluesky_fetch_notifications($argv[1]); - Logger::notice('importing notifications - done', ['user' => $argv[1]]); + DI::logger()->notice('importing notifications - done', ['user' => $argv[1]]); } diff --git a/bluesky/bluesky_timeline.php b/bluesky/bluesky_timeline.php index fda846ba..37b22d99 100644 --- a/bluesky/bluesky_timeline.php +++ b/bluesky/bluesky_timeline.php @@ -1,6 +1,6 @@ $argv[1]]); + DI::logger()->notice('importing timeline - start', ['user' => $argv[1]]); bluesky_fetch_timeline($argv[1]); - Logger::notice('importing timeline - done', ['user' => $argv[1]]); + DI::logger()->notice('importing timeline - done', ['user' => $argv[1]]); } From 77ebaca28102deb1c8ae398aeb18903c5188d0a6 Mon Sep 17 00:00:00 2001 From: Art4 Date: Fri, 24 Jan 2025 11:37:28 +0000 Subject: [PATCH 147/222] Replace call for Logger with DI::logger() in ratioed addon --- ratioed/RatioedPanel.php | 5 ++--- ratioed/ratioed.php | 7 +++---- 2 files changed, 5 insertions(+), 7 deletions(-) diff --git a/ratioed/RatioedPanel.php b/ratioed/RatioedPanel.php index 91665640..4cf5d7ff 100644 --- a/ratioed/RatioedPanel.php +++ b/ratioed/RatioedPanel.php @@ -3,7 +3,6 @@ namespace Friendica\Addon\ratioed; use Friendica\Content\Pager; -use Friendica\Core\Logger; use Friendica\Core\Renderer; use Friendica\Database\DBA; use Friendica\DI; @@ -260,7 +259,7 @@ FROM ( protected function setupUserCallback(): \Closure { - Logger::debug("ratioed: setupUserCallback"); + DI::logger()->debug("ratioed: setupUserCallback"); $parentCallback = parent::setupUserCallback(); return function ($user) use ($parentCallback) { $blocked_count = DBA::count('user-contact', ['uid' => $user['uid'], 'is-blocked' => 1]); @@ -310,7 +309,7 @@ FROM ( $this->fillReplyGuyData($user); $user = $parentCallback($user); - Logger::debug("ratioed: setupUserCallback", [ + DI::logger()->debug("ratioed: setupUserCallback", [ 'uid' => $user['uid'], 'blocked_by' => $user['blocked_by'], 'comments' => $user['comments'], diff --git a/ratioed/ratioed.php b/ratioed/ratioed.php index 443fdaa9..5cc6d539 100644 --- a/ratioed/ratioed.php +++ b/ratioed/ratioed.php @@ -8,7 +8,6 @@ use Friendica\Addon\ratioed\RatioedPanel; use Friendica\Core\Hook; -use Friendica\Core\Logger; use Friendica\DI; /** @@ -18,7 +17,7 @@ function ratioed_install() { Hook::register('moderation_users_tabs', 'addon/ratioed/ratioed.php', 'ratioed_users_tabs'); - Logger::info("ratioed: installed"); + DI::logger()->info("ratioed: installed"); } /** @@ -34,7 +33,7 @@ function ratioed_module() {} * @param array $arr Parameters, including "tabs" which is the list to modify, and "selectedTab", which is the currently selected tab ID */ function ratioed_users_tabs(array &$arr) { - Logger::debug("ratioed: users tabs"); + DI::logger()->debug("ratioed: users tabs"); array_push($arr['tabs'], [ 'label' => DI::l10n()->t('Behaviour'), @@ -50,7 +49,7 @@ function ratioed_users_tabs(array &$arr) { * @brief Displays the ratioed tab in the moderation panel */ function ratioed_content() { - Logger::debug("ratioed: content"); + DI::logger()->debug("ratioed: content"); $ratioed = DI::getDice()->create(RatioedPanel::class, [$_SERVER]); $httpException = DI::getDice()->create(Friendica\Module\Special\HTTPException::class); From 1d1a00df275d19e81fdf44580d126c2affc89f74 Mon Sep 17 00:00:00 2001 From: Art4 Date: Fri, 24 Jan 2025 11:37:58 +0000 Subject: [PATCH 148/222] Replace call for Logger with DI::logger() in cld addon --- cld/cld.php | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/cld/cld.php b/cld/cld.php index 83361e2b..d4fef6c5 100644 --- a/cld/cld.php +++ b/cld/cld.php @@ -7,7 +7,6 @@ */ use Friendica\Core\Hook; -use Friendica\Core\Logger; use Friendica\DI; function cld_install() @@ -18,17 +17,17 @@ function cld_install() function cld_detect_languages(array &$data) { if (!in_array('cld2', get_loaded_extensions())) { - Logger::warning('CLD2 is not installed.'); + DI::logger()->warning('CLD2 is not installed.'); return; } if (!class_exists('CLD2Detector')) { - Logger::warning('CLD2Detector class does not exist.'); + DI::logger()->warning('CLD2Detector class does not exist.'); return; } if (!class_exists('CLD2Encoding')) { - Logger::warning('CLD2Encoding class does not exist.'); + DI::logger()->warning('CLD2Encoding class does not exist.'); return; } @@ -53,7 +52,7 @@ function cld_detect_languages(array &$data) } if (!$result['is_reliable']) { - Logger::debug('Unreliable detection', ['uri-id' => $data['uri-id'], 'original' => $original, 'detected' => $detected, 'name' => $result['language_name'], 'probability' => $result['language_probability'], 'text' => $data['text']]); + DI::logger()->debug('Unreliable detection', ['uri-id' => $data['uri-id'], 'original' => $original, 'detected' => $detected, 'name' => $result['language_name'], 'probability' => $result['language_probability'], 'text' => $data['text']]); if (($original == $detected) && ($data['detected'][$original] < $result['language_probability'] / 100)) { $data['detected'][$original] = $result['language_probability'] / 100; } @@ -63,12 +62,12 @@ function cld_detect_languages(array &$data) $available = array_keys(DI::l10n()->getLanguageCodes()); if (!in_array($detected, $available)) { - Logger::debug('Unsupported language', ['uri-id' => $data['uri-id'], 'original' => $original, 'detected' => $detected, 'name' => $result['language_name'], 'probability' => $result['language_probability'], 'text' => $data['text']]); + DI::logger()->debug('Unsupported language', ['uri-id' => $data['uri-id'], 'original' => $original, 'detected' => $detected, 'name' => $result['language_name'], 'probability' => $result['language_probability'], 'text' => $data['text']]); return; } if ($original != $detected) { - Logger::debug('Detected different language', ['uri-id' => $data['uri-id'], 'original' => $original, 'detected' => $detected, 'name' => $result['language_name'], 'probability' => $result['language_probability'], 'text' => $data['text']]); + DI::logger()->debug('Detected different language', ['uri-id' => $data['uri-id'], 'original' => $original, 'detected' => $detected, 'name' => $result['language_name'], 'probability' => $result['language_probability'], 'text' => $data['text']]); } $length = count($data['detected']); From 4881e6004a9bc883714fe31eff59484a41ad8e2e Mon Sep 17 00:00:00 2001 From: Art4 Date: Fri, 24 Jan 2025 11:38:27 +0000 Subject: [PATCH 149/222] Replace call for Logger with DI::logger() in diaspora addon --- diaspora/diaspora.php | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/diaspora/diaspora.php b/diaspora/diaspora.php index d6c98e34..3c4b4c0e 100644 --- a/diaspora/diaspora.php +++ b/diaspora/diaspora.php @@ -11,7 +11,6 @@ require_once 'addon/diaspora/Diaspora_Connection.php'; use Friendica\Content\Text\BBCode; use Friendica\Core\Hook; -use Friendica\Core\Logger; use Friendica\Core\Renderer; use Friendica\Database\DBA; use Friendica\Core\Worker; @@ -186,7 +185,7 @@ function diaspora_send(array &$b) { $hostname = DI::baseUrl()->getHost(); - Logger::notice('diaspora_send: invoked'); + DI::logger()->notice('diaspora_send: invoked'); if ($b['deleted'] || ($b['private'] == Item::PRIVATE) || ($b['created'] !== $b['edited'])) { return; @@ -210,14 +209,14 @@ function diaspora_send(array &$b) return; } - Logger::info('diaspora_send: prepare posting'); + DI::logger()->info('diaspora_send: prepare posting'); $handle = DI::pConfig()->get($b['uid'], 'diaspora', 'handle'); $password = DI::pConfig()->get($b['uid'], 'diaspora', 'password'); $aspect = DI::pConfig()->get($b['uid'], 'diaspora', 'aspect'); if ($handle && $password) { - Logger::info('diaspora_send: all values seem to be okay'); + DI::logger()->info('diaspora_send: all values seem to be okay'); $title = $b['title']; $body = $b['body']; @@ -248,20 +247,20 @@ function diaspora_send(array &$b) require_once "addon/diaspora/diasphp.php"; try { - Logger::info('diaspora_send: prepare'); + DI::logger()->info('diaspora_send: prepare'); $conn = new Diaspora_Connection($handle, $password); - Logger::info('diaspora_send: try to log in ' . $handle); + DI::logger()->info('diaspora_send: try to log in ' . $handle); $conn->logIn(); - Logger::info('diaspora_send: try to send ' . $body); + DI::logger()->info('diaspora_send: try to send ' . $body); $conn->provider = $hostname; $conn->postStatusMessage($body, $aspect); - Logger::notice('diaspora_send: success'); + DI::logger()->notice('diaspora_send: success'); } catch (Exception $e) { - Logger::notice("diaspora_send: Error submitting the post: " . $e->getMessage()); + DI::logger()->notice("diaspora_send: Error submitting the post: " . $e->getMessage()); - Logger::info('diaspora_send: requeueing ' . $b['uid']); + DI::logger()->info('diaspora_send: requeueing ' . $b['uid']); Worker::defer(); } From b38c2d18be2d0174e7e5866cdbbae8cfa75b5b88 Mon Sep 17 00:00:00 2001 From: Art4 Date: Fri, 24 Jan 2025 11:38:48 +0000 Subject: [PATCH 150/222] Replace call for Logger with DI::logger() in discourse addon --- discourse/discourse.php | 33 ++++++++++++++++----------------- 1 file changed, 16 insertions(+), 17 deletions(-) diff --git a/discourse/discourse.php b/discourse/discourse.php index e97a4fd8..b8d0d996 100644 --- a/discourse/discourse.php +++ b/discourse/discourse.php @@ -10,7 +10,6 @@ use Friendica\Content\Text\Markdown; use Friendica\Core\Hook; -use Friendica\Core\Logger; use Friendica\Core\Protocol; use Friendica\Core\Renderer; use Friendica\Database\DBA; @@ -79,13 +78,13 @@ function discourse_email_getmessage(&$message) // We do assume that all Discourse servers are running with SSL if (preg_match('=topic/(.*\d)/(.*\d)@(.*)=', $message['item']['uri'], $matches) && discourse_fetch_post_from_api($message, $matches[2], $matches[3])) { - Logger::info('Fetched comment via API (message-id mode)', ['host' => $matches[3], 'topic' => $matches[1], 'post' => $matches[2]]); + DI::logger()->info('Fetched comment via API (message-id mode)', ['host' => $matches[3], 'topic' => $matches[1], 'post' => $matches[2]]); return; } if (preg_match('=topic/(.*\d)@(.*)=', $message['item']['uri'], $matches) && discourse_fetch_topic_from_api($message, 'https://' . $matches[2], $matches[1], 1)) { - Logger::info('Fetched starting post via API (message-id mode)', ['host' => $matches[2], 'topic' => $matches[1]]); + DI::logger()->info('Fetched starting post via API (message-id mode)', ['host' => $matches[2], 'topic' => $matches[1]]); return; } @@ -95,16 +94,16 @@ function discourse_email_getmessage(&$message) } if (empty($message['item']['plink']) || !preg_match('=(http.*)/t/.*/(.*\d)/(.*\d)=', $message['item']['plink'], $matches)) { - Logger::info('This is no Discourse post'); + DI::logger()->info('This is no Discourse post'); return; } if (discourse_fetch_topic_from_api($message, $matches[1], $matches[2], $matches[3])) { - Logger::info('Fetched post via API (plink mode)', ['host' => $matches[1], 'topic' => $matches[2], 'id' => $matches[3]]); + DI::logger()->info('Fetched post via API (plink mode)', ['host' => $matches[1], 'topic' => $matches[2], 'id' => $matches[3]]); return; } - Logger::info('Fallback mode', ['plink' => $message['item']['plink']]); + DI::logger()->info('Fallback mode', ['plink' => $message['item']['plink']]); // Search in the HTML part for the discourse entry and the author profile if (!empty($message['html'])) { $message = discourse_get_html($message); @@ -121,7 +120,7 @@ function discourse_fetch_post($host, $topic, $pid) $url = $host . '/t/' . $topic . '/' . $pid . '.json'; $curlResult = DI::httpClient()->get($url); if (!$curlResult->isSuccess()) { - Logger::info('No success', ['url' => $url]); + DI::logger()->info('No success', ['url' => $url]); return false; } @@ -133,11 +132,11 @@ function discourse_fetch_post($host, $topic, $pid) /// @todo Possibly fetch missing posts here continue; } - Logger::info('Got post data from topic', $post); + DI::logger()->info('Got post data from topic', $post); return $post; } - Logger::info('Post not found', ['host' => $host, 'topic' => $topic, 'pid' => $pid]); + DI::logger()->info('Post not found', ['host' => $host, 'topic' => $topic, 'pid' => $pid]); return false; } @@ -169,7 +168,7 @@ function discourse_fetch_post_from_api(&$message, $post, $host) $message = discourse_process_post($message, $data, $hostaddr); - Logger::info('Got API data', $message); + DI::logger()->info('Got API data', $message); return true; } @@ -202,7 +201,7 @@ function discourse_get_user($post, $hostaddr) $contact['url'] = $hostaddr . '/u/' . $contact['nick']; $contact['nurl'] = Strings::normaliseLink($contact['url']); $contact['baseurl'] = $hostaddr; - Logger::info('Contact', $contact); + DI::logger()->info('Contact', $contact); $contact['id'] = Contact::getIdForURL($contact['url'], 0, false, $contact); if (!empty($contact['id'])) { $avatar = $contact['photo']; @@ -268,11 +267,11 @@ function discourse_get_html($message) $div = $doc2->importNode($result->item(0), true); $doc2->appendChild($div); $message['html'] = $doc2->saveHTML(); - Logger::info('Found html body', ['html' => $message['html']]); + DI::logger()->info('Found html body', ['html' => $message['html']]); $profile = discourse_get_profile($xpath); if (!empty($profile['url'])) { - Logger::info('Found profile', $profile); + DI::logger()->info('Found profile', $profile); $message['item']['author-id'] = Contact::getIdForURL($profile['url'], 0, false, $profile); $message['item']['author-link'] = $profile['url']; $message['item']['author-name'] = $profile['name']; @@ -288,21 +287,21 @@ function discourse_get_text($message) $text = str_replace("\r", '', $text); $pos = strpos($text, "\n---\n"); if ($pos == 0) { - Logger::info('No separator found', ['text' => $text]); + DI::logger()->info('No separator found', ['text' => $text]); return $message; } $message['text'] = trim(substr($text, 0, $pos)); - Logger::info('Found text body', ['text' => $message['text']]); + DI::logger()->info('Found text body', ['text' => $message['text']]); $message['text'] = Markdown::toBBCode($message['text']); $text = substr($text, $pos); - Logger::info('Found footer', ['text' => $text]); + DI::logger()->info('Found footer', ['text' => $text]); if (preg_match('=\((http.*/t/.*/.*\d/.*\d)\)=', $text, $link)) { $message['item']['plink'] = $link[1]; - Logger::info('Found plink', ['plink' => $message['item']['plink']]); + DI::logger()->info('Found plink', ['plink' => $message['item']['plink']]); } return $message; } From 1db552ead93ef398b6f3fb689c95d763c4d93a72 Mon Sep 17 00:00:00 2001 From: Art4 Date: Fri, 24 Jan 2025 11:39:11 +0000 Subject: [PATCH 151/222] Replace call for Logger with DI::logger() in dwpost addon --- dwpost/dwpost.php | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/dwpost/dwpost.php b/dwpost/dwpost.php index 7ce30086..7bad85dc 100644 --- a/dwpost/dwpost.php +++ b/dwpost/dwpost.php @@ -10,7 +10,6 @@ use Friendica\Content\Text\BBCode; use Friendica\Core\Hook; -use Friendica\Core\Logger; use Friendica\Core\Renderer; use Friendica\DI; use Friendica\Model\Item; @@ -185,12 +184,12 @@ function dwpost_send(array &$b) EOT; - Logger::debug('dwpost: data: ' . $xml); + DI::logger()->debug('dwpost: data: ' . $xml); if ($dw_blog !== 'test') { $x = DI::httpClient()->post($dw_blog, $xml, ['Content-Type' => 'text/xml'])->getBodyString(); } - Logger::info('posted to dreamwidth: ' . ($x) ? $x : ''); + DI::logger()->info('posted to dreamwidth: ' . ($x) ? $x : ''); } } From e7755584cbbd3850389495420613ebfe2b59ddb1 Mon Sep 17 00:00:00 2001 From: Art4 Date: Fri, 24 Jan 2025 11:40:12 +0000 Subject: [PATCH 152/222] Replace call for Logger with DI::logger() in geocoordinates addon --- geocoordinates/geocoordinates.php | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/geocoordinates/geocoordinates.php b/geocoordinates/geocoordinates.php index eb56f093..5af1defc 100644 --- a/geocoordinates/geocoordinates.php +++ b/geocoordinates/geocoordinates.php @@ -7,7 +7,6 @@ */ use Friendica\Core\Hook; -use Friendica\Core\Logger; use Friendica\Core\Renderer; use Friendica\DI; @@ -51,25 +50,25 @@ function geocoordinates_resolve_item(array &$item) $s = DI::httpClient()->fetch('https://api.opencagedata.com/geocode/v1/json?q=' . $coords[0] . ',' . $coords[1] . '&key=' . $key . '&language=' . $language); if (!$s) { - Logger::info('API could not be queried'); + DI::logger()->info('API could not be queried'); return; } $data = json_decode($s); if ($data->status->code != '200') { - Logger::info('API returned error ' . $data->status->code . ' ' . $data->status->message); + DI::logger()->info('API returned error ' . $data->status->code . ' ' . $data->status->message); return; } if (($data->total_results == 0) || (count($data->results) == 0)) { - Logger::info('No results found for coordinates ' . $item['coord']); + DI::logger()->info('No results found for coordinates ' . $item['coord']); return; } $item['location'] = $data->results[0]->formatted; - Logger::info('Got location for coordinates ' . $coords[0] . '-' . $coords[1] . ': ' . $item['location']); + DI::logger()->info('Got location for coordinates ' . $coords[0] . '-' . $coords[1] . ': ' . $item['location']); if ($item['location'] != '') { DI::cache()->set('geocoordinates:' . $language.':' . $coords[0] . '-' . $coords[1], $item['location']); From 15a951235f1f2d2039315851eb0a38831b77c05a Mon Sep 17 00:00:00 2001 From: Art4 Date: Fri, 24 Jan 2025 11:40:32 +0000 Subject: [PATCH 153/222] Replace call for Logger with DI::logger() in ifttt addon --- ifttt/ifttt.php | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/ifttt/ifttt.php b/ifttt/ifttt.php index 51fa8db8..cb23032b 100644 --- a/ifttt/ifttt.php +++ b/ifttt/ifttt.php @@ -8,7 +8,6 @@ */ use Friendica\Content\PageInfo; use Friendica\Core\Hook; -use Friendica\Core\Logger; use Friendica\Core\Renderer; use Friendica\Core\Worker; use Friendica\Database\DBA; @@ -86,16 +85,16 @@ function ifttt_post() $user = DBA::selectFirst('user', ['uid'], ['nickname' => $nickname]); if (!DBA::isResult($user)) { - Logger::info('User ' . $nickname . ' not found.'); + DI::logger()->info('User ' . $nickname . ' not found.'); return; } $uid = $user['uid']; - Logger::info('Received a post for user ' . $uid . ' from ifttt ' . print_r($_REQUEST, true)); + DI::logger()->info('Received a post for user ' . $uid . ' from ifttt ' . print_r($_REQUEST, true)); if (!isset($_REQUEST['key'])) { - Logger::notice('No key found.'); + DI::logger()->notice('No key found.'); return; } @@ -103,7 +102,7 @@ function ifttt_post() // Check the key if ($key != DI::pConfig()->get($uid, 'ifttt', 'key')) { - Logger::info('Invalid key for user ' . $uid); + DI::logger()->info('Invalid key for user ' . $uid); return; } @@ -114,7 +113,7 @@ function ifttt_post() } if (!in_array($item['type'], ['status', 'link', 'photo'])) { - Logger::info('Unknown item type ' . $item['type']); + DI::logger()->info('Unknown item type ' . $item['type']); return; } From 50023180895a4c1e70163762bd90d56d38d823ba Mon Sep 17 00:00:00 2001 From: Art4 Date: Fri, 24 Jan 2025 11:41:02 +0000 Subject: [PATCH 154/222] Replace call for Logger with DI::logger() in ijpost addon --- ijpost/ijpost.php | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/ijpost/ijpost.php b/ijpost/ijpost.php index 37c3cd45..9fe502af 100644 --- a/ijpost/ijpost.php +++ b/ijpost/ijpost.php @@ -10,7 +10,6 @@ use Friendica\Content\Text\BBCode; use Friendica\Core\Hook; -use Friendica\Core\Logger; use Friendica\Core\Renderer; use Friendica\DI; use Friendica\Model\Item; @@ -178,11 +177,11 @@ function ijpost_send(array &$b) EOT; - Logger::debug('ijpost: data: ' . $xml); + DI::logger()->debug('ijpost: data: ' . $xml); if ($ij_blog !== 'test') { $x = DI::httpClient()->post($ij_blog, $xml, ['Content-Type' => 'text/xml'])->getBodyString(); } - Logger::info('posted to insanejournal: ' . $x ? $x : ''); + DI::logger()->info('posted to insanejournal: ' . $x ? $x : ''); } } From 5d51c5b56ecbbc220332fd5b2bea6bb34c436e5f Mon Sep 17 00:00:00 2001 From: Art4 Date: Fri, 24 Jan 2025 11:42:25 +0000 Subject: [PATCH 155/222] Replace call for Logger with DI::logger() in js_upload addon --- js_upload/js_upload.php | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/js_upload/js_upload.php b/js_upload/js_upload.php index f1d85aa3..c0a2467d 100644 --- a/js_upload/js_upload.php +++ b/js_upload/js_upload.php @@ -8,7 +8,6 @@ */ use Friendica\Core\Hook; -use Friendica\Core\Logger; use Friendica\Core\Renderer; use Friendica\DI; use Friendica\Util\Images; @@ -68,7 +67,7 @@ function js_upload_post_init(array &$b) $js_upload_jsonresponse = htmlspecialchars(json_encode($result), ENT_NOQUOTES); if (isset($result['error'])) { - Logger::info('mod/photos.php: photos_post(): error uploading photo: ' . $result['error']); + DI::logger()->info('mod/photos.php: photos_post(): error uploading photo: ' . $result['error']); echo json_encode($result); exit(); } @@ -91,7 +90,7 @@ function js_upload_post_end(int &$b) { global $js_upload_jsonresponse; - Logger::notice('upload_post_end'); + DI::logger()->notice('upload_post_end'); if (!empty($js_upload_jsonresponse)) { echo $js_upload_jsonresponse; exit(); @@ -187,6 +186,10 @@ class js_upload_qqFileUploader { private $allowedExtensions; private $sizeLimit; + + /** + * @var js_upload_qqUploadedFileXhr|js_upload_qqUploadedFileForm + */ private $file; function __construct(array $allowedExtensions = [], $sizeLimit) @@ -234,7 +237,7 @@ class js_upload_qqFileUploader $filename = $pathinfo['filename']; if (!isset($pathinfo['extension'])) { - Logger::warning('extension isn\'t set.', ['filename' => $filename]); + DI::logger()->warning('extension isn\'t set.', ['filename' => $filename]); } $ext = $pathinfo['extension'] ?? ''; From a488f2513159b44765400fa03f3351f5885e851f Mon Sep 17 00:00:00 2001 From: Art4 Date: Fri, 24 Jan 2025 11:44:48 +0000 Subject: [PATCH 156/222] Replace call for Logger with DI::logger() in ldapauth addon --- ldapauth/ldapauth.php | 29 ++++++++++++++--------------- 1 file changed, 14 insertions(+), 15 deletions(-) diff --git a/ldapauth/ldapauth.php b/ldapauth/ldapauth.php index f834b4d5..b80c5226 100644 --- a/ldapauth/ldapauth.php +++ b/ldapauth/ldapauth.php @@ -30,7 +30,6 @@ */ use Friendica\Core\Hook; -use Friendica\Core\Logger; use Friendica\Database\DBA; use Friendica\DI; use Friendica\Model\User; @@ -69,54 +68,54 @@ function ldapauth_authenticate($username, $password) $ldap_autocreateaccount_nameattribute = DI::config()->get('ldapauth', 'ldap_autocreateaccount_nameattribute'); if (!extension_loaded('ldap') || !strlen($ldap_server)) { - Logger::error('Addon not configured or missing php-ldap extension', ['extension_loaded' => extension_loaded('ldap'), 'server' => $ldap_server]); + DI::logger()->error('Addon not configured or missing php-ldap extension', ['extension_loaded' => extension_loaded('ldap'), 'server' => $ldap_server]); return false; } if (!strlen($password)) { - Logger::error('Empty password disallowed', ['provided_password_length' => strlen($password)]); + DI::logger()->error('Empty password disallowed', ['provided_password_length' => strlen($password)]); return false; } $connect = @ldap_connect($ldap_server); if ($connect === false) { - Logger::warning('Could not connect to LDAP server', ['server' => $ldap_server]); + DI::logger()->warning('Could not connect to LDAP server', ['server' => $ldap_server]); return false; } @ldap_set_option($connect, LDAP_OPT_PROTOCOL_VERSION, 3); @ldap_set_option($connect, LDAP_OPT_REFERRALS, 0); if ((@ldap_bind($connect, $ldap_binddn, $ldap_bindpw)) === false) { - Logger::warning('Could not bind to LDAP server', ['server' => $ldap_server, 'binddn' => $ldap_binddn, 'errno' => ldap_errno($connect), 'error' => ldap_error($connect)]); + DI::logger()->warning('Could not bind to LDAP server', ['server' => $ldap_server, 'binddn' => $ldap_binddn, 'errno' => ldap_errno($connect), 'error' => ldap_error($connect)]); return false; } $res = @ldap_search($connect, $ldap_searchdn, $ldap_userattr . '=' . $username); if (!$res) { - Logger::notice('LDAP user not found.', ['searchdn' => $ldap_searchdn, 'userattr' => $ldap_userattr, 'username' => $username, 'errno' => ldap_errno($connect), 'error' => ldap_error($connect)]); + DI::logger()->notice('LDAP user not found.', ['searchdn' => $ldap_searchdn, 'userattr' => $ldap_userattr, 'username' => $username, 'errno' => ldap_errno($connect), 'error' => ldap_error($connect)]); return false; } $id = @ldap_first_entry($connect, $res); if (!$id) { - Logger::notice('Could not retrieve first LDAP entry.', ['searchdn' => $ldap_searchdn, 'userattr' => $ldap_userattr, 'username' => $username, 'errno' => ldap_errno($connect), 'error' => ldap_error($connect)]); + DI::logger()->notice('Could not retrieve first LDAP entry.', ['searchdn' => $ldap_searchdn, 'userattr' => $ldap_userattr, 'username' => $username, 'errno' => ldap_errno($connect), 'error' => ldap_error($connect)]); return false; } $dn = @ldap_get_dn($connect, $id); if (!@ldap_bind($connect, $dn, $password)) { - Logger::notice('Could not authenticate LDAP user with provided password', ['errno' => ldap_errno($connect), 'error' => ldap_error($connect)]); + DI::logger()->notice('Could not authenticate LDAP user with provided password', ['errno' => ldap_errno($connect), 'error' => ldap_error($connect)]); return false; } if (strlen($ldap_group) && @ldap_compare($connect, $ldap_group, 'member', $dn) !== true) { $errno = @ldap_errno($connect); if ($errno === 32) { - Logger::notice('LDAP Access Control Group does not exist', ['errno' => $errno, 'error' => ldap_error($connect)]); + DI::logger()->notice('LDAP Access Control Group does not exist', ['errno' => $errno, 'error' => ldap_error($connect)]); } elseif ($errno === 16) { - Logger::notice('LDAP membership attribute does not exist in access control group', ['errno' => $errno, 'error' => ldap_error($connect)]); + DI::logger()->notice('LDAP membership attribute does not exist in access control group', ['errno' => $errno, 'error' => ldap_error($connect)]); } else { - Logger::notice('LDAP user isn\'t part of the authorized group', ['dn' => $dn]); + DI::logger()->notice('LDAP user isn\'t part of the authorized group', ['dn' => $dn]); } @ldap_close($connect); @@ -140,7 +139,7 @@ function ldapauth_authenticate($username, $password) $authentication = User::getAuthenticationInfo($username); return User::getById($authentication['uid']); } catch (Exception $e) { - Logger::notice('LDAP authentication error: ' . $e->getMessage()); + DI::logger()->notice('LDAP authentication error: ' . $e->getMessage()); return false; } } @@ -148,7 +147,7 @@ function ldapauth_authenticate($username, $password) function ldap_createaccount($username, $password, $email, $name) { if (!strlen($email) || !strlen($name)) { - Logger::notice('Could not create local user from LDAP data, no email or nickname provided'); + DI::logger()->notice('Could not create local user from LDAP data, no email or nickname provided'); return false; } @@ -160,10 +159,10 @@ function ldap_createaccount($username, $password, $email, $name) 'password' => $password, 'verified' => 1 ]); - Logger::info('Local user created from LDAP data', ['username' => $username, 'name' => $name]); + DI::logger()->info('Local user created from LDAP data', ['username' => $username, 'name' => $name]); return $user; } catch (Exception $ex) { - Logger::error('Could not create local user from LDAP data', ['username' => $username, 'exception' => $ex->getMessage()]); + DI::logger()->error('Could not create local user from LDAP data', ['username' => $username, 'exception' => $ex->getMessage()]); } return false; From f08750199df1a0b7833e2eaba774f41c88cfe049 Mon Sep 17 00:00:00 2001 From: Art4 Date: Fri, 24 Jan 2025 11:45:25 +0000 Subject: [PATCH 157/222] Replace call for Logger with DI::logger() in libertree addon --- libertree/libertree.php | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/libertree/libertree.php b/libertree/libertree.php index c138e597..1489a029 100644 --- a/libertree/libertree.php +++ b/libertree/libertree.php @@ -8,7 +8,6 @@ use Friendica\Content\Text\BBCode; use Friendica\Core\Hook; -use Friendica\Core\Logger; use Friendica\Core\Renderer; use Friendica\Database\DBA; use Friendica\DI; @@ -130,7 +129,7 @@ function libertree_post_local(array &$b) function libertree_send(array &$b) { - Logger::notice('libertree_send: invoked'); + DI::logger()->notice('libertree_send: invoked'); if ($b['deleted'] || ($b['private'] == Item::PRIVATE) || ($b['created'] !== $b['edited'])) { return; @@ -196,6 +195,6 @@ function libertree_send(array &$b) ]; $result = DI::httpClient()->post($ltree_blog, $params)->getBodyString(); - Logger::notice('libertree: ' . $result); + DI::logger()->notice('libertree: ' . $result); } } From 9ed02034f1755ae5832b96d34800a7758ad37bf5 Mon Sep 17 00:00:00 2001 From: Art4 Date: Fri, 24 Jan 2025 11:46:04 +0000 Subject: [PATCH 158/222] Replace call for Logger with DI::logger() in ljpost addon --- ljpost/ljpost.php | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/ljpost/ljpost.php b/ljpost/ljpost.php index b416c605..fd7d1bd8 100644 --- a/ljpost/ljpost.php +++ b/ljpost/ljpost.php @@ -10,7 +10,6 @@ use Friendica\Content\Text\BBCode; use Friendica\Core\Hook; -use Friendica\Core\Logger; use Friendica\Core\Renderer; use Friendica\DI; use Friendica\Model\Item; @@ -200,7 +199,7 @@ function ljpost_send(array &$b) EOT; - Logger::debug('ljpost: data: ' . $xml); + DI::logger()->debug('ljpost: data: ' . $xml); $x = ''; @@ -208,6 +207,6 @@ EOT; $x = DI::httpClient()->post($lj_blog, $xml, ['Content-Type' => 'text/xml'])->getBodyString(); } - Logger::info('posted to livejournal: ' . $x); + DI::logger()->info('posted to livejournal: ' . $x); } } From 9a91bae363392fd1df0849afb4a21e24de994579 Mon Sep 17 00:00:00 2001 From: Art4 Date: Fri, 24 Jan 2025 11:46:30 +0000 Subject: [PATCH 159/222] Replace call for Logger with DI::logger() in mailstream addon --- mailstream/mailstream.php | 45 +++++++++++++++++++-------------------- 1 file changed, 22 insertions(+), 23 deletions(-) diff --git a/mailstream/mailstream.php b/mailstream/mailstream.php index 9910a63d..5228b168 100644 --- a/mailstream/mailstream.php +++ b/mailstream/mailstream.php @@ -8,7 +8,6 @@ use Friendica\Content\Text\BBCode; use Friendica\Core\Hook; -use Friendica\Core\Logger; use Friendica\Core\Renderer; use Friendica\Core\System; use Friendica\Core\Worker; @@ -32,7 +31,7 @@ function mailstream_install() Hook::register('post_remote_end', 'addon/mailstream/mailstream.php', 'mailstream_post_hook'); Hook::register('mailstream_send_hook', 'addon/mailstream/mailstream.php', 'mailstream_send_hook'); - Logger::info("installed mailstream"); + DI::logger()->info("installed mailstream"); } /** @@ -86,7 +85,7 @@ function mailstream_generate_id(string $uri): string $host = DI::baseUrl()->getHost(); $resource = hash('md5', $uri); $message_id = "<" . $resource . "@" . $host . ">"; - Logger::debug('generated message ID', ['id' => $message_id, 'uri' => $uri]); + DI::logger()->debug('generated message ID', ['id' => $message_id, 'uri' => $uri]); return $message_id; } @@ -95,20 +94,20 @@ function mailstream_send_hook(array $data) $criteria = array('uid' => $data['uid'], 'contact-id' => $data['contact-id'], 'uri' => $data['uri']); $item = Post::selectFirst([], $criteria); if (empty($item)) { - Logger::error('could not find item'); + DI::logger()->error('could not find item'); return; } $user = User::getById($item['uid']); if (empty($user)) { - Logger::error('could not find user', ['uid' => $item['uid']]); + DI::logger()->error('could not find user', ['uid' => $item['uid']]); return; } if (!mailstream_send($data['message_id'], $item, $user)) { - Logger::debug('send failed, will retry', $data); + DI::logger()->debug('send failed, will retry', $data); if (!Worker::defer()) { - Logger::error('failed and could not defer', $data); + DI::logger()->error('failed and could not defer', $data); } } } @@ -124,32 +123,32 @@ function mailstream_send_hook(array $data) function mailstream_post_hook(array &$item) { if ($item['uid'] === 0) { - Logger::debug('mailstream: root user, skipping item ' . $item['id']); + DI::logger()->debug('mailstream: root user, skipping item ' . $item['id']); return; } if (!DI::pConfig()->get($item['uid'], 'mailstream', 'enabled')) { - Logger::debug('mailstream: not enabled.', ['item' => $item['id'], ' uid ' => $item['uid']]); + DI::logger()->debug('mailstream: not enabled.', ['item' => $item['id'], ' uid ' => $item['uid']]); return; } if (!$item['contact-id']) { - Logger::debug('no contact-id', ['item' => $item['id']]); + DI::logger()->debug('no contact-id', ['item' => $item['id']]); return; } if (!$item['uri']) { - Logger::debug('no uri', ['item' => $item['id']]); + DI::logger()->debug('no uri', ['item' => $item['id']]); return; } if ($item['verb'] == Activity::ANNOUNCE) { - Logger::debug('ignoring announce', ['item' => $item['id']]); + DI::logger()->debug('ignoring announce', ['item' => $item['id']]); return; } if (DI::pConfig()->get($item['uid'], 'mailstream', 'nolikes')) { if ($item['verb'] == Activity::LIKE) { - Logger::debug('ignoring like', ['item' => $item['id']]); + DI::logger()->debug('ignoring like', ['item' => $item['id']]); return; } if ($item['verb'] == Activity::DISLIKE) { - Logger::debug('ignoring dislike', ['item' => $item['id']]); + DI::logger()->debug('ignoring dislike', ['item' => $item['id']]); return; } } @@ -200,7 +199,7 @@ function mailstream_do_images(array &$item, array &$attachments) try { $curlResult = DI::httpClient()->get($url, HttpClientAccept::DEFAULT, [HttpClientOptions::COOKIEJAR => $cookiejar]); if (!$curlResult->isSuccess()) { - Logger::debug('mailstream: fetch image url failed', [ + DI::logger()->debug('mailstream: fetch image url failed', [ 'url' => $url, 'item_id' => $item['id'], 'return_code' => $curlResult->getReturnCode() @@ -208,7 +207,7 @@ function mailstream_do_images(array &$item, array &$attachments) continue; } } catch (InvalidArgumentException $e) { - Logger::error('exception fetching url', ['url' => $url, 'item_id' => $item['id']]); + DI::logger()->error('exception fetching url', ['url' => $url, 'item_id' => $item['id']]); continue; } $attachments[$url] = [ @@ -309,7 +308,7 @@ function mailstream_subject(array $item): string } $contact = Contact::selectFirst([], ['id' => $item['contact-id'], 'uid' => $item['uid']]); if (!DBA::isResult($contact)) { - Logger::error('no contact', [ + DI::logger()->error('no contact', [ 'item' => $item['id'], 'plink' => $item['plink'], 'contact id' => $item['contact-id'], @@ -351,16 +350,16 @@ function mailstream_subject(array $item): string function mailstream_send(string $message_id, array $item, array $user): bool { if (!is_array($item)) { - Logger::error('item is empty', ['message_id' => $message_id]); + DI::logger()->error('item is empty', ['message_id' => $message_id]); return false; } if (!$item['visible']) { - Logger::debug('item not yet visible', ['item uri' => $item['uri']]); + DI::logger()->debug('item not yet visible', ['item uri' => $item['uri']]); return false; } if (!$message_id) { - Logger::error('no message ID supplied', ['item uri' => $item['uri'], 'user email' => $user['email']]); + DI::logger()->error('no message ID supplied', ['item uri' => $item['uri'], 'user email' => $user['email']]); return true; } @@ -418,15 +417,15 @@ function mailstream_send(string $message_id, array $item, array $user): bool if (!$mail->Send()) { throw new Exception($mail->ErrorInfo); } - Logger::debug('sent message', [ + DI::logger()->debug('sent message', [ 'message ID' => $mail->MessageID, 'subject' => $mail->Subject, 'address' => $address ]); } catch (phpmailerException $e) { - Logger::debug('PHPMailer exception sending message', ['id' => $message_id, 'error' => $e->errorMessage()]); + DI::logger()->debug('PHPMailer exception sending message', ['id' => $message_id, 'error' => $e->errorMessage()]); } catch (Exception $e) { - Logger::debug('exception sending message', ['id' => $message_id, 'error' => $e->getMessage()]); + DI::logger()->debug('exception sending message', ['id' => $message_id, 'error' => $e->getMessage()]); } return true; From 9ceff8f5929d7899b91cc8b1acc26e47cd3dfce7 Mon Sep 17 00:00:00 2001 From: Art4 Date: Fri, 24 Jan 2025 11:46:58 +0000 Subject: [PATCH 160/222] Replace call for Logger with DI::logger() in nominatim addon --- nominatim/nominatim.php | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/nominatim/nominatim.php b/nominatim/nominatim.php index a3d14af5..3a567b7b 100644 --- a/nominatim/nominatim.php +++ b/nominatim/nominatim.php @@ -7,7 +7,6 @@ */ use Friendica\Core\Hook; -use Friendica\Core\Logger; use Friendica\Core\Renderer; use Friendica\DI; @@ -45,19 +44,19 @@ function nominatim_resolve_item(array &$item) $s = DI::httpClient()->fetch('https://nominatim.openstreetmap.org/reverse?lat=' . $coords[0] . '&lon=' . $coords[1] . '&format=json&addressdetails=0&accept-language=' . $language); if (empty($s)) { - Logger::info('API could not be queried'); + DI::logger()->info('API could not be queried'); return; } $data = json_decode($s, true); if (empty($data['display_name'])) { - Logger::info('No results found for coordinates', ['coordinates' => $item['coord'], 'data' => $data]); + DI::logger()->info('No results found for coordinates', ['coordinates' => $item['coord'], 'data' => $data]); return; } $item['location'] = $data['display_name']; - Logger::info('Got location', ['lat' => $coords[0], 'long' => $coords[1], 'location' => $item['location']]); + DI::logger()->info('Got location', ['lat' => $coords[0], 'long' => $coords[1], 'location' => $item['location']]); if (!empty($item['location'])) { DI::cache()->set('nominatim:' . $language . ':' . $coords[0] . '-' . $coords[1], $item['location']); From 757d72c360396a06a58f91c4c9d14f7726a9f644 Mon Sep 17 00:00:00 2001 From: Art4 Date: Fri, 24 Jan 2025 11:47:24 +0000 Subject: [PATCH 161/222] Replace call for Logger with DI::logger() in openstreetmap addon --- openstreetmap/openstreetmap.php | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/openstreetmap/openstreetmap.php b/openstreetmap/openstreetmap.php index fc5ebbbe..bf0f54b6 100644 --- a/openstreetmap/openstreetmap.php +++ b/openstreetmap/openstreetmap.php @@ -11,7 +11,6 @@ use Friendica\Core\Cache\Enum\Duration; use Friendica\Core\Hook; -use Friendica\Core\Logger; use Friendica\Core\Renderer; use Friendica\DI; use Friendica\Core\Config\Util\ConfigFileManager; @@ -31,7 +30,7 @@ function openstreetmap_install() Hook::register('Map::getCoordinates', 'addon/openstreetmap/openstreetmap.php', 'openstreetmap_get_coordinates'); Hook::register('page_header', 'addon/openstreetmap/openstreetmap.php', 'openstreetmap_alterheader'); - Logger::notice("installed openstreetmap"); + DI::logger()->notice("installed openstreetmap"); } function openstreetmap_load_config(ConfigFileManager $loader) @@ -154,8 +153,8 @@ function openstreetmap_generate_map(array &$b) $lat = $b['lat']; // round($b['lat'], 5); $lon = $b['lon']; // round($b['lon'], 5); - Logger::debug('lat: ' . $lat); - Logger::debug('lon: ' . $lon); + DI::logger()->debug('lat: ' . $lat); + DI::logger()->debug('lon: ' . $lon); $cardlink = 'notice("installed planets"); } /** @@ -39,7 +38,7 @@ function planets_install() */ function planets_post_hook(&$item) { - Logger::notice('planets invoked'); + DI::logger()->notice('planets invoked'); if (!DI::userSession()->getLocalUserId()) { /* non-zero if this is a logged in user of this system */ From 119ba0a78e1d578d802bf87b1d39e6da35a02da6 Mon Sep 17 00:00:00 2001 From: Art4 Date: Fri, 24 Jan 2025 11:48:21 +0000 Subject: [PATCH 163/222] Replace call for Logger with DI::logger() in pnut addon --- pnut/pnut.php | 23 +++++++++++------------ 1 file changed, 11 insertions(+), 12 deletions(-) diff --git a/pnut/pnut.php b/pnut/pnut.php index f298997b..5460b991 100644 --- a/pnut/pnut.php +++ b/pnut/pnut.php @@ -14,7 +14,6 @@ use Friendica\Content\Text\BBCode; use Friendica\Content\Text\Plaintext; use Friendica\Core\Config\Util\ConfigFileManager; use Friendica\Core\Hook; -use Friendica\Core\Logger; use Friendica\Core\Renderer; use Friendica\Core\System; use Friendica\DI; @@ -76,7 +75,7 @@ function pnut_connect() try { $token = $nut->getAccessToken($callback_url); - Logger::debug('Got Token', [$token]); + DI::logger()->debug('Got Token', [$token]); $o = DI::l10n()->t('You are now authenticated with pnut.io.'); DI::pConfig()->set(DI::userSession()->getLocalUserId(), 'pnut', 'access_token', $token); } catch (phpnutException $e) { @@ -266,8 +265,8 @@ function pnut_post_hook(array &$b) return; } - Logger::notice('PNUT post invoked', ['id' => $b['id'], 'guid' => $b['guid'], 'plink' => $b['plink']]); - Logger::debug('PNUT array', $b); + DI::logger()->notice('PNUT post invoked', ['id' => $b['id'], 'guid' => $b['guid'], 'plink' => $b['plink']]); + DI::logger()->debug('PNUT array', $b); $token = DI::pConfig()->get($b['uid'], 'pnut', 'access_token'); $nut = new phpnut\phpnut($token); @@ -276,7 +275,7 @@ function pnut_post_hook(array &$b) $text = $msgarr['text']; $raw = []; - Logger::debug('PNUT msgarr', $msgarr); + DI::logger()->debug('PNUT msgarr', $msgarr); if (count($msgarr['parts']) > 1) { $tstamp = time(); @@ -292,23 +291,23 @@ function pnut_post_hook(array &$b) if ($msgarr['type'] == 'photo') { $fileraw = ['type' => 'dev.mcmillian.friendica.image', 'kind' => 'image', 'is_public' => true]; foreach ($msgarr['images'] as $image) { - Logger::debug('PNUT image', $image); + DI::logger()->debug('PNUT image', $image); if (!empty($image['id'])) { $photo = Photo::selectFirst([], ['id' => $image['id']]); - Logger::debug('PNUT selectFirst'); + DI::logger()->debug('PNUT selectFirst'); } else { $photo = Photo::createPhotoForExternalResource($image['url']); - Logger::debug('PNUT createPhotoForExternalResource'); + DI::logger()->debug('PNUT createPhotoForExternalResource'); } $picturedata = Photo::getImageForPhoto($photo); - Logger::debug('PNUT photo', $photo); + DI::logger()->debug('PNUT photo', $photo); $picurefile = tempnam(System::getTempPath(), 'pnut'); file_put_contents($picurefile, $picturedata); - Logger::debug('PNUT got file?', ['filename' => $picurefile]); + DI::logger()->debug('PNUT got file?', ['filename' => $picurefile]); $imagefile = $nut->createFile($picurefile, $fileraw); - Logger::debug('PNUT file', ['pnutimagefile' => $imagefile]); + DI::logger()->debug('PNUT file', ['pnutimagefile' => $imagefile]); unlink($picurefile); $raw['io.pnut.core.oembed'][] = ['+io.pnut.core.file' => ['file_id' => $imagefile['id'], 'file_token' => $imagefile['file_token'], 'format' => 'oembed']]; @@ -318,5 +317,5 @@ function pnut_post_hook(array &$b) $raw['io.pnut.core.crosspost'][] = ['canonical_url' => $b['plink']]; $nut->createPost($text, ['raw' => $raw]); - Logger::debug('PNUT post complete', ['id' => $b['id'], 'text' => $text, 'raw' => $raw]); + DI::logger()->debug('PNUT post complete', ['id' => $b['id'], 'text' => $text, 'raw' => $raw]); } From e32ba1ce7b0a1baad29d47df9dcb6328834fbd94 Mon Sep 17 00:00:00 2001 From: Art4 Date: Fri, 24 Jan 2025 11:54:34 +0000 Subject: [PATCH 164/222] Replace call for Logger with DI::logger() in public_server addon --- public_server/public_server.php | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/public_server/public_server.php b/public_server/public_server.php index eb7af1e7..9cd0f667 100644 --- a/public_server/public_server.php +++ b/public_server/public_server.php @@ -8,7 +8,6 @@ use Friendica\BaseModule; use Friendica\Core\Hook; -use Friendica\Core\Logger; use Friendica\Core\Renderer; use Friendica\Database\DBA; use Friendica\DI; @@ -47,7 +46,7 @@ function public_server_register_account($b) function public_server_cron($b) { - Logger::notice("public_server: cron start"); + DI::logger()->notice("public_server: cron start"); $users = DBA::selectToArray('user', [], ["`account_expires_on` > ? AND `account_expires_on` < ? AND `expire_notification_sent` <= ?", DBA::NULL_DATETIME, DateTimeFormat::utc('now + 5 days'), DBA::NULL_DATETIME]); @@ -96,7 +95,7 @@ function public_server_cron($b) } } - Logger::notice("public_server: cron end"); + DI::logger()->notice("public_server: cron end"); } function public_server_enotify(array &$b) From d50650b8cfe7284ee17b482f261e0a8778ad3758 Mon Sep 17 00:00:00 2001 From: Art4 Date: Fri, 24 Jan 2025 11:55:13 +0000 Subject: [PATCH 165/222] Replace call for Logger with DI::logger() in pumpio addon --- pumpio/pumpio.php | 73 +++++++++++++++++++++++------------------------ 1 file changed, 36 insertions(+), 37 deletions(-) diff --git a/pumpio/pumpio.php b/pumpio/pumpio.php index ffe5f187..c3445b48 100644 --- a/pumpio/pumpio.php +++ b/pumpio/pumpio.php @@ -10,7 +10,6 @@ use Friendica\Content\Text\BBCode; use Friendica\Content\Text\HTML; use Friendica\Core\Addon; use Friendica\Core\Hook; -use Friendica\Core\Logger; use Friendica\Core\Protocol; use Friendica\Core\Renderer; use Friendica\Core\Worker; @@ -107,7 +106,7 @@ function pumpio_registerclient($host) $params['logo_url'] = DI::baseUrl() . '/images/friendica-256.png'; $params['redirect_uris'] = DI::baseUrl() . '/pumpio/connect'; - Logger::info('pumpio_registerclient: ' . $url . ' parameters', $params); + DI::logger()->info('pumpio_registerclient: ' . $url . ' parameters', $params); // @TODO Rewrite this to our own HTTP client $ch = curl_init($url); @@ -122,10 +121,10 @@ function pumpio_registerclient($host) if ($curl_info['http_code'] == '200') { $values = json_decode($s); - Logger::info('pumpio_registerclient: success ', (array)$values); + DI::logger()->info('pumpio_registerclient: success ', (array)$values); return $values; } - Logger::info('pumpio_registerclient: failed: ', $curl_info); + DI::logger()->info('pumpio_registerclient: failed: ', $curl_info); return false; } @@ -138,7 +137,7 @@ function pumpio_connect() $hostname = DI::pConfig()->get(DI::userSession()->getLocalUserId(), 'pumpio', 'host'); if ((($consumer_key == '') || ($consumer_secret == '')) && ($hostname != '')) { - Logger::notice('pumpio_connect: register client'); + DI::logger()->notice('pumpio_connect: register client'); $clientdata = pumpio_registerclient($hostname); DI::pConfig()->set(DI::userSession()->getLocalUserId(), 'pumpio', 'consumer_key', $clientdata->client_id); DI::pConfig()->set(DI::userSession()->getLocalUserId(), 'pumpio', 'consumer_secret', $clientdata->client_secret); @@ -146,11 +145,11 @@ function pumpio_connect() $consumer_key = DI::pConfig()->get(DI::userSession()->getLocalUserId(), 'pumpio', 'consumer_key'); $consumer_secret = DI::pConfig()->get(DI::userSession()->getLocalUserId(), 'pumpio', 'consumer_secret'); - Logger::info('pumpio_connect: ckey: ' . $consumer_key . ' csecrect: ' . $consumer_secret); + DI::logger()->info('pumpio_connect: ckey: ' . $consumer_key . ' csecrect: ' . $consumer_secret); } if (($consumer_key == '') || ($consumer_secret == '')) { - Logger::notice('pumpio_connect: '.sprintf('Unable to register the client at the pump.io server "%s".', $hostname)); + DI::logger()->notice('pumpio_connect: '.sprintf('Unable to register the client at the pump.io server "%s".', $hostname)); return DI::l10n()->t("Unable to register the client at the pump.io server '%s'.", $hostname); } @@ -179,7 +178,7 @@ function pumpio_connect() if (($success = $client->Initialize())) { if (($success = $client->Process())) { if (strlen($client->access_token)) { - Logger::info('pumpio_connect: otoken: ' . $client->access_token . ', osecrect: ' . $client->access_token_secret); + DI::logger()->info('pumpio_connect: otoken: ' . $client->access_token . ', osecrect: ' . $client->access_token_secret); DI::pConfig()->set(DI::userSession()->getLocalUserId(), 'pumpio', 'oauth_token', $client->access_token); DI::pConfig()->set(DI::userSession()->getLocalUserId(), 'pumpio', 'oauth_token_secret', $client->access_token_secret); } @@ -191,11 +190,11 @@ function pumpio_connect() } if ($success) { - Logger::notice('pumpio_connect: authenticated'); + DI::logger()->notice('pumpio_connect: authenticated'); $o = DI::l10n()->t('You are now authenticated to pumpio.'); $o .= '
' . DI::l10n()->t('return to the connector page') . ''; } else { - Logger::notice('pumpio_connect: could not connect'); + DI::logger()->notice('pumpio_connect: could not connect'); $o = 'Could not connect to pumpio. Refresh the page or try again later.'; } @@ -345,7 +344,7 @@ function pumpio_hook_fork(array &$b) if (DI::pConfig()->get($post['uid'], 'pumpio', 'import')) { // Don't fork if it isn't a reply to a pump.io post if (($post['gravity'] != Item::GRAVITY_PARENT) && !Post::exists(['id' => $post['parent'], 'network' => Protocol::PUMPIO])) { - Logger::notice('No pump.io parent found for item ' . $post['id']); + DI::logger()->notice('No pump.io parent found for item ' . $post['id']); $b['execute'] = false; return; } @@ -389,7 +388,7 @@ function pumpio_send(array &$b) return; } - Logger::debug('pumpio_send: parameter ', $b); + DI::logger()->debug('pumpio_send: parameter ', $b); $b['body'] = Post\Media::addAttachmentsToBody($b['uri-id'], DI::contentItem()->addSharedPost($b)); @@ -399,7 +398,7 @@ function pumpio_send(array &$b) $orig_post = Post::selectFirst([], $condition); if (!DBA::isResult($orig_post)) { - Logger::notice('pumpio_send: no pumpio post ' . $b['parent']); + DI::logger()->notice('pumpio_send: no pumpio post ' . $b['parent']); return; } else { $iscomment = true; @@ -409,7 +408,7 @@ function pumpio_send(array &$b) $receiver = pumpio_getreceiver($b); - Logger::notice('pumpio_send: receiver ', $receiver); + DI::logger()->notice('pumpio_send: receiver ', $receiver); if (!count($receiver) && ($b['private'] == Item::PRIVATE) || !strstr($b['postopts'], 'pumpio')) { return; @@ -543,13 +542,13 @@ function pumpio_send(array &$b) } $post_id = $user->object->id; - Logger::notice('pumpio_send ' . $username . ': success ' . $post_id); + DI::logger()->notice('pumpio_send ' . $username . ': success ' . $post_id); if ($post_id && $iscomment) { - Logger::notice('pumpio_send ' . $username . ': Update extid ' . $post_id . ' for post id ' . $b['id']); + DI::logger()->notice('pumpio_send ' . $username . ': Update extid ' . $post_id . ' for post id ' . $b['id']); Item::update(['extid' => $post_id], ['id' => $b['id']]); } } else { - Logger::notice('pumpio_send '.$username.': '.$url.' general error: ' . print_r($user, true)); + DI::logger()->notice('pumpio_send '.$username.': '.$url.' general error: ' . print_r($user, true)); Worker::defer(); } } @@ -619,9 +618,9 @@ function pumpio_action(int $uid, string $uri, string $action, string $content = } if ($success) { - Logger::notice('pumpio_action '.$username.' '.$action.': success '.$uri); + DI::logger()->notice('pumpio_action '.$username.' '.$action.': success '.$uri); } else { - Logger::notice('pumpio_action '.$username.' '.$action.': general error: '.$uri); + DI::logger()->notice('pumpio_action '.$username.' '.$action.': general error: '.$uri); Worker::defer(); } } @@ -639,15 +638,15 @@ function pumpio_sync() if ($last) { $next = $last + ($poll_interval * 60); if ($next > time()) { - Logger::notice('pumpio: poll intervall not reached'); + DI::logger()->notice('pumpio: poll intervall not reached'); return; } } - Logger::notice('pumpio: cron_start'); + DI::logger()->notice('pumpio: cron_start'); $pconfigs = DBA::selectToArray('pconfig', ['uid'], ['cat' => 'pumpio', 'k' => 'mirror', 'v' => '1']); foreach ($pconfigs as $rr) { - Logger::notice('pumpio: mirroring user '.$rr['uid']); + DI::logger()->notice('pumpio: mirroring user '.$rr['uid']); pumpio_fetchtimeline($rr['uid']); } @@ -662,12 +661,12 @@ function pumpio_sync() foreach ($pconfigs as $rr) { if ($abandon_days != 0) { if (DBA::exists('user', ["uid = ? AND `login_date` >= ?", $rr['uid'], $abandon_limit])) { - Logger::notice('abandoned account: timeline from user '.$rr['uid'].' will not be imported'); + DI::logger()->notice('abandoned account: timeline from user '.$rr['uid'].' will not be imported'); continue; } } - Logger::notice('pumpio: importing timeline from user '.$rr['uid']); + DI::logger()->notice('pumpio: importing timeline from user '.$rr['uid']); pumpio_fetchinbox($rr['uid']); // check for new contacts once a day @@ -684,7 +683,7 @@ function pumpio_sync() } } - Logger::notice('pumpio: cron_end'); + DI::logger()->notice('pumpio: cron_end'); DI::keyValue()->set('pumpio_last_poll', time()); } @@ -729,7 +728,7 @@ function pumpio_fetchtimeline(int $uid) $url = 'https://'.$hostname.'/api/user/'.$username.'/feed/major'; - Logger::notice('pumpio: fetching for user ' . $uid . ' ' . $url . ' C:' . $client->client_id . ' CS:' . $client->client_secret . ' T:' . $client->access_token . ' TS:' . $client->access_token_secret); + DI::logger()->notice('pumpio: fetching for user ' . $uid . ' ' . $url . ' C:' . $client->client_id . ' CS:' . $client->client_secret . ' T:' . $client->access_token . ' TS:' . $client->access_token_secret); $useraddr = $username.'@'.$hostname; @@ -741,7 +740,7 @@ function pumpio_fetchtimeline(int $uid) } if (!$success) { - Logger::notice('pumpio: error fetching posts for user ' . $uid . ' ' . $useraddr . ' ', $user); + DI::logger()->notice('pumpio: error fetching posts for user ' . $uid . ' ' . $useraddr . ' ', $user); return; } @@ -801,11 +800,11 @@ function pumpio_fetchtimeline(int $uid) } } - Logger::notice('pumpio: posting for user ' . $uid); + DI::logger()->notice('pumpio: posting for user ' . $uid); Item::insert($postarray, true); - Logger::notice('pumpio: posting done - user ' . $uid); + DI::logger()->notice('pumpio: posting done - user ' . $uid); } } } @@ -846,16 +845,16 @@ function pumpio_dounlike(int $uid, array $self, $post, string $own_id) Item::markForDeletion(['verb' => Activity::LIKE, 'uid' => $uid, 'contact-id' => $contactid, 'thr-parent' => $orig_post['uri']]); if (DBA::isResult($contact)) { - Logger::notice('pumpio_dounlike: unliked existing like. User ' . $own_id . ' ' . $uid . ' Contact: ' . $contactid . ' URI ' . $orig_post['uri']); + DI::logger()->notice('pumpio_dounlike: unliked existing like. User ' . $own_id . ' ' . $uid . ' Contact: ' . $contactid . ' URI ' . $orig_post['uri']); } else { - Logger::notice('pumpio_dounlike: not found. User ' . $own_id . ' ' . $uid . ' Contact: ' . $contactid . ' Url ' . $orig_post['uri']); + DI::logger()->notice('pumpio_dounlike: not found. User ' . $own_id . ' ' . $uid . ' Contact: ' . $contactid . ' Url ' . $orig_post['uri']); } } function pumpio_dolike(int $uid, array $self, $post, string $own_id, $threadcompletion = true) { if (empty($post->object->id)) { - Logger::info('Got empty like: '.print_r($post, true)); + DI::logger()->info('Got empty like: '.print_r($post, true)); return; } @@ -900,7 +899,7 @@ function pumpio_dolike(int $uid, array $self, $post, string $own_id, $threadcomp ]; if (Post::exists($condition)) { - Logger::notice('pumpio_dolike: found existing like. User ' . $own_id . ' ' . $uid . ' Contact: ' . $contactid . ' URI ' . $orig_post['uri']); + DI::logger()->notice('pumpio_dolike: found existing like. User ' . $own_id . ' ' . $uid . ' Contact: ' . $contactid . ' URI ' . $orig_post['uri']); return; } @@ -934,7 +933,7 @@ function pumpio_dolike(int $uid, array $self, $post, string $own_id, $threadcomp $ret = Item::insert($likedata); - Logger::notice('pumpio_dolike: ' . $ret . ' User ' . $own_id . ' ' . $uid . ' Contact: ' . $contactid . ' URI ' . $orig_post['uri']); + DI::logger()->notice('pumpio_dolike: ' . $ret . ' User ' . $own_id . ' ' . $uid . ' Contact: ' . $contactid . ' URI ' . $orig_post['uri']); } function pumpio_get_contact($uid, $contact, $no_insert = false) @@ -1405,7 +1404,7 @@ function pumpio_fetchallcomments($uid, $id) $hostname = DI::pConfig()->get($uid, 'pumpio', 'host'); $username = DI::pConfig()->get($uid, 'pumpio', 'user'); - Logger::notice('pumpio_fetchallcomments: completing comment for user ' . $uid . ' post id ' . $id); + DI::logger()->notice('pumpio_fetchallcomments: completing comment for user ' . $uid . ' post id ' . $id); $own_id = 'https://' . $hostname . '/' . $username; @@ -1430,7 +1429,7 @@ function pumpio_fetchallcomments($uid, $id) $client->access_token = $otoken; $client->access_token_secret = $osecret; - Logger::notice('pumpio_fetchallcomments: fetching comment for user ' . $uid . ', URL ' . $url); + DI::logger()->notice('pumpio_fetchallcomments: fetching comment for user ' . $uid . ', URL ' . $url); $item = new \stdClass(); @@ -1495,7 +1494,7 @@ function pumpio_fetchallcomments($uid, $id) $post->object = $item; - Logger::notice('pumpio_fetchallcomments: posting comment ' . $post->object->id . ' ', json_decode(json_encode($post), true)); + DI::logger()->notice('pumpio_fetchallcomments: posting comment ' . $post->object->id . ' ', json_decode(json_encode($post), true)); pumpio_dopost($client, $uid, $self, $post, $own_id, false); } } From 32a3160445d6a148b81daadd169705ddfe5558af Mon Sep 17 00:00:00 2001 From: Art4 Date: Fri, 24 Jan 2025 11:56:09 +0000 Subject: [PATCH 166/222] Replace call for Logger with DI::logger() in randplace addon --- randplace/randplace.php | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/randplace/randplace.php b/randplace/randplace.php index 5cb07597..89a75f98 100644 --- a/randplace/randplace.php +++ b/randplace/randplace.php @@ -20,7 +20,6 @@ */ use Friendica\Core\Hook; -use Friendica\Core\Logger; use Friendica\Core\Renderer; use Friendica\DI; @@ -40,7 +39,7 @@ function randplace_install() Hook::register('addon_settings', 'addon/randplace/randplace.php', 'randplace_settings'); Hook::register('addon_settings_post', 'addon/randplace/randplace.php', 'randplace_settings_post'); - Logger::notice("installed randplace"); + DI::logger()->notice("installed randplace"); } function randplace_uninstall() @@ -50,7 +49,7 @@ function randplace_uninstall() * * Except hooks, they are all unregistered automatically and don't need to be unregistered manually. */ - Logger::notice("removed randplace"); + DI::logger()->notice("removed randplace"); } function randplace_post_hook(&$item) @@ -61,7 +60,7 @@ function randplace_post_hook(&$item) * - A status post by a profile owner * - The profile owner must have allowed our addon */ - Logger::notice('randplace invoked'); + DI::logger()->notice('randplace invoked'); if (!DI::userSession()->getLocalUserId()) { /* non-zero if this is a logged in user of this system */ From ac6c1d7a49a386555c054faa6d13bb108856ebd0 Mon Sep 17 00:00:00 2001 From: Art4 Date: Fri, 24 Jan 2025 11:56:29 +0000 Subject: [PATCH 167/222] Replace call for Logger with DI::logger() in saml addon --- saml/saml.php | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/saml/saml.php b/saml/saml.php index 81a6bfcc..c8824b46 100755 --- a/saml/saml.php +++ b/saml/saml.php @@ -8,7 +8,6 @@ use Friendica\Content\Text\BBCode; use Friendica\Core\Hook; -use Friendica\Core\Logger; use Friendica\Core\Renderer; use Friendica\Database\DBA; use Friendica\DI; @@ -63,7 +62,7 @@ function saml_metadata() ); } } catch (Exception $e) { - Logger::error($e->getMessage()); + DI::logger()->error($e->getMessage()); } } @@ -125,7 +124,7 @@ function saml_is_configured() function saml_sso_initiate(string &$body) { if (!saml_is_configured()) { - Logger::warning('SAML SSO tried to trigger, but the SAML addon is not configured yet!'); + DI::logger()->warning('SAML SSO tried to trigger, but the SAML addon is not configured yet!'); return; } @@ -154,7 +153,7 @@ function saml_sso_reply() if (!empty($errors)) { echo 'Errors encountered.'; - Logger::error(implode(', ', $errors)); + DI::logger()->error(implode(', ', $errors)); exit(); } @@ -190,7 +189,7 @@ function saml_sso_reply() function saml_slo_initiate() { if (!saml_is_configured()) { - Logger::warning('SAML SLO tried to trigger, but the SAML addon is not configured yet!'); + DI::logger()->warning('SAML SLO tried to trigger, but the SAML addon is not configured yet!'); return; } @@ -221,7 +220,7 @@ function saml_slo_reply() if (empty($errors)) { $auth->redirectTo(DI::baseUrl()); } else { - Logger::error(implode(', ', $errors)); + DI::logger()->error(implode(', ', $errors)); } } @@ -314,7 +313,7 @@ function saml_addon_admin_post() function saml_create_user($username, $email, $name) { if (!strlen($email) || !strlen($name)) { - Logger::error('Could not create user: no email or username given.'); + DI::logger()->error('Could not create user: no email or username given.'); return false; } @@ -336,7 +335,7 @@ function saml_create_user($username, $email, $name) return $user; } catch (Exception $e) { - Logger::error( + DI::logger()->error( 'Exception while creating user', [ 'username' => $username, From bfdccb451ce391361de025d01565b4a52af99d6c Mon Sep 17 00:00:00 2001 From: Art4 Date: Fri, 24 Jan 2025 11:56:45 +0000 Subject: [PATCH 168/222] Replace call for Logger with DI::logger() in statusnet addon --- statusnet/statusnet.php | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/statusnet/statusnet.php b/statusnet/statusnet.php index bd115115..8663aaea 100644 --- a/statusnet/statusnet.php +++ b/statusnet/statusnet.php @@ -40,7 +40,6 @@ require_once __DIR__ . DIRECTORY_SEPARATOR . 'library' . DIRECTORY_SEPARATOR . ' use CodebirdSN\CodebirdSN; use Friendica\Content\Text\Plaintext; use Friendica\Core\Hook; -use Friendica\Core\Logger; use Friendica\Core\Renderer; use Friendica\Core\System; use Friendica\Database\DBA; @@ -58,7 +57,7 @@ function statusnet_install() Hook::register('hook_fork', 'addon/statusnet/statusnet.php', 'statusnet_hook_fork'); Hook::register('post_local', 'addon/statusnet/statusnet.php', 'statusnet_post_local'); Hook::register('jot_networks', 'addon/statusnet/statusnet.php', 'statusnet_jot_nets'); - Logger::notice('installed GNU Social'); + DI::logger()->notice('installed GNU Social'); } function statusnet_jot_nets(array &$jotnets_fields) @@ -355,7 +354,7 @@ function statusnet_post_hook(array &$b) return; } - Logger::notice('GNU Socialpost invoked'); + DI::logger()->notice('GNU Socialpost invoked'); DI::pConfig()->load($b['uid'], 'statusnet'); @@ -407,7 +406,7 @@ function statusnet_post_hook(array &$b) $cb->setToken($otoken, $osecret); $result = $cb->statuses_update($postdata); //$result = $dent->post('statuses/update', $postdata); - Logger::info('statusnet_post send, result: ' . print_r($result, true) . + DI::logger()->info('statusnet_post send, result: ' . print_r($result, true) . "\nmessage: " . $msg . "\nOriginal post: " . print_r($b, true) . "\nPost Data: " . print_r($postdata, true)); if (!empty($result->source)) { @@ -415,9 +414,9 @@ function statusnet_post_hook(array &$b) } if (!empty($result->error)) { - Logger::notice('Send to GNU Social failed: "' . $result->error . '"'); + DI::logger()->notice('Send to GNU Social failed: "' . $result->error . '"'); } elseif ($iscomment) { - Logger::notice('statusnet_post: Update extid ' . $result->id . ' for post id ' . $b['id']); + DI::logger()->notice('statusnet_post: Update extid ' . $result->id . ' for post id ' . $b['id']); Item::update(['extid' => $hostname . '::' . $result->id, 'body' => $result->text], ['id' => $b['id']]); } } From 763c5026f237a569f9f6cc9b4b65311556ca0087 Mon Sep 17 00:00:00 2001 From: Art4 Date: Fri, 24 Jan 2025 11:57:12 +0000 Subject: [PATCH 169/222] Replace call for Logger with DI::logger() in tumblr addon --- tumblr/tumblr.php | 99 +++++++++++++++++++++++------------------------ 1 file changed, 49 insertions(+), 50 deletions(-) diff --git a/tumblr/tumblr.php b/tumblr/tumblr.php index 12f13aa8..819c0ca5 100644 --- a/tumblr/tumblr.php +++ b/tumblr/tumblr.php @@ -14,7 +14,6 @@ use Friendica\Content\Text\NPF; use Friendica\Core\Cache\Enum\Duration; use Friendica\Core\Config\Util\ConfigFileManager; use Friendica\Core\Hook; -use Friendica\Core\Logger; use Friendica\Core\Protocol; use Friendica\Core\Renderer; use Friendica\Core\System; @@ -60,7 +59,7 @@ function tumblr_install() Hook::register('check_item_notification', __FILE__, 'tumblr_check_item_notification'); Hook::register('probe_detect', __FILE__, 'tumblr_probe_detect'); Hook::register('item_by_link', __FILE__, 'tumblr_item_by_link'); - Logger::info('installed tumblr'); + DI::logger()->info('installed tumblr'); } function tumblr_load_config(ConfigFileManager $loader) @@ -121,16 +120,16 @@ function tumblr_item_by_link(array &$hookData) return; } - Logger::debug('Found tumblr post', ['url' => $hookData['uri'], 'blog' => $matches[1], 'id' => $matches[2]]); + DI::logger()->debug('Found tumblr post', ['url' => $hookData['uri'], 'blog' => $matches[1], 'id' => $matches[2]]); $parameters = ['id' => $matches[2], 'reblog_info' => false, 'notes_info' => false, 'npf' => false]; $result = tumblr_get($hookData['uid'], 'blog/' . $matches[1] . '/posts', $parameters); if ($result->meta->status > 399) { - Logger::notice('Error fetching status', ['meta' => $result->meta, 'response' => $result->response, 'errors' => $result->errors, 'blog' => $matches[1], 'id' => $matches[2]]); + DI::logger()->notice('Error fetching status', ['meta' => $result->meta, 'response' => $result->response, 'errors' => $result->errors, 'blog' => $matches[1], 'id' => $matches[2]]); return []; } - Logger::debug('Got post', ['blog' => $matches[1], 'id' => $matches[2], 'result' => $result->response->posts]); + DI::logger()->debug('Got post', ['blog' => $matches[1], 'id' => $matches[2], 'result' => $result->response->posts]); if (!empty($result->response->posts)) { $hookData['item_id'] = tumblr_process_post($result->response->posts[0], $hookData['uid'], Item::PR_FETCHED); Item::incrementInbound(Protocol::TUMBLR); @@ -159,20 +158,20 @@ function tumblr_follow(array &$hook_data) return; } - Logger::debug('Check if contact is Tumblr', ['url' => $hook_data['url']]); + DI::logger()->debug('Check if contact is Tumblr', ['url' => $hook_data['url']]); $fields = tumblr_get_contact_by_url($hook_data['url'], $uid); if (empty($fields)) { - Logger::debug('Contact is not a Tumblr contact', ['url' => $hook_data['url']]); + DI::logger()->debug('Contact is not a Tumblr contact', ['url' => $hook_data['url']]); return; } $result = tumblr_post($uid, 'user/follow', ['url' => $fields['url']]); if ($result->meta->status <= 399) { $hook_data['contact'] = $fields; - Logger::debug('Successfully start following', ['url' => $fields['url']]); + DI::logger()->debug('Successfully start following', ['url' => $fields['url']]); } else { - Logger::notice('Following failed', ['meta' => $result->meta, 'response' => $result->response, 'errors' => $result->errors, 'url' => $fields['url']]); + DI::logger()->notice('Following failed', ['meta' => $result->meta, 'response' => $result->response, 'errors' => $result->errors, 'url' => $fields['url']]); } } @@ -415,11 +414,11 @@ function tumblr_cron() if ($last) { $next = $last + ($poll_interval * 60); if ($next > time()) { - Logger::notice('poll interval not reached'); + DI::logger()->notice('poll interval not reached'); return; } } - Logger::notice('cron_start'); + DI::logger()->notice('cron_start'); $abandon_days = intval(DI::config()->get('system', 'account_abandon_days')); if ($abandon_days < 1) { @@ -432,30 +431,30 @@ function tumblr_cron() foreach ($pconfigs as $pconfig) { if ($abandon_days != 0) { if (!DBA::exists('user', ["`uid` = ? AND `login_date` >= ?", $pconfig['uid'], $abandon_limit])) { - Logger::notice('abandoned account: timeline from user will not be imported', ['user' => $pconfig['uid']]); + DI::logger()->notice('abandoned account: timeline from user will not be imported', ['user' => $pconfig['uid']]); continue; } } - Logger::notice('importing timeline - start', ['user' => $pconfig['uid']]); + DI::logger()->notice('importing timeline - start', ['user' => $pconfig['uid']]); tumblr_fetch_dashboard($pconfig['uid'], $last); tumblr_fetch_tags($pconfig['uid'], $last); - Logger::notice('importing timeline - done', ['user' => $pconfig['uid']]); + DI::logger()->notice('importing timeline - done', ['user' => $pconfig['uid']]); } $last_clean = DI::keyValue()->get('tumblr_last_clean'); if (empty($last_clean) || ($last_clean + 86400 < time())) { - Logger::notice('Start contact cleanup'); + DI::logger()->notice('Start contact cleanup'); $contacts = DBA::select('account-user-view', ['id', 'pid'], ["`network` = ? AND `uid` != ? AND `rel` = ?", Protocol::TUMBLR, 0, Contact::NOTHING]); while ($contact = DBA::fetch($contacts)) { Worker::add(Worker::PRIORITY_LOW, 'MergeContact', $contact['pid'], $contact['id'], 0); } DBA::close($contacts); DI::keyValue()->set('tumblr_last_clean', time()); - Logger::notice('Contact cleanup done'); + DI::logger()->notice('Contact cleanup done'); } - Logger::notice('cron_end'); + DI::logger()->notice('cron_end'); DI::keyValue()->set('tumblr_last_poll', time()); } @@ -478,7 +477,7 @@ function tumblr_hook_fork(array &$b) if (DI::pConfig()->get($post['uid'], 'tumblr', 'import')) { // Don't post if it isn't a reply to a tumblr post if (($post['gravity'] != Item::GRAVITY_PARENT) && !Post::exists(['id' => $post['parent'], 'network' => Protocol::TUMBLR])) { - Logger::notice('No tumblr parent found', ['item' => $post['id']]); + DI::logger()->notice('No tumblr parent found', ['item' => $post['id']]); $b['execute'] = false; return; } @@ -525,20 +524,20 @@ function tumblr_send(array &$b) } if ($b['gravity'] != Item::GRAVITY_PARENT) { - Logger::debug('Got comment', ['item' => $b]); + DI::logger()->debug('Got comment', ['item' => $b]); $parent = tumblr_get_post_from_uri($b['thr-parent']); if (empty($parent)) { - Logger::notice('No tumblr post', ['thr-parent' => $b['thr-parent']]); + DI::logger()->notice('No tumblr post', ['thr-parent' => $b['thr-parent']]); return; } - Logger::debug('Parent found', ['parent' => $parent]); + DI::logger()->debug('Parent found', ['parent' => $parent]); $page = tumblr_get_page($b['uid']); if ($b['gravity'] == Item::GRAVITY_COMMENT) { - Logger::notice('Commenting is not supported (yet)'); + DI::logger()->notice('Commenting is not supported (yet)'); } else { if (($b['verb'] == Activity::LIKE) && !$b['deleted']) { $params = ['id' => $parent['id'], 'reblog_key' => $parent['reblog_key']]; @@ -562,12 +561,12 @@ function tumblr_send(array &$b) } if ($result->meta->status < 400) { - Logger::info('Successfully performed activity', ['verb' => $b['verb'], 'deleted' => $b['deleted'], 'meta' => $result->meta, 'response' => $result->response]); + DI::logger()->info('Successfully performed activity', ['verb' => $b['verb'], 'deleted' => $b['deleted'], 'meta' => $result->meta, 'response' => $result->response]); if (!$b['deleted'] && !empty($result->response->id_string)) { Item::update(['extid' => 'tumblr::' . $result->response->id_string], ['guid' => $b['guid']]); } } else { - Logger::notice('Error while performing activity', ['verb' => $b['verb'], 'deleted' => $b['deleted'], 'meta' => $result->meta, 'response' => $result->response, 'errors' => $result->errors, 'params' => $params]); + DI::logger()->notice('Error while performing activity', ['verb' => $b['verb'], 'deleted' => $b['deleted'], 'meta' => $result->meta, 'response' => $result->response, 'errors' => $result->errors, 'params' => $params]); } } return; @@ -665,9 +664,9 @@ function tumblr_send_legacy(array $b) $result = tumblr_post($b['uid'], 'blog/' . $page . '/post', $params); if ($result->meta->status < 400) { - Logger::info('Success (legacy)', ['blog' => $page, 'meta' => $result->meta, 'response' => $result->response]); + DI::logger()->info('Success (legacy)', ['blog' => $page, 'meta' => $result->meta, 'response' => $result->response]); } else { - Logger::notice('Error posting blog (legacy)', ['blog' => $page, 'meta' => $result->meta, 'response' => $result->response, 'errors' => $result->errors, 'params' => $params]); + DI::logger()->notice('Error posting blog (legacy)', ['blog' => $page, 'meta' => $result->meta, 'response' => $result->response, 'errors' => $result->errors, 'params' => $params]); } } @@ -676,7 +675,7 @@ function tumblr_send_npf(array $post): bool $page = tumblr_get_page($post['uid']); if (empty($page)) { - Logger::notice('Missing page, post will not be send to Tumblr.', ['uid' => $post['uid'], 'page' => $page, 'id' => $post['id']]); + DI::logger()->notice('Missing page, post will not be send to Tumblr.', ['uid' => $post['uid'], 'page' => $page, 'id' => $post['id']]); // "true" is returned, since the legacy function will fail as well. return true; } @@ -707,10 +706,10 @@ function tumblr_send_npf(array $post): bool $result = tumblr_post($post['uid'], 'blog/' . $page . '/posts', $params); if ($result->meta->status < 400) { - Logger::info('Success (NPF)', ['blog' => $page, 'meta' => $result->meta, 'response' => $result->response]); + DI::logger()->info('Success (NPF)', ['blog' => $page, 'meta' => $result->meta, 'response' => $result->response]); return true; } else { - Logger::notice('Error posting blog (NPF)', ['blog' => $page, 'meta' => $result->meta, 'response' => $result->response, 'errors' => $result->errors, 'params' => $params]); + DI::logger()->notice('Error posting blog (NPF)', ['blog' => $page, 'meta' => $result->meta, 'response' => $result->response, 'errors' => $result->errors, 'params' => $params]); return false; } } @@ -747,10 +746,10 @@ function tumblr_fetch_tags(int $uid, int $last_poll) foreach (array_reverse($data->response) as $post) { $id = tumblr_process_post($post, $uid, Item::PR_TAG, $last_poll); if (!empty($id)) { - Logger::debug('Tag post imported', ['tag' => $tag, 'id' => $id]); + DI::logger()->debug('Tag post imported', ['tag' => $tag, 'id' => $id]); $post = Post::selectFirst(['uri-id'], ['id' => $id]); $stored = Post\Category::storeFileByURIId($post['uri-id'], $uid, Post\Category::SUBCRIPTION, $tag); - Logger::debug('Stored tag subscription for user', ['uri-id' => $post['uri-id'], 'uid' => $uid, 'tag' => $tag, 'stored' => $stored]); + DI::logger()->debug('Stored tag subscription for user', ['uri-id' => $post['uri-id'], 'uid' => $uid, 'tag' => $tag, 'stored' => $stored]); Item::incrementInbound(Protocol::TUMBLR); } } @@ -775,7 +774,7 @@ function tumblr_fetch_dashboard(int $uid, int $last_poll) $dashboard = tumblr_get($uid, 'user/dashboard', $parameters); if ($dashboard->meta->status > 399) { - Logger::notice('Error fetching dashboard', ['meta' => $dashboard->meta, 'response' => $dashboard->response, 'errors' => $dashboard->errors]); + DI::logger()->notice('Error fetching dashboard', ['meta' => $dashboard->meta, 'response' => $dashboard->response, 'errors' => $dashboard->errors]); return []; } @@ -788,7 +787,7 @@ function tumblr_fetch_dashboard(int $uid, int $last_poll) $last = $post->id; } - Logger::debug('Importing post', ['uid' => $uid, 'created' => date(DateTimeFormat::MYSQL, $post->timestamp), 'id' => $post->id_string]); + DI::logger()->debug('Importing post', ['uid' => $uid, 'created' => date(DateTimeFormat::MYSQL, $post->timestamp), 'id' => $post->id_string]); tumblr_process_post($post, $uid, Item::PR_NONE, $last_poll); Item::incrementInbound(Protocol::TUMBLR); @@ -1063,7 +1062,7 @@ function tumblr_get_type_replacement(array $data, string $plink): string } default: - Logger::notice('Unknown type', ['type' => $data['type'], 'data' => $data, 'plink' => $plink]); + DI::logger()->notice('Unknown type', ['type' => $data['type'], 'data' => $data, 'plink' => $plink]); $body = ''; } @@ -1118,9 +1117,9 @@ function tumblr_get_contact(stdClass $blog, int $uid): array $cid = $contact['id']; Contact::update($fields, ['id' => $cid], true); } - Logger::debug('Get user contact', ['id' => $cid, 'uid' => $uid, 'update' => $update]); + DI::logger()->debug('Get user contact', ['id' => $cid, 'uid' => $uid, 'update' => $update]); } else { - Logger::debug('Get public contact', ['id' => $cid, 'uid' => $uid, 'update' => $update]); + DI::logger()->debug('Get public contact', ['id' => $cid, 'uid' => $uid, 'update' => $update]); } if (!empty($avatar)) { @@ -1156,13 +1155,13 @@ function tumblr_get_contact_fields(stdClass $blog, int $uid, bool $update): arra ]; if (!$update) { - Logger::debug('Got contact fields', ['uid' => $uid, 'url' => $fields['url']]); + DI::logger()->debug('Got contact fields', ['uid' => $uid, 'url' => $fields['url']]); return $fields; } $info = tumblr_get($uid, 'blog/' . $blog->uuid . '/info'); if ($info->meta->status > 399) { - Logger::notice('Error fetching blog info', ['meta' => $info->meta, 'response' => $info->response, 'errors' => $info->errors]); + DI::logger()->notice('Error fetching blog info', ['meta' => $info->meta, 'response' => $info->response, 'errors' => $info->errors]); return $fields; } Item::incrementInbound(Protocol::TUMBLR); @@ -1184,7 +1183,7 @@ function tumblr_get_contact_fields(stdClass $blog, int $uid, bool $update): arra $fields['header'] = $info->response->blog->theme->header_image_focused; - Logger::debug('Got updated contact fields', ['uid' => $uid, 'url' => $fields['url']]); + DI::logger()->debug('Got updated contact fields', ['uid' => $uid, 'url' => $fields['url']]); return $fields; } @@ -1226,7 +1225,7 @@ function tumblr_get_blogs(int $uid): array { $userinfo = tumblr_get($uid, 'user/info'); if ($userinfo->meta->status > 399) { - Logger::notice('Error fetching blogs', ['meta' => $userinfo->meta, 'response' => $userinfo->response, 'errors' => $userinfo->errors]); + DI::logger()->notice('Error fetching blogs', ['meta' => $userinfo->meta, 'response' => $userinfo->response, 'errors' => $userinfo->errors]); return []; } @@ -1282,15 +1281,15 @@ function tumblr_get_contact_by_url(string $url, int $uid): ?array return null; } - Logger::debug('Update Tumblr blog data', ['url' => $url, 'blog' => $blog, 'uid' => $uid]); + DI::logger()->debug('Update Tumblr blog data', ['url' => $url, 'blog' => $blog, 'uid' => $uid]); $info = tumblr_get($uid, 'blog/' . $blog . '/info'); if ($info->meta->status > 399) { - Logger::notice('Error fetching blog info', ['meta' => $info->meta, 'response' => $info->response, 'errors' => $info->errors, 'blog' => $blog, 'uid' => $uid]); + DI::logger()->notice('Error fetching blog info', ['meta' => $info->meta, 'response' => $info->response, 'errors' => $info->errors, 'blog' => $blog, 'uid' => $uid]); return null; } - Logger::debug('Got data', ['blog' => $blog, 'meta' => $info->meta]); + DI::logger()->debug('Got data', ['blog' => $blog, 'meta' => $info->meta]); Item::incrementInbound(Protocol::TUMBLR); $baseurl = 'https://tumblr.com'; @@ -1419,7 +1418,7 @@ function tumblr_get_token(int $uid, string $code = ''): string $refresh_token = DI::pConfig()->get($uid, 'tumblr', 'refresh_token'); if (empty($code) && !empty($access_token) && ($expires_at > (time()))) { - Logger::debug('Got token', ['uid' => $uid, 'expires_at' => date('c', $expires_at)]); + DI::logger()->debug('Got token', ['uid' => $uid, 'expires_at' => date('c', $expires_at)]); return $access_token; } @@ -1431,11 +1430,11 @@ function tumblr_get_token(int $uid, string $code = ''): string if (empty($refresh_token) && empty($code)) { $result = tumblr_exchange_token($uid); if (empty($result->refresh_token)) { - Logger::info('Invalid result while exchanging token', ['uid' => $uid]); + DI::logger()->info('Invalid result while exchanging token', ['uid' => $uid]); return ''; } $expires_at = time() + $result->expires_in; - Logger::debug('Updated token from OAuth1 to OAuth2', ['uid' => $uid, 'expires_at' => date('c', $expires_at)]); + DI::logger()->debug('Updated token from OAuth1 to OAuth2', ['uid' => $uid, 'expires_at' => date('c', $expires_at)]); } else { if (!empty($code)) { $parameters['code'] = $code; @@ -1447,18 +1446,18 @@ function tumblr_get_token(int $uid, string $code = ''): string $curlResult = DI::httpClient()->post('https://api.tumblr.com/v2/oauth2/token', $parameters); if (!$curlResult->isSuccess()) { - Logger::info('Error fetching token', ['uid' => $uid, 'code' => $code, 'result' => $curlResult->getBodyString(), 'parameters' => $parameters]); + DI::logger()->info('Error fetching token', ['uid' => $uid, 'code' => $code, 'result' => $curlResult->getBodyString(), 'parameters' => $parameters]); return ''; } $result = json_decode($curlResult->getBodyString()); if (empty($result)) { - Logger::info('Invalid result when updating token', ['uid' => $uid]); + DI::logger()->info('Invalid result when updating token', ['uid' => $uid]); return ''; } $expires_at = time() + $result->expires_in; - Logger::debug('Renewed token', ['uid' => $uid, 'expires_at' => date('c', $expires_at)]); + DI::logger()->debug('Renewed token', ['uid' => $uid, 'expires_at' => date('c', $expires_at)]); } DI::pConfig()->set($uid, 'tumblr', 'access_token', $result->access_token); @@ -1502,7 +1501,7 @@ function tumblr_exchange_token(int $uid): stdClass $response = $client->post('oauth2/exchange', ['auth' => 'oauth']); return json_decode($response->getBody()->getContents()); } catch (RequestException $exception) { - Logger::notice('Exchange failed', ['code' => $exception->getCode(), 'message' => $exception->getMessage()]); + DI::logger()->notice('Exchange failed', ['code' => $exception->getCode(), 'message' => $exception->getMessage()]); return new stdClass; } } From a7b26f64538159e72799fae87679d1d10e0b1bb3 Mon Sep 17 00:00:00 2001 From: Art4 Date: Fri, 24 Jan 2025 11:57:34 +0000 Subject: [PATCH 170/222] Replace call for Logger with DI::logger() in tesseract addon --- tesseract/tesseract.php | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/tesseract/tesseract.php b/tesseract/tesseract.php index 4c630dbb..ea048032 100644 --- a/tesseract/tesseract.php +++ b/tesseract/tesseract.php @@ -7,7 +7,6 @@ */ use Friendica\Core\Hook; -use Friendica\Core\Logger; use Friendica\Core\System; use thiagoalessio\TesseractOCR\TesseractOCR; @@ -17,7 +16,7 @@ function tesseract_install() { Hook::register('ocr-detection', __FILE__, 'tesseract_ocr_detection'); - Logger::notice('installed tesseract'); + DI::logger()->notice('installed tesseract'); } function tesseract_ocr_detection(&$media) @@ -33,6 +32,6 @@ function tesseract_ocr_detection(&$media) $ocr->imageData($media['img_str'], strlen($media['img_str'])); $media['description'] = $ocr->run(); } catch (\Throwable $th) { - Logger::info('Error calling TesseractOCR', ['message' => $th->getMessage()]); + DI::logger()->info('Error calling TesseractOCR', ['message' => $th->getMessage()]); } } From e4d14cab62755aa91d986584b4898d75054b3471 Mon Sep 17 00:00:00 2001 From: Art4 Date: Fri, 24 Jan 2025 11:58:10 +0000 Subject: [PATCH 171/222] Replace call for Logger with DI::logger() in twitter addon --- tesseract/tesseract.php | 1 + twitter/twitter.php | 31 +++++++++++++++---------------- 2 files changed, 16 insertions(+), 16 deletions(-) diff --git a/tesseract/tesseract.php b/tesseract/tesseract.php index ea048032..a07c690c 100644 --- a/tesseract/tesseract.php +++ b/tesseract/tesseract.php @@ -8,6 +8,7 @@ use Friendica\Core\Hook; use Friendica\Core\System; +use Friendica\DI; use thiagoalessio\TesseractOCR\TesseractOCR; require_once __DIR__ . DIRECTORY_SEPARATOR . 'vendor' . DIRECTORY_SEPARATOR . 'autoload.php'; diff --git a/twitter/twitter.php b/twitter/twitter.php index ea4ae356..a9654405 100644 --- a/twitter/twitter.php +++ b/twitter/twitter.php @@ -38,7 +38,6 @@ use Friendica\Content\Text\BBCode; use Friendica\Content\Text\Plaintext; use Friendica\Core\Hook; -use Friendica\Core\Logger; use Friendica\Core\Renderer; use Friendica\Core\Worker; use Friendica\DI; @@ -217,7 +216,7 @@ function twitter_post_hook(array &$b) $b['body'] = Post\Media::addAttachmentsToBody($b['uri-id'], DI::contentItem()->addSharedPost($b)); - Logger::notice('twitter post invoked', ['id' => $b['id'], 'guid' => $b['guid']]); + DI::logger()->notice('twitter post invoked', ['id' => $b['id'], 'guid' => $b['guid']]); DI::pConfig()->load($b['uid'], 'twitter'); @@ -227,17 +226,17 @@ function twitter_post_hook(array &$b) $access_secret = DI::pConfig()->get($b['uid'], 'twitter', 'access_secret'); if (empty($api_key) || empty($api_secret) || empty($access_token) || empty($access_secret)) { - Logger::info('Missing keys, secrets or tokens.'); + DI::logger()->info('Missing keys, secrets or tokens.'); return; } $msgarr = Plaintext::getPost($b, 280, true, BBCode::TWITTER); - Logger::debug('Got plaintext', ['id' => $b['id'], 'message' => $msgarr]); + DI::logger()->debug('Got plaintext', ['id' => $b['id'], 'message' => $msgarr]); $media_ids = []; if (!empty($msgarr['images']) || !empty($msgarr['remote_images'])) { - Logger::info('Got images', ['id' => $b['id'], 'images' => $msgarr['images'] ?? []]); + DI::logger()->info('Got images', ['id' => $b['id'], 'images' => $msgarr['images'] ?? []]); $retrial = Worker::getRetrial(); if ($retrial > 4) { @@ -250,7 +249,7 @@ function twitter_post_hook(array &$b) try { $media_ids[] = twitter_upload_image($b['uid'], $image, $retrial); } catch (RequestException $exception) { - Logger::warning('Error while uploading image', ['image' => $image, 'code' => $exception->getCode(), 'message' => $exception->getMessage()]); + DI::logger()->warning('Error while uploading image', ['image' => $image, 'code' => $exception->getCode(), 'message' => $exception->getMessage()]); Worker::defer(); return; } @@ -259,13 +258,13 @@ function twitter_post_hook(array &$b) $in_reply_to_tweet_id = 0; - Logger::debug('Post message', ['id' => $b['id'], 'parts' => count($msgarr['parts'])]); + DI::logger()->debug('Post message', ['id' => $b['id'], 'parts' => count($msgarr['parts'])]); foreach ($msgarr['parts'] as $key => $part) { try { $id = twitter_post_status($b['uid'], $part, $media_ids, $in_reply_to_tweet_id); - Logger::info('twitter_post send', ['part' => $key, 'id' => $b['id'], 'result' => $id]); + DI::logger()->info('twitter_post send', ['part' => $key, 'id' => $b['id'], 'result' => $id]); } catch (RequestException $exception) { - Logger::warning('Error while posting message', ['part' => $key, 'id' => $b['id'], 'code' => $exception->getCode(), 'message' => $exception->getMessage()]); + DI::logger()->warning('Error while posting message', ['part' => $key, 'id' => $b['id'], 'code' => $exception->getCode(), 'message' => $exception->getMessage()]); $status = [ 'code' => $exception->getCode(), 'reason' => $exception->getResponse()->getReasonPhrase(), @@ -319,9 +318,9 @@ function twitter_upload_image(int $uid, array $image, int $retrial) $picturedata = $picture->asString(); $new_size = strlen($picturedata); - Logger::info('Uploading', ['uid' => $uid, 'retrial' => $retrial, 'height' => $new_height, 'width' => $new_width, 'size' => $new_size, 'orig-height' => $height, 'orig-width' => $width, 'orig-size' => $size, 'image' => $image]); + DI::logger()->info('Uploading', ['uid' => $uid, 'retrial' => $retrial, 'height' => $new_height, 'width' => $new_width, 'size' => $new_size, 'orig-height' => $height, 'orig-width' => $width, 'orig-size' => $size, 'image' => $image]); $media = twitter_post($uid, 'https://upload.twitter.com/1.1/media/upload.json', 'form_params', ['media' => base64_encode($picturedata)]); - Logger::info('Uploading done', ['uid' => $uid, 'retrial' => $retrial, 'height' => $new_height, 'width' => $new_width, 'size' => $new_size, 'orig-height' => $height, 'orig-width' => $width, 'orig-size' => $size, 'image' => $image]); + DI::logger()->info('Uploading done', ['uid' => $uid, 'retrial' => $retrial, 'height' => $new_height, 'width' => $new_width, 'size' => $new_size, 'orig-height' => $height, 'orig-width' => $width, 'orig-size' => $size, 'image' => $image]); if (isset($media->media_id_string)) { $media_id = $media->media_id_string; @@ -334,10 +333,10 @@ function twitter_upload_image(int $uid, array $image, int $retrial) ] ]; $ret = twitter_post($uid, 'https://upload.twitter.com/1.1/media/metadata/create.json', 'json', $data); - Logger::info('Metadata create', ['uid' => $uid, 'data' => $data, 'return' => $ret]); + DI::logger()->info('Metadata create', ['uid' => $uid, 'data' => $data, 'return' => $ret]); } } else { - Logger::error('Failed upload', ['uid' => $uid, 'size' => strlen($picturedata), 'image' => $image['url'], 'return' => $media]); + DI::logger()->error('Failed upload', ['uid' => $uid, 'size' => strlen($picturedata), 'image' => $image['url'], 'return' => $media]); throw new Exception('Failed upload of ' . $image['url']); } @@ -373,7 +372,7 @@ function twitter_post(int $uid, string $url, string $type, array $data): stdClas DI::pConfig()->set($uid, 'twitter', 'last_status', $status); $content = json_decode($body) ?? new stdClass; - Logger::debug('Success', ['content' => $content]); + DI::logger()->debug('Success', ['content' => $content]); return $content; } @@ -402,7 +401,7 @@ function twitter_test_connection(int $uid) 'content' => $response->getBody()->getContents() ]; DI::pConfig()->set(1, 'twitter', 'last_status', $status); - Logger::info('Test successful', ['uid' => $uid]); + DI::logger()->info('Test successful', ['uid' => $uid]); } catch (RequestException $exception) { $status = [ 'code' => $exception->getCode(), @@ -410,6 +409,6 @@ function twitter_test_connection(int $uid) 'content' => $exception->getMessage() ]; DI::pConfig()->set(1, 'twitter', 'last_status', $status); - Logger::info('Test failed', ['uid' => $uid]); + DI::logger()->info('Test failed', ['uid' => $uid]); } } From dd775645d48b0309e08f604500e2baf85171800f Mon Sep 17 00:00:00 2001 From: Art4 Date: Fri, 24 Jan 2025 11:58:32 +0000 Subject: [PATCH 172/222] Replace call for Logger with DI::logger() in wppost addon --- wppost/wppost.php | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/wppost/wppost.php b/wppost/wppost.php index f2ee5d21..de216806 100644 --- a/wppost/wppost.php +++ b/wppost/wppost.php @@ -9,7 +9,6 @@ use Friendica\Content\Text\BBCode; use Friendica\Content\Text\HTML; use Friendica\Core\Hook; -use Friendica\Core\Logger; use Friendica\Core\Renderer; use Friendica\Database\DBA; use Friendica\DI; @@ -257,13 +256,13 @@ function wppost_send(array &$b) EOT; - Logger::debug('wppost: data: ' . $xml); + DI::logger()->debug('wppost: data: ' . $xml); $x = ''; if ($wp_blog !== 'test') { $x = DI::httpClient()->post($wp_blog, $xml)->getBodyString(); } - Logger::info('posted to wordpress: ' . $x); + DI::logger()->info('posted to wordpress: ' . $x); } } From 4c8c262b07f61d08a6f9a67c325a54dcb95b4c75 Mon Sep 17 00:00:00 2001 From: Art4 Date: Fri, 24 Jan 2025 12:10:58 +0000 Subject: [PATCH 173/222] fix in googlemaps addon --- googlemaps/googlemaps.php | 1 + 1 file changed, 1 insertion(+) diff --git a/googlemaps/googlemaps.php b/googlemaps/googlemaps.php index a0bba8ad..94a3a96b 100644 --- a/googlemaps/googlemaps.php +++ b/googlemaps/googlemaps.php @@ -8,6 +8,7 @@ */ use Friendica\Core\Hook; +use Friendica\DI; function googlemaps_install() { From cbfcfb33494d1662de1a5f5689caa23d723d6bca Mon Sep 17 00:00:00 2001 From: Michael Date: Sat, 25 Jan 2025 02:44:54 +0000 Subject: [PATCH 174/222] Issue 14692: Avoid loop situation --- blockbot/blockbot.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/blockbot/blockbot.php b/blockbot/blockbot.php index 163d0cbc..71e35c93 100644 --- a/blockbot/blockbot.php +++ b/blockbot/blockbot.php @@ -208,7 +208,7 @@ function blockbot_log_activitypub(string $url, string $agent) blockbot_save('activitypub-inbox-agents', $agent); } - if (!empty($_SERVER['HTTP_SIGNATURE']) && !empty(HTTPSignature::getSigner('', $_SERVER))) { + if (!empty($_SERVER['HTTP_SIGNATURE']) && !empty(HTTPSignature::getSigner('', $_SERVER, false))) { blockbot_save('activitypub-signature-agents', $agent); } } From 8384b74696b54c126a2b2c835a010403b6413b7d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakobus=20Sch=C3=BCrz?= Date: Thu, 23 Jan 2025 16:32:22 +0100 Subject: [PATCH 175/222] add condition for selected theme --- saml/saml.php | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/saml/saml.php b/saml/saml.php index c8824b46..83e4d3fd 100755 --- a/saml/saml.php +++ b/saml/saml.php @@ -82,11 +82,13 @@ function saml_footer(string &$body) diff --git a/xmppchat/templates/xmppchat.tpl b/xmppchat/templates/xmppchat.tpl new file mode 100644 index 00000000..0fbd1168 --- /dev/null +++ b/xmppchat/templates/xmppchat.tpl @@ -0,0 +1,61 @@ +{{* + * XMPP Chat Widget Template (Converse.js) + * SPDX-License-Identifier: AGPL-3.0-or-later + *}} + + +
+ + diff --git a/xmppchat/vendor/converse.min.css b/xmppchat/vendor/converse.min.css new file mode 100644 index 00000000..ac8bb670 --- /dev/null +++ b/xmppchat/vendor/converse.min.css @@ -0,0 +1,50 @@ +/*! + * Converse.js (Web-based XMPP instant messaging client) + * https://conversejs.org + * + * Copyright (c) 2013-2021, JC Brand + * Licensed under the Mozilla Public License + */@font-face{font-family:"Baumans";font-style:normal;font-weight:400;src:local("Baumans Regular"),local("Baumans-Regular"),url("webfonts/baumans.ttf") format("truetype")}@font-face{font-family:"Muli";font-style:normal;font-weight:400;src:local("Muli Regular"),local("Muli-Regular"),url("webfonts/muli.ttf") format("truetype")}.conversejs converse-icon:before,.converse-website converse-icon:before{content:none !important}.conversejs .fa-info-circle,.converse-website .fa-info-circle{height:1em}.conversejs :root{--blue: #007bff;--indigo: #6610f2;--purple: #6f42c1;--pink: #e83e8c;--red: #dc3545;--orange: #fd7e14;--yellow: #ffc107;--green: #28a745;--teal: #20c997;--cyan: #17a2b8;--white: #fff;--gray: #6c757d;--gray-dark: #343a40;--primary: #007bff;--secondary: #6c757d;--success: #28a745;--info: #17a2b8;--warning: #ffc107;--danger: #dc3545;--light: #f8f9fa;--dark: #343a40;--breakpoint-xs: 0;--breakpoint-sm: 576px;--breakpoint-md: 768px;--breakpoint-lg: 992px;--breakpoint-xl: 1200px;--font-family-sans-serif: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", "Liberation Sans", sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";--font-family-monospace: SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace}.conversejs *,.conversejs *::before,.conversejs *::after{box-sizing:border-box}.conversejs html{font-family:sans-serif;line-height:1.15;-webkit-text-size-adjust:100%;-webkit-tap-highlight-color:rgba(0,0,0,0)}.conversejs article,.conversejs aside,.conversejs figcaption,.conversejs figure,.conversejs footer,.conversejs header,.conversejs hgroup,.conversejs main,.conversejs nav,.conversejs section{display:block}.conversejs body{margin:0;font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,"Noto Sans","Liberation Sans",sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji";font-size:1rem;font-weight:400;line-height:1.5;color:#212529;text-align:left;background-color:#fff}.conversejs [tabindex="-1"]:focus:not(:focus-visible){outline:0 !important}.conversejs hr{box-sizing:content-box;height:0;overflow:visible}.conversejs h1,.conversejs h2,.conversejs h3,.conversejs h4,.conversejs h5,.conversejs h6{margin-top:0;margin-bottom:.5rem}.conversejs p{margin-top:0;margin-bottom:1rem}.conversejs abbr[title],.conversejs abbr[data-original-title]{text-decoration:underline;-webkit-text-decoration:underline dotted;text-decoration:underline dotted;cursor:help;border-bottom:0;-webkit-text-decoration-skip-ink:none;text-decoration-skip-ink:none}.conversejs address{margin-bottom:1rem;font-style:normal;line-height:inherit}.conversejs ol,.conversejs ul,.conversejs dl{margin-top:0;margin-bottom:1rem}.conversejs ol ol,.conversejs ul ul,.conversejs ol ul,.conversejs ul ol{margin-bottom:0}.conversejs dt{font-weight:700}.conversejs dd{margin-bottom:.5rem;margin-left:0}.conversejs blockquote{margin:0 0 1rem}.conversejs b,.conversejs strong{font-weight:bolder}.conversejs small{font-size:80%}.conversejs sub,.conversejs sup{position:relative;font-size:75%;line-height:0;vertical-align:baseline}.conversejs sub{bottom:-0.25em}.conversejs sup{top:-0.5em}.conversejs a{color:#007bff;text-decoration:none;background-color:rgba(0,0,0,0)}.conversejs a:hover{color:#0056b3;text-decoration:underline}.conversejs a:not([href]):not([class]){color:inherit;text-decoration:none}.conversejs a:not([href]):not([class]):hover{color:inherit;text-decoration:none}.conversejs pre,.conversejs code,.conversejs kbd,.conversejs samp{font-family:SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace;font-size:1em}.conversejs pre{margin-top:0;margin-bottom:1rem;overflow:auto;-ms-overflow-style:scrollbar}.conversejs figure{margin:0 0 1rem}.conversejs img{vertical-align:middle;border-style:none}.conversejs svg{overflow:hidden;vertical-align:middle}.conversejs table{border-collapse:collapse}.conversejs caption{padding-top:.75rem;padding-bottom:.75rem;color:#6c757d;text-align:left;caption-side:bottom}.conversejs th{text-align:inherit;text-align:-webkit-match-parent}.conversejs label{display:inline-block;margin-bottom:.5rem}.conversejs button{border-radius:0}.conversejs button:focus:not(:focus-visible){outline:0}.conversejs input,.conversejs button,.conversejs select,.conversejs optgroup,.conversejs textarea{margin:0;font-family:inherit;font-size:inherit;line-height:inherit}.conversejs button,.conversejs input{overflow:visible}.conversejs button,.conversejs select{text-transform:none}.conversejs [role=button]{cursor:pointer}.conversejs select{word-wrap:normal}.conversejs button,.conversejs [type=button],.conversejs [type=reset],.conversejs [type=submit]{-webkit-appearance:button}.conversejs button:not(:disabled),.conversejs [type=button]:not(:disabled),.conversejs [type=reset]:not(:disabled),.conversejs [type=submit]:not(:disabled){cursor:pointer}.conversejs button::-moz-focus-inner,.conversejs [type=button]::-moz-focus-inner,.conversejs [type=reset]::-moz-focus-inner,.conversejs [type=submit]::-moz-focus-inner{padding:0;border-style:none}.conversejs input[type=radio],.conversejs input[type=checkbox]{box-sizing:border-box;padding:0}.conversejs textarea{overflow:auto;resize:vertical}.conversejs fieldset{min-width:0;padding:0;margin:0;border:0}.conversejs legend{display:block;width:100%;max-width:100%;padding:0;margin-bottom:.5rem;font-size:1.5rem;line-height:inherit;color:inherit;white-space:normal}.conversejs progress{vertical-align:baseline}.conversejs [type=number]::-webkit-inner-spin-button,.conversejs [type=number]::-webkit-outer-spin-button{height:auto}.conversejs [type=search]{outline-offset:-2px;-webkit-appearance:none}.conversejs [type=search]::-webkit-search-decoration{-webkit-appearance:none}.conversejs ::-webkit-file-upload-button{font:inherit;-webkit-appearance:button}.conversejs output{display:inline-block}.conversejs summary{display:list-item;cursor:pointer}.conversejs template{display:none}.conversejs [hidden]{display:none !important}.conversejs h1,.conversejs h2,.conversejs h3,.conversejs h4,.conversejs h5,.conversejs h6,.conversejs .h1,.conversejs .h2,.conversejs .h3,.conversejs .h4,.conversejs .h5,.conversejs .h6{margin-bottom:.5rem;font-weight:500;line-height:1.2}.conversejs h1,.conversejs .h1{font-size:2.5rem}.conversejs h2,.conversejs .h2{font-size:2rem}.conversejs h3,.conversejs .h3{font-size:1.75rem}.conversejs h4,.conversejs .h4{font-size:1.5rem}.conversejs h5,.conversejs .h5{font-size:1.25rem}.conversejs h6,.conversejs .h6{font-size:1rem}.conversejs .lead{font-size:1.25rem;font-weight:300}.conversejs .display-1{font-size:6rem;font-weight:300;line-height:1.2}.conversejs .display-2{font-size:5.5rem;font-weight:300;line-height:1.2}.conversejs .display-3{font-size:4.5rem;font-weight:300;line-height:1.2}.conversejs .display-4{font-size:3.5rem;font-weight:300;line-height:1.2}.conversejs hr{margin-top:1rem;margin-bottom:1rem;border:0;border-top:1px solid rgba(0,0,0,.1)}.conversejs small,.conversejs .small{font-size:0.875em;font-weight:400}.conversejs mark,.conversejs .mark{padding:.2em;background-color:#fcf8e3}.conversejs .list-unstyled{padding-left:0;list-style:none}.conversejs .list-inline{padding-left:0;list-style:none}.conversejs .list-inline-item{display:inline-block}.conversejs .list-inline-item:not(:last-child){margin-right:.5rem}.conversejs .initialism{font-size:90%;text-transform:uppercase}.conversejs .blockquote{margin-bottom:1rem;font-size:1.25rem}.conversejs .blockquote-footer{display:block;font-size:0.875em;color:#6c757d}.conversejs .blockquote-footer::before{content:"— "}.conversejs .img-fluid{max-width:100%;height:auto}.conversejs .img-thumbnail{padding:.25rem;background-color:#fff;border:1px solid #dee2e6;border-radius:.25rem;max-width:100%;height:auto}.conversejs .figure{display:inline-block}.conversejs .figure-img{margin-bottom:.5rem;line-height:1}.conversejs .figure-caption{font-size:90%;color:#6c757d}.conversejs .container,.conversejs .container-fluid,.conversejs .container-xl,.conversejs .container-lg,.conversejs .container-md,.conversejs .container-sm{width:100%;padding-right:15px;padding-left:15px;margin-right:auto;margin-left:auto}@media(min-width: 576px){.conversejs .container-sm,.conversejs .container{max-width:540px}}@media(min-width: 768px){.conversejs .container-md,.conversejs .container-sm,.conversejs .container{max-width:720px}}@media(min-width: 992px){.conversejs .container-lg,.conversejs .container-md,.conversejs .container-sm,.conversejs .container{max-width:960px}}@media(min-width: 1200px){.conversejs .container-xl,.conversejs .container-lg,.conversejs .container-md,.conversejs .container-sm,.conversejs .container{max-width:1140px}}.conversejs .row{display:flex;flex-wrap:wrap;margin-right:-15px;margin-left:-15px}.conversejs .no-gutters{margin-right:0;margin-left:0}.conversejs .no-gutters>.col,.conversejs .no-gutters>[class*=col-]{padding-right:0;padding-left:0}.conversejs .col-xl,.conversejs .col-xl-auto,.conversejs .col-xl-12,.conversejs .col-xl-11,.conversejs .col-xl-10,.conversejs .col-xl-9,.conversejs .col-xl-8,.conversejs .col-xl-7,.conversejs .col-xl-6,.conversejs .col-xl-5,.conversejs .col-xl-4,.conversejs .col-xl-3,.conversejs .col-xl-2,.conversejs .col-xl-1,.conversejs .col-lg,.conversejs .col-lg-auto,.conversejs .col-lg-12,.conversejs .col-lg-11,.conversejs .col-lg-10,.conversejs .col-lg-9,.conversejs .col-lg-8,.conversejs .col-lg-7,.conversejs .col-lg-6,.conversejs .col-lg-5,.conversejs .col-lg-4,.conversejs .col-lg-3,.conversejs .col-lg-2,.conversejs .col-lg-1,.conversejs .col-md,.conversejs .col-md-auto,.conversejs .col-md-12,.conversejs .col-md-11,.conversejs .col-md-10,.conversejs .col-md-9,.conversejs .col-md-8,.conversejs .col-md-7,.conversejs .col-md-6,.conversejs .col-md-5,.conversejs .col-md-4,.conversejs .col-md-3,.conversejs .col-md-2,.conversejs .col-md-1,.conversejs .col-sm,.conversejs .col-sm-auto,.conversejs .col-sm-12,.conversejs .col-sm-11,.conversejs .col-sm-10,.conversejs .col-sm-9,.conversejs .col-sm-8,.conversejs .col-sm-7,.conversejs .col-sm-6,.conversejs .col-sm-5,.conversejs .col-sm-4,.conversejs .col-sm-3,.conversejs .col-sm-2,.conversejs .col-sm-1,.conversejs .col,.conversejs .col-auto,.conversejs .col-12,.conversejs .col-11,.conversejs .col-10,.conversejs .col-9,.conversejs .col-8,.conversejs .col-7,.conversejs .col-6,.conversejs .col-5,.conversejs .col-4,.conversejs .col-3,.conversejs .col-2,.conversejs .col-1{position:relative;width:100%;padding-right:15px;padding-left:15px}.conversejs .col{flex-basis:0;flex-grow:1;max-width:100%}.conversejs .row-cols-1>*{flex:0 0 100%;max-width:100%}.conversejs .row-cols-2>*{flex:0 0 50%;max-width:50%}.conversejs .row-cols-3>*{flex:0 0 33.3333333333%;max-width:33.3333333333%}.conversejs .row-cols-4>*{flex:0 0 25%;max-width:25%}.conversejs .row-cols-5>*{flex:0 0 20%;max-width:20%}.conversejs .row-cols-6>*{flex:0 0 16.6666666667%;max-width:16.6666666667%}.conversejs .col-auto{flex:0 0 auto;width:auto;max-width:100%}.conversejs .col-1{flex:0 0 8.33333333%;max-width:8.33333333%}.conversejs .col-2{flex:0 0 16.66666667%;max-width:16.66666667%}.conversejs .col-3{flex:0 0 25%;max-width:25%}.conversejs .col-4{flex:0 0 33.33333333%;max-width:33.33333333%}.conversejs .col-5{flex:0 0 41.66666667%;max-width:41.66666667%}.conversejs .col-6{flex:0 0 50%;max-width:50%}.conversejs .col-7{flex:0 0 58.33333333%;max-width:58.33333333%}.conversejs .col-8{flex:0 0 66.66666667%;max-width:66.66666667%}.conversejs .col-9{flex:0 0 75%;max-width:75%}.conversejs .col-10{flex:0 0 83.33333333%;max-width:83.33333333%}.conversejs .col-11{flex:0 0 91.66666667%;max-width:91.66666667%}.conversejs .col-12{flex:0 0 100%;max-width:100%}.conversejs .order-first{order:-1}.conversejs .order-last{order:13}.conversejs .order-0{order:0}.conversejs .order-1{order:1}.conversejs .order-2{order:2}.conversejs .order-3{order:3}.conversejs .order-4{order:4}.conversejs .order-5{order:5}.conversejs .order-6{order:6}.conversejs .order-7{order:7}.conversejs .order-8{order:8}.conversejs .order-9{order:9}.conversejs .order-10{order:10}.conversejs .order-11{order:11}.conversejs .order-12{order:12}.conversejs .offset-1{margin-left:8.33333333%}.conversejs .offset-2{margin-left:16.66666667%}.conversejs .offset-3{margin-left:25%}.conversejs .offset-4{margin-left:33.33333333%}.conversejs .offset-5{margin-left:41.66666667%}.conversejs .offset-6{margin-left:50%}.conversejs .offset-7{margin-left:58.33333333%}.conversejs .offset-8{margin-left:66.66666667%}.conversejs .offset-9{margin-left:75%}.conversejs .offset-10{margin-left:83.33333333%}.conversejs .offset-11{margin-left:91.66666667%}@media(min-width: 576px){.conversejs .col-sm{flex-basis:0;flex-grow:1;max-width:100%}.conversejs .row-cols-sm-1>*{flex:0 0 100%;max-width:100%}.conversejs .row-cols-sm-2>*{flex:0 0 50%;max-width:50%}.conversejs .row-cols-sm-3>*{flex:0 0 33.3333333333%;max-width:33.3333333333%}.conversejs .row-cols-sm-4>*{flex:0 0 25%;max-width:25%}.conversejs .row-cols-sm-5>*{flex:0 0 20%;max-width:20%}.conversejs .row-cols-sm-6>*{flex:0 0 16.6666666667%;max-width:16.6666666667%}.conversejs .col-sm-auto{flex:0 0 auto;width:auto;max-width:100%}.conversejs .col-sm-1{flex:0 0 8.33333333%;max-width:8.33333333%}.conversejs .col-sm-2{flex:0 0 16.66666667%;max-width:16.66666667%}.conversejs .col-sm-3{flex:0 0 25%;max-width:25%}.conversejs .col-sm-4{flex:0 0 33.33333333%;max-width:33.33333333%}.conversejs .col-sm-5{flex:0 0 41.66666667%;max-width:41.66666667%}.conversejs .col-sm-6{flex:0 0 50%;max-width:50%}.conversejs .col-sm-7{flex:0 0 58.33333333%;max-width:58.33333333%}.conversejs .col-sm-8{flex:0 0 66.66666667%;max-width:66.66666667%}.conversejs .col-sm-9{flex:0 0 75%;max-width:75%}.conversejs .col-sm-10{flex:0 0 83.33333333%;max-width:83.33333333%}.conversejs .col-sm-11{flex:0 0 91.66666667%;max-width:91.66666667%}.conversejs .col-sm-12{flex:0 0 100%;max-width:100%}.conversejs .order-sm-first{order:-1}.conversejs .order-sm-last{order:13}.conversejs .order-sm-0{order:0}.conversejs .order-sm-1{order:1}.conversejs .order-sm-2{order:2}.conversejs .order-sm-3{order:3}.conversejs .order-sm-4{order:4}.conversejs .order-sm-5{order:5}.conversejs .order-sm-6{order:6}.conversejs .order-sm-7{order:7}.conversejs .order-sm-8{order:8}.conversejs .order-sm-9{order:9}.conversejs .order-sm-10{order:10}.conversejs .order-sm-11{order:11}.conversejs .order-sm-12{order:12}.conversejs .offset-sm-0{margin-left:0}.conversejs .offset-sm-1{margin-left:8.33333333%}.conversejs .offset-sm-2{margin-left:16.66666667%}.conversejs .offset-sm-3{margin-left:25%}.conversejs .offset-sm-4{margin-left:33.33333333%}.conversejs .offset-sm-5{margin-left:41.66666667%}.conversejs .offset-sm-6{margin-left:50%}.conversejs .offset-sm-7{margin-left:58.33333333%}.conversejs .offset-sm-8{margin-left:66.66666667%}.conversejs .offset-sm-9{margin-left:75%}.conversejs .offset-sm-10{margin-left:83.33333333%}.conversejs .offset-sm-11{margin-left:91.66666667%}}@media(min-width: 768px){.conversejs .col-md{flex-basis:0;flex-grow:1;max-width:100%}.conversejs .row-cols-md-1>*{flex:0 0 100%;max-width:100%}.conversejs .row-cols-md-2>*{flex:0 0 50%;max-width:50%}.conversejs .row-cols-md-3>*{flex:0 0 33.3333333333%;max-width:33.3333333333%}.conversejs .row-cols-md-4>*{flex:0 0 25%;max-width:25%}.conversejs .row-cols-md-5>*{flex:0 0 20%;max-width:20%}.conversejs .row-cols-md-6>*{flex:0 0 16.6666666667%;max-width:16.6666666667%}.conversejs .col-md-auto{flex:0 0 auto;width:auto;max-width:100%}.conversejs .col-md-1{flex:0 0 8.33333333%;max-width:8.33333333%}.conversejs .col-md-2{flex:0 0 16.66666667%;max-width:16.66666667%}.conversejs .col-md-3{flex:0 0 25%;max-width:25%}.conversejs .col-md-4{flex:0 0 33.33333333%;max-width:33.33333333%}.conversejs .col-md-5{flex:0 0 41.66666667%;max-width:41.66666667%}.conversejs .col-md-6{flex:0 0 50%;max-width:50%}.conversejs .col-md-7{flex:0 0 58.33333333%;max-width:58.33333333%}.conversejs .col-md-8{flex:0 0 66.66666667%;max-width:66.66666667%}.conversejs .col-md-9{flex:0 0 75%;max-width:75%}.conversejs .col-md-10{flex:0 0 83.33333333%;max-width:83.33333333%}.conversejs .col-md-11{flex:0 0 91.66666667%;max-width:91.66666667%}.conversejs .col-md-12{flex:0 0 100%;max-width:100%}.conversejs .order-md-first{order:-1}.conversejs .order-md-last{order:13}.conversejs .order-md-0{order:0}.conversejs .order-md-1{order:1}.conversejs .order-md-2{order:2}.conversejs .order-md-3{order:3}.conversejs .order-md-4{order:4}.conversejs .order-md-5{order:5}.conversejs .order-md-6{order:6}.conversejs .order-md-7{order:7}.conversejs .order-md-8{order:8}.conversejs .order-md-9{order:9}.conversejs .order-md-10{order:10}.conversejs .order-md-11{order:11}.conversejs .order-md-12{order:12}.conversejs .offset-md-0{margin-left:0}.conversejs .offset-md-1{margin-left:8.33333333%}.conversejs .offset-md-2{margin-left:16.66666667%}.conversejs .offset-md-3{margin-left:25%}.conversejs .offset-md-4{margin-left:33.33333333%}.conversejs .offset-md-5{margin-left:41.66666667%}.conversejs .offset-md-6{margin-left:50%}.conversejs .offset-md-7{margin-left:58.33333333%}.conversejs .offset-md-8{margin-left:66.66666667%}.conversejs .offset-md-9{margin-left:75%}.conversejs .offset-md-10{margin-left:83.33333333%}.conversejs .offset-md-11{margin-left:91.66666667%}}@media(min-width: 992px){.conversejs .col-lg{flex-basis:0;flex-grow:1;max-width:100%}.conversejs .row-cols-lg-1>*{flex:0 0 100%;max-width:100%}.conversejs .row-cols-lg-2>*{flex:0 0 50%;max-width:50%}.conversejs .row-cols-lg-3>*{flex:0 0 33.3333333333%;max-width:33.3333333333%}.conversejs .row-cols-lg-4>*{flex:0 0 25%;max-width:25%}.conversejs .row-cols-lg-5>*{flex:0 0 20%;max-width:20%}.conversejs .row-cols-lg-6>*{flex:0 0 16.6666666667%;max-width:16.6666666667%}.conversejs .col-lg-auto{flex:0 0 auto;width:auto;max-width:100%}.conversejs .col-lg-1{flex:0 0 8.33333333%;max-width:8.33333333%}.conversejs .col-lg-2{flex:0 0 16.66666667%;max-width:16.66666667%}.conversejs .col-lg-3{flex:0 0 25%;max-width:25%}.conversejs .col-lg-4{flex:0 0 33.33333333%;max-width:33.33333333%}.conversejs .col-lg-5{flex:0 0 41.66666667%;max-width:41.66666667%}.conversejs .col-lg-6{flex:0 0 50%;max-width:50%}.conversejs .col-lg-7{flex:0 0 58.33333333%;max-width:58.33333333%}.conversejs .col-lg-8{flex:0 0 66.66666667%;max-width:66.66666667%}.conversejs .col-lg-9{flex:0 0 75%;max-width:75%}.conversejs .col-lg-10{flex:0 0 83.33333333%;max-width:83.33333333%}.conversejs .col-lg-11{flex:0 0 91.66666667%;max-width:91.66666667%}.conversejs .col-lg-12{flex:0 0 100%;max-width:100%}.conversejs .order-lg-first{order:-1}.conversejs .order-lg-last{order:13}.conversejs .order-lg-0{order:0}.conversejs .order-lg-1{order:1}.conversejs .order-lg-2{order:2}.conversejs .order-lg-3{order:3}.conversejs .order-lg-4{order:4}.conversejs .order-lg-5{order:5}.conversejs .order-lg-6{order:6}.conversejs .order-lg-7{order:7}.conversejs .order-lg-8{order:8}.conversejs .order-lg-9{order:9}.conversejs .order-lg-10{order:10}.conversejs .order-lg-11{order:11}.conversejs .order-lg-12{order:12}.conversejs .offset-lg-0{margin-left:0}.conversejs .offset-lg-1{margin-left:8.33333333%}.conversejs .offset-lg-2{margin-left:16.66666667%}.conversejs .offset-lg-3{margin-left:25%}.conversejs .offset-lg-4{margin-left:33.33333333%}.conversejs .offset-lg-5{margin-left:41.66666667%}.conversejs .offset-lg-6{margin-left:50%}.conversejs .offset-lg-7{margin-left:58.33333333%}.conversejs .offset-lg-8{margin-left:66.66666667%}.conversejs .offset-lg-9{margin-left:75%}.conversejs .offset-lg-10{margin-left:83.33333333%}.conversejs .offset-lg-11{margin-left:91.66666667%}}@media(min-width: 1200px){.conversejs .col-xl{flex-basis:0;flex-grow:1;max-width:100%}.conversejs .row-cols-xl-1>*{flex:0 0 100%;max-width:100%}.conversejs .row-cols-xl-2>*{flex:0 0 50%;max-width:50%}.conversejs .row-cols-xl-3>*{flex:0 0 33.3333333333%;max-width:33.3333333333%}.conversejs .row-cols-xl-4>*{flex:0 0 25%;max-width:25%}.conversejs .row-cols-xl-5>*{flex:0 0 20%;max-width:20%}.conversejs .row-cols-xl-6>*{flex:0 0 16.6666666667%;max-width:16.6666666667%}.conversejs .col-xl-auto{flex:0 0 auto;width:auto;max-width:100%}.conversejs .col-xl-1{flex:0 0 8.33333333%;max-width:8.33333333%}.conversejs .col-xl-2{flex:0 0 16.66666667%;max-width:16.66666667%}.conversejs .col-xl-3{flex:0 0 25%;max-width:25%}.conversejs .col-xl-4{flex:0 0 33.33333333%;max-width:33.33333333%}.conversejs .col-xl-5{flex:0 0 41.66666667%;max-width:41.66666667%}.conversejs .col-xl-6{flex:0 0 50%;max-width:50%}.conversejs .col-xl-7{flex:0 0 58.33333333%;max-width:58.33333333%}.conversejs .col-xl-8{flex:0 0 66.66666667%;max-width:66.66666667%}.conversejs .col-xl-9{flex:0 0 75%;max-width:75%}.conversejs .col-xl-10{flex:0 0 83.33333333%;max-width:83.33333333%}.conversejs .col-xl-11{flex:0 0 91.66666667%;max-width:91.66666667%}.conversejs .col-xl-12{flex:0 0 100%;max-width:100%}.conversejs .order-xl-first{order:-1}.conversejs .order-xl-last{order:13}.conversejs .order-xl-0{order:0}.conversejs .order-xl-1{order:1}.conversejs .order-xl-2{order:2}.conversejs .order-xl-3{order:3}.conversejs .order-xl-4{order:4}.conversejs .order-xl-5{order:5}.conversejs .order-xl-6{order:6}.conversejs .order-xl-7{order:7}.conversejs .order-xl-8{order:8}.conversejs .order-xl-9{order:9}.conversejs .order-xl-10{order:10}.conversejs .order-xl-11{order:11}.conversejs .order-xl-12{order:12}.conversejs .offset-xl-0{margin-left:0}.conversejs .offset-xl-1{margin-left:8.33333333%}.conversejs .offset-xl-2{margin-left:16.66666667%}.conversejs .offset-xl-3{margin-left:25%}.conversejs .offset-xl-4{margin-left:33.33333333%}.conversejs .offset-xl-5{margin-left:41.66666667%}.conversejs .offset-xl-6{margin-left:50%}.conversejs .offset-xl-7{margin-left:58.33333333%}.conversejs .offset-xl-8{margin-left:66.66666667%}.conversejs .offset-xl-9{margin-left:75%}.conversejs .offset-xl-10{margin-left:83.33333333%}.conversejs .offset-xl-11{margin-left:91.66666667%}}.conversejs .fade{transition:opacity .15s linear}@media(prefers-reduced-motion: reduce){.conversejs .fade{transition:none}}.conversejs .fade:not(.show){opacity:0}.conversejs .collapse:not(.show){display:none}.conversejs .collapsing{position:relative;height:0;overflow:hidden;transition:height .35s ease}@media(prefers-reduced-motion: reduce){.conversejs .collapsing{transition:none}}.conversejs .collapsing.width{width:0;height:auto;transition:width .35s ease}@media(prefers-reduced-motion: reduce){.conversejs .collapsing.width{transition:none}}.conversejs .nav{display:flex;flex-wrap:wrap;padding-left:0;margin-bottom:0;list-style:none}.conversejs .nav-link{display:block;padding:.5rem 1rem}.conversejs .nav-link:hover,.conversejs .nav-link:focus{text-decoration:none}.conversejs .nav-link.disabled{color:#6c757d;pointer-events:none;cursor:default}.conversejs .nav-tabs{border-bottom:1px solid #dee2e6}.conversejs .nav-tabs .nav-link{margin-bottom:-1px;background-color:rgba(0,0,0,0);border:1px solid rgba(0,0,0,0);border-top-left-radius:.25rem;border-top-right-radius:.25rem}.conversejs .nav-tabs .nav-link:hover,.conversejs .nav-tabs .nav-link:focus{isolation:isolate;border-color:#e9ecef #e9ecef #dee2e6}.conversejs .nav-tabs .nav-link.disabled{color:#6c757d;background-color:rgba(0,0,0,0);border-color:rgba(0,0,0,0)}.conversejs .nav-tabs .nav-link.active,.conversejs .nav-tabs .nav-item.show .nav-link{color:#495057;background-color:#fff;border-color:#dee2e6 #dee2e6 #fff}.conversejs .nav-tabs .dropdown-menu{margin-top:-1px;border-top-left-radius:0;border-top-right-radius:0}.conversejs .nav-pills .nav-link{background:none;border:0;border-radius:.25rem}.conversejs .nav-pills .nav-link.active,.conversejs .nav-pills .show>.nav-link{color:#fff;background-color:#007bff}.conversejs .nav-fill>.nav-link,.conversejs .nav-fill .nav-item{flex:1 1 auto;text-align:center}.conversejs .nav-justified>.nav-link,.conversejs .nav-justified .nav-item{flex-basis:0;flex-grow:1;text-align:center}.conversejs .tab-content>.tab-pane{display:none}.conversejs .tab-content>.active{display:block}.conversejs .alert{position:relative;padding:.75rem 1.25rem;margin-bottom:1rem;border:1px solid rgba(0,0,0,0);border-radius:.25rem}.conversejs .alert-heading{color:inherit}.conversejs .alert-link{font-weight:700}.conversejs .alert-dismissible{padding-right:4rem}.conversejs .alert-dismissible .close{position:absolute;top:0;right:0;z-index:2;padding:.75rem 1.25rem;color:inherit}.conversejs .alert-primary{color:#004085;background-color:#cce5ff;border-color:#b8daff}.conversejs .alert-primary hr{border-top-color:#9fcdff}.conversejs .alert-primary .alert-link{color:#002752}.conversejs .alert-secondary{color:#383d41;background-color:#e2e3e5;border-color:#d6d8db}.conversejs .alert-secondary hr{border-top-color:#c8cbcf}.conversejs .alert-secondary .alert-link{color:#202326}.conversejs .alert-success{color:#155724;background-color:#d4edda;border-color:#c3e6cb}.conversejs .alert-success hr{border-top-color:#b1dfbb}.conversejs .alert-success .alert-link{color:#0b2e13}.conversejs .alert-info{color:#0c5460;background-color:#d1ecf1;border-color:#bee5eb}.conversejs .alert-info hr{border-top-color:#abdde5}.conversejs .alert-info .alert-link{color:#062c33}.conversejs .alert-warning{color:#856404;background-color:#fff3cd;border-color:#ffeeba}.conversejs .alert-warning hr{border-top-color:#ffe8a1}.conversejs .alert-warning .alert-link{color:#533f03}.conversejs .alert-danger{color:#721c24;background-color:#f8d7da;border-color:#f5c6cb}.conversejs .alert-danger hr{border-top-color:#f1b0b7}.conversejs .alert-danger .alert-link{color:#491217}.conversejs .alert-light{color:#818182;background-color:#fefefe;border-color:#fdfdfe}.conversejs .alert-light hr{border-top-color:#ececf6}.conversejs .alert-light .alert-link{color:#686868}.conversejs .alert-dark{color:#1b1e21;background-color:#d6d8d9;border-color:#c6c8ca}.conversejs .alert-dark hr{border-top-color:#b9bbbe}.conversejs .alert-dark .alert-link{color:#040505}.conversejs .media{display:flex;align-items:flex-start}.conversejs .media-body{flex:1}.conversejs .close{float:right;font-size:1.5rem;font-weight:700;line-height:1;color:#000;text-shadow:0 1px 0 #fff;opacity:.5}.conversejs .close:hover{color:#000;text-decoration:none}.conversejs .close:not(:disabled):not(.disabled):hover,.conversejs .close:not(:disabled):not(.disabled):focus{opacity:.75}.conversejs button.close{padding:0;background-color:rgba(0,0,0,0);border:0}.conversejs a.close.disabled{pointer-events:none}.conversejs .popover{position:absolute;top:0;left:0;z-index:1060;display:block;max-width:276px;font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,"Noto Sans","Liberation Sans",sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji";font-style:normal;font-weight:400;line-height:1.5;text-align:left;text-align:start;text-decoration:none;text-shadow:none;text-transform:none;letter-spacing:normal;word-break:normal;white-space:normal;word-spacing:normal;line-break:auto;font-size:0.875rem;word-wrap:break-word;background-color:#fff;background-clip:padding-box;border:1px solid rgba(0,0,0,.2);border-radius:.3rem}.conversejs .popover .arrow{position:absolute;display:block;width:1rem;height:.5rem;margin:0 .3rem}.conversejs .popover .arrow::before,.conversejs .popover .arrow::after{position:absolute;display:block;content:"";border-color:rgba(0,0,0,0);border-style:solid}.conversejs .bs-popover-top,.conversejs .bs-popover-auto[x-placement^=top]{margin-bottom:.5rem}.conversejs .bs-popover-top>.arrow,.conversejs .bs-popover-auto[x-placement^=top]>.arrow{bottom:calc(-0.5rem - 1px)}.conversejs .bs-popover-top>.arrow::before,.conversejs .bs-popover-auto[x-placement^=top]>.arrow::before{bottom:0;border-width:.5rem .5rem 0;border-top-color:rgba(0,0,0,.25)}.conversejs .bs-popover-top>.arrow::after,.conversejs .bs-popover-auto[x-placement^=top]>.arrow::after{bottom:1px;border-width:.5rem .5rem 0;border-top-color:#fff}.conversejs .bs-popover-right,.conversejs .bs-popover-auto[x-placement^=right]{margin-left:.5rem}.conversejs .bs-popover-right>.arrow,.conversejs .bs-popover-auto[x-placement^=right]>.arrow{left:calc(-0.5rem - 1px);width:.5rem;height:1rem;margin:.3rem 0}.conversejs .bs-popover-right>.arrow::before,.conversejs .bs-popover-auto[x-placement^=right]>.arrow::before{left:0;border-width:.5rem .5rem .5rem 0;border-right-color:rgba(0,0,0,.25)}.conversejs .bs-popover-right>.arrow::after,.conversejs .bs-popover-auto[x-placement^=right]>.arrow::after{left:1px;border-width:.5rem .5rem .5rem 0;border-right-color:#fff}.conversejs .bs-popover-bottom,.conversejs .bs-popover-auto[x-placement^=bottom]{margin-top:.5rem}.conversejs .bs-popover-bottom>.arrow,.conversejs .bs-popover-auto[x-placement^=bottom]>.arrow{top:calc(-0.5rem - 1px)}.conversejs .bs-popover-bottom>.arrow::before,.conversejs .bs-popover-auto[x-placement^=bottom]>.arrow::before{top:0;border-width:0 .5rem .5rem .5rem;border-bottom-color:rgba(0,0,0,.25)}.conversejs .bs-popover-bottom>.arrow::after,.conversejs .bs-popover-auto[x-placement^=bottom]>.arrow::after{top:1px;border-width:0 .5rem .5rem .5rem;border-bottom-color:#fff}.conversejs .bs-popover-bottom .popover-header::before,.conversejs .bs-popover-auto[x-placement^=bottom] .popover-header::before{position:absolute;top:0;left:50%;display:block;width:1rem;margin-left:-0.5rem;content:"";border-bottom:1px solid #f7f7f7}.conversejs .bs-popover-left,.conversejs .bs-popover-auto[x-placement^=left]{margin-right:.5rem}.conversejs .bs-popover-left>.arrow,.conversejs .bs-popover-auto[x-placement^=left]>.arrow{right:calc(-0.5rem - 1px);width:.5rem;height:1rem;margin:.3rem 0}.conversejs .bs-popover-left>.arrow::before,.conversejs .bs-popover-auto[x-placement^=left]>.arrow::before{right:0;border-width:.5rem 0 .5rem .5rem;border-left-color:rgba(0,0,0,.25)}.conversejs .bs-popover-left>.arrow::after,.conversejs .bs-popover-auto[x-placement^=left]>.arrow::after{right:1px;border-width:.5rem 0 .5rem .5rem;border-left-color:#fff}.conversejs .popover-header{padding:.5rem .75rem;margin-bottom:0;font-size:1rem;background-color:#f7f7f7;border-bottom:1px solid #ebebeb;border-top-left-radius:calc(0.3rem - 1px);border-top-right-radius:calc(0.3rem - 1px)}.conversejs .popover-header:empty{display:none}.conversejs .popover-body{padding:.5rem .75rem;color:#212529}.conversejs .align-baseline{vertical-align:baseline !important}.conversejs .align-top{vertical-align:top !important}.conversejs .align-middle{vertical-align:middle !important}.conversejs .align-bottom{vertical-align:bottom !important}.conversejs .align-text-bottom{vertical-align:text-bottom !important}.conversejs .align-text-top{vertical-align:text-top !important}.conversejs .bg-primary{background-color:#007bff !important}.conversejs a.bg-primary:hover,.conversejs a.bg-primary:focus,.conversejs button.bg-primary:hover,.conversejs button.bg-primary:focus{background-color:#0062cc !important}.conversejs .bg-secondary{background-color:#6c757d !important}.conversejs a.bg-secondary:hover,.conversejs a.bg-secondary:focus,.conversejs button.bg-secondary:hover,.conversejs button.bg-secondary:focus{background-color:#545b62 !important}.conversejs .bg-success{background-color:#28a745 !important}.conversejs a.bg-success:hover,.conversejs a.bg-success:focus,.conversejs button.bg-success:hover,.conversejs button.bg-success:focus{background-color:#1e7e34 !important}.conversejs .bg-info{background-color:#17a2b8 !important}.conversejs a.bg-info:hover,.conversejs a.bg-info:focus,.conversejs button.bg-info:hover,.conversejs button.bg-info:focus{background-color:#117a8b !important}.conversejs .bg-warning{background-color:#ffc107 !important}.conversejs a.bg-warning:hover,.conversejs a.bg-warning:focus,.conversejs button.bg-warning:hover,.conversejs button.bg-warning:focus{background-color:#d39e00 !important}.conversejs .bg-danger{background-color:#dc3545 !important}.conversejs a.bg-danger:hover,.conversejs a.bg-danger:focus,.conversejs button.bg-danger:hover,.conversejs button.bg-danger:focus{background-color:#bd2130 !important}.conversejs .bg-light{background-color:#f8f9fa !important}.conversejs a.bg-light:hover,.conversejs a.bg-light:focus,.conversejs button.bg-light:hover,.conversejs button.bg-light:focus{background-color:#dae0e5 !important}.conversejs .bg-dark{background-color:#343a40 !important}.conversejs a.bg-dark:hover,.conversejs a.bg-dark:focus,.conversejs button.bg-dark:hover,.conversejs button.bg-dark:focus{background-color:#1d2124 !important}.conversejs .bg-white{background-color:#fff !important}.conversejs .bg-transparent{background-color:rgba(0,0,0,0) !important}.conversejs .border{border:1px solid #dee2e6 !important}.conversejs .border-top{border-top:1px solid #dee2e6 !important}.conversejs .border-right{border-right:1px solid #dee2e6 !important}.conversejs .border-bottom{border-bottom:1px solid #dee2e6 !important}.conversejs .border-left{border-left:1px solid #dee2e6 !important}.conversejs .border-0{border:0 !important}.conversejs .border-top-0{border-top:0 !important}.conversejs .border-right-0{border-right:0 !important}.conversejs .border-bottom-0{border-bottom:0 !important}.conversejs .border-left-0{border-left:0 !important}.conversejs .border-primary{border-color:#007bff !important}.conversejs .border-secondary{border-color:#6c757d !important}.conversejs .border-success{border-color:#28a745 !important}.conversejs .border-info{border-color:#17a2b8 !important}.conversejs .border-warning{border-color:#ffc107 !important}.conversejs .border-danger{border-color:#dc3545 !important}.conversejs .border-light{border-color:#f8f9fa !important}.conversejs .border-dark{border-color:#343a40 !important}.conversejs .border-white{border-color:#fff !important}.conversejs .rounded-sm{border-radius:.2rem !important}.conversejs .rounded{border-radius:.25rem !important}.conversejs .rounded-top{border-top-left-radius:.25rem !important;border-top-right-radius:.25rem !important}.conversejs .rounded-right{border-top-right-radius:.25rem !important;border-bottom-right-radius:.25rem !important}.conversejs .rounded-bottom{border-bottom-right-radius:.25rem !important;border-bottom-left-radius:.25rem !important}.conversejs .rounded-left{border-top-left-radius:.25rem !important;border-bottom-left-radius:.25rem !important}.conversejs .rounded-lg{border-radius:.3rem !important}.conversejs .rounded-circle{border-radius:50% !important}.conversejs .rounded-pill{border-radius:50rem !important}.conversejs .rounded-0{border-radius:0 !important}.conversejs .clearfix::after{display:block;clear:both;content:""}.conversejs .d-none{display:none !important}.conversejs .d-inline{display:inline !important}.conversejs .d-inline-block{display:inline-block !important}.conversejs .d-block{display:block !important}.conversejs .d-table{display:table !important}.conversejs .d-table-row{display:table-row !important}.conversejs .d-table-cell{display:table-cell !important}.conversejs .d-flex{display:flex !important}.conversejs .d-inline-flex{display:inline-flex !important}@media(min-width: 576px){.conversejs .d-sm-none{display:none !important}.conversejs .d-sm-inline{display:inline !important}.conversejs .d-sm-inline-block{display:inline-block !important}.conversejs .d-sm-block{display:block !important}.conversejs .d-sm-table{display:table !important}.conversejs .d-sm-table-row{display:table-row !important}.conversejs .d-sm-table-cell{display:table-cell !important}.conversejs .d-sm-flex{display:flex !important}.conversejs .d-sm-inline-flex{display:inline-flex !important}}@media(min-width: 768px){.conversejs .d-md-none{display:none !important}.conversejs .d-md-inline{display:inline !important}.conversejs .d-md-inline-block{display:inline-block !important}.conversejs .d-md-block{display:block !important}.conversejs .d-md-table{display:table !important}.conversejs .d-md-table-row{display:table-row !important}.conversejs .d-md-table-cell{display:table-cell !important}.conversejs .d-md-flex{display:flex !important}.conversejs .d-md-inline-flex{display:inline-flex !important}}@media(min-width: 992px){.conversejs .d-lg-none{display:none !important}.conversejs .d-lg-inline{display:inline !important}.conversejs .d-lg-inline-block{display:inline-block !important}.conversejs .d-lg-block{display:block !important}.conversejs .d-lg-table{display:table !important}.conversejs .d-lg-table-row{display:table-row !important}.conversejs .d-lg-table-cell{display:table-cell !important}.conversejs .d-lg-flex{display:flex !important}.conversejs .d-lg-inline-flex{display:inline-flex !important}}@media(min-width: 1200px){.conversejs .d-xl-none{display:none !important}.conversejs .d-xl-inline{display:inline !important}.conversejs .d-xl-inline-block{display:inline-block !important}.conversejs .d-xl-block{display:block !important}.conversejs .d-xl-table{display:table !important}.conversejs .d-xl-table-row{display:table-row !important}.conversejs .d-xl-table-cell{display:table-cell !important}.conversejs .d-xl-flex{display:flex !important}.conversejs .d-xl-inline-flex{display:inline-flex !important}}@media print{.conversejs .d-print-none{display:none !important}.conversejs .d-print-inline{display:inline !important}.conversejs .d-print-inline-block{display:inline-block !important}.conversejs .d-print-block{display:block !important}.conversejs .d-print-table{display:table !important}.conversejs .d-print-table-row{display:table-row !important}.conversejs .d-print-table-cell{display:table-cell !important}.conversejs .d-print-flex{display:flex !important}.conversejs .d-print-inline-flex{display:inline-flex !important}}.conversejs .embed-responsive{position:relative;display:block;width:100%;padding:0;overflow:hidden}.conversejs .embed-responsive::before{display:block;content:""}.conversejs .embed-responsive .embed-responsive-item,.conversejs .embed-responsive iframe,.conversejs .embed-responsive embed,.conversejs .embed-responsive object,.conversejs .embed-responsive video{position:absolute;top:0;bottom:0;left:0;width:100%;height:100%;border:0}.conversejs .embed-responsive-21by9::before{padding-top:42.85714286%}.conversejs .embed-responsive-16by9::before{padding-top:56.25%}.conversejs .embed-responsive-4by3::before{padding-top:75%}.conversejs .embed-responsive-1by1::before{padding-top:100%}.conversejs .flex-row{flex-direction:row !important}.conversejs .flex-column{flex-direction:column !important}.conversejs .flex-row-reverse{flex-direction:row-reverse !important}.conversejs .flex-column-reverse{flex-direction:column-reverse !important}.conversejs .flex-wrap{flex-wrap:wrap !important}.conversejs .flex-nowrap{flex-wrap:nowrap !important}.conversejs .flex-wrap-reverse{flex-wrap:wrap-reverse !important}.conversejs .flex-fill{flex:1 1 auto !important}.conversejs .flex-grow-0{flex-grow:0 !important}.conversejs .flex-grow-1{flex-grow:1 !important}.conversejs .flex-shrink-0{flex-shrink:0 !important}.conversejs .flex-shrink-1{flex-shrink:1 !important}.conversejs .justify-content-start{justify-content:flex-start !important}.conversejs .justify-content-end{justify-content:flex-end !important}.conversejs .justify-content-center{justify-content:center !important}.conversejs .justify-content-between{justify-content:space-between !important}.conversejs .justify-content-around{justify-content:space-around !important}.conversejs .align-items-start{align-items:flex-start !important}.conversejs .align-items-end{align-items:flex-end !important}.conversejs .align-items-center{align-items:center !important}.conversejs .align-items-baseline{align-items:baseline !important}.conversejs .align-items-stretch{align-items:stretch !important}.conversejs .align-content-start{align-content:flex-start !important}.conversejs .align-content-end{align-content:flex-end !important}.conversejs .align-content-center{align-content:center !important}.conversejs .align-content-between{align-content:space-between !important}.conversejs .align-content-around{align-content:space-around !important}.conversejs .align-content-stretch{align-content:stretch !important}.conversejs .align-self-auto{align-self:auto !important}.conversejs .align-self-start{align-self:flex-start !important}.conversejs .align-self-end{align-self:flex-end !important}.conversejs .align-self-center{align-self:center !important}.conversejs .align-self-baseline{align-self:baseline !important}.conversejs .align-self-stretch{align-self:stretch !important}@media(min-width: 576px){.conversejs .flex-sm-row{flex-direction:row !important}.conversejs .flex-sm-column{flex-direction:column !important}.conversejs .flex-sm-row-reverse{flex-direction:row-reverse !important}.conversejs .flex-sm-column-reverse{flex-direction:column-reverse !important}.conversejs .flex-sm-wrap{flex-wrap:wrap !important}.conversejs .flex-sm-nowrap{flex-wrap:nowrap !important}.conversejs .flex-sm-wrap-reverse{flex-wrap:wrap-reverse !important}.conversejs .flex-sm-fill{flex:1 1 auto !important}.conversejs .flex-sm-grow-0{flex-grow:0 !important}.conversejs .flex-sm-grow-1{flex-grow:1 !important}.conversejs .flex-sm-shrink-0{flex-shrink:0 !important}.conversejs .flex-sm-shrink-1{flex-shrink:1 !important}.conversejs .justify-content-sm-start{justify-content:flex-start !important}.conversejs .justify-content-sm-end{justify-content:flex-end !important}.conversejs .justify-content-sm-center{justify-content:center !important}.conversejs .justify-content-sm-between{justify-content:space-between !important}.conversejs .justify-content-sm-around{justify-content:space-around !important}.conversejs .align-items-sm-start{align-items:flex-start !important}.conversejs .align-items-sm-end{align-items:flex-end !important}.conversejs .align-items-sm-center{align-items:center !important}.conversejs .align-items-sm-baseline{align-items:baseline !important}.conversejs .align-items-sm-stretch{align-items:stretch !important}.conversejs .align-content-sm-start{align-content:flex-start !important}.conversejs .align-content-sm-end{align-content:flex-end !important}.conversejs .align-content-sm-center{align-content:center !important}.conversejs .align-content-sm-between{align-content:space-between !important}.conversejs .align-content-sm-around{align-content:space-around !important}.conversejs .align-content-sm-stretch{align-content:stretch !important}.conversejs .align-self-sm-auto{align-self:auto !important}.conversejs .align-self-sm-start{align-self:flex-start !important}.conversejs .align-self-sm-end{align-self:flex-end !important}.conversejs .align-self-sm-center{align-self:center !important}.conversejs .align-self-sm-baseline{align-self:baseline !important}.conversejs .align-self-sm-stretch{align-self:stretch !important}}@media(min-width: 768px){.conversejs .flex-md-row{flex-direction:row !important}.conversejs .flex-md-column{flex-direction:column !important}.conversejs .flex-md-row-reverse{flex-direction:row-reverse !important}.conversejs .flex-md-column-reverse{flex-direction:column-reverse !important}.conversejs .flex-md-wrap{flex-wrap:wrap !important}.conversejs .flex-md-nowrap{flex-wrap:nowrap !important}.conversejs .flex-md-wrap-reverse{flex-wrap:wrap-reverse !important}.conversejs .flex-md-fill{flex:1 1 auto !important}.conversejs .flex-md-grow-0{flex-grow:0 !important}.conversejs .flex-md-grow-1{flex-grow:1 !important}.conversejs .flex-md-shrink-0{flex-shrink:0 !important}.conversejs .flex-md-shrink-1{flex-shrink:1 !important}.conversejs .justify-content-md-start{justify-content:flex-start !important}.conversejs .justify-content-md-end{justify-content:flex-end !important}.conversejs .justify-content-md-center{justify-content:center !important}.conversejs .justify-content-md-between{justify-content:space-between !important}.conversejs .justify-content-md-around{justify-content:space-around !important}.conversejs .align-items-md-start{align-items:flex-start !important}.conversejs .align-items-md-end{align-items:flex-end !important}.conversejs .align-items-md-center{align-items:center !important}.conversejs .align-items-md-baseline{align-items:baseline !important}.conversejs .align-items-md-stretch{align-items:stretch !important}.conversejs .align-content-md-start{align-content:flex-start !important}.conversejs .align-content-md-end{align-content:flex-end !important}.conversejs .align-content-md-center{align-content:center !important}.conversejs .align-content-md-between{align-content:space-between !important}.conversejs .align-content-md-around{align-content:space-around !important}.conversejs .align-content-md-stretch{align-content:stretch !important}.conversejs .align-self-md-auto{align-self:auto !important}.conversejs .align-self-md-start{align-self:flex-start !important}.conversejs .align-self-md-end{align-self:flex-end !important}.conversejs .align-self-md-center{align-self:center !important}.conversejs .align-self-md-baseline{align-self:baseline !important}.conversejs .align-self-md-stretch{align-self:stretch !important}}@media(min-width: 992px){.conversejs .flex-lg-row{flex-direction:row !important}.conversejs .flex-lg-column{flex-direction:column !important}.conversejs .flex-lg-row-reverse{flex-direction:row-reverse !important}.conversejs .flex-lg-column-reverse{flex-direction:column-reverse !important}.conversejs .flex-lg-wrap{flex-wrap:wrap !important}.conversejs .flex-lg-nowrap{flex-wrap:nowrap !important}.conversejs .flex-lg-wrap-reverse{flex-wrap:wrap-reverse !important}.conversejs .flex-lg-fill{flex:1 1 auto !important}.conversejs .flex-lg-grow-0{flex-grow:0 !important}.conversejs .flex-lg-grow-1{flex-grow:1 !important}.conversejs .flex-lg-shrink-0{flex-shrink:0 !important}.conversejs .flex-lg-shrink-1{flex-shrink:1 !important}.conversejs .justify-content-lg-start{justify-content:flex-start !important}.conversejs .justify-content-lg-end{justify-content:flex-end !important}.conversejs .justify-content-lg-center{justify-content:center !important}.conversejs .justify-content-lg-between{justify-content:space-between !important}.conversejs .justify-content-lg-around{justify-content:space-around !important}.conversejs .align-items-lg-start{align-items:flex-start !important}.conversejs .align-items-lg-end{align-items:flex-end !important}.conversejs .align-items-lg-center{align-items:center !important}.conversejs .align-items-lg-baseline{align-items:baseline !important}.conversejs .align-items-lg-stretch{align-items:stretch !important}.conversejs .align-content-lg-start{align-content:flex-start !important}.conversejs .align-content-lg-end{align-content:flex-end !important}.conversejs .align-content-lg-center{align-content:center !important}.conversejs .align-content-lg-between{align-content:space-between !important}.conversejs .align-content-lg-around{align-content:space-around !important}.conversejs .align-content-lg-stretch{align-content:stretch !important}.conversejs .align-self-lg-auto{align-self:auto !important}.conversejs .align-self-lg-start{align-self:flex-start !important}.conversejs .align-self-lg-end{align-self:flex-end !important}.conversejs .align-self-lg-center{align-self:center !important}.conversejs .align-self-lg-baseline{align-self:baseline !important}.conversejs .align-self-lg-stretch{align-self:stretch !important}}@media(min-width: 1200px){.conversejs .flex-xl-row{flex-direction:row !important}.conversejs .flex-xl-column{flex-direction:column !important}.conversejs .flex-xl-row-reverse{flex-direction:row-reverse !important}.conversejs .flex-xl-column-reverse{flex-direction:column-reverse !important}.conversejs .flex-xl-wrap{flex-wrap:wrap !important}.conversejs .flex-xl-nowrap{flex-wrap:nowrap !important}.conversejs .flex-xl-wrap-reverse{flex-wrap:wrap-reverse !important}.conversejs .flex-xl-fill{flex:1 1 auto !important}.conversejs .flex-xl-grow-0{flex-grow:0 !important}.conversejs .flex-xl-grow-1{flex-grow:1 !important}.conversejs .flex-xl-shrink-0{flex-shrink:0 !important}.conversejs .flex-xl-shrink-1{flex-shrink:1 !important}.conversejs .justify-content-xl-start{justify-content:flex-start !important}.conversejs .justify-content-xl-end{justify-content:flex-end !important}.conversejs .justify-content-xl-center{justify-content:center !important}.conversejs .justify-content-xl-between{justify-content:space-between !important}.conversejs .justify-content-xl-around{justify-content:space-around !important}.conversejs .align-items-xl-start{align-items:flex-start !important}.conversejs .align-items-xl-end{align-items:flex-end !important}.conversejs .align-items-xl-center{align-items:center !important}.conversejs .align-items-xl-baseline{align-items:baseline !important}.conversejs .align-items-xl-stretch{align-items:stretch !important}.conversejs .align-content-xl-start{align-content:flex-start !important}.conversejs .align-content-xl-end{align-content:flex-end !important}.conversejs .align-content-xl-center{align-content:center !important}.conversejs .align-content-xl-between{align-content:space-between !important}.conversejs .align-content-xl-around{align-content:space-around !important}.conversejs .align-content-xl-stretch{align-content:stretch !important}.conversejs .align-self-xl-auto{align-self:auto !important}.conversejs .align-self-xl-start{align-self:flex-start !important}.conversejs .align-self-xl-end{align-self:flex-end !important}.conversejs .align-self-xl-center{align-self:center !important}.conversejs .align-self-xl-baseline{align-self:baseline !important}.conversejs .align-self-xl-stretch{align-self:stretch !important}}.conversejs .float-left{float:left !important}.conversejs .float-right{float:right !important}.conversejs .float-none{float:none !important}@media(min-width: 576px){.conversejs .float-sm-left{float:left !important}.conversejs .float-sm-right{float:right !important}.conversejs .float-sm-none{float:none !important}}@media(min-width: 768px){.conversejs .float-md-left{float:left !important}.conversejs .float-md-right{float:right !important}.conversejs .float-md-none{float:none !important}}@media(min-width: 992px){.conversejs .float-lg-left{float:left !important}.conversejs .float-lg-right{float:right !important}.conversejs .float-lg-none{float:none !important}}@media(min-width: 1200px){.conversejs .float-xl-left{float:left !important}.conversejs .float-xl-right{float:right !important}.conversejs .float-xl-none{float:none !important}}.conversejs .user-select-all{-webkit-user-select:all !important;-moz-user-select:all !important;user-select:all !important}.conversejs .user-select-auto{-webkit-user-select:auto !important;-moz-user-select:auto !important;user-select:auto !important}.conversejs .user-select-none{-webkit-user-select:none !important;-moz-user-select:none !important;user-select:none !important}.conversejs .overflow-auto{overflow:auto !important}.conversejs .overflow-hidden{overflow:hidden !important}.conversejs .position-static{position:static !important}.conversejs .position-relative{position:relative !important}.conversejs .position-absolute{position:absolute !important}.conversejs .position-fixed{position:fixed !important}.conversejs .position-sticky{position:sticky !important}.conversejs .fixed-top{position:fixed;top:0;right:0;left:0;z-index:1030}.conversejs .fixed-bottom{position:fixed;right:0;bottom:0;left:0;z-index:1030}@supports(position: sticky){.conversejs .sticky-top{position:sticky;top:0;z-index:1020}}.conversejs .sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0, 0, 0, 0);white-space:nowrap;border:0}.conversejs .sr-only-focusable:active,.conversejs .sr-only-focusable:focus{position:static;width:auto;height:auto;overflow:visible;clip:auto;white-space:normal}.conversejs .shadow-sm{box-shadow:0 .125rem .25rem rgba(0,0,0,.075) !important}.conversejs .shadow{box-shadow:0 .5rem 1rem rgba(0,0,0,.15) !important}.conversejs .shadow-lg{box-shadow:0 1rem 3rem rgba(0,0,0,.175) !important}.conversejs .shadow-none{box-shadow:none !important}.conversejs .w-25{width:25% !important}.conversejs .w-50{width:50% !important}.conversejs .w-75{width:75% !important}.conversejs .w-100{width:100% !important}.conversejs .w-auto{width:auto !important}.conversejs .h-25{height:25% !important}.conversejs .h-50{height:50% !important}.conversejs .h-75{height:75% !important}.conversejs .h-100{height:100% !important}.conversejs .h-auto{height:auto !important}.conversejs .mw-100{max-width:100% !important}.conversejs .mh-100{max-height:100% !important}.conversejs .min-vw-100{min-width:100vw !important}.conversejs .min-vh-100{min-height:100vh !important}.conversejs .vw-100{width:100vw !important}.conversejs .vh-100{height:100vh !important}.conversejs .m-0{margin:0 !important}.conversejs .mt-0,.conversejs .my-0{margin-top:0 !important}.conversejs .mr-0,.conversejs .mx-0{margin-right:0 !important}.conversejs .mb-0,.conversejs .my-0{margin-bottom:0 !important}.conversejs .ml-0,.conversejs .mx-0{margin-left:0 !important}.conversejs .m-1{margin:.25rem !important}.conversejs .mt-1,.conversejs .my-1{margin-top:.25rem !important}.conversejs .mr-1,.conversejs .mx-1{margin-right:.25rem !important}.conversejs .mb-1,.conversejs .my-1{margin-bottom:.25rem !important}.conversejs .ml-1,.conversejs .mx-1{margin-left:.25rem !important}.conversejs .m-2{margin:.5rem !important}.conversejs .mt-2,.conversejs .my-2{margin-top:.5rem !important}.conversejs .mr-2,.conversejs .mx-2{margin-right:.5rem !important}.conversejs .mb-2,.conversejs .my-2{margin-bottom:.5rem !important}.conversejs .ml-2,.conversejs .mx-2{margin-left:.5rem !important}.conversejs .m-3{margin:1rem !important}.conversejs .mt-3,.conversejs .my-3{margin-top:1rem !important}.conversejs .mr-3,.conversejs .mx-3{margin-right:1rem !important}.conversejs .mb-3,.conversejs .my-3{margin-bottom:1rem !important}.conversejs .ml-3,.conversejs .mx-3{margin-left:1rem !important}.conversejs .m-4{margin:1.5rem !important}.conversejs .mt-4,.conversejs .my-4{margin-top:1.5rem !important}.conversejs .mr-4,.conversejs .mx-4{margin-right:1.5rem !important}.conversejs .mb-4,.conversejs .my-4{margin-bottom:1.5rem !important}.conversejs .ml-4,.conversejs .mx-4{margin-left:1.5rem !important}.conversejs .m-5{margin:3rem !important}.conversejs .mt-5,.conversejs .my-5{margin-top:3rem !important}.conversejs .mr-5,.conversejs .mx-5{margin-right:3rem !important}.conversejs .mb-5,.conversejs .my-5{margin-bottom:3rem !important}.conversejs .ml-5,.conversejs .mx-5{margin-left:3rem !important}.conversejs .p-0{padding:0 !important}.conversejs .pt-0,.conversejs .py-0{padding-top:0 !important}.conversejs .pr-0,.conversejs .px-0{padding-right:0 !important}.conversejs .pb-0,.conversejs .py-0{padding-bottom:0 !important}.conversejs .pl-0,.conversejs .px-0{padding-left:0 !important}.conversejs .p-1{padding:.25rem !important}.conversejs .pt-1,.conversejs .py-1{padding-top:.25rem !important}.conversejs .pr-1,.conversejs .px-1{padding-right:.25rem !important}.conversejs .pb-1,.conversejs .py-1{padding-bottom:.25rem !important}.conversejs .pl-1,.conversejs .px-1{padding-left:.25rem !important}.conversejs .p-2{padding:.5rem !important}.conversejs .pt-2,.conversejs .py-2{padding-top:.5rem !important}.conversejs .pr-2,.conversejs .px-2{padding-right:.5rem !important}.conversejs .pb-2,.conversejs .py-2{padding-bottom:.5rem !important}.conversejs .pl-2,.conversejs .px-2{padding-left:.5rem !important}.conversejs .p-3{padding:1rem !important}.conversejs .pt-3,.conversejs .py-3{padding-top:1rem !important}.conversejs .pr-3,.conversejs .px-3{padding-right:1rem !important}.conversejs .pb-3,.conversejs .py-3{padding-bottom:1rem !important}.conversejs .pl-3,.conversejs .px-3{padding-left:1rem !important}.conversejs .p-4{padding:1.5rem !important}.conversejs .pt-4,.conversejs .py-4{padding-top:1.5rem !important}.conversejs .pr-4,.conversejs .px-4{padding-right:1.5rem !important}.conversejs .pb-4,.conversejs .py-4{padding-bottom:1.5rem !important}.conversejs .pl-4,.conversejs .px-4{padding-left:1.5rem !important}.conversejs .p-5{padding:3rem !important}.conversejs .pt-5,.conversejs .py-5{padding-top:3rem !important}.conversejs .pr-5,.conversejs .px-5{padding-right:3rem !important}.conversejs .pb-5,.conversejs .py-5{padding-bottom:3rem !important}.conversejs .pl-5,.conversejs .px-5{padding-left:3rem !important}.conversejs .m-n1{margin:-0.25rem !important}.conversejs .mt-n1,.conversejs .my-n1{margin-top:-0.25rem !important}.conversejs .mr-n1,.conversejs .mx-n1{margin-right:-0.25rem !important}.conversejs .mb-n1,.conversejs .my-n1{margin-bottom:-0.25rem !important}.conversejs .ml-n1,.conversejs .mx-n1{margin-left:-0.25rem !important}.conversejs .m-n2{margin:-0.5rem !important}.conversejs .mt-n2,.conversejs .my-n2{margin-top:-0.5rem !important}.conversejs .mr-n2,.conversejs .mx-n2{margin-right:-0.5rem !important}.conversejs .mb-n2,.conversejs .my-n2{margin-bottom:-0.5rem !important}.conversejs .ml-n2,.conversejs .mx-n2{margin-left:-0.5rem !important}.conversejs .m-n3{margin:-1rem !important}.conversejs .mt-n3,.conversejs .my-n3{margin-top:-1rem !important}.conversejs .mr-n3,.conversejs .mx-n3{margin-right:-1rem !important}.conversejs .mb-n3,.conversejs .my-n3{margin-bottom:-1rem !important}.conversejs .ml-n3,.conversejs .mx-n3{margin-left:-1rem !important}.conversejs .m-n4{margin:-1.5rem !important}.conversejs .mt-n4,.conversejs .my-n4{margin-top:-1.5rem !important}.conversejs .mr-n4,.conversejs .mx-n4{margin-right:-1.5rem !important}.conversejs .mb-n4,.conversejs .my-n4{margin-bottom:-1.5rem !important}.conversejs .ml-n4,.conversejs .mx-n4{margin-left:-1.5rem !important}.conversejs .m-n5{margin:-3rem !important}.conversejs .mt-n5,.conversejs .my-n5{margin-top:-3rem !important}.conversejs .mr-n5,.conversejs .mx-n5{margin-right:-3rem !important}.conversejs .mb-n5,.conversejs .my-n5{margin-bottom:-3rem !important}.conversejs .ml-n5,.conversejs .mx-n5{margin-left:-3rem !important}.conversejs .m-auto{margin:auto !important}.conversejs .mt-auto,.conversejs .my-auto{margin-top:auto !important}.conversejs .mr-auto,.conversejs .mx-auto{margin-right:auto !important}.conversejs .mb-auto,.conversejs .my-auto{margin-bottom:auto !important}.conversejs .ml-auto,.conversejs .mx-auto{margin-left:auto !important}@media(min-width: 576px){.conversejs .m-sm-0{margin:0 !important}.conversejs .mt-sm-0,.conversejs .my-sm-0{margin-top:0 !important}.conversejs .mr-sm-0,.conversejs .mx-sm-0{margin-right:0 !important}.conversejs .mb-sm-0,.conversejs .my-sm-0{margin-bottom:0 !important}.conversejs .ml-sm-0,.conversejs .mx-sm-0{margin-left:0 !important}.conversejs .m-sm-1{margin:.25rem !important}.conversejs .mt-sm-1,.conversejs .my-sm-1{margin-top:.25rem !important}.conversejs .mr-sm-1,.conversejs .mx-sm-1{margin-right:.25rem !important}.conversejs .mb-sm-1,.conversejs .my-sm-1{margin-bottom:.25rem !important}.conversejs .ml-sm-1,.conversejs .mx-sm-1{margin-left:.25rem !important}.conversejs .m-sm-2{margin:.5rem !important}.conversejs .mt-sm-2,.conversejs .my-sm-2{margin-top:.5rem !important}.conversejs .mr-sm-2,.conversejs .mx-sm-2{margin-right:.5rem !important}.conversejs .mb-sm-2,.conversejs .my-sm-2{margin-bottom:.5rem !important}.conversejs .ml-sm-2,.conversejs .mx-sm-2{margin-left:.5rem !important}.conversejs .m-sm-3{margin:1rem !important}.conversejs .mt-sm-3,.conversejs .my-sm-3{margin-top:1rem !important}.conversejs .mr-sm-3,.conversejs .mx-sm-3{margin-right:1rem !important}.conversejs .mb-sm-3,.conversejs .my-sm-3{margin-bottom:1rem !important}.conversejs .ml-sm-3,.conversejs .mx-sm-3{margin-left:1rem !important}.conversejs .m-sm-4{margin:1.5rem !important}.conversejs .mt-sm-4,.conversejs .my-sm-4{margin-top:1.5rem !important}.conversejs .mr-sm-4,.conversejs .mx-sm-4{margin-right:1.5rem !important}.conversejs .mb-sm-4,.conversejs .my-sm-4{margin-bottom:1.5rem !important}.conversejs .ml-sm-4,.conversejs .mx-sm-4{margin-left:1.5rem !important}.conversejs .m-sm-5{margin:3rem !important}.conversejs .mt-sm-5,.conversejs .my-sm-5{margin-top:3rem !important}.conversejs .mr-sm-5,.conversejs .mx-sm-5{margin-right:3rem !important}.conversejs .mb-sm-5,.conversejs .my-sm-5{margin-bottom:3rem !important}.conversejs .ml-sm-5,.conversejs .mx-sm-5{margin-left:3rem !important}.conversejs .p-sm-0{padding:0 !important}.conversejs .pt-sm-0,.conversejs .py-sm-0{padding-top:0 !important}.conversejs .pr-sm-0,.conversejs .px-sm-0{padding-right:0 !important}.conversejs .pb-sm-0,.conversejs .py-sm-0{padding-bottom:0 !important}.conversejs .pl-sm-0,.conversejs .px-sm-0{padding-left:0 !important}.conversejs .p-sm-1{padding:.25rem !important}.conversejs .pt-sm-1,.conversejs .py-sm-1{padding-top:.25rem !important}.conversejs .pr-sm-1,.conversejs .px-sm-1{padding-right:.25rem !important}.conversejs .pb-sm-1,.conversejs .py-sm-1{padding-bottom:.25rem !important}.conversejs .pl-sm-1,.conversejs .px-sm-1{padding-left:.25rem !important}.conversejs .p-sm-2{padding:.5rem !important}.conversejs .pt-sm-2,.conversejs .py-sm-2{padding-top:.5rem !important}.conversejs .pr-sm-2,.conversejs .px-sm-2{padding-right:.5rem !important}.conversejs .pb-sm-2,.conversejs .py-sm-2{padding-bottom:.5rem !important}.conversejs .pl-sm-2,.conversejs .px-sm-2{padding-left:.5rem !important}.conversejs .p-sm-3{padding:1rem !important}.conversejs .pt-sm-3,.conversejs .py-sm-3{padding-top:1rem !important}.conversejs .pr-sm-3,.conversejs .px-sm-3{padding-right:1rem !important}.conversejs .pb-sm-3,.conversejs .py-sm-3{padding-bottom:1rem !important}.conversejs .pl-sm-3,.conversejs .px-sm-3{padding-left:1rem !important}.conversejs .p-sm-4{padding:1.5rem !important}.conversejs .pt-sm-4,.conversejs .py-sm-4{padding-top:1.5rem !important}.conversejs .pr-sm-4,.conversejs .px-sm-4{padding-right:1.5rem !important}.conversejs .pb-sm-4,.conversejs .py-sm-4{padding-bottom:1.5rem !important}.conversejs .pl-sm-4,.conversejs .px-sm-4{padding-left:1.5rem !important}.conversejs .p-sm-5{padding:3rem !important}.conversejs .pt-sm-5,.conversejs .py-sm-5{padding-top:3rem !important}.conversejs .pr-sm-5,.conversejs .px-sm-5{padding-right:3rem !important}.conversejs .pb-sm-5,.conversejs .py-sm-5{padding-bottom:3rem !important}.conversejs .pl-sm-5,.conversejs .px-sm-5{padding-left:3rem !important}.conversejs .m-sm-n1{margin:-0.25rem !important}.conversejs .mt-sm-n1,.conversejs .my-sm-n1{margin-top:-0.25rem !important}.conversejs .mr-sm-n1,.conversejs .mx-sm-n1{margin-right:-0.25rem !important}.conversejs .mb-sm-n1,.conversejs .my-sm-n1{margin-bottom:-0.25rem !important}.conversejs .ml-sm-n1,.conversejs .mx-sm-n1{margin-left:-0.25rem !important}.conversejs .m-sm-n2{margin:-0.5rem !important}.conversejs .mt-sm-n2,.conversejs .my-sm-n2{margin-top:-0.5rem !important}.conversejs .mr-sm-n2,.conversejs .mx-sm-n2{margin-right:-0.5rem !important}.conversejs .mb-sm-n2,.conversejs .my-sm-n2{margin-bottom:-0.5rem !important}.conversejs .ml-sm-n2,.conversejs .mx-sm-n2{margin-left:-0.5rem !important}.conversejs .m-sm-n3{margin:-1rem !important}.conversejs .mt-sm-n3,.conversejs .my-sm-n3{margin-top:-1rem !important}.conversejs .mr-sm-n3,.conversejs .mx-sm-n3{margin-right:-1rem !important}.conversejs .mb-sm-n3,.conversejs .my-sm-n3{margin-bottom:-1rem !important}.conversejs .ml-sm-n3,.conversejs .mx-sm-n3{margin-left:-1rem !important}.conversejs .m-sm-n4{margin:-1.5rem !important}.conversejs .mt-sm-n4,.conversejs .my-sm-n4{margin-top:-1.5rem !important}.conversejs .mr-sm-n4,.conversejs .mx-sm-n4{margin-right:-1.5rem !important}.conversejs .mb-sm-n4,.conversejs .my-sm-n4{margin-bottom:-1.5rem !important}.conversejs .ml-sm-n4,.conversejs .mx-sm-n4{margin-left:-1.5rem !important}.conversejs .m-sm-n5{margin:-3rem !important}.conversejs .mt-sm-n5,.conversejs .my-sm-n5{margin-top:-3rem !important}.conversejs .mr-sm-n5,.conversejs .mx-sm-n5{margin-right:-3rem !important}.conversejs .mb-sm-n5,.conversejs .my-sm-n5{margin-bottom:-3rem !important}.conversejs .ml-sm-n5,.conversejs .mx-sm-n5{margin-left:-3rem !important}.conversejs .m-sm-auto{margin:auto !important}.conversejs .mt-sm-auto,.conversejs .my-sm-auto{margin-top:auto !important}.conversejs .mr-sm-auto,.conversejs .mx-sm-auto{margin-right:auto !important}.conversejs .mb-sm-auto,.conversejs .my-sm-auto{margin-bottom:auto !important}.conversejs .ml-sm-auto,.conversejs .mx-sm-auto{margin-left:auto !important}}@media(min-width: 768px){.conversejs .m-md-0{margin:0 !important}.conversejs .mt-md-0,.conversejs .my-md-0{margin-top:0 !important}.conversejs .mr-md-0,.conversejs .mx-md-0{margin-right:0 !important}.conversejs .mb-md-0,.conversejs .my-md-0{margin-bottom:0 !important}.conversejs .ml-md-0,.conversejs .mx-md-0{margin-left:0 !important}.conversejs .m-md-1{margin:.25rem !important}.conversejs .mt-md-1,.conversejs .my-md-1{margin-top:.25rem !important}.conversejs .mr-md-1,.conversejs .mx-md-1{margin-right:.25rem !important}.conversejs .mb-md-1,.conversejs .my-md-1{margin-bottom:.25rem !important}.conversejs .ml-md-1,.conversejs .mx-md-1{margin-left:.25rem !important}.conversejs .m-md-2{margin:.5rem !important}.conversejs .mt-md-2,.conversejs .my-md-2{margin-top:.5rem !important}.conversejs .mr-md-2,.conversejs .mx-md-2{margin-right:.5rem !important}.conversejs .mb-md-2,.conversejs .my-md-2{margin-bottom:.5rem !important}.conversejs .ml-md-2,.conversejs .mx-md-2{margin-left:.5rem !important}.conversejs .m-md-3{margin:1rem !important}.conversejs .mt-md-3,.conversejs .my-md-3{margin-top:1rem !important}.conversejs .mr-md-3,.conversejs .mx-md-3{margin-right:1rem !important}.conversejs .mb-md-3,.conversejs .my-md-3{margin-bottom:1rem !important}.conversejs .ml-md-3,.conversejs .mx-md-3{margin-left:1rem !important}.conversejs .m-md-4{margin:1.5rem !important}.conversejs .mt-md-4,.conversejs .my-md-4{margin-top:1.5rem !important}.conversejs .mr-md-4,.conversejs .mx-md-4{margin-right:1.5rem !important}.conversejs .mb-md-4,.conversejs .my-md-4{margin-bottom:1.5rem !important}.conversejs .ml-md-4,.conversejs .mx-md-4{margin-left:1.5rem !important}.conversejs .m-md-5{margin:3rem !important}.conversejs .mt-md-5,.conversejs .my-md-5{margin-top:3rem !important}.conversejs .mr-md-5,.conversejs .mx-md-5{margin-right:3rem !important}.conversejs .mb-md-5,.conversejs .my-md-5{margin-bottom:3rem !important}.conversejs .ml-md-5,.conversejs .mx-md-5{margin-left:3rem !important}.conversejs .p-md-0{padding:0 !important}.conversejs .pt-md-0,.conversejs .py-md-0{padding-top:0 !important}.conversejs .pr-md-0,.conversejs .px-md-0{padding-right:0 !important}.conversejs .pb-md-0,.conversejs .py-md-0{padding-bottom:0 !important}.conversejs .pl-md-0,.conversejs .px-md-0{padding-left:0 !important}.conversejs .p-md-1{padding:.25rem !important}.conversejs .pt-md-1,.conversejs .py-md-1{padding-top:.25rem !important}.conversejs .pr-md-1,.conversejs .px-md-1{padding-right:.25rem !important}.conversejs .pb-md-1,.conversejs .py-md-1{padding-bottom:.25rem !important}.conversejs .pl-md-1,.conversejs .px-md-1{padding-left:.25rem !important}.conversejs .p-md-2{padding:.5rem !important}.conversejs .pt-md-2,.conversejs .py-md-2{padding-top:.5rem !important}.conversejs .pr-md-2,.conversejs .px-md-2{padding-right:.5rem !important}.conversejs .pb-md-2,.conversejs .py-md-2{padding-bottom:.5rem !important}.conversejs .pl-md-2,.conversejs .px-md-2{padding-left:.5rem !important}.conversejs .p-md-3{padding:1rem !important}.conversejs .pt-md-3,.conversejs .py-md-3{padding-top:1rem !important}.conversejs .pr-md-3,.conversejs .px-md-3{padding-right:1rem !important}.conversejs .pb-md-3,.conversejs .py-md-3{padding-bottom:1rem !important}.conversejs .pl-md-3,.conversejs .px-md-3{padding-left:1rem !important}.conversejs .p-md-4{padding:1.5rem !important}.conversejs .pt-md-4,.conversejs .py-md-4{padding-top:1.5rem !important}.conversejs .pr-md-4,.conversejs .px-md-4{padding-right:1.5rem !important}.conversejs .pb-md-4,.conversejs .py-md-4{padding-bottom:1.5rem !important}.conversejs .pl-md-4,.conversejs .px-md-4{padding-left:1.5rem !important}.conversejs .p-md-5{padding:3rem !important}.conversejs .pt-md-5,.conversejs .py-md-5{padding-top:3rem !important}.conversejs .pr-md-5,.conversejs .px-md-5{padding-right:3rem !important}.conversejs .pb-md-5,.conversejs .py-md-5{padding-bottom:3rem !important}.conversejs .pl-md-5,.conversejs .px-md-5{padding-left:3rem !important}.conversejs .m-md-n1{margin:-0.25rem !important}.conversejs .mt-md-n1,.conversejs .my-md-n1{margin-top:-0.25rem !important}.conversejs .mr-md-n1,.conversejs .mx-md-n1{margin-right:-0.25rem !important}.conversejs .mb-md-n1,.conversejs .my-md-n1{margin-bottom:-0.25rem !important}.conversejs .ml-md-n1,.conversejs .mx-md-n1{margin-left:-0.25rem !important}.conversejs .m-md-n2{margin:-0.5rem !important}.conversejs .mt-md-n2,.conversejs .my-md-n2{margin-top:-0.5rem !important}.conversejs .mr-md-n2,.conversejs .mx-md-n2{margin-right:-0.5rem !important}.conversejs .mb-md-n2,.conversejs .my-md-n2{margin-bottom:-0.5rem !important}.conversejs .ml-md-n2,.conversejs .mx-md-n2{margin-left:-0.5rem !important}.conversejs .m-md-n3{margin:-1rem !important}.conversejs .mt-md-n3,.conversejs .my-md-n3{margin-top:-1rem !important}.conversejs .mr-md-n3,.conversejs .mx-md-n3{margin-right:-1rem !important}.conversejs .mb-md-n3,.conversejs .my-md-n3{margin-bottom:-1rem !important}.conversejs .ml-md-n3,.conversejs .mx-md-n3{margin-left:-1rem !important}.conversejs .m-md-n4{margin:-1.5rem !important}.conversejs .mt-md-n4,.conversejs .my-md-n4{margin-top:-1.5rem !important}.conversejs .mr-md-n4,.conversejs .mx-md-n4{margin-right:-1.5rem !important}.conversejs .mb-md-n4,.conversejs .my-md-n4{margin-bottom:-1.5rem !important}.conversejs .ml-md-n4,.conversejs .mx-md-n4{margin-left:-1.5rem !important}.conversejs .m-md-n5{margin:-3rem !important}.conversejs .mt-md-n5,.conversejs .my-md-n5{margin-top:-3rem !important}.conversejs .mr-md-n5,.conversejs .mx-md-n5{margin-right:-3rem !important}.conversejs .mb-md-n5,.conversejs .my-md-n5{margin-bottom:-3rem !important}.conversejs .ml-md-n5,.conversejs .mx-md-n5{margin-left:-3rem !important}.conversejs .m-md-auto{margin:auto !important}.conversejs .mt-md-auto,.conversejs .my-md-auto{margin-top:auto !important}.conversejs .mr-md-auto,.conversejs .mx-md-auto{margin-right:auto !important}.conversejs .mb-md-auto,.conversejs .my-md-auto{margin-bottom:auto !important}.conversejs .ml-md-auto,.conversejs .mx-md-auto{margin-left:auto !important}}@media(min-width: 992px){.conversejs .m-lg-0{margin:0 !important}.conversejs .mt-lg-0,.conversejs .my-lg-0{margin-top:0 !important}.conversejs .mr-lg-0,.conversejs .mx-lg-0{margin-right:0 !important}.conversejs .mb-lg-0,.conversejs .my-lg-0{margin-bottom:0 !important}.conversejs .ml-lg-0,.conversejs .mx-lg-0{margin-left:0 !important}.conversejs .m-lg-1{margin:.25rem !important}.conversejs .mt-lg-1,.conversejs .my-lg-1{margin-top:.25rem !important}.conversejs .mr-lg-1,.conversejs .mx-lg-1{margin-right:.25rem !important}.conversejs .mb-lg-1,.conversejs .my-lg-1{margin-bottom:.25rem !important}.conversejs .ml-lg-1,.conversejs .mx-lg-1{margin-left:.25rem !important}.conversejs .m-lg-2{margin:.5rem !important}.conversejs .mt-lg-2,.conversejs .my-lg-2{margin-top:.5rem !important}.conversejs .mr-lg-2,.conversejs .mx-lg-2{margin-right:.5rem !important}.conversejs .mb-lg-2,.conversejs .my-lg-2{margin-bottom:.5rem !important}.conversejs .ml-lg-2,.conversejs .mx-lg-2{margin-left:.5rem !important}.conversejs .m-lg-3{margin:1rem !important}.conversejs .mt-lg-3,.conversejs .my-lg-3{margin-top:1rem !important}.conversejs .mr-lg-3,.conversejs .mx-lg-3{margin-right:1rem !important}.conversejs .mb-lg-3,.conversejs .my-lg-3{margin-bottom:1rem !important}.conversejs .ml-lg-3,.conversejs .mx-lg-3{margin-left:1rem !important}.conversejs .m-lg-4{margin:1.5rem !important}.conversejs .mt-lg-4,.conversejs .my-lg-4{margin-top:1.5rem !important}.conversejs .mr-lg-4,.conversejs .mx-lg-4{margin-right:1.5rem !important}.conversejs .mb-lg-4,.conversejs .my-lg-4{margin-bottom:1.5rem !important}.conversejs .ml-lg-4,.conversejs .mx-lg-4{margin-left:1.5rem !important}.conversejs .m-lg-5{margin:3rem !important}.conversejs .mt-lg-5,.conversejs .my-lg-5{margin-top:3rem !important}.conversejs .mr-lg-5,.conversejs .mx-lg-5{margin-right:3rem !important}.conversejs .mb-lg-5,.conversejs .my-lg-5{margin-bottom:3rem !important}.conversejs .ml-lg-5,.conversejs .mx-lg-5{margin-left:3rem !important}.conversejs .p-lg-0{padding:0 !important}.conversejs .pt-lg-0,.conversejs .py-lg-0{padding-top:0 !important}.conversejs .pr-lg-0,.conversejs .px-lg-0{padding-right:0 !important}.conversejs .pb-lg-0,.conversejs .py-lg-0{padding-bottom:0 !important}.conversejs .pl-lg-0,.conversejs .px-lg-0{padding-left:0 !important}.conversejs .p-lg-1{padding:.25rem !important}.conversejs .pt-lg-1,.conversejs .py-lg-1{padding-top:.25rem !important}.conversejs .pr-lg-1,.conversejs .px-lg-1{padding-right:.25rem !important}.conversejs .pb-lg-1,.conversejs .py-lg-1{padding-bottom:.25rem !important}.conversejs .pl-lg-1,.conversejs .px-lg-1{padding-left:.25rem !important}.conversejs .p-lg-2{padding:.5rem !important}.conversejs .pt-lg-2,.conversejs .py-lg-2{padding-top:.5rem !important}.conversejs .pr-lg-2,.conversejs .px-lg-2{padding-right:.5rem !important}.conversejs .pb-lg-2,.conversejs .py-lg-2{padding-bottom:.5rem !important}.conversejs .pl-lg-2,.conversejs .px-lg-2{padding-left:.5rem !important}.conversejs .p-lg-3{padding:1rem !important}.conversejs .pt-lg-3,.conversejs .py-lg-3{padding-top:1rem !important}.conversejs .pr-lg-3,.conversejs .px-lg-3{padding-right:1rem !important}.conversejs .pb-lg-3,.conversejs .py-lg-3{padding-bottom:1rem !important}.conversejs .pl-lg-3,.conversejs .px-lg-3{padding-left:1rem !important}.conversejs .p-lg-4{padding:1.5rem !important}.conversejs .pt-lg-4,.conversejs .py-lg-4{padding-top:1.5rem !important}.conversejs .pr-lg-4,.conversejs .px-lg-4{padding-right:1.5rem !important}.conversejs .pb-lg-4,.conversejs .py-lg-4{padding-bottom:1.5rem !important}.conversejs .pl-lg-4,.conversejs .px-lg-4{padding-left:1.5rem !important}.conversejs .p-lg-5{padding:3rem !important}.conversejs .pt-lg-5,.conversejs .py-lg-5{padding-top:3rem !important}.conversejs .pr-lg-5,.conversejs .px-lg-5{padding-right:3rem !important}.conversejs .pb-lg-5,.conversejs .py-lg-5{padding-bottom:3rem !important}.conversejs .pl-lg-5,.conversejs .px-lg-5{padding-left:3rem !important}.conversejs .m-lg-n1{margin:-0.25rem !important}.conversejs .mt-lg-n1,.conversejs .my-lg-n1{margin-top:-0.25rem !important}.conversejs .mr-lg-n1,.conversejs .mx-lg-n1{margin-right:-0.25rem !important}.conversejs .mb-lg-n1,.conversejs .my-lg-n1{margin-bottom:-0.25rem !important}.conversejs .ml-lg-n1,.conversejs .mx-lg-n1{margin-left:-0.25rem !important}.conversejs .m-lg-n2{margin:-0.5rem !important}.conversejs .mt-lg-n2,.conversejs .my-lg-n2{margin-top:-0.5rem !important}.conversejs .mr-lg-n2,.conversejs .mx-lg-n2{margin-right:-0.5rem !important}.conversejs .mb-lg-n2,.conversejs .my-lg-n2{margin-bottom:-0.5rem !important}.conversejs .ml-lg-n2,.conversejs .mx-lg-n2{margin-left:-0.5rem !important}.conversejs .m-lg-n3{margin:-1rem !important}.conversejs .mt-lg-n3,.conversejs .my-lg-n3{margin-top:-1rem !important}.conversejs .mr-lg-n3,.conversejs .mx-lg-n3{margin-right:-1rem !important}.conversejs .mb-lg-n3,.conversejs .my-lg-n3{margin-bottom:-1rem !important}.conversejs .ml-lg-n3,.conversejs .mx-lg-n3{margin-left:-1rem !important}.conversejs .m-lg-n4{margin:-1.5rem !important}.conversejs .mt-lg-n4,.conversejs .my-lg-n4{margin-top:-1.5rem !important}.conversejs .mr-lg-n4,.conversejs .mx-lg-n4{margin-right:-1.5rem !important}.conversejs .mb-lg-n4,.conversejs .my-lg-n4{margin-bottom:-1.5rem !important}.conversejs .ml-lg-n4,.conversejs .mx-lg-n4{margin-left:-1.5rem !important}.conversejs .m-lg-n5{margin:-3rem !important}.conversejs .mt-lg-n5,.conversejs .my-lg-n5{margin-top:-3rem !important}.conversejs .mr-lg-n5,.conversejs .mx-lg-n5{margin-right:-3rem !important}.conversejs .mb-lg-n5,.conversejs .my-lg-n5{margin-bottom:-3rem !important}.conversejs .ml-lg-n5,.conversejs .mx-lg-n5{margin-left:-3rem !important}.conversejs .m-lg-auto{margin:auto !important}.conversejs .mt-lg-auto,.conversejs .my-lg-auto{margin-top:auto !important}.conversejs .mr-lg-auto,.conversejs .mx-lg-auto{margin-right:auto !important}.conversejs .mb-lg-auto,.conversejs .my-lg-auto{margin-bottom:auto !important}.conversejs .ml-lg-auto,.conversejs .mx-lg-auto{margin-left:auto !important}}@media(min-width: 1200px){.conversejs .m-xl-0{margin:0 !important}.conversejs .mt-xl-0,.conversejs .my-xl-0{margin-top:0 !important}.conversejs .mr-xl-0,.conversejs .mx-xl-0{margin-right:0 !important}.conversejs .mb-xl-0,.conversejs .my-xl-0{margin-bottom:0 !important}.conversejs .ml-xl-0,.conversejs .mx-xl-0{margin-left:0 !important}.conversejs .m-xl-1{margin:.25rem !important}.conversejs .mt-xl-1,.conversejs .my-xl-1{margin-top:.25rem !important}.conversejs .mr-xl-1,.conversejs .mx-xl-1{margin-right:.25rem !important}.conversejs .mb-xl-1,.conversejs .my-xl-1{margin-bottom:.25rem !important}.conversejs .ml-xl-1,.conversejs .mx-xl-1{margin-left:.25rem !important}.conversejs .m-xl-2{margin:.5rem !important}.conversejs .mt-xl-2,.conversejs .my-xl-2{margin-top:.5rem !important}.conversejs .mr-xl-2,.conversejs .mx-xl-2{margin-right:.5rem !important}.conversejs .mb-xl-2,.conversejs .my-xl-2{margin-bottom:.5rem !important}.conversejs .ml-xl-2,.conversejs .mx-xl-2{margin-left:.5rem !important}.conversejs .m-xl-3{margin:1rem !important}.conversejs .mt-xl-3,.conversejs .my-xl-3{margin-top:1rem !important}.conversejs .mr-xl-3,.conversejs .mx-xl-3{margin-right:1rem !important}.conversejs .mb-xl-3,.conversejs .my-xl-3{margin-bottom:1rem !important}.conversejs .ml-xl-3,.conversejs .mx-xl-3{margin-left:1rem !important}.conversejs .m-xl-4{margin:1.5rem !important}.conversejs .mt-xl-4,.conversejs .my-xl-4{margin-top:1.5rem !important}.conversejs .mr-xl-4,.conversejs .mx-xl-4{margin-right:1.5rem !important}.conversejs .mb-xl-4,.conversejs .my-xl-4{margin-bottom:1.5rem !important}.conversejs .ml-xl-4,.conversejs .mx-xl-4{margin-left:1.5rem !important}.conversejs .m-xl-5{margin:3rem !important}.conversejs .mt-xl-5,.conversejs .my-xl-5{margin-top:3rem !important}.conversejs .mr-xl-5,.conversejs .mx-xl-5{margin-right:3rem !important}.conversejs .mb-xl-5,.conversejs .my-xl-5{margin-bottom:3rem !important}.conversejs .ml-xl-5,.conversejs .mx-xl-5{margin-left:3rem !important}.conversejs .p-xl-0{padding:0 !important}.conversejs .pt-xl-0,.conversejs .py-xl-0{padding-top:0 !important}.conversejs .pr-xl-0,.conversejs .px-xl-0{padding-right:0 !important}.conversejs .pb-xl-0,.conversejs .py-xl-0{padding-bottom:0 !important}.conversejs .pl-xl-0,.conversejs .px-xl-0{padding-left:0 !important}.conversejs .p-xl-1{padding:.25rem !important}.conversejs .pt-xl-1,.conversejs .py-xl-1{padding-top:.25rem !important}.conversejs .pr-xl-1,.conversejs .px-xl-1{padding-right:.25rem !important}.conversejs .pb-xl-1,.conversejs .py-xl-1{padding-bottom:.25rem !important}.conversejs .pl-xl-1,.conversejs .px-xl-1{padding-left:.25rem !important}.conversejs .p-xl-2{padding:.5rem !important}.conversejs .pt-xl-2,.conversejs .py-xl-2{padding-top:.5rem !important}.conversejs .pr-xl-2,.conversejs .px-xl-2{padding-right:.5rem !important}.conversejs .pb-xl-2,.conversejs .py-xl-2{padding-bottom:.5rem !important}.conversejs .pl-xl-2,.conversejs .px-xl-2{padding-left:.5rem !important}.conversejs .p-xl-3{padding:1rem !important}.conversejs .pt-xl-3,.conversejs .py-xl-3{padding-top:1rem !important}.conversejs .pr-xl-3,.conversejs .px-xl-3{padding-right:1rem !important}.conversejs .pb-xl-3,.conversejs .py-xl-3{padding-bottom:1rem !important}.conversejs .pl-xl-3,.conversejs .px-xl-3{padding-left:1rem !important}.conversejs .p-xl-4{padding:1.5rem !important}.conversejs .pt-xl-4,.conversejs .py-xl-4{padding-top:1.5rem !important}.conversejs .pr-xl-4,.conversejs .px-xl-4{padding-right:1.5rem !important}.conversejs .pb-xl-4,.conversejs .py-xl-4{padding-bottom:1.5rem !important}.conversejs .pl-xl-4,.conversejs .px-xl-4{padding-left:1.5rem !important}.conversejs .p-xl-5{padding:3rem !important}.conversejs .pt-xl-5,.conversejs .py-xl-5{padding-top:3rem !important}.conversejs .pr-xl-5,.conversejs .px-xl-5{padding-right:3rem !important}.conversejs .pb-xl-5,.conversejs .py-xl-5{padding-bottom:3rem !important}.conversejs .pl-xl-5,.conversejs .px-xl-5{padding-left:3rem !important}.conversejs .m-xl-n1{margin:-0.25rem !important}.conversejs .mt-xl-n1,.conversejs .my-xl-n1{margin-top:-0.25rem !important}.conversejs .mr-xl-n1,.conversejs .mx-xl-n1{margin-right:-0.25rem !important}.conversejs .mb-xl-n1,.conversejs .my-xl-n1{margin-bottom:-0.25rem !important}.conversejs .ml-xl-n1,.conversejs .mx-xl-n1{margin-left:-0.25rem !important}.conversejs .m-xl-n2{margin:-0.5rem !important}.conversejs .mt-xl-n2,.conversejs .my-xl-n2{margin-top:-0.5rem !important}.conversejs .mr-xl-n2,.conversejs .mx-xl-n2{margin-right:-0.5rem !important}.conversejs .mb-xl-n2,.conversejs .my-xl-n2{margin-bottom:-0.5rem !important}.conversejs .ml-xl-n2,.conversejs .mx-xl-n2{margin-left:-0.5rem !important}.conversejs .m-xl-n3{margin:-1rem !important}.conversejs .mt-xl-n3,.conversejs .my-xl-n3{margin-top:-1rem !important}.conversejs .mr-xl-n3,.conversejs .mx-xl-n3{margin-right:-1rem !important}.conversejs .mb-xl-n3,.conversejs .my-xl-n3{margin-bottom:-1rem !important}.conversejs .ml-xl-n3,.conversejs .mx-xl-n3{margin-left:-1rem !important}.conversejs .m-xl-n4{margin:-1.5rem !important}.conversejs .mt-xl-n4,.conversejs .my-xl-n4{margin-top:-1.5rem !important}.conversejs .mr-xl-n4,.conversejs .mx-xl-n4{margin-right:-1.5rem !important}.conversejs .mb-xl-n4,.conversejs .my-xl-n4{margin-bottom:-1.5rem !important}.conversejs .ml-xl-n4,.conversejs .mx-xl-n4{margin-left:-1.5rem !important}.conversejs .m-xl-n5{margin:-3rem !important}.conversejs .mt-xl-n5,.conversejs .my-xl-n5{margin-top:-3rem !important}.conversejs .mr-xl-n5,.conversejs .mx-xl-n5{margin-right:-3rem !important}.conversejs .mb-xl-n5,.conversejs .my-xl-n5{margin-bottom:-3rem !important}.conversejs .ml-xl-n5,.conversejs .mx-xl-n5{margin-left:-3rem !important}.conversejs .m-xl-auto{margin:auto !important}.conversejs .mt-xl-auto,.conversejs .my-xl-auto{margin-top:auto !important}.conversejs .mr-xl-auto,.conversejs .mx-xl-auto{margin-right:auto !important}.conversejs .mb-xl-auto,.conversejs .my-xl-auto{margin-bottom:auto !important}.conversejs .ml-xl-auto,.conversejs .mx-xl-auto{margin-left:auto !important}}.conversejs .stretched-link::after{position:absolute;top:0;right:0;bottom:0;left:0;z-index:1;pointer-events:auto;content:"";background-color:rgba(0,0,0,0)}.conversejs .text-monospace{font-family:SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace !important}.conversejs .text-justify{text-align:justify !important}.conversejs .text-wrap{white-space:normal !important}.conversejs .text-nowrap{white-space:nowrap !important}.conversejs .text-truncate{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.conversejs .text-left{text-align:left !important}.conversejs .text-right{text-align:right !important}.conversejs .text-center{text-align:center !important}@media(min-width: 576px){.conversejs .text-sm-left{text-align:left !important}.conversejs .text-sm-right{text-align:right !important}.conversejs .text-sm-center{text-align:center !important}}@media(min-width: 768px){.conversejs .text-md-left{text-align:left !important}.conversejs .text-md-right{text-align:right !important}.conversejs .text-md-center{text-align:center !important}}@media(min-width: 992px){.conversejs .text-lg-left{text-align:left !important}.conversejs .text-lg-right{text-align:right !important}.conversejs .text-lg-center{text-align:center !important}}@media(min-width: 1200px){.conversejs .text-xl-left{text-align:left !important}.conversejs .text-xl-right{text-align:right !important}.conversejs .text-xl-center{text-align:center !important}}.conversejs .text-lowercase{text-transform:lowercase !important}.conversejs .text-uppercase{text-transform:uppercase !important}.conversejs .text-capitalize{text-transform:capitalize !important}.conversejs .font-weight-light{font-weight:300 !important}.conversejs .font-weight-lighter{font-weight:lighter !important}.conversejs .font-weight-normal{font-weight:400 !important}.conversejs .font-weight-bold{font-weight:700 !important}.conversejs .font-weight-bolder{font-weight:bolder !important}.conversejs .font-italic{font-style:italic !important}.conversejs .text-white{color:#fff !important}.conversejs .text-primary{color:#007bff !important}.conversejs a.text-primary:hover,.conversejs a.text-primary:focus{color:#0056b3 !important}.conversejs .text-secondary{color:#6c757d !important}.conversejs a.text-secondary:hover,.conversejs a.text-secondary:focus{color:#494f54 !important}.conversejs .text-success{color:#28a745 !important}.conversejs a.text-success:hover,.conversejs a.text-success:focus{color:#19692c !important}.conversejs .text-info{color:#17a2b8 !important}.conversejs a.text-info:hover,.conversejs a.text-info:focus{color:#0f6674 !important}.conversejs .text-warning{color:#ffc107 !important}.conversejs a.text-warning:hover,.conversejs a.text-warning:focus{color:#ba8b00 !important}.conversejs .text-danger{color:#dc3545 !important}.conversejs a.text-danger:hover,.conversejs a.text-danger:focus{color:#a71d2a !important}.conversejs .text-light{color:#f8f9fa !important}.conversejs a.text-light:hover,.conversejs a.text-light:focus{color:#cbd3da !important}.conversejs .text-dark{color:#343a40 !important}.conversejs a.text-dark:hover,.conversejs a.text-dark:focus{color:#121416 !important}.conversejs .text-body{color:#212529 !important}.conversejs .text-muted{color:#6c757d !important}.conversejs .text-black-50{color:rgba(0,0,0,.5) !important}.conversejs .text-white-50{color:rgba(255,255,255,.5) !important}.conversejs .text-hide{font:0/0 a;color:rgba(0,0,0,0);text-shadow:none;background-color:rgba(0,0,0,0);border:0}.conversejs .text-decoration-none{text-decoration:none !important}.conversejs .text-break{word-break:break-word !important;word-wrap:break-word !important}.conversejs .text-reset{color:inherit !important}.conversejs .visible{visibility:visible !important}.conversejs .invisible{visibility:hidden !important}.conversejs,.conversejs-bg,#conversejs-bg,body.converse-fullscreen{--avatar-border-radius: 10%;--message-avatar-width: 36px;--message-avatar-height: 36px;--chatroom-width: 500px;--send-button-height: 27px;--send-button-margin: 3px;--inline-action-margin: 0.75em;--roster-height: 194px;--button-border-radius: 5px;--chatbox-border-radius: 4px;--normal-font: "Helvetica", "Arial", sans-serif;--heading-font: "Muli", normal;--branding-font: "Baumans", cursive;--font-size-tiny: 10px;--font-size-small: 12px;--font-size: 14px;--font-size-large: 16px;--font-size-huge: 20px;--message-font-size: var(--font-size);--line-height-small: 14px;--line-height: 16px;--line-height-large: 20px;--line-height-huge: 27px;--embedded-emoji-picker-height: 300px;--chat-gutter: 0.5em;--occupants-padding: 1em;--minimized-chats-width: 130px;--mobile-chat-width: 100%;--mobile-chat-height: 400px;--overlayed-chat-head-height: 55px;--overlayed-chat-height: 450px;--overlayed-chat-width: 300px;--overlayed-chatbox-hover-height: 1em;--overlayed-emoji-picker-height: 200px;--overlayed-max-chat-textarea-height: 200px;--list-toggle-font-weight: normal}.conversejs,.conversejs-bg,#conversejs-bg,body.converse-fullscreen{--green: #3AA569;--dark-green: #1E9652;--blue: #387592;--dark-blue: #397491;--redder-orange: #E77051;--orange: #E7A151;--light-blue: #578EA9;--lighter-blue: #eff4f7;--dark-red: #D24E2B;--comment: #A8ABA1;--gray: #818479;--foreground: #666;--background: white;--subdued-color: var(--comment);--muc-color: var(--redder-orange);--chat-color: var(--green);--disabled-color: gray;--error-color: var(--dark-red);--focus-color: var(--background);--icon-hover-color: var(--text-color);--info-color: var(--dark-green);--chat-status-online: var(--green);--chat-status-busy: var(--redder-orange);--chat-status-away: var(--orange);--brand-heading-color: var(--blue);--completion-light-color: #FFB9A7;--completion-normal-color: var(--redder-orange);--completion-dark-color: #D24E2B;--dark-link-color: #206485;--inverse-link-color: var(--background);--link-color-lighten-10-percent: #79a5ba;--link-color: var(--light-blue);--link-hover-color: #345566;--global-background-color: var(--dark-blue);--modal-background-color: var(--background);--img-thumbnail-background-color: var(--background);--img-thumbnail-border-color: #DEE2E6;--text-shadow-color: #FAFAFA;--text-color: var(--foreground);--controlbox-text-color: var(--foreground);--text-color-lighten-15-percent: #8c8c8c;--message-author-color: var(--text-color);--text-color-invert: var(--background);--message-text-color: #555;--message-receipt-color: var(--green);--save-button-color: var(--green);--button-text-color: var(--background);--button-hover-text-color: var(--background);--chat-background-color: var(--background);--chat-textarea-color: var(--foreground);--chat-textarea-background-color: var(--background);--chat-textarea-disabled-bg-color: #EEE;--chat-textarea-height: 60px;--chat-correcting-color: var(--chat-head-color-lighten-50-percent);--chat-head-fg-color: var(--background);--chat-head-color-dark: var(--dark-green);--chat-head-color-darker: #0E763B;--chat-head-color-lighten-50-percent: #e7f7ee;--chat-head-color: var(--green);--chat-head-text-color: var(--background);--chat-toolbar-btn-color: var(--green);--chat-toolbar-btn-disabled-color: gray;--toolbar-btn-text-color: var(--background);--chat-content-background-color: var(--background);--chat-info-color: var(--chatroom-head-bg-color);--danger-color-dark: #A93415;--danger-color: var(--redder-orange);--highlight-color-darker: #B0E8E2;--highlight-color: #DCF9F6;--primary-color-dark: var(--dark-blue);--primary-color: var(--light-blue);--primary-color-light: var(--lighter-blue);--secondary-color-dark: #585B51;--secondary-color: var(--gray);--warning-color-dark: #D2842B;--warning-color: var(--orange);--light-background-color: #FCFDFD;--groupchats-header-color: var(--chatroom-head-bg-color);--groupchats-header-color-dark: var(--chatroom-head-bg-color-dark);--controlbox-width: 250px;--controlbox-head-color: var(--light-blue);--controlbox-head-btn-color: var(--light-blue);--controlbox-heading-color: inherit;--controlbox-heading-font-weight: bold;--controlbox-heading-top-margin: 0.75em;--controlbox-pane-background-color: var(--background);--controlbox-pane-bg-hover-color: #eff4f7;--panel-divider-color: #e7e7e7;--heading-display: block;--heading-color: var(--background);--badge-color: var(--background);--chatroom-color: var(--redder-orange);--chatroom-badge-color: var(--chatroom-head-bg-color);--chatroom-badge-hover-color: var(--chatroom-head-bg-color-dark);--chatroom-correcting-color: #fadfd7;--chatroom-head-bg-color-dark: #D24E2B;--chatroom-head-bg-color: var(--redder-orange);--chatroom-head-border-bottom: 0px;--chatroom-head-button-color: var(--chatroom-head-bg-color);--chatroom-head-color: var(--background);--chatroom-head-description-display: block;--chatroom-head-description-link-color: var(--background);--chatroom-head-fg-color: var(--background);--chatroom-head-title-font-weight: normal;--chatroom-head-title-padding-right: 0px;--muc-toolbar-btn-color: var(--redder-orange);--muc-toolbar-btn-disabled-color: gray;--headlines-color: var(--orange);--headlines-head-text-color: var(--background);--headlines-head-fg-color: var(--background);--headlines-head-bg-color: var(--headlines-color);--headline-message-color: #D2842B;--headline-separator-border-bottom: 2px solid var(--headlines-color);--chatbox-button-size: 14px;--fullpage-chatbox-button-size: 16px;--separator-text-color: var(--message-text-color);--chat-separator-border-bottom: 2px solid var(--chat-color);--chatroom-separator-border-bottom: 2px solid var(--chatroom-head-bg-color);--chatbox-message-input-border-top: 4px solid var(--chat-head-color);--chatroom-message-input-border-top: 4px solid var(--chatroom-head-bg-color);--occupants-background-color: var(--background);--occupants-border-left: 0.2rem solid var(--panel-divider-color);--occupants-border-bottom: 1px solid lightgrey;--fullpage-chat-height: calc(var(--vh, 1vh) * 100);--fullpage-chat-width: 100%;--fullpage-emoji-picker-height: 300px;--fullpage-max-chat-textarea-height: 15em;--overlayed-badge-color: var(--gray);--close-color: var(--text-color);--close-color: #585B51;--list-toggle-color: var(--gray);--list-toggle-hover-color: #585B51;--list-item-hover-color: rgba(0, 0, 0, 0.035);--list-item-action-color: #e3eef3;--list-item-link-color: inherit;--list-item-link-hover-color: var(--dark-link-color);--list-item-open-color: var(--controlbox-head-color);--list-item-open-hover-color: var(--controlbox-head-color);--list-dot-circle-color: #f6dec1;--list-item-action-hover-color: var(--inverse-link-color);--list-group-item-bg-color: var(--background);--chat-msg-hover-color: var(--list-item-hover-color)}.conversejs.theme-concord{--controlbox-pane-background-color: #333;--panel-divider-color: #333;--controlbox-pane-bg-hover-color: #464646;--controlbox-heading-color: #777;--controlbox-heading-font-weight: bold;--groupchats-header-color: var(--redder-orange);--chat-textarea-background-color: #F6F6F6;--chat-correcting-color: #FFFFC0;--controlbox-text-color: #DDD;--chat-info-color: var(--subdued-color);--chatbox-border-radius: 0px;--heading-display: inline;--heading-color: #9B4D;--link-hover-color: var(--light-blue);--chatroom-badge-color: var(--redder-orange);--chatroom-badge-hover-color: #D24E2B;--chatroom-correcting-color: #FFFFC0;--chatroom-head-bg-color: white;--chatroom-head-border-bottom: 1px solid #EEE;--chatroom-head-fg-color: #999;--chatroom-head-color: #7E7E7E;--chatroom-head-description-border-left: 1px solid #DDD;--chatroom-head-description-color: black;--chatroom-head-description-display: inline;--chatroom-head-description-link-color: #00b3f4;--chatroom-head-description-padding-left: 12px;--chatroom-head-title-font-weight: bold;--chatroom-head-title-padding-right: 12px;--muc-toolbar-btn-color: #7E7E7E;--muc-toolbar-btn-disabled-color: lightgray;--occupants-background-color: #F3F3F3;--occupants-border-left: 0px;--occupants-border-bottom: 0px;--separator-text-color: #AAA;--chat-separator-border-bottom: 1px solid #AAA;--chatroom-separator-border-bottom: 1px solid #AAA;--chatroom-message-input-border-top: 1px solid #CCC;--chatbox-message-input-border-top: 1px solid #CCC;--fullpage-chatbox-button-size: 24px;--list-toggle-font-weight: bold;--list-item-link-color: #A1A1A1;--list-item-link-hover-color: #DDD;--list-item-open-color: #444;--list-item-open-hover-color: #444;--unread-msgs-color: #F1F1F1}.conversejs.theme-dracula{--current-line: #44475a;--comment: #6272a4;--cyan: #8be9fd;--green: #50fa7b;--orange: #ffb86c;--pink: #ff79c6;--purple: #bd93f9;--red: #ff5555;--yellow: #f1fa8c;--background: #282a36;--foreground: #f8f8f2;--subdued-color: var(--comment);--muc-color: var(--orange);--chat-color: var(--green);--disabled-color: var(--comment);--error-color: var(--red);--focus-color: var(--comment);--headlines-color: var(--pink);--headlines-head-text-color: var(--headlines-color);--headlines-head-fg-color: var(--headlines-color);--headlines-head-bg-color: var(--background);--headline-message-color: var(--headlines-color);--headline-separator-border-bottom: 2px solid var(--headlines-color);--headlines-head-border-bottom: 0.15em solid var(--headlines-color);--icon-hover-color: var(--cyan);--gray-color: var(--comment);--highlight-color: var(--foreground);--highlight-color-darker: var(--comment);--redder-orange: var(--muc-color);--light-background-color: var(--background);--chat-background-color: var(--background);--chat-content-background-color: var(--background);--chat-textarea-background-color: var(--background);--chat-textarea-disabled-bg-color: var(--disabled-color);--controlbox-pane-background-color: var(--background);--controlbox-pane-bg-hover-color: var(--list-item-hover-color);--chat-msg-hover-color: var(--current-line);--chat-textarea-color: var(--foreground);--close-color: var(--foreground);--close-color-hover: var(--purple);--global-background-color: var(--background);--groupchats-header-color-dark: var(--muc-color);--groupchats-header-color: var(--muc-color);--img-thumbnail-background-color: var(--comment);--img-thumbnail-border-color: black;--modal-background-color: var(--background);--occupants-background-color: var(--background);--raised-el-shadow: 1px 1px 10px black;--badge-color: var(--background);--chatroom-correcting-color: var(--comment);--chatroom-head-bg-color-dark: var(--muc-color);--chatroom-head-bg-color: var(--background);--chatroom-head-border-bottom: 0.15em solid var(--muc-color);--chatroom-head-fg-color: var(--muc-color);--chatroom-head-color: var(--muc-color);--chatroom-head-description-link-color: var(--link-color);--chatroom-message-input-border-top: 0.15em solid var(--muc-color);--chatroom-separator-border-bottom: 0.15em solid var(--muc-color);--muc-toolbar-btn-disabled-color: var(--disabled-color);--occupants-border-left: 0.15em solid var(--muc-color);--occupants-border-bottom: 0.15em solid var(--muc-color);--chat-correcting-color: var(--comment);--chat-head-border-bottom: 0.15em solid var(--chat-color);--chat-head-fg-color: var(--chat-color);--chat-head-color-dark: var(--chat-color);--chat-head-color-darker: var(--chat-color);--chat-head-color-lighten-50-percent: var(--chat-color);--chat-head-color: var(--background);--chat-head-text-color: var(--chat-color);--chat-toolbar-btn-color: var(--chat-color);--chat-toolbar-btn-color: var(--green);--chatbox-message-input-border-top: 0.15em solid var(--chat-color);--toolbar-btn-text-color: var(--background);--unread-msgs-color: var(--yellow);--panel-divider-color: var(--comment);--chat-status-online: var(--green);--chat-status-busy: var(--red);--chat-status-away: var(--orange);--chat-info-color: var(--orange);--brand-heading-color: var(--cyan);--completion-light-color: var(--pink);--completion-normal-color: var(--red);--completion-dark-color: var(--current-line);--button-text-color: var(--background);--button-hover-text-color: var(--background);--controlbox-text-color: var(--foreground);--message-text-color: var(--foreground);--text-color: var(--foreground);--text-color-lighten-15-percent: var(--yellow);--text-color-invert: var(--background);--message-author-color: var(--purple);--controlbox-head-color: var(--purple);--controlbox-head-btn-color: var(--subdued-color);--message-receipt-color: var(--green);--heading-color: var(--purple);--inverse-link-color: var(--foreground);--link-color: var(--cyan);--dark-link-color: var(--cyan);--link-hover-color: var(--green);--primary-color: var(--purple);--primary-color-dark: var(--purple);--primary-color-light: var(--pink);--danger-color-dark: var(--pink);--danger-color: var(--pink);--error-color: var(--red);--info-color: var(--comment);--secondary-color-dark: var(--cyan);--secondary-color: var(--cyan);--warning-color-dark: var(--orange);--warning-color: var(--orange);--list-toggle-color: var(--comment);--list-toggle-hover-color: var(--comment);--list-item-hover-color: var(--current-line);--list-item-action-color: var(--comment);--list-item-link-color: var(--foreground);--list-item-link-hover-color: var(--link-color);--list-item-open-color: var(--current-line);--list-item-open-hover-color: var(--current-line);--list-dot-circle-color: var(--orange);--list-item-action-hover-color: var(--cyan);--list-group-item-bg-color: var(--comment)}.conversejs{color:var(--text-color);font-family:var(--normal-font);font-size:var(--font-size);direction:ltr}.conversejs .flyout{position:absolute}.conversejs .img-thumbnail{background-color:var(--img-thumbnail-background-color);border:1px solid var(--img-thumbnail-border-color)}.conversejs textarea:disabled{background-color:var(--chat-textarea-disabled-bg-color) !important}.conversejs .subdued{opacity:.35}.conversejs .close{color:var(--close-color);text-shadow:none}.conversejs .close:hover{color:var(--close-color-hover)}.conversejs .fit-content{width:-moz-fit-content !important;width:fit-content !important;max-width:-moz-fit-content !important;max-width:fit-content !important}.conversejs .nopadding{padding:0 !important}.conversejs .no-scrolling{overflow-x:none;overflow-y:none}.conversejs converse-brand-heading{text-align:center}.conversejs .brand-heading{display:inline-flex;flex-direction:row;align-items:flex-start;font-family:var(--branding-font);color:var(--link-color);margin-bottom:.75em}.conversejs .brand-heading .brand-name-wrapper{display:flex;white-space:nowrap;margin:auto}.conversejs .brand-heading .brand-name{color:var(--link-color);display:flex;flex-direction:column;align-items:center;margin-top:-0.25em}.conversejs .brand-heading .brand-name .byline{font-family:var(--heading-font);font-size:.3em;margin-bottom:.75em;margin-left:-2.7em;opacity:.55;word-spacing:5px}.conversejs .brand-heading .brand-subtitle{color:var(--text-color)}.conversejs .brand-heading .brand-name__text{font-size:120%;vertical-align:text-bottom}.conversejs .brand-heading .converse-svg-logo{color:var(--link-color);height:1.5em;margin-right:.25em;margin-bottom:-0.25em}.conversejs .brand-heading .converse-svg-logo .cls-1{isolation:isolate}.conversejs .brand-heading .converse-svg-logo .cls-2{opacity:.5;mix-blend-mode:multiply}.conversejs .brand-heading .converse-svg-logo .cls-3{fill:var(--link-color)}.conversejs .brand-heading .converse-svg-logo .cls-4{fill:var(--link-color)}.conversejs .brand-heading--inverse .converse-svg-logo{margin-bottom:0em;margin-top:-0.2em}.conversejs .brand-heading--inverse .byline{margin:0;font-family:var(--heading-font);font-size:.25em;opacity:.55;margin-left:-7em;word-spacing:5px}.conversejs .popover{position:fixed}.conversejs ::-moz-placeholder{color:var(--subdued-color)}.conversejs ::placeholder{color:var(--subdued-color)}.conversejs ::-moz-selection{background-color:var(--highlight-color)}.conversejs ::selection{background-color:var(--highlight-color)}.conversejs ::-moz-selection{background-color:var(--highlight-color)}@media screen and (max-width: 480px){.conversejs{margin:0;right:10px;left:10px;bottom:5px}}@media screen and (max-height: 450px){.conversejs{margin:0;right:10px;left:10px;bottom:5px}}.conversejs ul li{height:auto}.conversejs div,.conversejs span,.conversejs h1,.conversejs h2,.conversejs h3,.conversejs h4,.conversejs h5,.conversejs h6,.conversejs p,.conversejs blockquote,.conversejs pre,.conversejs a,.conversejs em,.conversejs img,.conversejs strong,.conversejs dl,.conversejs dt,.conversejs dd,.conversejs ol,.conversejs ul,.conversejs li,.conversejs fieldset,.conversejs form,.conversejs legend,.conversejs table,.conversejs caption,.conversejs tbody,.conversejs tfoot,.conversejs thead,.conversejs tr,.conversejs th,.conversejs td,.conversejs article,.conversejs aside,.conversejs details,.conversejs embed,.conversejs figure,.conversejs figcaption,.conversejs footer,.conversejs header,.conversejs hgroup,.conversejs menu,.conversejs nav,.conversejs output,.conversejs ruby,.conversejs section,.conversejs summary,.conversejs time,.conversejs mark,.conversejs audio,.conversejs video{margin:0;padding:0;border:0;font:inherit;vertical-align:baseline}.conversejs textarea,.conversejs input[type=submit],.conversejs input[type=button],.conversejs input[type=text],.conversejs input[type=password],.conversejs button{font-size:var(--font-size);min-height:0}.conversejs strong{font-weight:700}.conversejs em{font-style:italic}.conversejs ol,.conversejs ul{list-style:none}.conversejs li{height:10px}.conversejs ul,.conversejs ol,.conversejs dl{font:inherit;margin:0}.conversejs a{cursor:pointer}.conversejs a,.conversejs a:visited,.conversejs a:not([href]):not([tabindex]),.conversejs .clickable{text-decoration:none;color:var(--link-color);text-shadow:none;cursor:pointer}.conversejs a:hover,.conversejs a:visited:hover,.conversejs a:not([href]):not([tabindex]):hover,.conversejs .clickable:hover{color:var(--link-hover-color);text-decoration:none;text-shadow:none}.conversejs a.fa,.conversejs a.far,.conversejs a.fas,.conversejs a:visited.fa,.conversejs a:visited.far,.conversejs a:visited.fas,.conversejs a:not([href]):not([tabindex]).fa,.conversejs a:not([href]):not([tabindex]).far,.conversejs a:not([href]):not([tabindex]).fas,.conversejs .clickable.fa,.conversejs .clickable.far,.conversejs .clickable.fas{color:var(--subdued-color)}.conversejs a.fa:hover,.conversejs a.far:hover,.conversejs a.fas:hover,.conversejs a:visited.fa:hover,.conversejs a:visited.far:hover,.conversejs a:visited.fas:hover,.conversejs a:not([href]):not([tabindex]).fa:hover,.conversejs a:not([href]):not([tabindex]).far:hover,.conversejs a:not([href]):not([tabindex]).fas:hover,.conversejs .clickable.fa:hover,.conversejs .clickable.far:hover,.conversejs .clickable.fas:hover{color:var(--icon-hover-color)}.conversejs .clickable:hover{cursor:pointer}.conversejs svg{border-radius:var(--chatbox-border-radius)}.conversejs .fa,.conversejs .far,.conversejs .fas{color:var(--subdued-color)}.conversejs q{quotes:"“" "”" "‘" "’"}.conversejs q.reason{display:inline}.conversejs q:before{content:open-quote}.conversejs q:after{content:close-quote}.conversejs .helptext{font-size:var(--font-size-tiny);color:var(--text-color-lighten-15-percent)}.conversejs .selected{color:var(--link-color) !important}.conversejs .selected svg{fill:var(--link-color)}.conversejs .circle{border-radius:50%}.conversejs .no-text-select{-webkit-touch-callout:none;-webkit-user-select:none;-moz-user-select:none;user-select:none}@keyframes colorchange-chatmessage{0%{background-color:#8dd8ae}25%{background-color:rgba(141,216,174,.75)}50%{background-color:rgba(141,216,174,.5)}75%{background-color:rgba(141,216,174,.25)}100%{background-color:rgba(0,0,0,0)}}@keyframes colorchange-chatmessage-muc{0%{background-color:#ffb5a2}25%{background-color:rgba(255,181,162,.75)}50%{background-color:rgba(255,181,162,.5)}75%{background-color:rgba(255,181,162,.25)}100%{background-color:rgba(0,0,0,0)}}@keyframes fadein{0%{opacity:0}100%{opacity:1}}@keyframes fadeOut{0%{opacity:1;visibility:visible}100%{opacity:0;visibility:hidden}}.conversejs .fade-in{opacity:0;animation-name:fadein;animation-fill-mode:forwards;animation-duration:.5s;animation-timing-function:ease}.conversejs .visible{opacity:0;animation-name:fadein;animation-fill-mode:forwards;animation-duration:500ms;animation-timing-function:ease}.conversejs .hidden{opacity:0 !important;display:none !important}.conversejs .fade-out{animation-duration:.5s;animation-fill-mode:forwards;animation-name:fadeOut;animation-timing-function:ease-in-out}.conversejs .collapsed{height:0 !important;overflow:hidden !important;padding:0 !important}.conversejs .locked{padding-right:22px}@keyframes spin{from{transform:rotate(0deg)}to{transform:rotate(359deg)}}.conversejs .left{float:left}.conversejs .right{float:right}.conversejs .centered{text-align:center;display:block;margin:auto}.conversejs .hor_centered{text-align:center;display:block !important;margin:0 auto;clear:both}.conversejs .error{color:var(--error-color) !important}.conversejs .info{color:var(--info-color)}.conversejs .reg-feedback{font-size:85%;margin-bottom:1em}.conversejs .reg-feedback,.conversejs #converse-login .conn-feedback{display:block;text-align:center;width:100%}.conversejs .avatar-autocomplete{margin-right:.5em;vertical-align:middle}.conversejs .activated{display:block !important}.conversejs .form-help{color:var(--subdued-color);font-size:90%}.conversejs .nav-pills .nav-link.active,.conversejs .nav-pills .show>.nav-link{background-color:var(--primary-color)}@media screen and (max-width: 575px){body .converse-brand{font-size:3.75em}.conversejs:not(.converse-embedded) .chatbox .chat-body{border-radius:var(--chatbox-border-radius)}.conversejs:not(.converse-embedded) .flyout{border-radius:var(--chatbox-border-radius)}}@media screen and (min-width: 576px){.conversejs .offset-sm-2{margin-left:16.666667%}}@media screen and (min-width: 768px){.conversejs .offset-md-2{margin-left:16.666667%}.conversejs .offset-md-3{margin-left:25%}}@media screen and (min-width: 992px){.conversejs .offset-lg-2{margin-left:16.666667%}.conversejs .offset-lg-3{margin-left:25%}}@media screen and (min-width: 1200px){.conversejs .offset-xl-2{margin-left:16.666667%}}@media screen and (max-height: 450px){.conversejs{left:0}}.conversejs .alert-info h3,.conversejs .alert-danger h3{color:var(--background);font-size:large}.conversejs .alert-info .modal-title,.conversejs .alert-danger .modal-title{font-size:110%}.conversejs .alert-info .close,.conversejs .alert-danger .close{color:var(--background)}.conversejs .alert-info{color:var(--background);background-color:var(--primary-color);border-color:var(--primary-color-dark)}.conversejs .alert-danger{color:var(--background);border-color:var(--danger-color-dark);background-color:var(--danger-color)}.conversejs .alert-danger .disconnect-msg{color:var(--background) !important}.conversejs .spinner__container{width:100%}.conversejs .spinner{animation:spin 2s infinite,linear;width:1em;display:block;text-align:center;padding:.5em 0;font-size:24px}.conversejs .spinner svg{fill:var(--primary-color)}.conversejs .btn{display:inline-block;font-weight:400;color:#212529;text-align:center;vertical-align:middle;-webkit-user-select:none;-moz-user-select:none;user-select:none;background-color:rgba(0,0,0,0);border:1px solid rgba(0,0,0,0);padding:.375rem .75rem;font-size:1rem;line-height:1.5;border-radius:.25rem;transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media(prefers-reduced-motion: reduce){.conversejs .btn{transition:none}}.conversejs .btn:hover{color:#212529;text-decoration:none}.conversejs .btn:focus,.conversejs .btn.focus{outline:0;box-shadow:0 0 0 .2rem rgba(0,123,255,.25)}.conversejs .btn.disabled,.conversejs .btn:disabled{opacity:.65}.conversejs .btn:not(:disabled):not(.disabled){cursor:pointer}.conversejs a.btn.disabled,.conversejs fieldset:disabled a.btn{pointer-events:none}.conversejs .btn-primary{color:#fff;background-color:#007bff;border-color:#007bff}.conversejs .btn-primary:hover{color:#fff;background-color:#0069d9;border-color:#0062cc}.conversejs .btn-primary:focus,.conversejs .btn-primary.focus{color:#fff;background-color:#0069d9;border-color:#0062cc;box-shadow:0 0 0 .2rem rgba(38,143,255,.5)}.conversejs .btn-primary.disabled,.conversejs .btn-primary:disabled{color:#fff;background-color:#007bff;border-color:#007bff}.conversejs .btn-primary:not(:disabled):not(.disabled):active,.conversejs .btn-primary:not(:disabled):not(.disabled).active,.show>.conversejs .btn-primary.dropdown-toggle{color:#fff;background-color:#0062cc;border-color:#005cbf}.conversejs .btn-primary:not(:disabled):not(.disabled):active:focus,.conversejs .btn-primary:not(:disabled):not(.disabled).active:focus,.show>.conversejs .btn-primary.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(38,143,255,.5)}.conversejs .btn-secondary{color:#fff;background-color:#6c757d;border-color:#6c757d}.conversejs .btn-secondary:hover{color:#fff;background-color:#5a6268;border-color:#545b62}.conversejs .btn-secondary:focus,.conversejs .btn-secondary.focus{color:#fff;background-color:#5a6268;border-color:#545b62;box-shadow:0 0 0 .2rem rgba(130,138,145,.5)}.conversejs .btn-secondary.disabled,.conversejs .btn-secondary:disabled{color:#fff;background-color:#6c757d;border-color:#6c757d}.conversejs .btn-secondary:not(:disabled):not(.disabled):active,.conversejs .btn-secondary:not(:disabled):not(.disabled).active,.show>.conversejs .btn-secondary.dropdown-toggle{color:#fff;background-color:#545b62;border-color:#4e555b}.conversejs .btn-secondary:not(:disabled):not(.disabled):active:focus,.conversejs .btn-secondary:not(:disabled):not(.disabled).active:focus,.show>.conversejs .btn-secondary.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(130,138,145,.5)}.conversejs .btn-success{color:#fff;background-color:#28a745;border-color:#28a745}.conversejs .btn-success:hover{color:#fff;background-color:#218838;border-color:#1e7e34}.conversejs .btn-success:focus,.conversejs .btn-success.focus{color:#fff;background-color:#218838;border-color:#1e7e34;box-shadow:0 0 0 .2rem rgba(72,180,97,.5)}.conversejs .btn-success.disabled,.conversejs .btn-success:disabled{color:#fff;background-color:#28a745;border-color:#28a745}.conversejs .btn-success:not(:disabled):not(.disabled):active,.conversejs .btn-success:not(:disabled):not(.disabled).active,.show>.conversejs .btn-success.dropdown-toggle{color:#fff;background-color:#1e7e34;border-color:#1c7430}.conversejs .btn-success:not(:disabled):not(.disabled):active:focus,.conversejs .btn-success:not(:disabled):not(.disabled).active:focus,.show>.conversejs .btn-success.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(72,180,97,.5)}.conversejs .btn-info{color:#fff;background-color:#17a2b8;border-color:#17a2b8}.conversejs .btn-info:hover{color:#fff;background-color:#138496;border-color:#117a8b}.conversejs .btn-info:focus,.conversejs .btn-info.focus{color:#fff;background-color:#138496;border-color:#117a8b;box-shadow:0 0 0 .2rem rgba(58,176,195,.5)}.conversejs .btn-info.disabled,.conversejs .btn-info:disabled{color:#fff;background-color:#17a2b8;border-color:#17a2b8}.conversejs .btn-info:not(:disabled):not(.disabled):active,.conversejs .btn-info:not(:disabled):not(.disabled).active,.show>.conversejs .btn-info.dropdown-toggle{color:#fff;background-color:#117a8b;border-color:#10707f}.conversejs .btn-info:not(:disabled):not(.disabled):active:focus,.conversejs .btn-info:not(:disabled):not(.disabled).active:focus,.show>.conversejs .btn-info.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(58,176,195,.5)}.conversejs .btn-warning{color:#212529;background-color:#ffc107;border-color:#ffc107}.conversejs .btn-warning:hover{color:#212529;background-color:#e0a800;border-color:#d39e00}.conversejs .btn-warning:focus,.conversejs .btn-warning.focus{color:#212529;background-color:#e0a800;border-color:#d39e00;box-shadow:0 0 0 .2rem rgba(222,170,12,.5)}.conversejs .btn-warning.disabled,.conversejs .btn-warning:disabled{color:#212529;background-color:#ffc107;border-color:#ffc107}.conversejs .btn-warning:not(:disabled):not(.disabled):active,.conversejs .btn-warning:not(:disabled):not(.disabled).active,.show>.conversejs .btn-warning.dropdown-toggle{color:#212529;background-color:#d39e00;border-color:#c69500}.conversejs .btn-warning:not(:disabled):not(.disabled):active:focus,.conversejs .btn-warning:not(:disabled):not(.disabled).active:focus,.show>.conversejs .btn-warning.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(222,170,12,.5)}.conversejs .btn-danger{color:#fff;background-color:#dc3545;border-color:#dc3545}.conversejs .btn-danger:hover{color:#fff;background-color:#c82333;border-color:#bd2130}.conversejs .btn-danger:focus,.conversejs .btn-danger.focus{color:#fff;background-color:#c82333;border-color:#bd2130;box-shadow:0 0 0 .2rem rgba(225,83,97,.5)}.conversejs .btn-danger.disabled,.conversejs .btn-danger:disabled{color:#fff;background-color:#dc3545;border-color:#dc3545}.conversejs .btn-danger:not(:disabled):not(.disabled):active,.conversejs .btn-danger:not(:disabled):not(.disabled).active,.show>.conversejs .btn-danger.dropdown-toggle{color:#fff;background-color:#bd2130;border-color:#b21f2d}.conversejs .btn-danger:not(:disabled):not(.disabled):active:focus,.conversejs .btn-danger:not(:disabled):not(.disabled).active:focus,.show>.conversejs .btn-danger.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(225,83,97,.5)}.conversejs .btn-light{color:#212529;background-color:#f8f9fa;border-color:#f8f9fa}.conversejs .btn-light:hover{color:#212529;background-color:#e2e6ea;border-color:#dae0e5}.conversejs .btn-light:focus,.conversejs .btn-light.focus{color:#212529;background-color:#e2e6ea;border-color:#dae0e5;box-shadow:0 0 0 .2rem rgba(216,217,219,.5)}.conversejs .btn-light.disabled,.conversejs .btn-light:disabled{color:#212529;background-color:#f8f9fa;border-color:#f8f9fa}.conversejs .btn-light:not(:disabled):not(.disabled):active,.conversejs .btn-light:not(:disabled):not(.disabled).active,.show>.conversejs .btn-light.dropdown-toggle{color:#212529;background-color:#dae0e5;border-color:#d3d9df}.conversejs .btn-light:not(:disabled):not(.disabled):active:focus,.conversejs .btn-light:not(:disabled):not(.disabled).active:focus,.show>.conversejs .btn-light.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(216,217,219,.5)}.conversejs .btn-dark{color:#fff;background-color:#343a40;border-color:#343a40}.conversejs .btn-dark:hover{color:#fff;background-color:#23272b;border-color:#1d2124}.conversejs .btn-dark:focus,.conversejs .btn-dark.focus{color:#fff;background-color:#23272b;border-color:#1d2124;box-shadow:0 0 0 .2rem rgba(82,88,93,.5)}.conversejs .btn-dark.disabled,.conversejs .btn-dark:disabled{color:#fff;background-color:#343a40;border-color:#343a40}.conversejs .btn-dark:not(:disabled):not(.disabled):active,.conversejs .btn-dark:not(:disabled):not(.disabled).active,.show>.conversejs .btn-dark.dropdown-toggle{color:#fff;background-color:#1d2124;border-color:#171a1d}.conversejs .btn-dark:not(:disabled):not(.disabled):active:focus,.conversejs .btn-dark:not(:disabled):not(.disabled).active:focus,.show>.conversejs .btn-dark.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(82,88,93,.5)}.conversejs .btn-outline-primary{color:#007bff;border-color:#007bff}.conversejs .btn-outline-primary:hover{color:#fff;background-color:#007bff;border-color:#007bff}.conversejs .btn-outline-primary:focus,.conversejs .btn-outline-primary.focus{box-shadow:0 0 0 .2rem rgba(0,123,255,.5)}.conversejs .btn-outline-primary.disabled,.conversejs .btn-outline-primary:disabled{color:#007bff;background-color:rgba(0,0,0,0)}.conversejs .btn-outline-primary:not(:disabled):not(.disabled):active,.conversejs .btn-outline-primary:not(:disabled):not(.disabled).active,.show>.conversejs .btn-outline-primary.dropdown-toggle{color:#fff;background-color:#007bff;border-color:#007bff}.conversejs .btn-outline-primary:not(:disabled):not(.disabled):active:focus,.conversejs .btn-outline-primary:not(:disabled):not(.disabled).active:focus,.show>.conversejs .btn-outline-primary.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(0,123,255,.5)}.conversejs .btn-outline-secondary{color:#6c757d;border-color:#6c757d}.conversejs .btn-outline-secondary:hover{color:#fff;background-color:#6c757d;border-color:#6c757d}.conversejs .btn-outline-secondary:focus,.conversejs .btn-outline-secondary.focus{box-shadow:0 0 0 .2rem rgba(108,117,125,.5)}.conversejs .btn-outline-secondary.disabled,.conversejs .btn-outline-secondary:disabled{color:#6c757d;background-color:rgba(0,0,0,0)}.conversejs .btn-outline-secondary:not(:disabled):not(.disabled):active,.conversejs .btn-outline-secondary:not(:disabled):not(.disabled).active,.show>.conversejs .btn-outline-secondary.dropdown-toggle{color:#fff;background-color:#6c757d;border-color:#6c757d}.conversejs .btn-outline-secondary:not(:disabled):not(.disabled):active:focus,.conversejs .btn-outline-secondary:not(:disabled):not(.disabled).active:focus,.show>.conversejs .btn-outline-secondary.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(108,117,125,.5)}.conversejs .btn-outline-success{color:#28a745;border-color:#28a745}.conversejs .btn-outline-success:hover{color:#fff;background-color:#28a745;border-color:#28a745}.conversejs .btn-outline-success:focus,.conversejs .btn-outline-success.focus{box-shadow:0 0 0 .2rem rgba(40,167,69,.5)}.conversejs .btn-outline-success.disabled,.conversejs .btn-outline-success:disabled{color:#28a745;background-color:rgba(0,0,0,0)}.conversejs .btn-outline-success:not(:disabled):not(.disabled):active,.conversejs .btn-outline-success:not(:disabled):not(.disabled).active,.show>.conversejs .btn-outline-success.dropdown-toggle{color:#fff;background-color:#28a745;border-color:#28a745}.conversejs .btn-outline-success:not(:disabled):not(.disabled):active:focus,.conversejs .btn-outline-success:not(:disabled):not(.disabled).active:focus,.show>.conversejs .btn-outline-success.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(40,167,69,.5)}.conversejs .btn-outline-info{color:#17a2b8;border-color:#17a2b8}.conversejs .btn-outline-info:hover{color:#fff;background-color:#17a2b8;border-color:#17a2b8}.conversejs .btn-outline-info:focus,.conversejs .btn-outline-info.focus{box-shadow:0 0 0 .2rem rgba(23,162,184,.5)}.conversejs .btn-outline-info.disabled,.conversejs .btn-outline-info:disabled{color:#17a2b8;background-color:rgba(0,0,0,0)}.conversejs .btn-outline-info:not(:disabled):not(.disabled):active,.conversejs .btn-outline-info:not(:disabled):not(.disabled).active,.show>.conversejs .btn-outline-info.dropdown-toggle{color:#fff;background-color:#17a2b8;border-color:#17a2b8}.conversejs .btn-outline-info:not(:disabled):not(.disabled):active:focus,.conversejs .btn-outline-info:not(:disabled):not(.disabled).active:focus,.show>.conversejs .btn-outline-info.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(23,162,184,.5)}.conversejs .btn-outline-warning{color:#ffc107;border-color:#ffc107}.conversejs .btn-outline-warning:hover{color:#212529;background-color:#ffc107;border-color:#ffc107}.conversejs .btn-outline-warning:focus,.conversejs .btn-outline-warning.focus{box-shadow:0 0 0 .2rem rgba(255,193,7,.5)}.conversejs .btn-outline-warning.disabled,.conversejs .btn-outline-warning:disabled{color:#ffc107;background-color:rgba(0,0,0,0)}.conversejs .btn-outline-warning:not(:disabled):not(.disabled):active,.conversejs .btn-outline-warning:not(:disabled):not(.disabled).active,.show>.conversejs .btn-outline-warning.dropdown-toggle{color:#212529;background-color:#ffc107;border-color:#ffc107}.conversejs .btn-outline-warning:not(:disabled):not(.disabled):active:focus,.conversejs .btn-outline-warning:not(:disabled):not(.disabled).active:focus,.show>.conversejs .btn-outline-warning.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(255,193,7,.5)}.conversejs .btn-outline-danger{color:#dc3545;border-color:#dc3545}.conversejs .btn-outline-danger:hover{color:#fff;background-color:#dc3545;border-color:#dc3545}.conversejs .btn-outline-danger:focus,.conversejs .btn-outline-danger.focus{box-shadow:0 0 0 .2rem rgba(220,53,69,.5)}.conversejs .btn-outline-danger.disabled,.conversejs .btn-outline-danger:disabled{color:#dc3545;background-color:rgba(0,0,0,0)}.conversejs .btn-outline-danger:not(:disabled):not(.disabled):active,.conversejs .btn-outline-danger:not(:disabled):not(.disabled).active,.show>.conversejs .btn-outline-danger.dropdown-toggle{color:#fff;background-color:#dc3545;border-color:#dc3545}.conversejs .btn-outline-danger:not(:disabled):not(.disabled):active:focus,.conversejs .btn-outline-danger:not(:disabled):not(.disabled).active:focus,.show>.conversejs .btn-outline-danger.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(220,53,69,.5)}.conversejs .btn-outline-light{color:#f8f9fa;border-color:#f8f9fa}.conversejs .btn-outline-light:hover{color:#212529;background-color:#f8f9fa;border-color:#f8f9fa}.conversejs .btn-outline-light:focus,.conversejs .btn-outline-light.focus{box-shadow:0 0 0 .2rem rgba(248,249,250,.5)}.conversejs .btn-outline-light.disabled,.conversejs .btn-outline-light:disabled{color:#f8f9fa;background-color:rgba(0,0,0,0)}.conversejs .btn-outline-light:not(:disabled):not(.disabled):active,.conversejs .btn-outline-light:not(:disabled):not(.disabled).active,.show>.conversejs .btn-outline-light.dropdown-toggle{color:#212529;background-color:#f8f9fa;border-color:#f8f9fa}.conversejs .btn-outline-light:not(:disabled):not(.disabled):active:focus,.conversejs .btn-outline-light:not(:disabled):not(.disabled).active:focus,.show>.conversejs .btn-outline-light.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(248,249,250,.5)}.conversejs .btn-outline-dark{color:#343a40;border-color:#343a40}.conversejs .btn-outline-dark:hover{color:#fff;background-color:#343a40;border-color:#343a40}.conversejs .btn-outline-dark:focus,.conversejs .btn-outline-dark.focus{box-shadow:0 0 0 .2rem rgba(52,58,64,.5)}.conversejs .btn-outline-dark.disabled,.conversejs .btn-outline-dark:disabled{color:#343a40;background-color:rgba(0,0,0,0)}.conversejs .btn-outline-dark:not(:disabled):not(.disabled):active,.conversejs .btn-outline-dark:not(:disabled):not(.disabled).active,.show>.conversejs .btn-outline-dark.dropdown-toggle{color:#fff;background-color:#343a40;border-color:#343a40}.conversejs .btn-outline-dark:not(:disabled):not(.disabled):active:focus,.conversejs .btn-outline-dark:not(:disabled):not(.disabled).active:focus,.show>.conversejs .btn-outline-dark.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(52,58,64,.5)}.conversejs .btn-link{font-weight:400;color:#007bff;text-decoration:none}.conversejs .btn-link:hover{color:#0056b3;text-decoration:underline}.conversejs .btn-link:focus,.conversejs .btn-link.focus{text-decoration:underline}.conversejs .btn-link:disabled,.conversejs .btn-link.disabled{color:#6c757d;pointer-events:none}.conversejs .btn-lg,.conversejs .btn-group-lg>.btn{padding:.5rem 1rem;font-size:1.25rem;line-height:1.5;border-radius:.3rem}.conversejs .btn-sm,.conversejs .btn-group-sm>.btn{padding:.25rem .5rem;font-size:0.875rem;line-height:1.5;border-radius:.2rem}.conversejs .btn-block{display:block;width:100%}.conversejs .btn-block+.btn-block{margin-top:.5rem}.conversejs input[type=submit].btn-block,.conversejs input[type=reset].btn-block,.conversejs input[type=button].btn-block{width:100%}.conversejs .btn-group,.conversejs .btn-group-vertical{position:relative;display:inline-flex;vertical-align:middle}.conversejs .btn-group>.btn,.conversejs .btn-group-vertical>.btn{position:relative;flex:1 1 auto}.conversejs .btn-group>.btn:hover,.conversejs .btn-group-vertical>.btn:hover{z-index:1}.conversejs .btn-group>.btn:focus,.conversejs .btn-group>.btn:active,.conversejs .btn-group>.btn.active,.conversejs .btn-group-vertical>.btn:focus,.conversejs .btn-group-vertical>.btn:active,.conversejs .btn-group-vertical>.btn.active{z-index:1}.conversejs .btn-toolbar{display:flex;flex-wrap:wrap;justify-content:flex-start}.conversejs .btn-toolbar .input-group{width:auto}.conversejs .btn-group>.btn:not(:first-child),.conversejs .btn-group>.btn-group:not(:first-child){margin-left:-1px}.conversejs .btn-group>.btn:not(:last-child):not(.dropdown-toggle),.conversejs .btn-group>.btn-group:not(:last-child)>.btn{border-top-right-radius:0;border-bottom-right-radius:0}.conversejs .btn-group>.btn:not(:first-child),.conversejs .btn-group>.btn-group:not(:first-child)>.btn{border-top-left-radius:0;border-bottom-left-radius:0}.conversejs .dropdown-toggle-split{padding-right:.5625rem;padding-left:.5625rem}.conversejs .dropdown-toggle-split::after,.dropup .conversejs .dropdown-toggle-split::after,.dropright .conversejs .dropdown-toggle-split::after{margin-left:0}.dropleft .conversejs .dropdown-toggle-split::before{margin-right:0}.conversejs .btn-sm+.dropdown-toggle-split,.conversejs .btn-group-sm>.btn+.dropdown-toggle-split{padding-right:.375rem;padding-left:.375rem}.conversejs .btn-lg+.dropdown-toggle-split,.conversejs .btn-group-lg>.btn+.dropdown-toggle-split{padding-right:.75rem;padding-left:.75rem}.conversejs .btn-group-vertical{flex-direction:column;align-items:flex-start;justify-content:center}.conversejs .btn-group-vertical>.btn,.conversejs .btn-group-vertical>.btn-group{width:100%}.conversejs .btn-group-vertical>.btn:not(:first-child),.conversejs .btn-group-vertical>.btn-group:not(:first-child){margin-top:-1px}.conversejs .btn-group-vertical>.btn:not(:last-child):not(.dropdown-toggle),.conversejs .btn-group-vertical>.btn-group:not(:last-child)>.btn{border-bottom-right-radius:0;border-bottom-left-radius:0}.conversejs .btn-group-vertical>.btn:not(:first-child),.conversejs .btn-group-vertical>.btn-group:not(:first-child)>.btn{border-top-left-radius:0;border-top-right-radius:0}.conversejs .btn-group-toggle>.btn,.conversejs .btn-group-toggle>.btn-group>.btn{margin-bottom:0}.conversejs .btn-group-toggle>.btn input[type=radio],.conversejs .btn-group-toggle>.btn input[type=checkbox],.conversejs .btn-group-toggle>.btn-group>.btn input[type=radio],.conversejs .btn-group-toggle>.btn-group>.btn input[type=checkbox]{position:absolute;clip:rect(0, 0, 0, 0);pointer-events:none}.conversejs .btn{font-weight:normal;color:var(--button-text-color)}.conversejs .btn:hover{color:var(--button-hover-text-color)}.conversejs .btn.fa{color:var(--button-text-color) !important}.conversejs .btn i.fa,.conversejs .btn i.far,.conversejs .btn i.fas{color:var(--button-text-color);margin-right:.5em}.conversejs .btn i.fa.only-icon,.conversejs .btn i.far.only-icon,.conversejs .btn i.fas.only-icon{margin-right:0}.conversejs .btn converse-icon{display:inline-block;margin-right:0}.conversejs .btn-primary{background-color:var(--primary-color) !important;border-color:rgba(0,0,0,0) !important}.conversejs .btn-primary:focus,.conversejs .btn-primary:hover,.conversejs .btn-primary:active{color:var(--button-text-color);background-color:var(--primary-color-dark) !important;border-color:rgba(0,0,0,0) !important}.conversejs .btn--transparent{background:rgba(0,0,0,0);border:none}.conversejs .btn-circle{width:30px;height:30px;text-align:center;padding:.5em 0;font-size:var(--font-size-small);line-height:1.428571429;border-radius:50%}.conversejs .btn-info,.conversejs .badge-info{background-color:var(--primary-color);border-color:var(--primary-color)}.conversejs .btn-info:hover,.conversejs .badge-info:hover{background-color:var(--primary-color-dark);border-color:var(--primary-color-dark)}.conversejs .button-cancel,.conversejs .btn-secondary,.conversejs .badge-secondary{color:var(--button-text-color);background-color:var(--secondary-color);border-color:var(--secondary-color)}.conversejs .button-cancel:hover,.conversejs .btn-secondary:hover,.conversejs .badge-secondary:hover{background-color:var(--secondary-color-dark);border-color:var(--secondary-color-dark)}.conversejs .btn-warning{color:var(--button-text-color);background-color:var(--warning-color);border-color:var(--warning-color)}.conversejs .btn-warning:hover{color:var(--button-text-color);background-color:var(--warning-color-dark);border-color:var(--warning-color-dark)}.conversejs .btn-danger{color:var(--button-text-color);background-color:var(--danger-color);border-color:var(--danger-color) !important}.conversejs .btn-danger:hover{background-color:var(--danger-color-dark);border-color:var(--danger-color-dark)}.conversejs .badge{display:inline-block;padding:.25em .4em;font-size:75%;font-weight:700;line-height:1;text-align:center;white-space:nowrap;vertical-align:baseline;border-radius:.25rem;transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media(prefers-reduced-motion: reduce){.conversejs .badge{transition:none}}a.conversejs .badge:hover,a.conversejs .badge:focus{text-decoration:none}.conversejs .badge:empty{display:none}.conversejs .btn .badge{position:relative;top:-1px}.conversejs .badge-pill{padding-right:.6em;padding-left:.6em;border-radius:10rem}.conversejs .badge-primary{color:#fff;background-color:#007bff}a.conversejs .badge-primary:hover,a.conversejs .badge-primary:focus{color:#fff;background-color:#0062cc}a.conversejs .badge-primary:focus,a.conversejs .badge-primary.focus{outline:0;box-shadow:0 0 0 .2rem rgba(0,123,255,.5)}.conversejs .badge-secondary{color:#fff;background-color:#6c757d}a.conversejs .badge-secondary:hover,a.conversejs .badge-secondary:focus{color:#fff;background-color:#545b62}a.conversejs .badge-secondary:focus,a.conversejs .badge-secondary.focus{outline:0;box-shadow:0 0 0 .2rem rgba(108,117,125,.5)}.conversejs .badge-success{color:#fff;background-color:#28a745}a.conversejs .badge-success:hover,a.conversejs .badge-success:focus{color:#fff;background-color:#1e7e34}a.conversejs .badge-success:focus,a.conversejs .badge-success.focus{outline:0;box-shadow:0 0 0 .2rem rgba(40,167,69,.5)}.conversejs .badge-info{color:#fff;background-color:#17a2b8}a.conversejs .badge-info:hover,a.conversejs .badge-info:focus{color:#fff;background-color:#117a8b}a.conversejs .badge-info:focus,a.conversejs .badge-info.focus{outline:0;box-shadow:0 0 0 .2rem rgba(23,162,184,.5)}.conversejs .badge-warning{color:#212529;background-color:#ffc107}a.conversejs .badge-warning:hover,a.conversejs .badge-warning:focus{color:#212529;background-color:#d39e00}a.conversejs .badge-warning:focus,a.conversejs .badge-warning.focus{outline:0;box-shadow:0 0 0 .2rem rgba(255,193,7,.5)}.conversejs .badge-danger{color:#fff;background-color:#dc3545}a.conversejs .badge-danger:hover,a.conversejs .badge-danger:focus{color:#fff;background-color:#bd2130}a.conversejs .badge-danger:focus,a.conversejs .badge-danger.focus{outline:0;box-shadow:0 0 0 .2rem rgba(220,53,69,.5)}.conversejs .badge-light{color:#212529;background-color:#f8f9fa}a.conversejs .badge-light:hover,a.conversejs .badge-light:focus{color:#212529;background-color:#dae0e5}a.conversejs .badge-light:focus,a.conversejs .badge-light.focus{outline:0;box-shadow:0 0 0 .2rem rgba(248,249,250,.5)}.conversejs .badge-dark{color:#fff;background-color:#343a40}a.conversejs .badge-dark:hover,a.conversejs .badge-dark:focus{color:#fff;background-color:#1d2124}a.conversejs .badge-dark:focus,a.conversejs .badge-dark.focus{outline:0;box-shadow:0 0 0 .2rem rgba(52,58,64,.5)}.conversejs .badge{color:var(--badge-color);font-size:90%;font-weight:normal;line-height:1;text-shadow:none}.conversejs .badge-light{color:var(--text-color)}.conversejs .badge-primary{background-color:var(--primary-color);border-color:rgba(0,0,0,0)}.conversejs .badge-primary:focus,.conversejs .badge-primary:hover,.conversejs .badge-primary:active{background-color:var(--primary-color-dark) !important;border-color:rgba(0,0,0,0) !important}.conversejs .badge-info{background-color:var(--primary-color);border-color:var(--primary-color)}.conversejs .badge-info:hover{background-color:var(--primary-color-dark);border-color:var(--primary-color-dark)}.conversejs .badge-secondary{background-color:var(--secondary-color);border-color:var(--secondary-color)}.conversejs .badge-secondary:hover{background-color:var(--secondary-color-dark);border-color:var(--secondary-color-dark)}.conversejs .form-control{display:block;width:100%;height:calc(1.5em + 0.75rem + 2px);padding:.375rem .75rem;font-size:1rem;font-weight:400;line-height:1.5;color:#495057;background-color:#fff;background-clip:padding-box;border:1px solid #ced4da;border-radius:.25rem;transition:border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media(prefers-reduced-motion: reduce){.conversejs .form-control{transition:none}}.conversejs .form-control::-ms-expand{background-color:rgba(0,0,0,0);border:0}.conversejs .form-control:focus{color:#495057;background-color:#fff;border-color:#80bdff;outline:0;box-shadow:0 0 0 .2rem rgba(0,123,255,.25)}.conversejs .form-control::-moz-placeholder{color:#6c757d;opacity:1}.conversejs .form-control::placeholder{color:#6c757d;opacity:1}.conversejs .form-control:disabled,.conversejs .form-control[readonly]{background-color:#e9ecef;opacity:1}.conversejs input[type=date].form-control,.conversejs input[type=time].form-control,.conversejs input[type=datetime-local].form-control,.conversejs input[type=month].form-control{-webkit-appearance:none;-moz-appearance:none;appearance:none}.conversejs select.form-control:-moz-focusring{color:rgba(0,0,0,0);text-shadow:0 0 0 #495057}.conversejs select.form-control:focus::-ms-value{color:#495057;background-color:#fff}.conversejs .form-control-file,.conversejs .form-control-range{display:block;width:100%}.conversejs .col-form-label{padding-top:calc(0.375rem + 1px);padding-bottom:calc(0.375rem + 1px);margin-bottom:0;font-size:inherit;line-height:1.5}.conversejs .col-form-label-lg{padding-top:calc(0.5rem + 1px);padding-bottom:calc(0.5rem + 1px);font-size:1.25rem;line-height:1.5}.conversejs .col-form-label-sm{padding-top:calc(0.25rem + 1px);padding-bottom:calc(0.25rem + 1px);font-size:0.875rem;line-height:1.5}.conversejs .form-control-plaintext{display:block;width:100%;padding:.375rem 0;margin-bottom:0;font-size:1rem;line-height:1.5;color:#212529;background-color:rgba(0,0,0,0);border:solid rgba(0,0,0,0);border-width:1px 0}.conversejs .form-control-plaintext.form-control-sm,.conversejs .form-control-plaintext.form-control-lg{padding-right:0;padding-left:0}.conversejs .form-control-sm{height:calc(1.5em + 0.5rem + 2px);padding:.25rem .5rem;font-size:0.875rem;line-height:1.5;border-radius:.2rem}.conversejs .form-control-lg{height:calc(1.5em + 1rem + 2px);padding:.5rem 1rem;font-size:1.25rem;line-height:1.5;border-radius:.3rem}.conversejs select.form-control[size],.conversejs select.form-control[multiple]{height:auto}.conversejs textarea.form-control{height:auto}.conversejs .form-group{margin-bottom:1rem}.conversejs .form-text{display:block;margin-top:.25rem}.conversejs .form-row{display:flex;flex-wrap:wrap;margin-right:-5px;margin-left:-5px}.conversejs .form-row>.col,.conversejs .form-row>[class*=col-]{padding-right:5px;padding-left:5px}.conversejs .form-check{position:relative;display:block;padding-left:1.25rem}.conversejs .form-check-input{position:absolute;margin-top:.3rem;margin-left:-1.25rem}.conversejs .form-check-input[disabled]~.form-check-label,.conversejs .form-check-input:disabled~.form-check-label{color:#6c757d}.conversejs .form-check-label{margin-bottom:0}.conversejs .form-check-inline{display:inline-flex;align-items:center;padding-left:0;margin-right:.75rem}.conversejs .form-check-inline .form-check-input{position:static;margin-top:0;margin-right:.3125rem;margin-left:0}.conversejs .valid-feedback{display:none;width:100%;margin-top:.25rem;font-size:0.875em;color:#28a745}.conversejs .valid-tooltip{position:absolute;top:100%;left:0;z-index:5;display:none;max-width:100%;padding:.25rem .5rem;margin-top:.1rem;font-size:0.875rem;line-height:1.5;color:#fff;background-color:rgba(40,167,69,.9);border-radius:.25rem}.form-row>.col>.conversejs .valid-tooltip,.form-row>[class*=col-]>.conversejs .valid-tooltip{left:5px}.was-validated .conversejs:valid~.valid-feedback,.was-validated .conversejs:valid~.valid-tooltip,.conversejs.is-valid~.valid-feedback,.conversejs.is-valid~.valid-tooltip{display:block}.was-validated .conversejs .form-control:valid,.conversejs .form-control.is-valid{border-color:#28a745;padding-right:calc(1.5em + 0.75rem) !important;background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='8' height='8' viewBox='0 0 8 8'%3e%3cpath fill='%2328a745' d='M2.3 6.73L.6 4.53c-.4-1.04.46-1.4 1.1-.8l1.1 1.4 3.4-3.8c.6-.63 1.6-.27 1.2.7l-4 4.6c-.43.5-.8.4-1.1.1z'/%3e%3c/svg%3e");background-repeat:no-repeat;background-position:right calc(0.375em + 0.1875rem) center;background-size:calc(0.75em + 0.375rem) calc(0.75em + 0.375rem)}.was-validated .conversejs .form-control:valid:focus,.conversejs .form-control.is-valid:focus{border-color:#28a745;box-shadow:0 0 0 .2rem rgba(40,167,69,.25)}.was-validated .conversejs select.form-control:valid,.conversejs select.form-control.is-valid{padding-right:3rem !important;background-position:right 1.5rem center}.was-validated .conversejs textarea.form-control:valid,.conversejs textarea.form-control.is-valid{padding-right:calc(1.5em + 0.75rem);background-position:top calc(0.375em + 0.1875rem) right calc(0.375em + 0.1875rem)}.was-validated .conversejs .custom-select:valid,.conversejs .custom-select.is-valid{border-color:#28a745;padding-right:calc(0.75em + 2.3125rem) !important;background:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='4' height='5' viewBox='0 0 4 5'%3e%3cpath fill='%23343a40' d='M2 0L0 2h4zm0 5L0 3h4z'/%3e%3c/svg%3e") right .75rem center/8px 10px no-repeat,#fff url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='8' height='8' viewBox='0 0 8 8'%3e%3cpath fill='%2328a745' d='M2.3 6.73L.6 4.53c-.4-1.04.46-1.4 1.1-.8l1.1 1.4 3.4-3.8c.6-.63 1.6-.27 1.2.7l-4 4.6c-.43.5-.8.4-1.1.1z'/%3e%3c/svg%3e") center right 1.75rem/calc(0.75em + 0.375rem) calc(0.75em + 0.375rem) no-repeat}.was-validated .conversejs .custom-select:valid:focus,.conversejs .custom-select.is-valid:focus{border-color:#28a745;box-shadow:0 0 0 .2rem rgba(40,167,69,.25)}.was-validated .conversejs .form-check-input:valid~.form-check-label,.conversejs .form-check-input.is-valid~.form-check-label{color:#28a745}.was-validated .conversejs .form-check-input:valid~.valid-feedback,.was-validated .conversejs .form-check-input:valid~.valid-tooltip,.conversejs .form-check-input.is-valid~.valid-feedback,.conversejs .form-check-input.is-valid~.valid-tooltip{display:block}.was-validated .conversejs .custom-control-input:valid~.custom-control-label,.conversejs .custom-control-input.is-valid~.custom-control-label{color:#28a745}.was-validated .conversejs .custom-control-input:valid~.custom-control-label::before,.conversejs .custom-control-input.is-valid~.custom-control-label::before{border-color:#28a745}.was-validated .conversejs .custom-control-input:valid:checked~.custom-control-label::before,.conversejs .custom-control-input.is-valid:checked~.custom-control-label::before{border-color:#34ce57;background-color:#34ce57}.was-validated .conversejs .custom-control-input:valid:focus~.custom-control-label::before,.conversejs .custom-control-input.is-valid:focus~.custom-control-label::before{box-shadow:0 0 0 .2rem rgba(40,167,69,.25)}.was-validated .conversejs .custom-control-input:valid:focus:not(:checked)~.custom-control-label::before,.conversejs .custom-control-input.is-valid:focus:not(:checked)~.custom-control-label::before{border-color:#28a745}.was-validated .conversejs .custom-file-input:valid~.custom-file-label,.conversejs .custom-file-input.is-valid~.custom-file-label{border-color:#28a745}.was-validated .conversejs .custom-file-input:valid:focus~.custom-file-label,.conversejs .custom-file-input.is-valid:focus~.custom-file-label{border-color:#28a745;box-shadow:0 0 0 .2rem rgba(40,167,69,.25)}.conversejs .invalid-feedback{display:none;width:100%;margin-top:.25rem;font-size:0.875em;color:#dc3545}.conversejs .invalid-tooltip{position:absolute;top:100%;left:0;z-index:5;display:none;max-width:100%;padding:.25rem .5rem;margin-top:.1rem;font-size:0.875rem;line-height:1.5;color:#fff;background-color:rgba(220,53,69,.9);border-radius:.25rem}.form-row>.col>.conversejs .invalid-tooltip,.form-row>[class*=col-]>.conversejs .invalid-tooltip{left:5px}.was-validated .conversejs:invalid~.invalid-feedback,.was-validated .conversejs:invalid~.invalid-tooltip,.conversejs.is-invalid~.invalid-feedback,.conversejs.is-invalid~.invalid-tooltip{display:block}.was-validated .conversejs .form-control:invalid,.conversejs .form-control.is-invalid{border-color:#dc3545;padding-right:calc(1.5em + 0.75rem) !important;background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' fill='none' stroke='%23dc3545' viewBox='0 0 12 12'%3e%3ccircle cx='6' cy='6' r='4.5'/%3e%3cpath stroke-linejoin='round' d='M5.8 3.6h.4L6 6.5z'/%3e%3ccircle cx='6' cy='8.2' r='.6' fill='%23dc3545' stroke='none'/%3e%3c/svg%3e");background-repeat:no-repeat;background-position:right calc(0.375em + 0.1875rem) center;background-size:calc(0.75em + 0.375rem) calc(0.75em + 0.375rem)}.was-validated .conversejs .form-control:invalid:focus,.conversejs .form-control.is-invalid:focus{border-color:#dc3545;box-shadow:0 0 0 .2rem rgba(220,53,69,.25)}.was-validated .conversejs select.form-control:invalid,.conversejs select.form-control.is-invalid{padding-right:3rem !important;background-position:right 1.5rem center}.was-validated .conversejs textarea.form-control:invalid,.conversejs textarea.form-control.is-invalid{padding-right:calc(1.5em + 0.75rem);background-position:top calc(0.375em + 0.1875rem) right calc(0.375em + 0.1875rem)}.was-validated .conversejs .custom-select:invalid,.conversejs .custom-select.is-invalid{border-color:#dc3545;padding-right:calc(0.75em + 2.3125rem) !important;background:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='4' height='5' viewBox='0 0 4 5'%3e%3cpath fill='%23343a40' d='M2 0L0 2h4zm0 5L0 3h4z'/%3e%3c/svg%3e") right .75rem center/8px 10px no-repeat,#fff url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' fill='none' stroke='%23dc3545' viewBox='0 0 12 12'%3e%3ccircle cx='6' cy='6' r='4.5'/%3e%3cpath stroke-linejoin='round' d='M5.8 3.6h.4L6 6.5z'/%3e%3ccircle cx='6' cy='8.2' r='.6' fill='%23dc3545' stroke='none'/%3e%3c/svg%3e") center right 1.75rem/calc(0.75em + 0.375rem) calc(0.75em + 0.375rem) no-repeat}.was-validated .conversejs .custom-select:invalid:focus,.conversejs .custom-select.is-invalid:focus{border-color:#dc3545;box-shadow:0 0 0 .2rem rgba(220,53,69,.25)}.was-validated .conversejs .form-check-input:invalid~.form-check-label,.conversejs .form-check-input.is-invalid~.form-check-label{color:#dc3545}.was-validated .conversejs .form-check-input:invalid~.invalid-feedback,.was-validated .conversejs .form-check-input:invalid~.invalid-tooltip,.conversejs .form-check-input.is-invalid~.invalid-feedback,.conversejs .form-check-input.is-invalid~.invalid-tooltip{display:block}.was-validated .conversejs .custom-control-input:invalid~.custom-control-label,.conversejs .custom-control-input.is-invalid~.custom-control-label{color:#dc3545}.was-validated .conversejs .custom-control-input:invalid~.custom-control-label::before,.conversejs .custom-control-input.is-invalid~.custom-control-label::before{border-color:#dc3545}.was-validated .conversejs .custom-control-input:invalid:checked~.custom-control-label::before,.conversejs .custom-control-input.is-invalid:checked~.custom-control-label::before{border-color:#e4606d;background-color:#e4606d}.was-validated .conversejs .custom-control-input:invalid:focus~.custom-control-label::before,.conversejs .custom-control-input.is-invalid:focus~.custom-control-label::before{box-shadow:0 0 0 .2rem rgba(220,53,69,.25)}.was-validated .conversejs .custom-control-input:invalid:focus:not(:checked)~.custom-control-label::before,.conversejs .custom-control-input.is-invalid:focus:not(:checked)~.custom-control-label::before{border-color:#dc3545}.was-validated .conversejs .custom-file-input:invalid~.custom-file-label,.conversejs .custom-file-input.is-invalid~.custom-file-label{border-color:#dc3545}.was-validated .conversejs .custom-file-input:invalid:focus~.custom-file-label,.conversejs .custom-file-input.is-invalid:focus~.custom-file-label{border-color:#dc3545;box-shadow:0 0 0 .2rem rgba(220,53,69,.25)}.conversejs .form-inline{display:flex;flex-flow:row wrap;align-items:center}.conversejs .form-inline .form-check{width:100%}@media(min-width: 576px){.conversejs .form-inline label{display:flex;align-items:center;justify-content:center;margin-bottom:0}.conversejs .form-inline .form-group{display:flex;flex:0 0 auto;flex-flow:row wrap;align-items:center;margin-bottom:0}.conversejs .form-inline .form-control{display:inline-block;width:auto;vertical-align:middle}.conversejs .form-inline .form-control-plaintext{display:inline-block}.conversejs .form-inline .input-group,.conversejs .form-inline .custom-select{width:auto}.conversejs .form-inline .form-check{display:flex;align-items:center;justify-content:center;width:auto;padding-left:0}.conversejs .form-inline .form-check-input{position:relative;flex-shrink:0;margin-top:0;margin-right:.25rem;margin-left:0}.conversejs .form-inline .custom-control{align-items:center;justify-content:center}.conversejs .form-inline .custom-control-label{margin-bottom:0}}.conversejs .input-group{position:relative;display:flex;flex-wrap:wrap;align-items:stretch;width:100%}.conversejs .input-group>.form-control,.conversejs .input-group>.form-control-plaintext,.conversejs .input-group>.custom-select,.conversejs .input-group>.custom-file{position:relative;flex:1 1 auto;width:1%;min-width:0;margin-bottom:0}.conversejs .input-group>.form-control+.form-control,.conversejs .input-group>.form-control+.custom-select,.conversejs .input-group>.form-control+.custom-file,.conversejs .input-group>.form-control-plaintext+.form-control,.conversejs .input-group>.form-control-plaintext+.custom-select,.conversejs .input-group>.form-control-plaintext+.custom-file,.conversejs .input-group>.custom-select+.form-control,.conversejs .input-group>.custom-select+.custom-select,.conversejs .input-group>.custom-select+.custom-file,.conversejs .input-group>.custom-file+.form-control,.conversejs .input-group>.custom-file+.custom-select,.conversejs .input-group>.custom-file+.custom-file{margin-left:-1px}.conversejs .input-group>.form-control:focus,.conversejs .input-group>.custom-select:focus,.conversejs .input-group>.custom-file .custom-file-input:focus~.custom-file-label{z-index:3}.conversejs .input-group>.custom-file .custom-file-input:focus{z-index:4}.conversejs .input-group>.form-control:not(:first-child),.conversejs .input-group>.custom-select:not(:first-child){border-top-left-radius:0;border-bottom-left-radius:0}.conversejs .input-group>.custom-file{display:flex;align-items:center}.conversejs .input-group>.custom-file:not(:last-child) .custom-file-label,.conversejs .input-group>.custom-file:not(:last-child) .custom-file-label::after{border-top-right-radius:0;border-bottom-right-radius:0}.conversejs .input-group>.custom-file:not(:first-child) .custom-file-label{border-top-left-radius:0;border-bottom-left-radius:0}.conversejs .input-group:not(.has-validation)>.form-control:not(:last-child),.conversejs .input-group:not(.has-validation)>.custom-select:not(:last-child),.conversejs .input-group:not(.has-validation)>.custom-file:not(:last-child) .custom-file-label,.conversejs .input-group:not(.has-validation)>.custom-file:not(:last-child) .custom-file-label::after{border-top-right-radius:0;border-bottom-right-radius:0}.conversejs .input-group.has-validation>.form-control:nth-last-child(n+3),.conversejs .input-group.has-validation>.custom-select:nth-last-child(n+3),.conversejs .input-group.has-validation>.custom-file:nth-last-child(n+3) .custom-file-label,.conversejs .input-group.has-validation>.custom-file:nth-last-child(n+3) .custom-file-label::after{border-top-right-radius:0;border-bottom-right-radius:0}.conversejs .input-group-prepend,.conversejs .input-group-append{display:flex}.conversejs .input-group-prepend .btn,.conversejs .input-group-append .btn{position:relative;z-index:2}.conversejs .input-group-prepend .btn:focus,.conversejs .input-group-append .btn:focus{z-index:3}.conversejs .input-group-prepend .btn+.btn,.conversejs .input-group-prepend .btn+.input-group-text,.conversejs .input-group-prepend .input-group-text+.input-group-text,.conversejs .input-group-prepend .input-group-text+.btn,.conversejs .input-group-append .btn+.btn,.conversejs .input-group-append .btn+.input-group-text,.conversejs .input-group-append .input-group-text+.input-group-text,.conversejs .input-group-append .input-group-text+.btn{margin-left:-1px}.conversejs .input-group-prepend{margin-right:-1px}.conversejs .input-group-append{margin-left:-1px}.conversejs .input-group-text{display:flex;align-items:center;padding:.375rem .75rem;margin-bottom:0;font-size:1rem;font-weight:400;line-height:1.5;color:#495057;text-align:center;white-space:nowrap;background-color:#e9ecef;border:1px solid #ced4da;border-radius:.25rem}.conversejs .input-group-text input[type=radio],.conversejs .input-group-text input[type=checkbox]{margin-top:0}.conversejs .input-group-lg>.form-control:not(textarea),.conversejs .input-group-lg>.custom-select{height:calc(1.5em + 1rem + 2px)}.conversejs .input-group-lg>.form-control,.conversejs .input-group-lg>.custom-select,.conversejs .input-group-lg>.input-group-prepend>.input-group-text,.conversejs .input-group-lg>.input-group-append>.input-group-text,.conversejs .input-group-lg>.input-group-prepend>.btn,.conversejs .input-group-lg>.input-group-append>.btn{padding:.5rem 1rem;font-size:1.25rem;line-height:1.5;border-radius:.3rem}.conversejs .input-group-sm>.form-control:not(textarea),.conversejs .input-group-sm>.custom-select{height:calc(1.5em + 0.5rem + 2px)}.conversejs .input-group-sm>.form-control,.conversejs .input-group-sm>.custom-select,.conversejs .input-group-sm>.input-group-prepend>.input-group-text,.conversejs .input-group-sm>.input-group-append>.input-group-text,.conversejs .input-group-sm>.input-group-prepend>.btn,.conversejs .input-group-sm>.input-group-append>.btn{padding:.25rem .5rem;font-size:0.875rem;line-height:1.5;border-radius:.2rem}.conversejs .input-group-lg>.custom-select,.conversejs .input-group-sm>.custom-select{padding-right:1.75rem}.conversejs .input-group>.input-group-prepend>.btn,.conversejs .input-group>.input-group-prepend>.input-group-text,.conversejs .input-group:not(.has-validation)>.input-group-append:not(:last-child)>.btn,.conversejs .input-group:not(.has-validation)>.input-group-append:not(:last-child)>.input-group-text,.conversejs .input-group.has-validation>.input-group-append:nth-last-child(n+3)>.btn,.conversejs .input-group.has-validation>.input-group-append:nth-last-child(n+3)>.input-group-text,.conversejs .input-group>.input-group-append:last-child>.btn:not(:last-child):not(.dropdown-toggle),.conversejs .input-group>.input-group-append:last-child>.input-group-text:not(:last-child){border-top-right-radius:0;border-bottom-right-radius:0}.conversejs .input-group>.input-group-append>.btn,.conversejs .input-group>.input-group-append>.input-group-text,.conversejs .input-group>.input-group-prepend:not(:first-child)>.btn,.conversejs .input-group>.input-group-prepend:not(:first-child)>.input-group-text,.conversejs .input-group>.input-group-prepend:first-child>.btn:not(:first-child),.conversejs .input-group>.input-group-prepend:first-child>.input-group-text:not(:first-child){border-top-left-radius:0;border-bottom-left-radius:0}.conversejs .custom-control{position:relative;z-index:1;display:block;min-height:1.5rem;padding-left:1.5rem;-webkit-print-color-adjust:exact;print-color-adjust:exact}.conversejs .custom-control-inline{display:inline-flex;margin-right:1rem}.conversejs .custom-control-input{position:absolute;left:0;z-index:-1;width:1rem;height:1.25rem;opacity:0}.conversejs .custom-control-input:checked~.custom-control-label::before{color:#fff;border-color:#007bff;background-color:#007bff}.conversejs .custom-control-input:focus~.custom-control-label::before{box-shadow:0 0 0 .2rem rgba(0,123,255,.25)}.conversejs .custom-control-input:focus:not(:checked)~.custom-control-label::before{border-color:#80bdff}.conversejs .custom-control-input:not(:disabled):active~.custom-control-label::before{color:#fff;background-color:#b3d7ff;border-color:#b3d7ff}.conversejs .custom-control-input[disabled]~.custom-control-label,.conversejs .custom-control-input:disabled~.custom-control-label{color:#6c757d}.conversejs .custom-control-input[disabled]~.custom-control-label::before,.conversejs .custom-control-input:disabled~.custom-control-label::before{background-color:#e9ecef}.conversejs .custom-control-label{position:relative;margin-bottom:0;vertical-align:top}.conversejs .custom-control-label::before{position:absolute;top:.25rem;left:-1.5rem;display:block;width:1rem;height:1rem;pointer-events:none;content:"";background-color:#fff;border:1px solid #adb5bd}.conversejs .custom-control-label::after{position:absolute;top:.25rem;left:-1.5rem;display:block;width:1rem;height:1rem;content:"";background:50%/50% 50% no-repeat}.conversejs .custom-checkbox .custom-control-label::before{border-radius:.25rem}.conversejs .custom-checkbox .custom-control-input:checked~.custom-control-label::after{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='8' height='8' viewBox='0 0 8 8'%3e%3cpath fill='%23fff' d='M6.564.75l-3.59 3.612-1.538-1.55L0 4.26l2.974 2.99L8 2.193z'/%3e%3c/svg%3e")}.conversejs .custom-checkbox .custom-control-input:indeterminate~.custom-control-label::before{border-color:#007bff;background-color:#007bff}.conversejs .custom-checkbox .custom-control-input:indeterminate~.custom-control-label::after{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='4' height='4' viewBox='0 0 4 4'%3e%3cpath stroke='%23fff' d='M0 2h4'/%3e%3c/svg%3e")}.conversejs .custom-checkbox .custom-control-input:disabled:checked~.custom-control-label::before{background-color:rgba(0,123,255,.5)}.conversejs .custom-checkbox .custom-control-input:disabled:indeterminate~.custom-control-label::before{background-color:rgba(0,123,255,.5)}.conversejs .custom-radio .custom-control-label::before{border-radius:50%}.conversejs .custom-radio .custom-control-input:checked~.custom-control-label::after{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='-4 -4 8 8'%3e%3ccircle r='3' fill='%23fff'/%3e%3c/svg%3e")}.conversejs .custom-radio .custom-control-input:disabled:checked~.custom-control-label::before{background-color:rgba(0,123,255,.5)}.conversejs .custom-switch{padding-left:2.25rem}.conversejs .custom-switch .custom-control-label::before{left:-2.25rem;width:1.75rem;pointer-events:all;border-radius:.5rem}.conversejs .custom-switch .custom-control-label::after{top:calc(0.25rem + 2px);left:calc(-2.25rem + 2px);width:calc(1rem - 4px);height:calc(1rem - 4px);background-color:#adb5bd;border-radius:.5rem;transition:transform .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media(prefers-reduced-motion: reduce){.conversejs .custom-switch .custom-control-label::after{transition:none}}.conversejs .custom-switch .custom-control-input:checked~.custom-control-label::after{background-color:#fff;transform:translateX(0.75rem)}.conversejs .custom-switch .custom-control-input:disabled:checked~.custom-control-label::before{background-color:rgba(0,123,255,.5)}.conversejs .custom-select{display:inline-block;width:100%;height:calc(1.5em + 0.75rem + 2px);padding:.375rem 1.75rem .375rem .75rem;font-size:1rem;font-weight:400;line-height:1.5;color:#495057;vertical-align:middle;background:#fff url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='4' height='5' viewBox='0 0 4 5'%3e%3cpath fill='%23343a40' d='M2 0L0 2h4zm0 5L0 3h4z'/%3e%3c/svg%3e") right .75rem center/8px 10px no-repeat;border:1px solid #ced4da;border-radius:.25rem;-webkit-appearance:none;-moz-appearance:none;appearance:none}.conversejs .custom-select:focus{border-color:#80bdff;outline:0;box-shadow:0 0 0 .2rem rgba(0,123,255,.25)}.conversejs .custom-select:focus::-ms-value{color:#495057;background-color:#fff}.conversejs .custom-select[multiple],.conversejs .custom-select[size]:not([size="1"]){height:auto;padding-right:.75rem;background-image:none}.conversejs .custom-select:disabled{color:#6c757d;background-color:#e9ecef}.conversejs .custom-select::-ms-expand{display:none}.conversejs .custom-select:-moz-focusring{color:rgba(0,0,0,0);text-shadow:0 0 0 #495057}.conversejs .custom-select-sm{height:calc(1.5em + 0.5rem + 2px);padding-top:.25rem;padding-bottom:.25rem;padding-left:.5rem;font-size:0.875rem}.conversejs .custom-select-lg{height:calc(1.5em + 1rem + 2px);padding-top:.5rem;padding-bottom:.5rem;padding-left:1rem;font-size:1.25rem}.conversejs .custom-file{position:relative;display:inline-block;width:100%;height:calc(1.5em + 0.75rem + 2px);margin-bottom:0}.conversejs .custom-file-input{position:relative;z-index:2;width:100%;height:calc(1.5em + 0.75rem + 2px);margin:0;overflow:hidden;opacity:0}.conversejs .custom-file-input:focus~.custom-file-label{border-color:#80bdff;box-shadow:0 0 0 .2rem rgba(0,123,255,.25)}.conversejs .custom-file-input[disabled]~.custom-file-label,.conversejs .custom-file-input:disabled~.custom-file-label{background-color:#e9ecef}.conversejs .custom-file-input:lang(en)~.custom-file-label::after{content:"Browse"}.conversejs .custom-file-input~.custom-file-label[data-browse]::after{content:attr(data-browse)}.conversejs .custom-file-label{position:absolute;top:0;right:0;left:0;z-index:1;height:calc(1.5em + 0.75rem + 2px);padding:.375rem .75rem;overflow:hidden;font-weight:400;line-height:1.5;color:#495057;background-color:#fff;border:1px solid #ced4da;border-radius:.25rem}.conversejs .custom-file-label::after{position:absolute;top:0;right:0;bottom:0;z-index:3;display:block;height:calc(1.5em + 0.75rem);padding:.375rem .75rem;line-height:1.5;color:#495057;content:"Browse";background-color:#e9ecef;border-left:inherit;border-radius:0 .25rem .25rem 0}.conversejs .custom-range{width:100%;height:1.4rem;padding:0;background-color:rgba(0,0,0,0);-webkit-appearance:none;-moz-appearance:none;appearance:none}.conversejs .custom-range:focus{outline:0}.conversejs .custom-range:focus::-webkit-slider-thumb{box-shadow:0 0 0 1px #fff,0 0 0 .2rem rgba(0,123,255,.25)}.conversejs .custom-range:focus::-moz-range-thumb{box-shadow:0 0 0 1px #fff,0 0 0 .2rem rgba(0,123,255,.25)}.conversejs .custom-range:focus::-ms-thumb{box-shadow:0 0 0 1px #fff,0 0 0 .2rem rgba(0,123,255,.25)}.conversejs .custom-range::-moz-focus-outer{border:0}.conversejs .custom-range::-webkit-slider-thumb{width:1rem;height:1rem;margin-top:-0.25rem;background-color:#007bff;border:0;border-radius:1rem;-webkit-transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;-webkit-appearance:none;appearance:none}@media(prefers-reduced-motion: reduce){.conversejs .custom-range::-webkit-slider-thumb{-webkit-transition:none;transition:none}}.conversejs .custom-range::-webkit-slider-thumb:active{background-color:#b3d7ff}.conversejs .custom-range::-webkit-slider-runnable-track{width:100%;height:.5rem;color:rgba(0,0,0,0);cursor:pointer;background-color:#dee2e6;border-color:rgba(0,0,0,0);border-radius:1rem}.conversejs .custom-range::-moz-range-thumb{width:1rem;height:1rem;background-color:#007bff;border:0;border-radius:1rem;-moz-transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;-moz-appearance:none;appearance:none}@media(prefers-reduced-motion: reduce){.conversejs .custom-range::-moz-range-thumb{-moz-transition:none;transition:none}}.conversejs .custom-range::-moz-range-thumb:active{background-color:#b3d7ff}.conversejs .custom-range::-moz-range-track{width:100%;height:.5rem;color:rgba(0,0,0,0);cursor:pointer;background-color:#dee2e6;border-color:rgba(0,0,0,0);border-radius:1rem}.conversejs .custom-range::-ms-thumb{width:1rem;height:1rem;margin-top:0;margin-right:.2rem;margin-left:.2rem;background-color:#007bff;border:0;border-radius:1rem;-ms-transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;appearance:none}@media(prefers-reduced-motion: reduce){.conversejs .custom-range::-ms-thumb{-ms-transition:none;transition:none}}.conversejs .custom-range::-ms-thumb:active{background-color:#b3d7ff}.conversejs .custom-range::-ms-track{width:100%;height:.5rem;color:rgba(0,0,0,0);cursor:pointer;background-color:rgba(0,0,0,0);border-color:rgba(0,0,0,0);border-width:.5rem}.conversejs .custom-range::-ms-fill-lower{background-color:#dee2e6;border-radius:1rem}.conversejs .custom-range::-ms-fill-upper{margin-right:15px;background-color:#dee2e6;border-radius:1rem}.conversejs .custom-range:disabled::-webkit-slider-thumb{background-color:#adb5bd}.conversejs .custom-range:disabled::-webkit-slider-runnable-track{cursor:default}.conversejs .custom-range:disabled::-moz-range-thumb{background-color:#adb5bd}.conversejs .custom-range:disabled::-moz-range-track{cursor:default}.conversejs .custom-range:disabled::-ms-thumb{background-color:#adb5bd}.conversejs .custom-control-label::before,.conversejs .custom-file-label,.conversejs .custom-select{transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media(prefers-reduced-motion: reduce){.conversejs .custom-control-label::before,.conversejs .custom-file-label,.conversejs .custom-select{transition:none}}.conversejs .btn--small{font-size:80%;font-weight:normal}.conversejs form label{font-weight:bold}.conversejs form .form-instructions{color:var(--text-color);margin-bottom:1em}.conversejs form .hidden-username{opacity:0 !important;height:0 !important;padding:0 !important}.conversejs form .error-feedback{margin-bottom:.5em}.conversejs form .form-check-label{margin-top:.3rem}.conversejs form .form-control{color:var(--text-color);background-color:var(--background)}.conversejs form .form-control:focus{color:var(--text-color);background-color:var(--focus-color)}.conversejs form .form-control::-moz-placeholder{color:var(--subdued-color)}.conversejs form .form-control::placeholder{color:var(--subdued-color)}.conversejs form .form-control--labeled{margin-top:.5em}.conversejs form .btn-group .clear-input{margin-top:.5em;margin-bottom:.5em;position:absolute;right:.2em;cursor:pointer;font-size:var(--font-size)}.conversejs form#converse-register,.conversejs form#converse-login{background:var(--controlbox-pane-background-color)}.conversejs form#converse-register legend,.conversejs form#converse-login legend{width:100%;text-align:center;margin:0 auto .5em auto}.conversejs form#converse-register fieldset.buttons,.conversejs form#converse-login fieldset.buttons{text-align:center}.conversejs form#converse-register .login-anon,.conversejs form#converse-login .login-anon{height:auto;white-space:normal}.conversejs form#converse-register .save-submit,.conversejs form#converse-login .save-submit{color:var(--save-button-color)}.conversejs form#converse-register .form-url,.conversejs form#converse-login .form-url{display:block;font-weight:normal;margin:1em 0}.conversejs form.converse-form{padding:1.2rem}.conversejs form.converse-form legend{color:var(--text-color);font-size:125%;margin-bottom:1.5em}.conversejs form.converse-form select,.conversejs form.converse-form input[type=password],.conversejs form.converse-form input[type=number],.conversejs form.converse-form input[type=text]{min-width:50%}.conversejs form.converse-form input[type=button],.conversejs form.converse-form input[type=submit]{margin-right:.25em;border:none}.conversejs form.converse-form input.error{border:1px solid var(--error-color);color:var(--text-color)}.conversejs form.converse-form .text-muted{color:var(--subdued-color) !important;font-size:85%;padding-top:.5em}.conversejs form.converse-form .text-muted a{color:var(--link-color-lighten-10-percent)}.conversejs form.converse-form .text-muted.error{color:var(--error-color)}.conversejs form.converse-form--modal{padding-bottom:0}.conversejs form.converse-form--spinner{height:100%}.conversejs form.converse-centered-form{min-height:66%;text-align:center}.conversejs form.converse-centered-form input{max-width:30em;margin:auto}.conversejs .list-group{display:flex;flex-direction:column;padding-left:0;margin-bottom:0;border-radius:.25rem}.conversejs .list-group-item-action{width:100%;color:#495057;text-align:inherit}.conversejs .list-group-item-action:hover,.conversejs .list-group-item-action:focus{z-index:1;color:#495057;text-decoration:none;background-color:#f8f9fa}.conversejs .list-group-item-action:active{color:#212529;background-color:#e9ecef}.conversejs .list-group-item{position:relative;display:block;padding:.75rem 1.25rem;background-color:#fff;border:1px solid rgba(0,0,0,.125)}.conversejs .list-group-item:first-child{border-top-left-radius:inherit;border-top-right-radius:inherit}.conversejs .list-group-item:last-child{border-bottom-right-radius:inherit;border-bottom-left-radius:inherit}.conversejs .list-group-item.disabled,.conversejs .list-group-item:disabled{color:#6c757d;pointer-events:none;background-color:#fff}.conversejs .list-group-item.active{z-index:2;color:#fff;background-color:#007bff;border-color:#007bff}.conversejs .list-group-item+.conversejs .list-group-item{border-top-width:0}.conversejs .list-group-item+.conversejs .list-group-item.active{margin-top:-1px;border-top-width:1px}.conversejs .list-group-horizontal{flex-direction:row}.conversejs .list-group-horizontal>.list-group-item:first-child{border-bottom-left-radius:.25rem;border-top-right-radius:0}.conversejs .list-group-horizontal>.list-group-item:last-child{border-top-right-radius:.25rem;border-bottom-left-radius:0}.conversejs .list-group-horizontal>.list-group-item.active{margin-top:0}.conversejs .list-group-horizontal>.list-group-item+.list-group-item{border-top-width:1px;border-left-width:0}.conversejs .list-group-horizontal>.list-group-item+.list-group-item.active{margin-left:-1px;border-left-width:1px}@media(min-width: 576px){.conversejs .list-group-horizontal-sm{flex-direction:row}.conversejs .list-group-horizontal-sm>.list-group-item:first-child{border-bottom-left-radius:.25rem;border-top-right-radius:0}.conversejs .list-group-horizontal-sm>.list-group-item:last-child{border-top-right-radius:.25rem;border-bottom-left-radius:0}.conversejs .list-group-horizontal-sm>.list-group-item.active{margin-top:0}.conversejs .list-group-horizontal-sm>.list-group-item+.list-group-item{border-top-width:1px;border-left-width:0}.conversejs .list-group-horizontal-sm>.list-group-item+.list-group-item.active{margin-left:-1px;border-left-width:1px}}@media(min-width: 768px){.conversejs .list-group-horizontal-md{flex-direction:row}.conversejs .list-group-horizontal-md>.list-group-item:first-child{border-bottom-left-radius:.25rem;border-top-right-radius:0}.conversejs .list-group-horizontal-md>.list-group-item:last-child{border-top-right-radius:.25rem;border-bottom-left-radius:0}.conversejs .list-group-horizontal-md>.list-group-item.active{margin-top:0}.conversejs .list-group-horizontal-md>.list-group-item+.list-group-item{border-top-width:1px;border-left-width:0}.conversejs .list-group-horizontal-md>.list-group-item+.list-group-item.active{margin-left:-1px;border-left-width:1px}}@media(min-width: 992px){.conversejs .list-group-horizontal-lg{flex-direction:row}.conversejs .list-group-horizontal-lg>.list-group-item:first-child{border-bottom-left-radius:.25rem;border-top-right-radius:0}.conversejs .list-group-horizontal-lg>.list-group-item:last-child{border-top-right-radius:.25rem;border-bottom-left-radius:0}.conversejs .list-group-horizontal-lg>.list-group-item.active{margin-top:0}.conversejs .list-group-horizontal-lg>.list-group-item+.list-group-item{border-top-width:1px;border-left-width:0}.conversejs .list-group-horizontal-lg>.list-group-item+.list-group-item.active{margin-left:-1px;border-left-width:1px}}@media(min-width: 1200px){.conversejs .list-group-horizontal-xl{flex-direction:row}.conversejs .list-group-horizontal-xl>.list-group-item:first-child{border-bottom-left-radius:.25rem;border-top-right-radius:0}.conversejs .list-group-horizontal-xl>.list-group-item:last-child{border-top-right-radius:.25rem;border-bottom-left-radius:0}.conversejs .list-group-horizontal-xl>.list-group-item.active{margin-top:0}.conversejs .list-group-horizontal-xl>.list-group-item+.list-group-item{border-top-width:1px;border-left-width:0}.conversejs .list-group-horizontal-xl>.list-group-item+.list-group-item.active{margin-left:-1px;border-left-width:1px}}.conversejs .list-group-flush{border-radius:0}.conversejs .list-group-flush>.list-group-item{border-width:0 0 1px}.conversejs .list-group-flush>.list-group-item:last-child{border-bottom-width:0}.conversejs .list-group-item-primary{color:#004085;background-color:#b8daff}.conversejs .list-group-item-primary.list-group-item-action:hover,.conversejs .list-group-item-primary.list-group-item-action:focus{color:#004085;background-color:#9fcdff}.conversejs .list-group-item-primary.list-group-item-action.active{color:#fff;background-color:#004085;border-color:#004085}.conversejs .list-group-item-secondary{color:#383d41;background-color:#d6d8db}.conversejs .list-group-item-secondary.list-group-item-action:hover,.conversejs .list-group-item-secondary.list-group-item-action:focus{color:#383d41;background-color:#c8cbcf}.conversejs .list-group-item-secondary.list-group-item-action.active{color:#fff;background-color:#383d41;border-color:#383d41}.conversejs .list-group-item-success{color:#155724;background-color:#c3e6cb}.conversejs .list-group-item-success.list-group-item-action:hover,.conversejs .list-group-item-success.list-group-item-action:focus{color:#155724;background-color:#b1dfbb}.conversejs .list-group-item-success.list-group-item-action.active{color:#fff;background-color:#155724;border-color:#155724}.conversejs .list-group-item-info{color:#0c5460;background-color:#bee5eb}.conversejs .list-group-item-info.list-group-item-action:hover,.conversejs .list-group-item-info.list-group-item-action:focus{color:#0c5460;background-color:#abdde5}.conversejs .list-group-item-info.list-group-item-action.active{color:#fff;background-color:#0c5460;border-color:#0c5460}.conversejs .list-group-item-warning{color:#856404;background-color:#ffeeba}.conversejs .list-group-item-warning.list-group-item-action:hover,.conversejs .list-group-item-warning.list-group-item-action:focus{color:#856404;background-color:#ffe8a1}.conversejs .list-group-item-warning.list-group-item-action.active{color:#fff;background-color:#856404;border-color:#856404}.conversejs .list-group-item-danger{color:#721c24;background-color:#f5c6cb}.conversejs .list-group-item-danger.list-group-item-action:hover,.conversejs .list-group-item-danger.list-group-item-action:focus{color:#721c24;background-color:#f1b0b7}.conversejs .list-group-item-danger.list-group-item-action.active{color:#fff;background-color:#721c24;border-color:#721c24}.conversejs .list-group-item-light{color:#818182;background-color:#fdfdfe}.conversejs .list-group-item-light.list-group-item-action:hover,.conversejs .list-group-item-light.list-group-item-action:focus{color:#818182;background-color:#ececf6}.conversejs .list-group-item-light.list-group-item-action.active{color:#fff;background-color:#818182;border-color:#818182}.conversejs .list-group-item-dark{color:#1b1e21;background-color:#c6c8ca}.conversejs .list-group-item-dark.list-group-item-action:hover,.conversejs .list-group-item-dark.list-group-item-action:focus{color:#1b1e21;background-color:#b9bbbe}.conversejs .list-group-item-dark.list-group-item-action.active{color:#fff;background-color:#1b1e21;border-color:#1b1e21}.conversejs .list-group-item{background-color:var(--list-group-item-bg-color)}.conversejs .list-group-item.active{background-color:var(--primary-color);border-color:var(--primary-color-dark)}.conversejs .list-container{text-align:left;padding:.3em 0}.conversejs .list-container .list-toggle{font-family:var(--heading-font);font-weight:var(--list-toggle-font-weight);display:block;color:var(--list-toggle-color);padding:0 0 .5rem 0}.conversejs .list-container .list-toggle:hover{color:var(--list-toggle-hover-color)}.conversejs .items-list{text-align:left}.conversejs .items-list .list-item{border:none;clear:both;color:var(--text-color);overflow:hidden;padding:.5em 0;text-shadow:0 1px 0 var(--text-shadow-color);word-wrap:break-word;height:2.5em}.conversejs .items-list .list-item.unread-msgs{font-weight:bold}.conversejs .items-list .list-item:hover .list-item-link{color:var(--list-item-link-hover-color)}.conversejs .items-list .list-item .list-item-link{color:var(--list-item-link-color);margin:auto;font-size:var(--font-size);overflow:hidden;white-space:nowrap;text-overflow:ellipsis;vertical-align:baseline}.conversejs .items-list .list-item .list-item-link:hover{color:var(--list-item-link-hover-color)}.conversejs .items-list .list-item .list-item-badge{opacity:1;border-radius:25%;color:#fff;font-size:var(--font-size-small);line-height:var(--font-size-small)}.conversejs .items-list .list-item .list-item-action{opacity:0;font-size:var(--font-size-tiny);padding:.3em 0 0 0;margin:0 0 0 var(--inline-action-margin);width:2em;height:2em;color:var(--subdued-color)}.conversejs .items-list .list-item .list-item-action:before{font-size:var(--font-size)}.conversejs .items-list .list-item .list-item-action.button-on{color:var(--list-item-link-color)}.conversejs .items-list .list-item .list-item-action.button-on:hover{color:var(--list-item-link-hover-color)}.conversejs .items-list .list-item .list-item-action:hover{color:var(--list-toggle-hover-color);opacity:1}.conversejs .items-list .list-item .list-item-action--visible{opacity:1 !important}.conversejs .items-list .list-item.open{background-color:var(--list-item-open-color)}.conversejs .items-list .list-item.open:hover .list-item-link{color:var(--inverse-link-color)}.conversejs .items-list .list-item.open:hover .list-item-link:hover{color:var(--inverse-link-color)}.conversejs .items-list .list-item.open:hover{background-color:var(--list-item-open-hover-color)}.conversejs .items-list .list-item.open a{color:var(--inverse-link-color)}.conversejs .items-list .list-item.open .list-item-action{color:var(--list-item-action-color)}.conversejs .items-list .list-item.open .list-item-action:hover{color:var(--list-item-action-hover-color)}.conversejs .items-list .list-item:hover{background-color:var(--controlbox-pane-bg-hover-color)}.conversejs .items-list .list-item:hover .list-item-action{opacity:1}.conversejs .items-list .list-item:hover .fa,.conversejs .items-list .list-item:hover .far,.conversejs .items-list .list-item:hover .fas{opacity:1}.conversejs .styling-directive{color:var(--subdued-color)}.conversejs .message .show-msg-author-modal{align-self:flex-start;color:var(--message-author-color) !important}.conversejs .message blockquote{margin-left:.5em;margin-bottom:.25em;padding-right:1em;color:var(--subdued-color);border-left:.3em solid var(--subdued-color);padding-left:.5em;display:inline-block}.conversejs .message code{font-family:monospace}.conversejs .message .mention{font-weight:bold}.conversejs .message .mention--self{font-weight:normal}.conversejs .message.date-separator,.conversejs .message.separator{height:2em;margin:0;position:relative;text-align:center;z-index:0}.conversejs .message.date-separator .separator,.conversejs .message.separator .separator{border-top:0px;border-bottom:var(--chat-separator-border-bottom);margin:0 1em;position:relative;top:1em;z-index:5}.conversejs .message.date-separator .separator-text,.conversejs .message.separator .separator-text{background:var(--chat-background-color);bottom:1px;color:var(--separator-text-color);display:inline-block;line-height:2em;padding:0 1em;position:relative;z-index:5}.conversejs .message.chat-info{color:var(--chat-info-color);font-size:var(--message-font-size);line-height:var(--line-height-small);font-size:90%;padding:.17rem 1rem}.conversejs .message.chat-info.badge{color:var(--chat-head-text-color)}.conversejs .message.chat-info.chat-state-notification{font-style:italic}.conversejs .message.chat-info.chat-event{clear:left;font-style:italic}.conversejs .message.chat-info.chat-error{color:var(--error-color);font-weight:bold}.conversejs .message.chat-info .q{font-style:italic}.conversejs .message .chat-image{height:auto;width:auto;max-height:15em;max-width:100%}.conversejs .message.chat-msg--action{font-style:italic}.conversejs .message.chat-msg--action .chat-msg__author{padding-right:.2em}.conversejs .message.chat-msg{display:inline-flex;width:100%;flex-direction:row;padding:.25em 1rem}.conversejs .message.chat-msg.onload{animation:colorchange-chatmessage 1s;-webkit-animation:colorchange-chatmessage 1s}.conversejs .message.chat-msg:hover{background-color:var(--chat-msg-hover-color)}.conversejs .message.chat-msg.correcting.groupchat{background-color:var(--chatroom-correcting-color)}.conversejs .message.chat-msg.correcting:not(.groupchat){background-color:var(--chat-correcting-color)}.conversejs .message.chat-msg .spoiler{margin-top:.5em}.conversejs .message.chat-msg .spoiler-hint{margin-bottom:.5em}.conversejs .message.chat-msg .spoiler-toggle{color:var(--background)}.conversejs .message.chat-msg .spoiler-toggle i{color:var(--background);padding-right:.5em}.conversejs .message.chat-msg .spoiler-toggle:before{padding-right:.25em;white-space:nowrap}.conversejs .message.chat-msg .chat-msg__content--me .chat-msg__body--groupchat .chat-msg__text{color:var(--subdued-color)}.conversejs .message.chat-msg .chat-msg__content--me .chat-msg__body--groupchat.chat-msg__body--delayed .chat-msg__text,.conversejs .message.chat-msg .chat-msg__content--me .chat-msg__body--groupchat.chat-msg__body--received .chat-msg__text{color:var(--message-text-color)}.conversejs .message.chat-msg .chat-msg__content--action{width:100%;margin-left:0}.conversejs .message.chat-msg .chat-msg__message{line-height:1.65em;display:inline-flex;flex-direction:column;width:100%;overflow-wrap:break-word}.conversejs .message.chat-msg .chat-msg__message .chat-msg__body--wrapper{display:flex}.conversejs .message.chat-msg .chat-msg__edit-modal{cursor:pointer;padding-right:.5em}.conversejs .message.chat-msg .chat-msg__subject{font-weight:bold;clear:right}.conversejs .message.chat-msg .chat-msg__text{color:var(--message-text-color);padding:0;white-space:pre-wrap;word-wrap:break-word;word-break:break-word}.conversejs .message.chat-msg .chat-msg__text a{word-wrap:break-word;word-break:break-all;display:inline}.conversejs .message.chat-msg .chat-msg__text a.chat-image__link{width:-moz-fit-content;width:fit-content;display:block}.conversejs .message.chat-msg .chat-msg__text img.emoji{height:1.5em;width:1.5em;margin:0 .05em 0 .1em;vertical-align:-0.1em}.conversejs .message.chat-msg .chat-msg__text .emojione{margin-bottom:-6px}.conversejs .message.chat-msg .chat-msg__text--larger{font-size:1.6em;padding-top:.25em;padding-bottom:.25em}.conversejs .message.chat-msg .chat-msg__error{color:var(--error-color)}.conversejs .message.chat-msg .chat-msg__media{margin-top:.25rem;word-break:break-all}.conversejs .message.chat-msg .chat-msg__media a{word-wrap:break-word}.conversejs .message.chat-msg .chat-msg__media audio{width:100%}.conversejs .message.chat-msg .chat-msg__author{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-family:var(--heading-font);font-size:115%;font-weight:bold;padding-bottom:1px}.conversejs .message.chat-msg .chat-msg__heading{width:100%;padding-right:.25rem}.conversejs .message.chat-msg .chat-msg__heading .badge{margin-left:.5em;font-family:var(--normal_font)}.conversejs .message.chat-msg .chat-msg__heading .chat-msg__time{padding-left:.25em;padding-right:.25em;color:var(--text-color-lighten-15-percent)}.conversejs .message.chat-msg .chat-msg__heading .fa-lock svg{padding-bottom:2px}.conversejs .message.chat-msg.chat-msg--action .chat-msg__message{flex-direction:row}.conversejs .message.chat-msg.chat-msg--action .chat-msg__text{width:auto}.conversejs .message.chat-msg.chat-msg--action .chat-msg__heading{margin-top:0;padding-bottom:0;width:auto}.conversejs .message.chat-msg.chat-msg--action .chat-msg__heading .fa{margin-left:.5em}.conversejs .message.chat-msg.chat-msg--action .chat-msg__author{font-size:var(--message-font-size)}.conversejs .message.chat-msg.chat-msg--action .chat-msg__time{margin-left:0}.conversejs .message.chat-msg .chat-msg__content{width:calc(100% - var(--message-avatar-width))}.conversejs .message.chat-msg.chat-msg--followup .chat-msg__heading,.conversejs .message.chat-msg.chat-msg--followup .show-msg-author-modal{display:none}.conversejs .message.chat-msg.chat-msg--followup.chat-msg--with-avatar .chat-msg__content{margin-left:2.75rem;width:100%}.conversejs .message.chat-msg .chat-msg__receipt{margin-left:.5em;margin-right:.5em;color:var(--message-receipt-color)}.conversejs .message .chat-msg__content{display:flex;flex-direction:column;justify-content:space-between;align-items:stretch;margin-left:.5rem}.conversejs .message .chat-msg__content:hover .btn--standalone{opacity:1}.conversejs .message .chat-msg__body{display:flex;flex-direction:row;justify-content:space-between}.conversejs .chatroom-body .message.onload{animation:colorchange-chatmessage-muc 1s;-webkit-animation:colorchange-chatmessage-muc 1s}.conversejs .chatroom-body .message .separator{border-top:0px;border-bottom:var(--chatroom-separator-border-bottom)}.conversejs converse-chats.converse-overlayed .message.chat-msg.chat-msg--followup .chat-msg__content{margin-left:0}@media screen and (max-width: 767px){converse-chats:not(.converse-embedded) .message.chat-msg .chat-msg__author{white-space:normal}}#conversejs-bg .subdued{opacity:.35}#conversejs-bg .converse-brand{display:flex;justify-content:space-between;margin-top:15vh;animation-name:fadein;animation-fill-mode:forwards;animation-duration:5s;animation-timing-function:ease}#conversejs-bg .converse-brand__text{color:#fff;font-family:var(--branding-font);font-weight:normal;text-align:center;font-size:140%;margin-left:.2em}#conversejs-bg .converse-brand__text .byline{margin:0;font-family:var(--heading-font);font-size:.3em;opacity:.55;margin-bottom:2em;margin-left:-2.7em;word-spacing:5px}@media screen and (max-width: 480px){#conversejs-bg .converse-brand{display:none}}@media(max-width: 767.98px){#conversejs-bg .converse-brand{display:none}}.converse-fullscreen #conversejs-bg .converse-brand__padding{position:relative;width:100%;padding-right:15px;padding-left:15px;padding:0}@media(min-width: 768px){.converse-fullscreen #conversejs-bg .converse-brand__padding{flex:0 0 33.33333333%;max-width:33.33333333%}}@media(min-width: 992px){.converse-fullscreen #conversejs-bg .converse-brand__padding{flex:0 0 25%;max-width:25%}}@media(min-width: 1200px){.converse-fullscreen #conversejs-bg .converse-brand__padding{flex:0 0 16.66666667%;max-width:16.66666667%}}.converse-fullscreen #conversejs-bg .converse-brand__heading{position:relative;width:100%;padding-right:15px;padding-left:15px;padding:0;display:flex;justify-content:center;margin:auto}@media(min-width: 768px){.converse-fullscreen #conversejs-bg .converse-brand__heading{font-size:4em;flex:0 0 66.66666667%;max-width:66.66666667%}}@media(min-width: 992px){.converse-fullscreen #conversejs-bg .converse-brand__heading{font-size:5em;flex:0 0 75%;max-width:75%}}@media(min-width: 1200px){.converse-fullscreen #conversejs-bg .converse-brand__heading{font-size:6em;flex:0 0 83.33333333%;max-width:83.33333333%}}.converse-fullscreen #conversejs-bg .converse-brand__heading svg{margin-top:.3em}.converse-overlayed #conversejs-bg .converse-brand__padding{position:relative;width:100%;padding-right:15px;padding-left:15px;padding:0}@media(min-width: 768px){.converse-overlayed #conversejs-bg .converse-brand__padding{flex:0 0 16.66666667%;max-width:16.66666667%}}@media(min-width: 992px){.converse-overlayed #conversejs-bg .converse-brand__padding{flex:0 0 8.33333333%;max-width:8.33333333%}}@media(min-width: 1200px){.converse-overlayed #conversejs-bg .converse-brand__padding{flex:0 0 8.33333333%;max-width:8.33333333%}}.converse-overlayed #conversejs-bg .converse-brand__heading{position:relative;width:100%;padding-right:15px;padding-left:15px;padding:0;display:flex;justify-content:center;margin:auto}@media(min-width: 768px){.converse-overlayed #conversejs-bg .converse-brand__heading{font-size:4em;flex:0 0 66.66666667%;max-width:66.66666667%}}@media(min-width: 992px){.converse-overlayed #conversejs-bg .converse-brand__heading{font-size:5em;flex:0 0 83.33333333%;max-width:83.33333333%}}@media(min-width: 1200px){.converse-overlayed #conversejs-bg .converse-brand__heading{font-size:6em;flex:0 0 83.33333333%;max-width:83.33333333%}}.converse-overlayed #conversejs-bg .converse-brand__heading svg{margin-top:.3em} +.conversejs .modal-open{overflow:hidden}.conversejs .modal-open .modal{overflow-x:hidden;overflow-y:auto}.conversejs .modal{position:fixed;top:0;left:0;z-index:1050;display:none;width:100%;height:100%;overflow:hidden;outline:0}.conversejs .modal-dialog{position:relative;width:auto;margin:.5rem;pointer-events:none}.modal.fade .conversejs .modal-dialog{transition:transform .3s ease-out;transform:translate(0, -50px)}@media(prefers-reduced-motion: reduce){.modal.fade .conversejs .modal-dialog{transition:none}}.modal.show .conversejs .modal-dialog{transform:none}.modal.modal-static .conversejs .modal-dialog{transform:scale(1.02)}.conversejs .modal-dialog-scrollable{display:flex;max-height:calc(100% - 1rem)}.conversejs .modal-dialog-scrollable .modal-content{max-height:calc(100vh - 1rem);overflow:hidden}.conversejs .modal-dialog-scrollable .modal-header,.conversejs .modal-dialog-scrollable .modal-footer{flex-shrink:0}.conversejs .modal-dialog-scrollable .modal-body{overflow-y:auto}.conversejs .modal-dialog-centered{display:flex;align-items:center;min-height:calc(100% - 1rem)}.conversejs .modal-dialog-centered::before{display:block;height:calc(100vh - 1rem);height:-moz-min-content;height:min-content;content:""}.conversejs .modal-dialog-centered.modal-dialog-scrollable{flex-direction:column;justify-content:center;height:100%}.conversejs .modal-dialog-centered.modal-dialog-scrollable .modal-content{max-height:none}.conversejs .modal-dialog-centered.modal-dialog-scrollable::before{content:none}.conversejs .modal-content{position:relative;display:flex;flex-direction:column;width:100%;pointer-events:auto;background-color:#fff;background-clip:padding-box;border:1px solid rgba(0,0,0,.2);border-radius:.3rem;outline:0}.conversejs .modal-backdrop{position:fixed;top:0;left:0;z-index:1040;width:100vw;height:100vh;background-color:#000}.conversejs .modal-backdrop.fade{opacity:0}.conversejs .modal-backdrop.show{opacity:.5}.conversejs .modal-header{display:flex;align-items:flex-start;justify-content:space-between;padding:1rem 1rem;border-bottom:1px solid #dee2e6;border-top-left-radius:calc(0.3rem - 1px);border-top-right-radius:calc(0.3rem - 1px)}.conversejs .modal-header .close{padding:1rem 1rem;margin:-1rem -1rem -1rem auto}.conversejs .modal-title{margin-bottom:0;line-height:1.5}.conversejs .modal-body{position:relative;flex:1 1 auto;padding:1rem}.conversejs .modal-footer{display:flex;flex-wrap:wrap;align-items:center;justify-content:flex-end;padding:.75rem;border-top:1px solid #dee2e6;border-bottom-right-radius:calc(0.3rem - 1px);border-bottom-left-radius:calc(0.3rem - 1px)}.conversejs .modal-footer>*{margin:.25rem}.conversejs .modal-scrollbar-measure{position:absolute;top:-9999px;width:50px;height:50px;overflow:scroll}@media(min-width: 576px){.conversejs .modal-dialog{max-width:500px;margin:1.75rem auto}.conversejs .modal-dialog-scrollable{max-height:calc(100% - 3.5rem)}.conversejs .modal-dialog-scrollable .modal-content{max-height:calc(100vh - 3.5rem)}.conversejs .modal-dialog-centered{min-height:calc(100% - 3.5rem)}.conversejs .modal-dialog-centered::before{height:calc(100vh - 3.5rem);height:-moz-min-content;height:min-content}.conversejs .modal-sm{max-width:300px}}@media(min-width: 992px){.conversejs .modal-lg,.conversejs .modal-xl{max-width:800px}}@media(min-width: 1200px){.conversejs .modal-xl{max-width:1140px}}.conversejs .modal-header.alert-danger{background-color:var(--error-color);color:var(--background);border-bottom:none}.conversejs .modal-header.alert-danger .close{color:var(--background)}.conversejs .modal-content{background-color:var(--modal-background-color)}.conversejs .modal-body .row{margin-left:0;margin-right:0}.conversejs .occupant-details li{margin-bottom:1em}.conversejs #converse-modals .modal .nav-item{margin:.25em}.conversejs #converse-modals .modal .nav-item .nav-link.active{color:var(--background)}.conversejs #converse-modals .modal .nav-item:hover .nav-link{color:var(--foreground);background-color:var(--primary-color-light)}.conversejs #converse-modals .modal .nav-item:hover .nav-link.active{color:var(--background);background-color:var(--primary-color)}.conversejs #converse-modals .modal .modal-content{box-shadow:var(--raised-el-shadow)}.conversejs #converse-modals .modal .modal-body{overflow-y:auto;max-height:75vh;margin-bottom:2em}.conversejs #converse-modals .modal .modal-body p{padding:.25rem 0}.conversejs #converse-modals .modal .modal-body .confirm .form-group p:first-child{font-size:110%;font-weight:bold}.conversejs #converse-modals .modal .modal-body.fit-content{box-sizing:content-box}.conversejs #converse-modals .modal .modal-body.fit-content img{max-width:90vw}.conversejs #converse-modals .modal .modal-footer{justify-content:flex-start}.conversejs #converse-modals .modal .roomid-policy-error{color:var(--error-color);font-size:var(--font-size-small);float:right}.conversejs #converse-modals .scrollable-container{max-height:45vh;overflow-y:auto}.conversejs #converse-modals .role-form,.conversejs #converse-modals .affiliation-form{padding:2em 0 1em 0}.conversejs #converse-modals .set-xmpp-status{margin:1em}.conversejs #converse-modals .set-xmpp-status .custom-control-label{padding-top:.25em}.conversejs #converse-modals #omemo-tabpanel{margin-top:1em}.conversejs #converse-modals .btn{font-weight:normal} +.conversejs [hidden]{display:none}.conversejs .visually-hidden{position:absolute;clip:rect(0, 0, 0, 0)}.conversejs .form-group .suggestion-box{width:100%}.conversejs .suggestion-box{position:relative}.conversejs .suggestion-box mark{background:var(--completion-light-color)}.conversejs .suggestion-box>input{display:block}.conversejs .suggestion-box .suggestion-box__results,.conversejs .suggestion-box>ul{border-radius:.3em;border:1px solid var(--focus-color);box-shadow:.05em .2em .6em rgba(0,0,0,.1);box-sizing:border-box;left:0;list-style:none;margin:.2em 0 0;min-width:100%;padding:0;position:absolute;right:0;text-shadow:none;z-index:2}.conversejs .suggestion-box .suggestion-box__results:before,.conversejs .suggestion-box>ul:before{content:"";position:absolute;top:-0.43em;left:1em;width:0;height:0;padding:.4em;background:var(--background);border:inherit;border-right:0;border-bottom:0;transform:rotate(45deg);z-index:-1}.conversejs .suggestion-box .suggestion-box__results>li,.conversejs .suggestion-box>ul>li{background:var(--background);color:var(--text-color);cursor:pointer;display:flex;overflow-x:hidden;padding:1em;position:relative;text-overflow:ellipsis}.conversejs .suggestion-box .suggestion-box__results--below{top:3em}.conversejs .suggestion-box .suggestion-box__results--above{bottom:4.5em}.conversejs .suggestion-box .suggestion-box__results--above:before{display:none}.conversejs .suggestion-box .suggestion-box__results--above:after{z-index:-1;content:"";position:absolute;bottom:-0.43em;left:1em;width:0;height:0;padding:.4em;background:var(--background);border:inherit;border-left:0;border-top:0;transform:rotate(45deg)}.conversejs .suggestion-box>ul[hidden],.conversejs .suggestion-box>ul:empty{display:none}@supports(transform: scale(0)){.conversejs .suggestion-box>ul{transition:.3s cubic-bezier(0.4, 0.2, 0.5, 1.4);transform-origin:1.43em -0.43em}.conversejs .suggestion-box>ul[hidden],.conversejs .suggestion-box>ul:empty{opacity:0;transform:scale(0);display:block;transition-timing-function:ease}}.conversejs .suggestion-box>ul>li[aria-selected=true]{background:var(--completion-dark-color);color:var(--inverse-link-color)}.conversejs .suggestion-box li:hover mark{background:var(--completion-light-color);color:var(--inverse-link-color)}.conversejs .suggestion-box li[aria-selected=true] mark{background:var(--completion-normal-color);color:inherit}.conversejs.converse-fullscreen .suggestion-box__results--above{bottom:4.5em}.conversejs.converse-overlayed .suggestion-box__results--above{bottom:3.5em} +converse-avatar{border:0;background:rgba(0,0,0,0)}converse-avatar.modal-avatar{display:block;margin-bottom:1em}converse-avatar .avatar{border-radius:var(--avatar-border-radius)} +converse-modtools converse-icon svg{fill:var(--link-color)} +.conversejs #controlbox .bookmarks-toggle,.conversejs #controlbox .bookmarks-toggle .fa{color:var(--groupchats-header-color) !important}.conversejs #controlbox .bookmarks-toggle:hover,.conversejs #controlbox .bookmarks-toggle .fa:hover{color:var(--chatroom-head-bg-color-dark) !important}.conversejs.fullscreen #controlbox #chatrooms .bookmarks-list dl.rooms-list.bookmarks dd.available-chatroom a.open-room{width:80%}converse-bookmarks .list-item-link{padding:0 1em} +.conversejs converse-chats.converse-chatboxes{z-index:1031;position:fixed;bottom:0;right:0}.conversejs converse-chats.converse-overlayed{height:3em}.conversejs converse-chats.converse-overlayed>.row{flex-direction:row-reverse}.conversejs converse-chats.converse-fullscreen,.conversejs converse-chats.converse-mobile{flex-wrap:nowrap;width:100vw}.conversejs converse-chats.converse-embedded{box-sizing:border-box;bottom:auto;height:100%;position:relative;right:auto;width:100%}.conversejs converse-chats.converse-embedded *,.conversejs converse-chats.converse-embedded *:before,.conversejs converse-chats.converse-embedded *:after{box-sizing:border-box}.conversejs converse-chats.converse-embedded.converse-chatboxes{z-index:1031;position:inherit;flex-wrap:nowrap;bottom:auto;height:100%;width:100%} +converse-message-actions{margin-left:.5em}converse-message-actions .chat-msg__actions .dropdown-menu{min-width:5rem}converse-message-actions .chat-msg__actions i{color:var(--text-color-lighten-15-percent);font-size:70%}converse-message-actions .chat-msg__actions button{border:none;background:rgba(0,0,0,0);color:var(--text-color-lighten-15-percent);padding:0 .25em}converse-message-actions .chat-msg__actions .btn--standalone{opacity:0;margin-top:-0.2em}converse-message-actions .chat-msg__actions .chat-msg__action{width:100%;padding:.5em 1em;text-align:left;white-space:nowrap}converse-message-actions .chat-msg__actions .chat-msg__action converse-icon{margin-right:.25em}converse-message-actions .chat-msg__actions .chat-msg__action:hover{color:var(--text-color);background-color:var(--list-item-hover-color)} +converse-image-modal .chat-image--modal{max-height:99%;max-width:100%} +converse-gif{display:block}img.gif{visibility:hidden}.gif-canvas{cursor:pointer;max-width:100%;max-height:100%;display:block}.gifcontrol{cursor:pointer;transition:background .25s ease-in-out;z-index:100;display:contents;position:relative}.gifcontrol:after{transition:background .25s ease-in-out;position:absolute;content:"";display:block;left:calc(50% - 25px);top:calc(50% - 25px)}.gifcontrol.loading{background:rgba(255,255,255,.75)}.gifcontrol.loading:after{background:#fff;width:50px;height:50px;border-radius:50px}.gifcontrol.playing:after{opacity:0;transition:opacity .25s ease-in-out;border-left:20px solid #fff;border-right:20px solid #fff;width:50px;height:50px}.gifcontrol.playing:hover:after{opacity:1}.gifcontrol.paused{background:rgba(255,255,255,.5)}.gifcontrol.paused:after{width:0;height:0;border-style:solid;border-width:25px 0 25px 50px;border-color:rgba(0,0,0,0) rgba(0,0,0,0) rgba(0,0,0,0) #fff} +converse-chat-message-body{margin-right:.5em;overflow-y:hidden}converse-chat-message-body audio{display:block}@media(max-width: 767.98px){converse-chat-message-body audio{max-width:95%}}@media(min-width: 768px){converse-chat-message-body audio{max-width:70%}}@media(min-width: 992px){converse-chat-message-body audio{max-width:50%}}@media(min-width: 1200px){converse-chat-message-body audio{max-width:40%}}converse-chat-message-body video{display:block;max-height:25em}@media(max-width: 767.98px){converse-chat-message-body video{max-width:95%}}@media(min-width: 768px){converse-chat-message-body video{max-width:70%}}@media(min-width: 992px){converse-chat-message-body video{max-width:50%}}@media(min-width: 1200px){converse-chat-message-body video{max-width:40%}}.converse-overlayed converse-chat-message-body audio{display:block;max-width:100%}.converse-overlayed converse-chat-message-body video{display:block;max-width:100%} +converse-icon{display:inline-block;padding:0;margin:0}converse-icon svg{fill:var(--subdued-color)}converse-icon.clickable:hover svg{fill:var(--icon-hover-color)}a converse-icon:hover svg,.clickable converse-icon:hover svg{fill:var(--icon-hover-color)} +.conversejs .dropup,.conversejs .dropright,.conversejs .dropdown,.conversejs .dropleft{position:relative}.conversejs .dropdown-toggle{white-space:nowrap}.conversejs .dropdown-toggle::after{display:inline-block;margin-left:.255em;vertical-align:.255em;content:"";border-top:.3em solid;border-right:.3em solid rgba(0,0,0,0);border-bottom:0;border-left:.3em solid rgba(0,0,0,0)}.conversejs .dropdown-toggle:empty::after{margin-left:0}.conversejs .dropdown-menu{position:absolute;top:100%;left:0;z-index:1000;display:none;float:left;min-width:10rem;padding:.5rem 0;margin:.125rem 0 0;font-size:1rem;color:#212529;text-align:left;list-style:none;background-color:#fff;background-clip:padding-box;border:1px solid rgba(0,0,0,.15);border-radius:.25rem}.conversejs .dropdown-menu-left{right:auto;left:0}.conversejs .dropdown-menu-right{right:0;left:auto}@media(min-width: 576px){.conversejs .dropdown-menu-sm-left{right:auto;left:0}.conversejs .dropdown-menu-sm-right{right:0;left:auto}}@media(min-width: 768px){.conversejs .dropdown-menu-md-left{right:auto;left:0}.conversejs .dropdown-menu-md-right{right:0;left:auto}}@media(min-width: 992px){.conversejs .dropdown-menu-lg-left{right:auto;left:0}.conversejs .dropdown-menu-lg-right{right:0;left:auto}}@media(min-width: 1200px){.conversejs .dropdown-menu-xl-left{right:auto;left:0}.conversejs .dropdown-menu-xl-right{right:0;left:auto}}.conversejs .dropup .dropdown-menu{top:auto;bottom:100%;margin-top:0;margin-bottom:.125rem}.conversejs .dropup .dropdown-toggle::after{display:inline-block;margin-left:.255em;vertical-align:.255em;content:"";border-top:0;border-right:.3em solid rgba(0,0,0,0);border-bottom:.3em solid;border-left:.3em solid rgba(0,0,0,0)}.conversejs .dropup .dropdown-toggle:empty::after{margin-left:0}.conversejs .dropright .dropdown-menu{top:0;right:auto;left:100%;margin-top:0;margin-left:.125rem}.conversejs .dropright .dropdown-toggle::after{display:inline-block;margin-left:.255em;vertical-align:.255em;content:"";border-top:.3em solid rgba(0,0,0,0);border-right:0;border-bottom:.3em solid rgba(0,0,0,0);border-left:.3em solid}.conversejs .dropright .dropdown-toggle:empty::after{margin-left:0}.conversejs .dropright .dropdown-toggle::after{vertical-align:0}.conversejs .dropleft .dropdown-menu{top:0;right:100%;left:auto;margin-top:0;margin-right:.125rem}.conversejs .dropleft .dropdown-toggle::after{display:inline-block;margin-left:.255em;vertical-align:.255em;content:""}.conversejs .dropleft .dropdown-toggle::after{display:none}.conversejs .dropleft .dropdown-toggle::before{display:inline-block;margin-right:.255em;vertical-align:.255em;content:"";border-top:.3em solid rgba(0,0,0,0);border-right:.3em solid;border-bottom:.3em solid rgba(0,0,0,0)}.conversejs .dropleft .dropdown-toggle:empty::after{margin-left:0}.conversejs .dropleft .dropdown-toggle::before{vertical-align:0}.conversejs .dropdown-menu[x-placement^=top],.conversejs .dropdown-menu[x-placement^=right],.conversejs .dropdown-menu[x-placement^=bottom],.conversejs .dropdown-menu[x-placement^=left]{right:auto;bottom:auto}.conversejs .dropdown-divider{height:0;margin:.5rem 0;overflow:hidden;border-top:1px solid #e9ecef}.conversejs .dropdown-item{display:block;width:100%;padding:.25rem 1.5rem;clear:both;font-weight:400;color:#212529;text-align:inherit;white-space:nowrap;background-color:rgba(0,0,0,0);border:0}.conversejs .dropdown-item:hover,.conversejs .dropdown-item:focus{color:#16181b;text-decoration:none;background-color:#e9ecef}.conversejs .dropdown-item.active,.conversejs .dropdown-item:active{color:#fff;text-decoration:none;background-color:#007bff}.conversejs .dropdown-item.disabled,.conversejs .dropdown-item:disabled{color:#adb5bd;pointer-events:none;background-color:rgba(0,0,0,0)}.conversejs .dropdown-menu.show{display:block}.conversejs .dropdown-header{display:block;padding:.5rem 1.5rem;margin-bottom:0;font-size:0.875rem;color:#6c757d;white-space:nowrap}.conversejs .dropdown-item-text{display:block;padding:.25rem 1.5rem;color:#212529}.conversejs converse-dropdown.dropup.dropup--left .dropdown-menu{right:100%;left:auto}.conversejs converse-dropdown .btn--standalone{padding:0 .2em;margin:0}.conversejs converse-dropdown .dropdown-menu{background:var(--background);margin-top:-0.2em !important;box-shadow:var(--raised-el-shadow)}.conversejs converse-dropdown .dropdown-item{line-height:1em;color:var(--text-color);padding:.5rem 1rem}.conversejs converse-dropdown .dropdown-item converse-icon{margin-top:-0.1em;width:1.25em;margin-right:0}.conversejs converse-dropdown .dropdown-item:active,.conversejs converse-dropdown .dropdown-item.selected{color:#fff !important;background-color:var(--list-item-open-color)}.conversejs converse-dropdown .dropdown-item:active .fa,.conversejs converse-dropdown .dropdown-item.selected .fa{color:#fff !important}.conversejs converse-dropdown .dropdown-item:hover{color:var(--text-color);background-color:var(--list-item-hover-color)} +.conversejs converse-message-versions time{font-weight:bold} +.conversejs .card{position:relative;display:flex;flex-direction:column;min-width:0;word-wrap:break-word;background-color:#fff;background-clip:border-box;border:1px solid rgba(0,0,0,.125);border-radius:.25rem}.conversejs .card>hr{margin-right:0;margin-left:0}.conversejs .card>.list-group{border-top:inherit;border-bottom:inherit}.conversejs .card>.list-group:first-child{border-top-width:0;border-top-left-radius:calc(0.25rem - 1px);border-top-right-radius:calc(0.25rem - 1px)}.conversejs .card>.list-group:last-child{border-bottom-width:0;border-bottom-right-radius:calc(0.25rem - 1px);border-bottom-left-radius:calc(0.25rem - 1px)}.conversejs .card>.card-header+.list-group,.conversejs .card>.list-group+.card-footer{border-top:0}.conversejs .card-body{flex:1 1 auto;min-height:1px;padding:1.25rem}.conversejs .card-title{margin-bottom:.75rem}.conversejs .card-subtitle{margin-top:-0.375rem;margin-bottom:0}.conversejs .card-text:last-child{margin-bottom:0}.conversejs .card-link:hover{text-decoration:none}.conversejs .card-link+.card-link{margin-left:1.25rem}.conversejs .card-header{padding:.75rem 1.25rem;margin-bottom:0;background-color:rgba(0,0,0,.03);border-bottom:1px solid rgba(0,0,0,.125)}.conversejs .card-header:first-child{border-radius:calc(0.25rem - 1px) calc(0.25rem - 1px) 0 0}.conversejs .card-footer{padding:.75rem 1.25rem;background-color:rgba(0,0,0,.03);border-top:1px solid rgba(0,0,0,.125)}.conversejs .card-footer:last-child{border-radius:0 0 calc(0.25rem - 1px) calc(0.25rem - 1px)}.conversejs .card-header-tabs{margin-right:-0.625rem;margin-bottom:-0.75rem;margin-left:-0.625rem;border-bottom:0}.conversejs .card-header-pills{margin-right:-0.625rem;margin-left:-0.625rem}.conversejs .card-img-overlay{position:absolute;top:0;right:0;bottom:0;left:0;padding:1.25rem;border-radius:calc(0.25rem - 1px)}.conversejs .card-img,.conversejs .card-img-top,.conversejs .card-img-bottom{flex-shrink:0;width:100%}.conversejs .card-img,.conversejs .card-img-top{border-top-left-radius:calc(0.25rem - 1px);border-top-right-radius:calc(0.25rem - 1px)}.conversejs .card-img,.conversejs .card-img-bottom{border-bottom-right-radius:calc(0.25rem - 1px);border-bottom-left-radius:calc(0.25rem - 1px)}.conversejs .card-deck .card{margin-bottom:15px}@media(min-width: 576px){.conversejs .card-deck{display:flex;flex-flow:row wrap;margin-right:-15px;margin-left:-15px}.conversejs .card-deck .card{flex:1 0 0%;margin-right:15px;margin-bottom:0;margin-left:15px}}.conversejs .card-group>.card{margin-bottom:15px}@media(min-width: 576px){.conversejs .card-group{display:flex;flex-flow:row wrap}.conversejs .card-group>.card{flex:1 0 0%;margin-bottom:0}.conversejs .card-group>.card+.card{margin-left:0;border-left:0}.conversejs .card-group>.card:not(:last-child){border-top-right-radius:0;border-bottom-right-radius:0}.conversejs .card-group>.card:not(:last-child) .card-img-top,.conversejs .card-group>.card:not(:last-child) .card-header{border-top-right-radius:0}.conversejs .card-group>.card:not(:last-child) .card-img-bottom,.conversejs .card-group>.card:not(:last-child) .card-footer{border-bottom-right-radius:0}.conversejs .card-group>.card:not(:first-child){border-top-left-radius:0;border-bottom-left-radius:0}.conversejs .card-group>.card:not(:first-child) .card-img-top,.conversejs .card-group>.card:not(:first-child) .card-header{border-top-left-radius:0}.conversejs .card-group>.card:not(:first-child) .card-img-bottom,.conversejs .card-group>.card:not(:first-child) .card-footer{border-bottom-left-radius:0}}.conversejs .card-columns .card{margin-bottom:.75rem}@media(min-width: 576px){.conversejs .card-columns{-moz-column-count:3;column-count:3;-moz-column-gap:1.25rem;column-gap:1.25rem;orphans:1;widows:1}.conversejs .card-columns .card{display:inline-block;width:100%}}.conversejs .accordion{overflow-anchor:none}.conversejs .accordion>.card{overflow:hidden}.conversejs .accordion>.card:not(:last-of-type){border-bottom:0;border-bottom-right-radius:0;border-bottom-left-radius:0}.conversejs .accordion>.card:not(:first-of-type){border-top-left-radius:0;border-top-right-radius:0}.conversejs .accordion>.card>.card-header{border-radius:0;margin-bottom:-1px}.conversejs converse-message-unfurl .card--unfurl{background-color:var(--chat-content-background-color)}.conversejs converse-message-unfurl .card--unfurl .card-body{padding:.75rem}.conversejs converse-message-unfurl .card--unfurl .card-body .vcard-title{font-size:90%}.conversejs converse-message-unfurl .card--unfurl .card-text converse-rich-text{font-size:80%}.conversejs converse-message-unfurl .card--unfurl .card-img-top{margin-top:.75rem}.conversejs converse-chats.converse-embedded .message .card--unfurl,.conversejs converse-chats.converse-fullscreen .message .card--unfurl{margin:1em 0}@media(max-width: 767.98px){.conversejs converse-chats.converse-embedded .message .card--unfurl,.conversejs converse-chats.converse-fullscreen .message .card--unfurl{max-width:95%}}@media(min-width: 768px){.conversejs converse-chats.converse-embedded .message .card--unfurl,.conversejs converse-chats.converse-fullscreen .message .card--unfurl{max-width:75%}}@media(min-width: 992px){.conversejs converse-chats.converse-embedded .message .card--unfurl,.conversejs converse-chats.converse-fullscreen .message .card--unfurl{max-width:60%}}@media(min-width: 1200px){.conversejs converse-chats.converse-embedded .message .card--unfurl,.conversejs converse-chats.converse-fullscreen .message .card--unfurl{max-width:30%}}.conversejs converse-chats.converse-overlayed .message .card--unfurl,.conversejs converse-chats.converse-mobile .message .card--unfurl{margin:1em 0;max-width:95%} +converse-chat-message .message.chat-msg--retracted .chat-msg__message{color:var(--subdued-color)} +converse-chat-content{display:flex;flex-direction:column-reverse;height:100%;justify-content:space-between;overflow:auto} +.conversejs .media{display:flex;align-items:flex-start}.conversejs .media-body{flex:1}.conversejs .chatbox img.emoji{height:1.2em;width:1.2em;margin:0 .05em 0 .1em;vertical-align:-0.1em}.conversejs .chatbox .sendXMPPMessage .toggle-smiley a.toggle-smiley{padding:0}.conversejs .chatbox converse-emoji-dropdown{display:inline-block}.conversejs .chatbox converse-emoji-dropdown .dropdown-menu{padding:0}.conversejs .chatbox converse-emoji-picker{width:100%;padding-top:0;padding-bottom:0;background-color:var(--chat-head-color);overflow-y:hidden}.conversejs .chatbox converse-emoji-picker converse-emoji-picker-content{width:100%}.conversejs .chatbox converse-emoji-picker converse-emoji-picker-content .emoji-picker__lists{background-color:var(--background);display:flex;flex-direction:column;height:8em;overflow-y:auto;width:100%}.conversejs .chatbox converse-emoji-picker converse-emoji-picker-content .emoji-picker__lists .emoji-category__heading{clear:both;color:var(--subdued-color);cursor:auto;display:block;font-size:var(--font-size);margin:0;padding:.75em 0 0 .5em}.conversejs .chatbox converse-emoji-picker converse-emoji-picker-content .emoji-picker__lists .emoji-lists__container{background-color:var(--background);overflow-x:hidden}.conversejs .chatbox converse-emoji-picker converse-emoji-picker-content .emoji-picker__lists .emoji-picker li{float:left}.conversejs .chatbox converse-emoji-picker .emoji-skintone-picker{display:flex;padding:.5em 0;background-color:var(--chat-head-color);width:100%;font-size:var(--font-size)}.conversejs .chatbox converse-emoji-picker .emoji-skintone-picker ul{display:flex;flex-direction:row;flex-wrap:wrap}.conversejs .chatbox converse-emoji-picker .emoji-skintone-picker ul li{padding:0 .25em}.conversejs .chatbox converse-emoji-picker .emoji-picker{background-color:var(--background);padding:.5em 0 0 .5em}.conversejs .chatbox converse-emoji-picker .emoji-picker:last-child{padding-bottom:.5em}.conversejs .chatbox converse-emoji-picker .emoji-picker li{display:inline-block;height:calc(var(--font-size-huge)*1.5);width:calc(var(--font-size-huge)*1.5);overflow:hidden;margin-left:0;list-style:none;position:relative}.conversejs .chatbox converse-emoji-picker .emoji-picker li.insert-emoji{padding:0 .2em;height:auto;width:auto;margin:0;display:block;text-align:center}.conversejs .chatbox converse-emoji-picker .emoji-picker li.insert-emoji.selected a{background-color:var(--highlight-color-darker)}.conversejs .chatbox converse-emoji-picker .emoji-picker li.insert-emoji img{margin:0 auto;height:var(--font-size-huge);width:var(--font-size-huge);display:inline-block;vertical-align:baseline}.conversejs .chatbox converse-emoji-picker .emoji-picker li.insert-emoji a{display:inline-block;font-size:var(--font-size-huge);line-height:calc(var(--font-size-huge)*1.5);height:calc(var(--font-size-huge)*1.5);width:calc(var(--font-size-huge)*1.5);overflow:hidden}.conversejs .chatbox converse-emoji-picker .emoji-picker li.insert-emoji a:hover{background-color:var(--highlight-color-darker)}.conversejs .chatbox converse-emoji-picker .emoji-picker__header{width:100%;display:flex;flex-direction:column;padding:.1em 0;background-color:var(--chat-head-color)}.conversejs .chatbox converse-emoji-picker .emoji-picker__header .emoji-search{width:auto;margin:.25em;height:2em;font-size:var(--font-size-small)}.conversejs .chatbox converse-emoji-picker .emoji-picker__header ul{display:flex;flex-direction:row;flex-wrap:wrap}.conversejs .chatbox converse-emoji-picker .emoji-picker__header ul .emoji-category{padding:.25em 0;font-size:var(--font-size-huge)}.conversejs .chatbox converse-emoji-picker .emoji-picker__header ul .emoji-category.picked a{background-color:var(--heading-color)}.conversejs .chatbox converse-emoji-picker .emoji-picker__header ul .emoji-category.selected a,.conversejs .chatbox converse-emoji-picker .emoji-picker__header ul .emoji-category:hover a{background-color:var(--highlight-color-darker)}.conversejs .chatbox converse-emoji-picker .emoji-picker__header ul .emoji-category a{padding:.25em;display:inline-block}.conversejs .chatbox converse-emoji-picker .emoji-picker__header ul .emoji-category img{height:var(--font-size-huge);width:var(--font-size-huge)}.conversejs .chatroom converse-emoji-picker{background-color:var(--chatroom-head-bg-color)}.conversejs .chatroom converse-emoji-picker .emoji-skintone-picker{background-color:var(--chatroom-head-bg-color)}.conversejs .chatroom converse-emoji-picker .emoji-picker__header{background-color:var(--chatroom-head-bg-color)}.conversejs converse-chats.converse-overlayed converse-emoji-dropdown .dropdown-menu{min-width:18em}.conversejs converse-chats.converse-overlayed .chatbox .emoji-picker__header .emoji-category img{height:var(--font-size) !important;width:var(--font-size) !important}.conversejs converse-chats.converse-overlayed .chatbox converse-emoji-picker .emoji-picker .insert-emoji a{font-size:var(--font-size);line-height:calc(var(--font-size)*1.5);padding:0;height:calc(var(--font-size)*1.5);width:calc(var(--font-size)*1.5)}.conversejs converse-chats.converse-overlayed .chatbox converse-emoji-picker .emoji-picker .insert-emoji img{height:var(--font-size);width:var(--font-size)}.conversejs converse-chats.converse-overlayed .chatbox converse-emoji-picker .emoji-skintone-picker{font-size:var(--font-size-small)}.conversejs converse-chats.converse-overlayed .chatbox converse-emoji-picker .emoji-picker__header .emoji-category{font-size:var(--font-size-small)}.conversejs converse-chats.converse-overlayed .chatbox converse-emoji-picker .emoji-picker__lists{height:7em}.conversejs converse-chats.converse-embedded converse-emoji-dropdown .dropdown-menu{min-width:20em}.conversejs converse-chats.converse-fullscreen converse-emoji-dropdown .dropdown-menu{min-width:22em}.conversejs converse-chats.converse-fullscreen .chatbox converse-emoji-picker .emoji-picker__lists{height:12em}.conversejs .chatbox converse-emoji-picker{max-width:40em} +.conversejs .send-button{border-radius:0;bottom:var(--send-button-bottom);color:var(--inverse-link-color)}.conversejs .chatbox .send-button{color:var(--background);background-color:var(--chat-toolbar-btn-color)}.conversejs .chatroom .send-button{background-color:var(--muc-toolbar-btn-color)}.conversejs .chat-toolbar .toolbar-buttons{width:100%}.conversejs .chat-toolbar .toolbar-buttons .message-limit{padding:.5em;font-weight:bold}.conversejs .chat-toolbar .toolbar-buttons *{float:left}.conversejs .chat-toolbar .toolbar-buttons .right{float:right}.conversejs .chat-toolbar .unverified a,.conversejs .chat-toolbar .unverified{color:#cf5300}.conversejs .chat-toolbar .private a,.conversejs .chat-toolbar .private{color:#4b7003}.conversejs .chat-toolbar li{cursor:pointer;display:inline-block;list-style:none;padding:0 .5em}.conversejs .chat-toolbar li:hover{cursor:pointer}.conversejs .chat-toolbar li .toolbar-menu{bottom:1.7rem;box-shadow:-1px -1px 2px 0 rgba(0,0,0,.4);height:auto;margin-bottom:0;min-width:21rem;position:absolute;right:0;top:auto;z-index:1000}.conversejs .chat-toolbar li .toolbar-menu.otr-menu{left:-6em;min-width:15rem}.conversejs .chat-toolbar li .toolbar-menu.otr-menu.show{display:flex;flex-direction:column}.conversejs .chat-toolbar li .toolbar-menu a{color:var(--link-color)}.conversejs .chat-toolbar li.toggle-otr ul{z-index:99}.conversejs .chat-toolbar li.toggle-otr ul li{display:block;padding:7px}.conversejs .chat-toolbar li.toggle-otr ul li:hover{background-color:var(--highlight-color)}.conversejs .chat-toolbar li.toggle-otr ul li a{display:block}.conversejs converse-chat-toolbar{background-color:var(--chat-background-color);box-sizing:border-box;display:flex;justify-content:space-between;margin:0;width:100%}.conversejs converse-chat-toolbar .fa,.conversejs converse-chat-toolbar .fa:hover,.conversejs converse-chat-toolbar .far,.conversejs converse-chat-toolbar .far:hover,.conversejs converse-chat-toolbar .fas,.conversejs converse-chat-toolbar .fas:hover{color:var(--chat-head-color);font-size:var(--font-size-large)}.conversejs converse-chat-toolbar .fa svg,.conversejs converse-chat-toolbar .fa:hover svg,.conversejs converse-chat-toolbar .far svg,.conversejs converse-chat-toolbar .far:hover svg,.conversejs converse-chat-toolbar .fas svg,.conversejs converse-chat-toolbar .fas:hover svg{fill:var(--chat-head-color)}.conversejs converse-chat-toolbar .unencrypted a,.conversejs converse-chat-toolbar .unencrypted{color:var(--text-color)}.conversejs converse-chat-toolbar .unencrypted a .toolbar-menu a,.conversejs converse-chat-toolbar .unencrypted .toolbar-menu a{color:var(--link-color)}.conversejs converse-chat-toolbar button{margin-top:.4em;border:1px rgba(0,0,0,0) solid;background-color:rgba(0,0,0,0)}.conversejs converse-chat-toolbar button.send-button{padding-top:.2em;padding-bottom:.2em;margin:0;margin-top:-1px}.conversejs .chatbox converse-chat-toolbar{border-top:var(--chatbox-message-input-border-top);color:var(--chat-toolbar-btn-color);background-color:var(--chat-background-color)}.conversejs .chatbox converse-chat-toolbar .fas,.conversejs .chatbox converse-chat-toolbar .fas:hover,.conversejs .chatbox converse-chat-toolbar .far,.conversejs .chatbox converse-chat-toolbar .far:hover,.conversejs .chatbox converse-chat-toolbar .fa,.conversejs .chatbox converse-chat-toolbar .fa:hover{color:var(--chat-toolbar-btn-color)}.conversejs .chatbox converse-chat-toolbar button:focus{outline-color:var(--chat-toolbar-btn-color) !important}.conversejs .chatbox converse-chat-toolbar button:disabled .fa{color:var(--chat-toolbar-btn-disabled-color)}.conversejs .chatbox converse-chat-toolbar button:disabled .fa:hover{color:var(--chat-toolbar-btn-disabled-color)}.conversejs .chatbox converse-chat-toolbar button:disabled .fa svg,.conversejs .chatbox converse-chat-toolbar button:disabled .fa svg:hover{fill:var(--chat-toolbar-btn-disabled-color)}.conversejs .chatroom converse-chat-toolbar{border-top:var(--chatroom-message-input-border-top);color:var(--muc-toolbar-btn-color)}.conversejs .chatroom converse-chat-toolbar .fas,.conversejs .chatroom converse-chat-toolbar .fas:hover,.conversejs .chatroom converse-chat-toolbar .far,.conversejs .chatroom converse-chat-toolbar .far:hover,.conversejs .chatroom converse-chat-toolbar .fa,.conversejs .chatroom converse-chat-toolbar .fa:hover{color:var(--muc-toolbar-btn-color);font-size:var(--font-size-large)}.conversejs .chatroom converse-chat-toolbar .fas svg,.conversejs .chatroom converse-chat-toolbar .fas:hover svg,.conversejs .chatroom converse-chat-toolbar .far svg,.conversejs .chatroom converse-chat-toolbar .far:hover svg,.conversejs .chatroom converse-chat-toolbar .fa svg,.conversejs .chatroom converse-chat-toolbar .fa:hover svg{fill:var(--muc-toolbar-btn-color)}.conversejs .chatroom converse-chat-toolbar button:focus{outline-color:var(--muc-toolbar-btn-color) !important}.conversejs .chatroom converse-chat-toolbar button:disabled .fa{color:var(--muc-toolbar-btn-disabled-color)}.conversejs .chatroom converse-chat-toolbar button:disabled .fa:hover{color:var(--muc-toolbar-btn-disabled-color)}.conversejs .chatroom converse-chat-toolbar button:disabled .fa svg,.conversejs .chatroom converse-chat-toolbar button:disabled .fa svg:hover{fill:var(--muc-toolbar-btn-disabled-color)}.conversejs converse-chats.converse-overlayed .chat-toolbar li .toolbar-menu{min-width:235px}.conversejs converse-chats.converse-overlayed .chatroom .chat-toolbar li .toolbar-menu{min-width:280px} +.conversejs .chatbox .chat-head{display:flex;flex-direction:row;color:#fff;font-size:100%;margin:0;padding:0;position:relative}.conversejs .chatbox .chat-head.chat-head-chatbox{background-color:var(--chat-head-color);border-bottom:var(--chat-head-border-bottom)}.conversejs .chatbox .chat-head .avatar{margin-right:.5em}.conversejs .chatbox .chat-head .show-msg-author-modal{color:var(--chat-head-text-color) !important}.conversejs .chatbox .chat-head .chat-head__desc{color:var(--chat-head-color-lighten-50-percent);font-size:var(--font-size-small);margin:0;overflow:hidden;padding:.5rem 1rem .5rem 1rem;text-overflow:ellipsis;width:100%}.conversejs .chatbox .chat-head .chatbox-title{padding:.75rem 1rem 0 1rem;display:flex;flex-direction:row;justify-content:space-between;width:100%}.conversejs .chatbox .chat-head .chatbox-title--no-desc{padding:.75rem 1rem}.conversejs .chatbox .chat-head .chatbox-title--row{display:flex;flex-direction:row;overflow:hidden;width:100%}.conversejs .chatbox .chat-head .chatbox-title__text{color:var(--chat-head-text-color);overflow:hidden;text-overflow:ellipsis}.conversejs .chatbox .chat-head .chatbox-title__buttons{display:flex;flex-direction:row-reverse;flex-wrap:nowrap;padding:0}.conversejs .chatbox .chat-head .chatbox-btn{color:#fff}.conversejs .chatbox .chat-head .chatbox-btn:active{position:relative;top:1px}.conversejs .chatbox .chat-head converse-dropdown .dropdown-menu converse-icon svg{fill:var(--chat-color)}.conversejs .chatbox .chat-head .chatbox-btn converse-icon svg{fill:var(--chat-head-fg-color)} +.conversejs,.conversejs-bg,#conversejs-bg,body.converse-fullscreen{--avatar-border-radius: 10%;--message-avatar-width: 36px;--message-avatar-height: 36px;--chatroom-width: 500px;--send-button-height: 27px;--send-button-margin: 3px;--inline-action-margin: 0.75em;--roster-height: 194px;--button-border-radius: 5px;--chatbox-border-radius: 4px;--normal-font: "Helvetica", "Arial", sans-serif;--heading-font: "Muli", normal;--branding-font: "Baumans", cursive;--font-size-tiny: 10px;--font-size-small: 12px;--font-size: 14px;--font-size-large: 16px;--font-size-huge: 20px;--message-font-size: var(--font-size);--line-height-small: 14px;--line-height: 16px;--line-height-large: 20px;--line-height-huge: 27px;--embedded-emoji-picker-height: 300px;--chat-gutter: 0.5em;--occupants-padding: 1em;--minimized-chats-width: 130px;--mobile-chat-width: 100%;--mobile-chat-height: 400px;--overlayed-chat-head-height: 55px;--overlayed-chat-height: 450px;--overlayed-chat-width: 300px;--overlayed-chatbox-hover-height: 1em;--overlayed-emoji-picker-height: 200px;--overlayed-max-chat-textarea-height: 200px;--list-toggle-font-weight: normal}.conversejs .chatbox .bottom-panel .chat-content-sendbutton{height:calc(100% - (var(--chat-textarea-height) + var(--send-button-height) + 2*var(--send-button-margin)))}.conversejs .chatbox .bottom-panel .sendXMPPMessage{-moz-background-clip:padding;-webkit-background-clip:padding-box;border-bottom-radius:var(--chatbox-border-radius);background-clip:padding-box;background-color:var(--chat-textarea-background-color);border:0;margin:0;padding:0}@media screen and (max-height: 450px){.conversejs .chatbox .bottom-panel .sendXMPPMessage{width:100%}}@media screen and (max-width: 480px){.conversejs .chatbox .bottom-panel .sendXMPPMessage{width:100%}}.conversejs .chatbox .bottom-panel .sendXMPPMessage .suggestion-box__results:after{display:none}.conversejs .chatbox .bottom-panel .sendXMPPMessage .spoiler-hint{width:100%;color:var(--foreground);background-color:var(--background)}.conversejs .chatbox .bottom-panel .sendXMPPMessage .chat-textarea:active,.conversejs .chatbox .bottom-panel .sendXMPPMessage .chat-textarea:focus,.conversejs .chatbox .bottom-panel .sendXMPPMessage input:active,.conversejs .chatbox .bottom-panel .sendXMPPMessage input:focus{outline-color:var(--chat-head-color)}.conversejs .chatbox .bottom-panel .sendXMPPMessage .chat-textarea.correcting,.conversejs .chatbox .bottom-panel .sendXMPPMessage input.correcting{background-color:var(--chat-correcting-color)}.conversejs .chatbox .bottom-panel .sendXMPPMessage .chat-textarea{color:var(--chat-textarea-color);background-color:var(--chat-textarea-background-color);border-top-left-radius:0;border-top-right-radius:0;border-bottom-radius:var(--chatbox-border-radius);padding-left:.5em;padding-right:4.5em;padding-top:.5em;padding-bottom:.5em;width:100%;border:none;min-height:var(--chat-textarea-height);margin-bottom:-4px;resize:none}.conversejs .chatbox .bottom-panel .sendXMPPMessage .chat-textarea.spoiler{height:42px} +.conversejs,.conversejs-bg,#conversejs-bg,body.converse-fullscreen{--avatar-border-radius: 10%;--message-avatar-width: 36px;--message-avatar-height: 36px;--chatroom-width: 500px;--send-button-height: 27px;--send-button-margin: 3px;--inline-action-margin: 0.75em;--roster-height: 194px;--button-border-radius: 5px;--chatbox-border-radius: 4px;--normal-font: "Helvetica", "Arial", sans-serif;--heading-font: "Muli", normal;--branding-font: "Baumans", cursive;--font-size-tiny: 10px;--font-size-small: 12px;--font-size: 14px;--font-size-large: 16px;--font-size-huge: 20px;--message-font-size: var(--font-size);--line-height-small: 14px;--line-height: 16px;--line-height-large: 20px;--line-height-huge: 27px;--embedded-emoji-picker-height: 300px;--chat-gutter: 0.5em;--occupants-padding: 1em;--minimized-chats-width: 130px;--mobile-chat-width: 100%;--mobile-chat-height: 400px;--overlayed-chat-head-height: 55px;--overlayed-chat-height: 450px;--overlayed-chat-width: 300px;--overlayed-chatbox-hover-height: 1em;--overlayed-emoji-picker-height: 200px;--overlayed-max-chat-textarea-height: 200px;--list-toggle-font-weight: normal}.media{display:flex;align-items:flex-start}.media-body{flex:1}.conversejs .chatbox{text-align:left;margin:0 var(--chat-gutter)}@media screen and (max-height: 450px){.conversejs .chatbox{margin:0;width:var(--mobile-chat-width)}}@media screen and (max-width: 480px){.conversejs .chatbox{margin:0;width:var(--mobile-chat-width)}}.conversejs .chatbox converse-controlbox-navback{display:none}.conversejs .chatbox .flyout{position:absolute}@media screen and (max-height: 450px){.conversejs .chatbox .flyout{border-radius:0}}@media screen and (max-width: 480px){.conversejs .chatbox .flyout{border-radius:0}}@media screen and (max-height: 450px){.conversejs .chatbox .flyout{bottom:0}}@media screen and (max-width: 480px){.conversejs .chatbox .flyout{bottom:0}}.conversejs .chatbox .chatbox-btn{border-radius:25%;border:none;cursor:pointer;font-size:var(--chatbox-button-size);margin:0 .2em;padding:0 0 0 .5em;text-decoration:none}.conversejs .chatbox .chatbox-btn:active{position:relative;top:1px}.conversejs .chatbox .box-flyout{display:flex;flex-direction:column;justify-content:space-between;box-shadow:1px 3px 5px 3px rgba(0,0,0,.4);z-index:2;overflow:hidden;width:100%}@media screen and (max-height: 450px){.conversejs .chatbox .box-flyout{height:var(--mobile-chat-height);width:var(--mobile-chat-width);height:var(--fullpage-chat-height)}}@media screen and (max-width: 480px){.conversejs .chatbox .box-flyout{height:var(--mobile-chat-height);width:var(--mobile-chat-width);height:var(--fullpage-chat-height)}}.conversejs .chatbox .chat-title{display:var(--heading-display);font-family:var(--heading-font);color:var(--heading-color);display:block;line-height:var(--line-height-large);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.conversejs .chatbox .chat-title.groupchat{padding-right:var(--chatroom-head-title-padding-right)}.conversejs .chatbox .chat-title a{color:var(--chat-head-text-color);width:100%}.conversejs .chatbox .chat-body{display:flex;flex-direction:column;justify-content:space-between;background-color:var(--chat-textarea-background-color);border-bottom-left-radius:var(--chatbox-border-radius);border-bottom-right-radius:var(--chatbox-border-radius);border-top:0;height:100%;width:100%;overflow:hidden}@media screen and (max-height: 450px){.conversejs .chatbox .chat-body{border-bottom-left-radius:0;border-bottom-right-radius:0}}@media screen and (max-width: 480px){.conversejs .chatbox .chat-body{border-bottom-left-radius:0;border-bottom-right-radius:0}}.conversejs .chatbox .chat-body p{color:var(--text-color);font-size:var(--message-font-size);margin:0;padding:5px}.conversejs .chatbox .new-msgs-indicator{position:relative;width:100%;cursor:pointer;background-color:var(--chat-head-color);color:var(--light-background-color);padding:.5em;font-size:.9em;text-align:center;z-index:20;white-space:nowrap;margin-bottom:.25em}.conversejs .chatbox .chat-content{background-color:var(--chat-content-background-color);border:0;color:var(--text-color);font-size:var(--message-font-size);height:100%;line-height:1.3em;overflow:hidden;padding:0;display:flex;flex-direction:column;justify-content:space-between}.conversejs .chatbox .chat-content converse-chat-message .spinner{width:100%;overflow-y:hidden}.conversejs .chatbox .chat-content .chat-content__help{max-height:100%}.conversejs .chatbox .chat-content .chat-content__help converse-chat-help{border-top:1px solid var(--chat-head-color);display:block;height:100%;overflow-y:auto;padding:.5em 0}.conversejs .chatbox .chat-content .chat-content__help .close-chat-help{float:right;padding-right:1em;cursor:pointer;color:var(--chat-content-background-color)}.conversejs .chatbox .chat-content .chat-content__help .close-chat-help svg{fill:var(--chat-head-color)}.conversejs .chatbox .chat-content .chat-content__messages{overflow-x:hidden;overflow-y:auto;height:100%}.conversejs .chatbox .chat-content .chat-content__notifications{height:1.7em;white-space:pre;background-color:var(--chat-content-background-color);color:var(--subdued-color);font-size:90%;font-style:italic;line-height:var(--line-height-small);padding:0 1em .3em}.conversejs .chatbox .chat-content .chat-content__notifications:before{content:" "}.conversejs .chatbox .chat-content progress{margin:.5em 0;width:100%}.conversejs .chatbox .dragresize{background:rgba(0,0,0,0);border:0;margin:0;position:absolute;top:0;z-index:20}.conversejs .chatbox .dragresize-top{cursor:n-resize;height:5px;width:100%}.conversejs .chatbox .dragresize-left,.conversejs .chatbox .dragresize-occupants-left{cursor:w-resize;width:5px;height:100%;left:0}.conversejs .chatbox .dragresize-topleft{cursor:nw-resize;width:15px;height:15px;top:0;left:0}.conversejs converse-chats.converse-embedded .controlbox-head,.conversejs converse-chats.converse-overlayed .controlbox-head{padding:.5em}.conversejs converse-chats.converse-embedded .chat-head,.conversejs converse-chats.converse-overlayed .chat-head{border-top-left-radius:0;border-top-right-radius:0}.conversejs converse-chats.converse-embedded .chatbox,.conversejs converse-chats.converse-overlayed .chatbox{min-width:var(--overlayed-chat-width) !important;width:var(--overlayed-chat-width)}.conversejs converse-chats.converse-embedded .chatbox .box-flyout,.conversejs converse-chats.converse-overlayed .chatbox .box-flyout{min-width:var(--overlayed-chat-width) !important;width:var(--overlayed-chat-width)}.conversejs converse-chats.converse-overlayed .chat-head,.conversejs converse-chats.converse-overlayed .box-flyout{border-top-left-radius:var(--chatbox-border-radius);border-top-right-radius:var(--chatbox-border-radius)}@media screen and (max-height: 450px){.conversejs converse-chats.converse-overlayed .chat-head,.conversejs converse-chats.converse-overlayed .box-flyout{border-top-left-radius:0;border-top-right-radius:0}}@media screen and (max-width: 480px){.conversejs converse-chats.converse-overlayed .chat-head,.conversejs converse-chats.converse-overlayed .box-flyout{border-top-left-radius:0;border-top-right-radius:0}}.conversejs converse-chats.converse-overlayed .flyout{bottom:var(--overlayed-chatbox-hover-height)}.conversejs converse-chats.converse-overlayed .box-flyout{height:var(--overlayed-chat-height);min-height:calc(var(--overlayed-chat-height)/2)}.conversejs converse-chats.converse-overlayed .chat-head{min-height:var(--overlayed-chat-head-height)}.conversejs converse-chats.converse-overlayed .minimized-chats-flyout .chat-head{cursor:default}.conversejs converse-chats.converse-overlayed .chat-textarea{max-height:var(--overlayed-max-chat-textarea-height)}.conversejs converse-chats.converse-overlayed .chatbox .chat-body{height:calc(100% - var(--overlayed-chat-head-height))}.conversejs converse-chats.converse-overlayed .chatbox .chatbox-title{padding:.5rem .75rem 0 .75rem}.conversejs converse-chats.converse-overlayed .chatbox .chatbox-title--no-desc{padding:.5rem .75rem}@media(max-width: 767.98px){.conversejs.converse-overlayed>.row{flex-direction:column}.conversejs.converse-overlayed>.row.no-gutters{margin:-1em}}.conversejs converse-chats.converse-embedded .flyout,.conversejs converse-chats.converse-fullscreen .flyout{border-radius:0;border:none;bottom:0}.conversejs converse-chats.converse-embedded .chatbox,.conversejs converse-chats.converse-fullscreen .chatbox{margin:0;margin-left:15px}.conversejs converse-chats.converse-embedded .chatbox .box-flyout,.conversejs converse-chats.converse-fullscreen .chatbox .box-flyout{box-shadow:none;overflow:hidden;margin-left:0}@media(min-width: 768px){.conversejs converse-chats.converse-fullscreen:not(.converse-singleton) .chatbox{flex:0 0 66.66666667%;max-width:66.66666667%}}@media(min-width: 992px){.conversejs converse-chats.converse-fullscreen:not(.converse-singleton) .chatbox{flex:0 0 75%;max-width:75%}}@media(min-width: 1200px){.conversejs converse-chats.converse-fullscreen:not(.converse-singleton) .chatbox{flex:0 0 83.33333333%;max-width:83.33333333%}}@media(min-width: 768px){.conversejs converse-chats.converse-fullscreen:not(.converse-singleton) .chatbox:not(#controlbox) .box-flyout{max-width:66.666667%}}@media(min-width: 992px){.conversejs converse-chats.converse-fullscreen:not(.converse-singleton) .chatbox:not(#controlbox) .box-flyout{max-width:75%}}@media(min-width: 1200px){.conversejs converse-chats.converse-fullscreen:not(.converse-singleton) .chatbox:not(#controlbox) .box-flyout{max-width:83.333333%}}.conversejs converse-chats.converse-embedded .chat-head{font-size:var(--font-size-huge)}.conversejs converse-chats.converse-embedded .chatbox .box-flyout{bottom:0;height:100%;min-width:auto;width:100%}.conversejs converse-chats.converse-embedded .chat-textarea{max-height:var(--fullpage-max-chat-textarea-height)}.conversejs converse-chats.converse-fullscreen .chatbox-btn{font-size:var(--fullpage-chatbox-button-size);margin:0 .3em}.conversejs converse-chats.converse-fullscreen .chat-head{font-size:var(--font-size-huge)}.conversejs converse-chats.converse-fullscreen .chat-textarea{max-height:var(--fullpage-max-chat-textarea-height)}.conversejs converse-chats.converse-fullscreen .chatbox .box-flyout{box-shadow:none;height:var(--fullpage-chat-height);min-height:calc(var(--fullpage-chat-height)/2);width:var(--fullpage-chat-width);overflow:hidden}.conversejs converse-chats.converse-fullscreen .chatbox .chat-body{height:inherit;overflow:hidden;background-color:var(--chat-background-color)}.conversejs converse-chats.converse-fullscreen .chatbox .chat-title{font-size:var(--font-size-huge);line-height:var(--line-height-huge)}.conversejs converse-chats.converse-fullscreen .chatbox .sendXMPPMessage ul{width:100%}@media(max-width: 767.98px){.conversejs converse-chats:not(.converse-embedded)>.row{flex-direction:row-reverse}.conversejs converse-chats:not(.converse-embedded) #converse-login-panel .converse-form{padding:3em 2em 3em}.conversejs converse-chats:not(.converse-embedded) .chatbox{width:calc(100% - 50px)}.conversejs converse-chats:not(.converse-embedded) .chatbox .row .box-flyout{left:50px;bottom:0;height:var(--fullpage-chat-height);box-shadow:none}.conversejs converse-chats.converse-mobile .chat-head converse-controlbox-navback,.conversejs converse-chats.converse-overlayed .chat-head converse-controlbox-navback,.conversejs converse-chats.converse-fullscreen .chat-head converse-controlbox-navback{margin:auto 0;margin-right:1em;display:flex}.conversejs converse-chats.converse-mobile .chat-head converse-controlbox-navback .fa-arrow-left svg,.conversejs converse-chats.converse-overlayed .chat-head converse-controlbox-navback .fa-arrow-left svg,.conversejs converse-chats.converse-fullscreen .chat-head converse-controlbox-navback .fa-arrow-left svg{fill:var(--chat-head-text-color)}} +.conversejs,.conversejs-bg,#conversejs-bg,body.converse-fullscreen{--avatar-border-radius: 10%;--message-avatar-width: 36px;--message-avatar-height: 36px;--chatroom-width: 500px;--send-button-height: 27px;--send-button-margin: 3px;--inline-action-margin: 0.75em;--roster-height: 194px;--button-border-radius: 5px;--chatbox-border-radius: 4px;--normal-font: "Helvetica", "Arial", sans-serif;--heading-font: "Muli", normal;--branding-font: "Baumans", cursive;--font-size-tiny: 10px;--font-size-small: 12px;--font-size: 14px;--font-size-large: 16px;--font-size-huge: 20px;--message-font-size: var(--font-size);--line-height-small: 14px;--line-height: 16px;--line-height-large: 20px;--line-height-huge: 27px;--embedded-emoji-picker-height: 300px;--chat-gutter: 0.5em;--occupants-padding: 1em;--minimized-chats-width: 130px;--mobile-chat-width: 100%;--mobile-chat-height: 400px;--overlayed-chat-head-height: 55px;--overlayed-chat-height: 450px;--overlayed-chat-width: 300px;--overlayed-chatbox-hover-height: 1em;--overlayed-emoji-picker-height: 200px;--overlayed-max-chat-textarea-height: 200px;--list-toggle-font-weight: normal}.conversejs .set-xmpp-status .chat-status--online,.conversejs .xmpp-status .chat-status--online{color:var(--chat-status-online)}.conversejs .set-xmpp-status .chat-status--busy,.conversejs .xmpp-status .chat-status--busy{color:var(--chat-status-busy)}.conversejs .set-xmpp-status .chat-status--away,.conversejs .xmpp-status .chat-status--away{color:var(--chat-status-away)}.conversejs .set-xmpp-status .far.fa-circle,.conversejs .set-xmpp-status .fa-times-circle,.conversejs .xmpp-status .far.fa-circle,.conversejs .xmpp-status .fa-times-circle{color:var(--subdued-color)}.conversejs .set-xmpp-status .chat-status{padding-right:.5em}.conversejs .room-info{font-size:var(--font-size-small);font-style:normal;font-weight:normal}.conversejs .room-info li.room-info{display:block;margin-left:5px}.conversejs .room-info p.room-info{line-height:var(--line-height);margin:0;display:block;white-space:normal}.conversejs div.room-info{padding:.3em 0;clear:left;width:100%}.conversejs #controlbox{order:-1;color:var(--controlbox-text-color);margin-right:calc(3*var(--chat-gutter))}.conversejs #controlbox .chat-status--avatar{border:1px solid var(--controlbox-pane-background-color);background:var(--controlbox-pane-background-color)}.conversejs #controlbox converse-brand-logo{width:100%;display:block}.conversejs #controlbox converse-brand-heading{width:100%;display:block}.conversejs #controlbox .brand-name-wrapper{font-size:200%}.conversejs #controlbox .brand-name-wrapper--fullscreen{font-size:100%}.conversejs #controlbox .box-flyout{background-color:var(--controlbox-pane-background-color)}.conversejs #controlbox.logged-out .box-flyout .controlbox-pane{overflow-y:auto}.conversejs #controlbox form.search-xmpp-contact{margin:0;padding-left:5px;padding:0 0 5px 5px}.conversejs #controlbox form.search-xmpp-contact input{width:8em}.conversejs #controlbox .msgs-indicator{margin-right:.5em}.conversejs #controlbox a.subscribe-to-user{padding-left:2em;font-weight:bold}.conversejs #controlbox .conn-feedback{color:var(--controlbox-head-color)}.conversejs #controlbox .conn-feedback.error{color:var(--error-color)}.conversejs #controlbox .conn-feedback p{padding-bottom:1em}.conversejs #controlbox .conn-feedback p.feedback-subject.error{font-weight:bold}.conversejs #controlbox #converse-login-panel,.conversejs #controlbox #converse-register-panel{padding-top:0;padding-bottom:0}.conversejs #controlbox #converse-login-panel{flex-direction:row}.conversejs #controlbox .toggle-register-login{font-weight:bold}.conversejs #controlbox .controlbox-pane .userinfo{padding-bottom:1em}.conversejs #controlbox .controlbox-pane .userinfo .username{margin-left:.5em;overflow:hidden;text-overflow:ellipsis}.conversejs #controlbox .controlbox-pane .userinfo .profile{margin-bottom:.75em}.conversejs #controlbox #chatrooms{padding:0}.conversejs #controlbox #chatrooms .add-chatroom{margin:0;padding:0}.conversejs #controlbox #chatrooms .add-chatroom input[type=button],.conversejs #controlbox #chatrooms .add-chatroom input[type=submit],.conversejs #controlbox #chatrooms .add-chatroom input[type=text]{width:100%}.conversejs #controlbox .controlbox-section .controlbox-heading{font-family:var(--heading-font);color:var(--controlbox-heading-color);font-weight:var(--controlbox-heading-font-weight);padding:0;font-size:1.1em;line-height:1.1em;text-transform:uppercase}.conversejs #controlbox .controlbox-section .controlbox-heading--groupchats{color:var(--groupchats-header-color)}.conversejs #controlbox .controlbox-section .controlbox-heading--contacts{color:var(--chat-head-color-dark)}.conversejs #controlbox .controlbox-section .controlbox-heading--headline{color:var(--headlines-head-color)}.conversejs #controlbox .controlbox-section .controlbox-heading__btn{cursor:pointer;padding:0 0 0 1em;font-size:1em;margin:var(--controlbox-heading-top-margin) 0 var(--inline-action-margin) 0;text-align:center}.conversejs #controlbox .controlbox-section .controlbox-heading__btn.fa-vcard{margin-top:1em}.conversejs #controlbox .dropdown a{width:143px;display:inline-block}.conversejs #controlbox .dropdown li{list-style:none;padding-left:0}.conversejs #controlbox .dropdown dd ul{padding:0;list-style:none;position:absolute;left:0;top:0;width:100%;z-index:21;background-color:var(--light-background-color)}.conversejs #controlbox .dropdown dd ul li:hover{background-color:var(--highlight-color)}.conversejs #controlbox .dropdown dd.search-xmpp{height:0}.conversejs #controlbox .dropdown dd.search-xmpp .contact-form-container{position:absolute;z-index:22}.conversejs #controlbox .dropdown dd.search-xmpp .contact-form-container form{box-shadow:1px 4px 10px 1px rgba(0,0,0,.4);background-color:#fff}.conversejs #controlbox .dropdown dd.search-xmpp li:hover{background-color:var(--light-background-color)}.conversejs #controlbox .dropdown dt a span{cursor:pointer;display:block;padding:4px 7px 0 5px}.conversejs #controlbox .controlbox-panes{background-color:var(--controlbox-pane-background-color);height:100%;overflow-y:auto}.conversejs #controlbox .controlbox-subtitle{font-size:90%;padding:.5em;text-align:right}.conversejs #controlbox .controlbox-pane{background-color:var(--controlbox-pane-background-color);border:0;font-size:var(--font-size);left:0;text-align:left;overflow-x:hidden;padding:0 0 1em 0}.conversejs #controlbox .controlbox-pane .controlbox-padded{padding-left:1em;padding-right:1em;align-items:center;line-height:normal}.conversejs #controlbox .controlbox-pane .controlbox-padded .change-status{min-width:25px;text-align:center}.conversejs #controlbox .controlbox-pane .add-converse-contact{margin:0 0 .75em 0}.conversejs #controlbox .controlbox-pane .chatbox-btn{margin:0}.conversejs #controlbox .controlbox-pane .switch-form{text-align:center;padding:2em 0}.conversejs #controlbox .controlbox-pane dd{margin-left:0;margin-bottom:0}.conversejs #controlbox .controlbox-pane dd.odd{background-color:#dceac5}.conversejs #controlbox .add-xmpp-contact{padding:1em .5em}.conversejs #controlbox .add-xmpp-contact input{margin:0 0 1rem;width:100%}.conversejs #controlbox .add-xmpp-contact button{width:100%}.conversejs converse-chats.converse-overlayed{display:flex;flex-direction:row-reverse}.conversejs converse-chats.converse-overlayed .toggle-controlbox{order:-2;text-align:center;background-color:var(--controlbox-head-color);border-top-left-radius:var(--button-border-radius);border-top-right-radius:var(--button-border-radius);color:#0a0a0a;float:right;height:100%;margin:0 var(--chat-gutter);padding:1em}.conversejs converse-chats.converse-overlayed .toggle-controlbox span{color:var(--inverse-link-color)}.conversejs converse-chats.converse-overlayed #controlbox{order:-1;min-width:var(--controlbox-width) !important;width:var(--controlbox-width)}.conversejs converse-chats.converse-overlayed #controlbox .box-flyout{min-width:var(--controlbox-width) !important;width:var(--controlbox-width)}@media screen and (max-width: 480px){.conversejs converse-chats.converse-overlayed #controlbox{margin-left:-15px}}@media(max-width: 767.98px){.conversejs converse-chats.converse-overlayed #controlbox{margin-left:-15px}}.conversejs converse-chats.converse-overlayed #controlbox .login-trusted{white-space:nowrap;font-size:90%}.conversejs converse-chats.converse-overlayed #controlbox #converse-login-trusted{margin-top:.5em}.conversejs converse-chats.converse-overlayed #controlbox:not(.logged-out) .controlbox-head{height:15px}.conversejs converse-chats.converse-overlayed #controlbox #converse-register,.conversejs converse-chats.converse-overlayed #controlbox #converse-login{flex:0 0 100%;max-width:100%;padding-bottom:0}.conversejs converse-chats.converse-overlayed #controlbox #converse-register .button-cancel{font-size:90%}.conversejs converse-chats.converse-overlayed .brand-heading{padding-top:.8rem;padding-left:.8rem;width:100%}.conversejs converse-chats.converse-overlayed .converse-svg-logo{height:1em}.conversejs converse-chats.converse-overlayed #controlbox #converse-login-panel{height:100%}.conversejs converse-chats.converse-overlayed #controlbox .controlbox-panes{margin-top:.5em}.conversejs converse-chats.converse-embedded .controlbox-panes,.conversejs converse-chats.converse-fullscreen .controlbox-panes{border-right:.2rem solid var(--panel-divider-color)}.conversejs converse-chats.converse-embedded .toggle-controlbox,.conversejs converse-chats.converse-fullscreen .toggle-controlbox{display:none}.conversejs converse-chats.converse-embedded #controlbox,.conversejs converse-chats.converse-fullscreen #controlbox,.conversejs converse-chats.converse-mobile #controlbox{position:relative;width:100%;padding-right:15px;padding-left:15px;margin:0}@media(min-width: 768px){.conversejs converse-chats.converse-embedded #controlbox,.conversejs converse-chats.converse-fullscreen #controlbox,.conversejs converse-chats.converse-mobile #controlbox{flex:0 0 33.33333333%;max-width:33.33333333%}}@media(min-width: 992px){.conversejs converse-chats.converse-embedded #controlbox,.conversejs converse-chats.converse-fullscreen #controlbox,.conversejs converse-chats.converse-mobile #controlbox{flex:0 0 25%;max-width:25%}}@media(min-width: 1200px){.conversejs converse-chats.converse-embedded #controlbox,.conversejs converse-chats.converse-fullscreen #controlbox,.conversejs converse-chats.converse-mobile #controlbox{flex:0 0 16.66666667%;max-width:16.66666667%}}.conversejs converse-chats.converse-embedded #controlbox.logged-out,.conversejs converse-chats.converse-fullscreen #controlbox.logged-out,.conversejs converse-chats.converse-mobile #controlbox.logged-out{flex:0 0 100%;max-width:100%}.conversejs converse-chats.converse-embedded #controlbox .flyout,.conversejs converse-chats.converse-fullscreen #controlbox .flyout,.conversejs converse-chats.converse-mobile #controlbox .flyout{border-radius:0}.conversejs converse-chats.converse-embedded #controlbox #converse-login-panel,.conversejs converse-chats.converse-fullscreen #controlbox #converse-login-panel,.conversejs converse-chats.converse-mobile #controlbox #converse-login-panel{border-radius:0}.conversejs converse-chats.converse-embedded #controlbox #converse-login-panel .converse-form,.conversejs converse-chats.converse-fullscreen #controlbox #converse-login-panel .converse-form,.conversejs converse-chats.converse-mobile #controlbox #converse-login-panel .converse-form{padding:3em 2em 3em}.conversejs converse-chats.converse-embedded #controlbox .toggle-register-login,.conversejs converse-chats.converse-fullscreen #controlbox .toggle-register-login,.conversejs converse-chats.converse-mobile #controlbox .toggle-register-login{line-height:var(--line-height-huge)}.conversejs converse-chats.converse-embedded #controlbox converse-brand-logo,.conversejs converse-chats.converse-fullscreen #controlbox converse-brand-logo,.conversejs converse-chats.converse-mobile #controlbox converse-brand-logo{flex:0 0 100%;max-width:100%;margin-top:5em;margin-bottom:1em}.conversejs converse-chats.converse-embedded #controlbox converse-brand-logo .brand-heading,.conversejs converse-chats.converse-fullscreen #controlbox converse-brand-logo .brand-heading,.conversejs converse-chats.converse-mobile #controlbox converse-brand-logo .brand-heading{width:100%;font-size:500%;padding:.7em 0 0 0;opacity:.8;color:var(--brand-heading-color)}.conversejs converse-chats.converse-embedded #controlbox converse-brand-logo .brand-subtitle,.conversejs converse-chats.converse-fullscreen #controlbox converse-brand-logo .brand-subtitle,.conversejs converse-chats.converse-mobile #controlbox converse-brand-logo .brand-subtitle{font-size:90%;padding:.5em}@media screen and (max-width: 480px){.conversejs converse-chats.converse-embedded #controlbox converse-brand-logo .brand-heading,.conversejs converse-chats.converse-fullscreen #controlbox converse-brand-logo .brand-heading,.conversejs converse-chats.converse-mobile #controlbox converse-brand-logo .brand-heading{font-size:300%}}.conversejs converse-chats.converse-embedded #controlbox.logged-out,.conversejs converse-chats.converse-fullscreen #controlbox.logged-out,.conversejs converse-chats.converse-mobile #controlbox.logged-out{flex:0 0 100%;max-width:100%;opacity:0;animation-name:fadein;animation-fill-mode:forwards;animation-duration:.5s;animation-timing-function:ease;width:100%}.conversejs converse-chats.converse-embedded #controlbox.logged-out .box-flyout,.conversejs converse-chats.converse-fullscreen #controlbox.logged-out .box-flyout,.conversejs converse-chats.converse-mobile #controlbox.logged-out .box-flyout{width:100%}.conversejs converse-chats.converse-embedded #controlbox .box-flyout,.conversejs converse-chats.converse-fullscreen #controlbox .box-flyout,.conversejs converse-chats.converse-mobile #controlbox .box-flyout{border:0;width:100%;z-index:1;background-color:var(--controlbox-head-color)}.conversejs converse-chats.converse-embedded #controlbox .box-flyout .controlbox-head,.conversejs converse-chats.converse-fullscreen #controlbox .box-flyout .controlbox-head,.conversejs converse-chats.converse-mobile #controlbox .box-flyout .controlbox-head{display:none}.conversejs converse-chats.converse-embedded #controlbox #converse-register,.conversejs converse-chats.converse-embedded #controlbox #converse-login,.conversejs converse-chats.converse-fullscreen #controlbox #converse-register,.conversejs converse-chats.converse-fullscreen #controlbox #converse-login,.conversejs converse-chats.converse-mobile #controlbox #converse-register,.conversejs converse-chats.converse-mobile #controlbox #converse-login{position:relative;width:100%;padding-right:15px;padding-left:15px;flex:0 0 66.66666667%;max-width:66.66666667%;margin-left:16.66666667%}@media(min-width: 576px){.conversejs converse-chats.converse-embedded #controlbox #converse-register,.conversejs converse-chats.converse-embedded #controlbox #converse-login,.conversejs converse-chats.converse-fullscreen #controlbox #converse-register,.conversejs converse-chats.converse-fullscreen #controlbox #converse-login,.conversejs converse-chats.converse-mobile #controlbox #converse-register,.conversejs converse-chats.converse-mobile #controlbox #converse-login{flex:0 0 66.66666667%;max-width:66.66666667%;margin-left:16.66666667%}}@media(min-width: 768px){.conversejs converse-chats.converse-embedded #controlbox #converse-register,.conversejs converse-chats.converse-embedded #controlbox #converse-login,.conversejs converse-chats.converse-fullscreen #controlbox #converse-register,.conversejs converse-chats.converse-fullscreen #controlbox #converse-login,.conversejs converse-chats.converse-mobile #controlbox #converse-register,.conversejs converse-chats.converse-mobile #controlbox #converse-login{flex:0 0 66.66666667%;max-width:66.66666667%;margin-left:16.66666667%}}@media(min-width: 992px){.conversejs converse-chats.converse-embedded #controlbox #converse-register,.conversejs converse-chats.converse-embedded #controlbox #converse-login,.conversejs converse-chats.converse-fullscreen #controlbox #converse-register,.conversejs converse-chats.converse-fullscreen #controlbox #converse-login,.conversejs converse-chats.converse-mobile #controlbox #converse-register,.conversejs converse-chats.converse-mobile #controlbox #converse-login{flex:0 0 50%;max-width:50%;margin-left:25%}}.conversejs converse-chats.converse-embedded #controlbox #converse-register .title,.conversejs converse-chats.converse-embedded #controlbox #converse-register .instructions,.conversejs converse-chats.converse-embedded #controlbox #converse-login .title,.conversejs converse-chats.converse-embedded #controlbox #converse-login .instructions,.conversejs converse-chats.converse-fullscreen #controlbox #converse-register .title,.conversejs converse-chats.converse-fullscreen #controlbox #converse-register .instructions,.conversejs converse-chats.converse-fullscreen #controlbox #converse-login .title,.conversejs converse-chats.converse-fullscreen #controlbox #converse-login .instructions,.conversejs converse-chats.converse-mobile #controlbox #converse-register .title,.conversejs converse-chats.converse-mobile #controlbox #converse-register .instructions,.conversejs converse-chats.converse-mobile #controlbox #converse-login .title,.conversejs converse-chats.converse-mobile #controlbox #converse-login .instructions{margin:1em 0}.conversejs converse-chats.converse-embedded #controlbox #converse-register input[type=submit],.conversejs converse-chats.converse-embedded #controlbox #converse-register input[type=button],.conversejs converse-chats.converse-embedded #controlbox #converse-login input[type=submit],.conversejs converse-chats.converse-embedded #controlbox #converse-login input[type=button],.conversejs converse-chats.converse-fullscreen #controlbox #converse-register input[type=submit],.conversejs converse-chats.converse-fullscreen #controlbox #converse-register input[type=button],.conversejs converse-chats.converse-fullscreen #controlbox #converse-login input[type=submit],.conversejs converse-chats.converse-fullscreen #controlbox #converse-login input[type=button],.conversejs converse-chats.converse-mobile #controlbox #converse-register input[type=submit],.conversejs converse-chats.converse-mobile #controlbox #converse-register input[type=button],.conversejs converse-chats.converse-mobile #controlbox #converse-login input[type=submit],.conversejs converse-chats.converse-mobile #controlbox #converse-login input[type=button]{width:auto}.conversejs converse-chats.converse-fullscreen #controlbox{margin-left:-15px}@media screen and (max-width: 480px){.conversejs converse-chats.converse-fullscreen #controlbox{margin-left:0}}@media(max-width: 767.98px){.conversejs converse-chats.converse-fullscreen #controlbox{margin-left:0}}.conversejs converse-chats.converse-fullscreen .controlbox-panes{padding-top:2em}@media(max-width: 767.98px){.conversejs{left:0;right:0;padding-left:env(safe-area-inset-left);padding-right:env(safe-area-inset-right)}.conversejs .converse-chatboxes{margin:0 !important;flex-direction:row !important;justify-content:space-between}.conversejs .converse-chatboxes .converse-chatroom{font-size:14px}.conversejs .converse-chatboxes .chatbox .box-flyout{left:0;bottom:0;border-radius:0;width:100vw !important;height:var(--fullpage-chat-height)}.conversejs .converse-chatboxes #controlbox{margin-left:0;width:100vw !important}.conversejs .converse-chatboxes #controlbox .box-flyout{width:100vw !important;height:var(--fullpage-chat-height);margin-right:-15px}.conversejs .converse-chatboxes #controlbox .sidebar{display:block}.conversejs .converse-chatboxes.sidebar-open .chatbox:not(#controlbox){display:none}.conversejs .converse-chatboxes.sidebar-open #controlbox .controlbox-pane{display:block}} +.conversejs #controlbox .controlbox-head{display:flex;flex-direction:row-reverse;flex-wrap:nowrap;justify-content:space-between;min-height:0}.conversejs #controlbox .controlbox-head .brand-heading{color:var(--controlbox-text-color);font-size:2em}.conversejs #controlbox .controlbox-head .chatbox-btn{margin:0}.conversejs #controlbox .controlbox-head .chatbox-btn converse-icon svg{fill:var(--controlbox-head-btn-color)} +.conversejs .chatbox.headlines .chat-body{background-color:var(--background)}.conversejs .chatbox.headlines .chat-body .chat-message{color:var(--headline-message-color)}.conversejs .chatbox.headlines .chat-body hr{border-bottom:var(--headline-separator-border-bottom)}.conversejs .chatbox.headlines .chat-content{height:100%}.conversejs .message.chat-msg.headline .chat-msg__body{margin-left:0}.conversejs #controlbox .controlbox-section .controlbox-heading--headline{color:var(--headlines-head-text-color)}.conversejs converse-chats.converse-fullscreen .chatbox.headlines .box-flyout{background-color:var(--headlines-head-text-color)}.conversejs converse-chats.converse-fullscreen .chatbox.headlines .flyout{border-color:var(--headlines-head-text-color)} +.conversejs .chatbox.headlines converse-headlines-heading.chat-head{background-color:var(--headlines-head-bg-color)}.conversejs .chatbox.headlines converse-headlines-heading.chat-head .chatbox-title--no-desc{padding:.75rem 1rem}.conversejs .chatbox.headlines converse-headlines-heading.chat-head.chat-head-chatbox{background-color:var(--headlines-head-bg-color);border-bottom:var(--headlines-head-border-bottom)}.conversejs .chatbox.headlines converse-headlines-heading.chat-head .chatbox-title__text{color:var(--headlines-head-text-color) !important}.conversejs .chatbox.headlines converse-headlines-heading.chat-head converse-dropdown .dropdown-menu converse-icon svg{fill:var(--headlines-color)}.conversejs .chatbox.headlines converse-headlines-heading.chat-head .chatbox-btn converse-icon svg{fill:var(--headlines-head-fg-color)}.conversejs .chatbox.headlines converse-chats.converse-fullscreen .chatbox.headlines .chat-head.chat-head-chatbox{background-color:var(--headlines-head-bg-color)} +converse-mam-placeholder .mam-placeholder{position:relative;height:2em;margin:.5em 0}converse-mam-placeholder .mam-placeholder:before,converse-mam-placeholder .mam-placeholder:after{content:"";display:block;position:absolute;left:0;right:0}converse-mam-placeholder .mam-placeholder:before{height:1em;top:1em;background:linear-gradient(-135deg, lightgray 0.5em, transparent 0) 0 .5em,linear-gradient(135deg, lightgray 0.5em, transparent 0) 0 .5em;background-position:top left;background-repeat:repeat-x;background-size:1em 1em}converse-mam-placeholder .mam-placeholder:after{height:1em;top:.75em;background:linear-gradient(-135deg, var(--chat-background-color) 0.5em, transparent 0) 0 .5em,linear-gradient(135deg, var(--chat-background-color) 0.5em, transparent 0) 0 .5em;background-position:top left;background-repeat:repeat-x;background-size:1em 1em} +converse-muc-nickname-form{width:100%} +.conversejs converse-muc.chatroom converse-muc-bottom-panel.bottom-panel{display:contents;height:3em;padding:.5em;text-align:center;font-size:var(--font-size-small);background-color:var(--chatroom-head-bg-color);color:#fff}.conversejs converse-muc.chatroom converse-muc-bottom-panel.bottom-panel.muc-bottom-panel--muted{height:4em;width:100%}.conversejs converse-muc.chatroom converse-muc-bottom-panel.bottom-panel.muc-bottom-panel--nickname{padding:0;height:16em}.conversejs converse-muc.chatroom converse-muc-bottom-panel.bottom-panel.muc-bottom-panel--nickname .muc-form-container .chatroom-form{padding-top:2em;padding-bottom:0}.conversejs converse-muc.chatroom converse-muc-bottom-panel.bottom-panel .sendXMPPMessage .suggestion-box__results--above{bottom:4.5em}.conversejs converse-muc.chatroom converse-muc-bottom-panel.bottom-panel .sendXMPPMessage .chat-textarea:active,.conversejs converse-muc.chatroom converse-muc-bottom-panel.bottom-panel .sendXMPPMessage .chat-textarea:focus,.conversejs converse-muc.chatroom converse-muc-bottom-panel.bottom-panel .sendXMPPMessage input:active,.conversejs converse-muc.chatroom converse-muc-bottom-panel.bottom-panel .sendXMPPMessage input:focus{outline-color:var(--chatroom-head-bg-color) !important}.conversejs converse-muc.chatroom converse-muc-bottom-panel.bottom-panel .sendXMPPMessage .chat-textarea.correcting,.conversejs converse-muc.chatroom converse-muc-bottom-panel.bottom-panel .sendXMPPMessage input.correcting{background-color:var(--chatroom-correcting-color)}.conversejs converse-muc.chatroom converse-muc-bottom-panel.bottom-panel .sendXMPPMessage .chat-textarea{width:100%;border:none;border-bottom-right-radius:0} +.conversejs .chat-status{vertical-align:middle;margin-right:0;border-radius:50%;font-size:1em}.conversejs .chat-status.chat-status--avatar{font-size:.6rem;margin-left:-0.7em;margin-bottom:-1.9em;border-radius:50%}.conversejs .chat-status--offline{margin-right:.8em}.conversejs .chat-status--online{color:var(--chat-status-online)}.conversejs .chat-status--online svg{fill:var(--chat-status-online)}.conversejs .chat-status--busy{color:var(--chat-status-busy)}.conversejs .chat-status--busy svg{fill:var(--chat-status-busy)}.conversejs .chat-status--away{color:var(--chat-status-away)}.conversejs .chat-status--away svg{fill:var(--chat-status-away)}.conversejs .chat-status--offline{display:none} +.conversejs converse-muc.chatroom .chat-status--avatar{background:var(--occupants-background-color);border:1px solid var(--occupants-background-color)}.conversejs converse-muc.chatroom .badge-groupchat{background-color:var(--groupchats-header-color)}.conversejs converse-muc.chatroom .box-flyout .occupants{display:flex;flex-direction:column;justify-content:space-between;overflow-x:hidden;overflow-y:hidden;vertical-align:top;background-color:var(--occupants-background-color);border-left:var(--occupants-border-left);padding:.5em;max-width:75%;min-width:20%;flex:0 0 25%}.conversejs converse-muc.chatroom .box-flyout .occupants .occupants-header--title{display:flex;flex-direction:row;margin-bottom:.5em}.conversejs converse-muc.chatroom .box-flyout .occupants .occupants-header--title .hide-occupants{align-self:flex-end;cursor:pointer;font-size:var(--font-size-small)}.conversejs converse-muc.chatroom .box-flyout .occupants .fa-user-plus{margin-right:.25em}.conversejs converse-muc.chatroom .box-flyout .occupants .occupants-heading{width:100%;font-family:var(--heading-font);color:var(--groupchats-header-color-dark);padding-left:0;margin-right:1em}.conversejs converse-muc.chatroom .box-flyout .occupants .suggestion-box ul{padding:0}.conversejs converse-muc.chatroom .box-flyout .occupants .suggestion-box ul li{padding:.5em}.conversejs converse-muc.chatroom .box-flyout .occupants ul{padding:0;margin-bottom:.5em;overflow-x:hidden;overflow-y:auto;list-style:none}.conversejs converse-muc.chatroom .box-flyout .occupants ul.occupant-list{overflow-y:auto;flex-basis:0;flex-grow:1}.conversejs converse-muc.chatroom .box-flyout .occupants ul li{cursor:default;display:block;font-size:var(--font-size-small);overflow:hidden;padding:.25em .25em .25em 0;text-overflow:ellipsis}.conversejs converse-muc.chatroom .box-flyout .occupants ul li .fa{margin-right:.5em}.conversejs converse-muc.chatroom .box-flyout .occupants ul li.feature{font-size:var(--font-size-tiny)}.conversejs converse-muc.chatroom .box-flyout .occupants ul li.occupant{cursor:pointer;color:var(--link-color)}.conversejs converse-muc.chatroom .box-flyout .occupants ul li.occupant:hover{color:var(--link-hover-color)}.conversejs converse-muc.chatroom .box-flyout .occupants ul li.occupant .occupant-nick-badge{display:flex;justify-content:space-between;flex-wrap:wrap}.conversejs converse-muc.chatroom .box-flyout .occupants ul li.occupant .occupant-nick-badge .occupant-badges{display:flex;justify-content:flex-end;flex-wrap:wrap;flex-direction:row}.conversejs converse-muc.chatroom .box-flyout .occupants ul li.occupant .occupant-nick-badge .occupant-badges span{height:1.6em;margin-right:.25rem}.conversejs converse-muc.chatroom .box-flyout .occupants ul li.occupant div.row.no-gutters{flex-wrap:nowrap;min-height:1.5em}.conversejs converse-muc.chatroom .box-flyout .occupants ul li.occupant .badge{margin-bottom:.125rem} +converse-muc-details-modal .features-list{margin-left:1em}converse-muc-details-modal .room-info strong{color:var(--muc-color)}converse-muc-details-modal .chatroom-features{width:100%}converse-muc-details-modal .chatroom-features .features-list{padding-top:0}converse-muc-details-modal .chatroom-features .features-list .feature{width:100%;margin-right:.5em;padding-right:0;font-size:1em;cursor:help}converse-muc-details-modal .chatroom-features .features-list .feature converse-icon{margin-right:.5em} +converse-rich-text{display:block}.reason converse-rich-text{display:inline-block} +.conversejs converse-muc.chatroom .chat-head-chatroom{color:var(--chatroom-head-color);background-color:var(--chatroom-head-bg-color);border-bottom:var(--chatroom-head-border-bottom)}.conversejs converse-muc.chatroom .chat-head-chatroom converse-controlbox-navback .fa-arrow-left svg{fill:var(--chatroom-head-color)}.conversejs converse-muc.chatroom .chat-head-chatroom .chat-head__desc{color:var(--chatroom-head-color);display:var(--chatroom-head-description-display)}.conversejs converse-muc.chatroom .chat-head-chatroom .chat-head__desc a{color:var(--chatroom-head-description-link-color)}.conversejs converse-muc.chatroom .chat-head-chatroom .chat-head__desc:hover button{display:inline-block}.conversejs converse-muc.chatroom .chat-head-chatroom .chatbox-title .btn--transparent i{color:var(--chatroom-head-color)}.conversejs converse-muc.chatroom .chat-head-chatroom .chatbox-title .chatbox-title__text--bookmarked{margin-left:.5em}.conversejs converse-muc.chatroom .chat-head-chatroom .chatbox-title__buttons{background-color:var(--chatroom-head-bg-color)}.conversejs converse-muc.chatroom .chat-head-chatroom a.chatbox-btn.fa,.conversejs converse-muc.chatroom .chat-head-chatroom a:visited.chatbox-btn.fa,.conversejs converse-muc.chatroom .chat-head-chatroom a:hover.chatbox-btn.fa,.conversejs converse-muc.chatroom .chat-head-chatroom a:not([href]):not([tabindex]).chatbox-btn.fa{color:var(--chatroom-head-color)}.conversejs converse-muc.chatroom .chat-head-chatroom a.chatbox-btn.fa.button-on:before,.conversejs converse-muc.chatroom .chat-head-chatroom a:visited.chatbox-btn.fa.button-on:before,.conversejs converse-muc.chatroom .chat-head-chatroom a:hover.chatbox-btn.fa.button-on:before,.conversejs converse-muc.chatroom .chat-head-chatroom a:not([href]):not([tabindex]).chatbox-btn.fa.button-on:before{color:var(--chatroom-head-fg-color)}.conversejs converse-muc.chatroom .chat-head-chatroom converse-dropdown .dropdown-menu converse-icon svg{fill:var(--chatroom-color)}.conversejs converse-muc.chatroom .chat-head-chatroom .chatbox-btn converse-icon svg{fill:var(--chatroom-head-fg-color)}.conversejs converse-muc.chatroom .chat-head-chatroom .chatbox-title__text{color:var(--chatroom-head-color);display:var(--heading-display);font-weight:var(--chatroom-head-title-font-weight);margin:auto 0;padding-right:var(--chatroom-head-title-padding-right);white-space:nowrap}.conversejs converse-muc.chatroom .chat-head-chatroom .chatbox-title__text .chatroom-jid{font-size:var(--font-size-small)} +.conversejs,.conversejs-bg,#conversejs-bg,body.converse-fullscreen{--avatar-border-radius: 10%;--message-avatar-width: 36px;--message-avatar-height: 36px;--chatroom-width: 500px;--send-button-height: 27px;--send-button-margin: 3px;--inline-action-margin: 0.75em;--roster-height: 194px;--button-border-radius: 5px;--chatbox-border-radius: 4px;--normal-font: "Helvetica", "Arial", sans-serif;--heading-font: "Muli", normal;--branding-font: "Baumans", cursive;--font-size-tiny: 10px;--font-size-small: 12px;--font-size: 14px;--font-size-large: 16px;--font-size-huge: 20px;--message-font-size: var(--font-size);--line-height-small: 14px;--line-height: 16px;--line-height-large: 20px;--line-height-huge: 27px;--embedded-emoji-picker-height: 300px;--chat-gutter: 0.5em;--occupants-padding: 1em;--minimized-chats-width: 130px;--mobile-chat-width: 100%;--mobile-chat-height: 400px;--overlayed-chat-head-height: 55px;--overlayed-chat-height: 450px;--overlayed-chat-width: 300px;--overlayed-chatbox-hover-height: 1em;--overlayed-emoji-picker-height: 200px;--overlayed-max-chat-textarea-height: 200px;--list-toggle-font-weight: normal}.conversejs #controlbox #chatrooms{padding:0}.conversejs #controlbox #chatrooms .add-chatroom{margin:0;padding:0}.conversejs #controlbox #chatrooms .add-chatroom input[type=button],.conversejs #controlbox #chatrooms .add-chatroom input[type=submit],.conversejs #controlbox #chatrooms .add-chatroom input[type=text]{width:100%}.conversejs #controlbox .open-rooms-toggle,.conversejs #controlbox .open-rooms-toggle .fa{color:var(--groupchats-header-color) !important}.conversejs #controlbox .open-rooms-toggle:hover,.conversejs #controlbox .open-rooms-toggle .fa:hover{color:var(--chatroom-head-bg-color-dark) !important}.conversejs #controlbox .open-rooms-toggle{white-space:nowrap}.conversejs,.conversejs-bg,#conversejs-bg,body.converse-fullscreen{--avatar-border-radius: 10%;--message-avatar-width: 36px;--message-avatar-height: 36px;--chatroom-width: 500px;--send-button-height: 27px;--send-button-margin: 3px;--inline-action-margin: 0.75em;--roster-height: 194px;--button-border-radius: 5px;--chatbox-border-radius: 4px;--normal-font: "Helvetica", "Arial", sans-serif;--heading-font: "Muli", normal;--branding-font: "Baumans", cursive;--font-size-tiny: 10px;--font-size-small: 12px;--font-size: 14px;--font-size-large: 16px;--font-size-huge: 20px;--message-font-size: var(--font-size);--line-height-small: 14px;--line-height: 16px;--line-height-large: 20px;--line-height-huge: 27px;--embedded-emoji-picker-height: 300px;--chat-gutter: 0.5em;--occupants-padding: 1em;--minimized-chats-width: 130px;--mobile-chat-width: 100%;--mobile-chat-height: 400px;--overlayed-chat-head-height: 55px;--overlayed-chat-height: 450px;--overlayed-chat-width: 300px;--overlayed-chatbox-hover-height: 1em;--overlayed-emoji-picker-height: 200px;--overlayed-max-chat-textarea-height: 200px;--list-toggle-font-weight: normal}.conversejs .chatbox{text-align:left;margin:0 var(--chat-gutter)}@media screen and (max-height: 450px){.conversejs .chatbox{margin:0;width:var(--mobile-chat-width)}}@media screen and (max-width: 480px){.conversejs .chatbox{margin:0;width:var(--mobile-chat-width)}}.conversejs .chatbox converse-controlbox-navback{display:none}.conversejs .chatbox .flyout{position:absolute}@media screen and (max-height: 450px){.conversejs .chatbox .flyout{border-radius:0}}@media screen and (max-width: 480px){.conversejs .chatbox .flyout{border-radius:0}}@media screen and (max-height: 450px){.conversejs .chatbox .flyout{bottom:0}}@media screen and (max-width: 480px){.conversejs .chatbox .flyout{bottom:0}}.conversejs .chatbox .chatbox-btn{border-radius:25%;border:none;cursor:pointer;font-size:var(--chatbox-button-size);margin:0 .2em;padding:0 0 0 .5em;text-decoration:none}.conversejs .chatbox .chatbox-btn:active{position:relative;top:1px}.conversejs .chatbox .box-flyout{display:flex;flex-direction:column;justify-content:space-between;box-shadow:1px 3px 5px 3px rgba(0,0,0,.4);z-index:2;overflow:hidden;width:100%}@media screen and (max-height: 450px){.conversejs .chatbox .box-flyout{height:var(--mobile-chat-height);width:var(--mobile-chat-width);height:var(--fullpage-chat-height)}}@media screen and (max-width: 480px){.conversejs .chatbox .box-flyout{height:var(--mobile-chat-height);width:var(--mobile-chat-width);height:var(--fullpage-chat-height)}}.conversejs .chatbox .chat-title{display:var(--heading-display);font-family:var(--heading-font);color:var(--heading-color);display:block;line-height:var(--line-height-large);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.conversejs .chatbox .chat-title.groupchat{padding-right:var(--chatroom-head-title-padding-right)}.conversejs .chatbox .chat-title a{color:var(--chat-head-text-color);width:100%}.conversejs .chatbox .chat-body{display:flex;flex-direction:column;justify-content:space-between;background-color:var(--chat-textarea-background-color);border-bottom-left-radius:var(--chatbox-border-radius);border-bottom-right-radius:var(--chatbox-border-radius);border-top:0;height:100%;width:100%;overflow:hidden}@media screen and (max-height: 450px){.conversejs .chatbox .chat-body{border-bottom-left-radius:0;border-bottom-right-radius:0}}@media screen and (max-width: 480px){.conversejs .chatbox .chat-body{border-bottom-left-radius:0;border-bottom-right-radius:0}}.conversejs .chatbox .chat-body p{color:var(--text-color);font-size:var(--message-font-size);margin:0;padding:5px}.conversejs .chatbox .new-msgs-indicator{position:relative;width:100%;cursor:pointer;background-color:var(--chat-head-color);color:var(--light-background-color);padding:.5em;font-size:.9em;text-align:center;z-index:20;white-space:nowrap;margin-bottom:.25em}.conversejs .chatbox .chat-content{background-color:var(--chat-content-background-color);border:0;color:var(--text-color);font-size:var(--message-font-size);height:100%;line-height:1.3em;overflow:hidden;padding:0;display:flex;flex-direction:column;justify-content:space-between}.conversejs .chatbox .chat-content converse-chat-message .spinner{width:100%;overflow-y:hidden}.conversejs .chatbox .chat-content .chat-content__help{max-height:100%}.conversejs .chatbox .chat-content .chat-content__help converse-chat-help{border-top:1px solid var(--chat-head-color);display:block;height:100%;overflow-y:auto;padding:.5em 0}.conversejs .chatbox .chat-content .chat-content__help .close-chat-help{float:right;padding-right:1em;cursor:pointer;color:var(--chat-content-background-color)}.conversejs .chatbox .chat-content .chat-content__help .close-chat-help svg{fill:var(--chat-head-color)}.conversejs .chatbox .chat-content .chat-content__messages{overflow-x:hidden;overflow-y:auto;height:100%}.conversejs .chatbox .chat-content .chat-content__notifications{height:1.7em;white-space:pre;background-color:var(--chat-content-background-color);color:var(--subdued-color);font-size:90%;font-style:italic;line-height:var(--line-height-small);padding:0 1em .3em}.conversejs .chatbox .chat-content .chat-content__notifications:before{content:" "}.conversejs .chatbox .chat-content progress{margin:.5em 0;width:100%}.conversejs .chatbox .dragresize{background:rgba(0,0,0,0);border:0;margin:0;position:absolute;top:0;z-index:20}.conversejs .chatbox .dragresize-top{cursor:n-resize;height:5px;width:100%}.conversejs .chatbox .dragresize-left,.conversejs .chatbox .dragresize-occupants-left{cursor:w-resize;width:5px;height:100%;left:0}.conversejs .chatbox .dragresize-topleft{cursor:nw-resize;width:15px;height:15px;top:0;left:0}converse-muc-config-form{width:100%;overflow:auto}.conversejs .chatroom .box-flyout .muc-form-container{background-color:var(--background);border:0;color:var(--text-color);font-size:var(--font-size);height:100%;width:100%;overflow-y:auto}.conversejs .chatroom .box-flyout .muc-form-container .validation-message{font-size:90%;color:var(--error-color)}.conversejs .chatroom .box-flyout .muc-form-container input[type=button],.conversejs .chatroom .box-flyout .muc-form-container input[type=submit]{margin:0 .5em}.conversejs .chatroom .box-flyout .muc-form-container .button-primary{background-color:var(--chatroom-head-fg-color)}.conversejs .chatroom .box-flyout .chatroom-form{display:flex;flex-direction:column;justify-content:center;padding:2em}.conversejs .chatroom{width:var(--chatroom-width)}@media screen and (max-height: 450px){.conversejs .chatroom{width:var(--mobile-chat-width)}}@media screen and (max-width: 480px){.conversejs .chatroom{width:var(--mobile-chat-width)}}.conversejs .chatroom .box-flyout{background-color:var(--chatroom-head-bg-color);overflow-y:hidden;width:var(--chatroom-width)}@media screen and (max-height: 450px){.conversejs .chatroom .box-flyout{height:var(--mobile-chat-height);width:var(--mobile-chat-width);height:var(--fullpage-chat-height)}}@media screen and (max-width: 480px){.conversejs .chatroom .box-flyout{height:var(--mobile-chat-height);width:var(--mobile-chat-width);height:var(--fullpage-chat-height)}}.conversejs .chatroom .box-flyout .empty-history-feedback{position:relative}.conversejs .chatroom .box-flyout .empty-history-feedback span{width:100%;text-align:center;position:absolute;margin-top:50%}.conversejs .chatroom .box-flyout .chatroom-body{flex-direction:row;flex-flow:nowrap;background-color:var(--background);border-top:0;height:100%;width:100%;overflow:hidden}.conversejs .chatroom .box-flyout .chatroom-body converse-muc-chatarea{width:100%;display:flex;flex-direction:row;flex-flow:nowrap}.conversejs .chatroom .box-flyout .chatroom-body .row{flex-direction:row}.conversejs .chatroom .box-flyout .chatroom-body .chat-topic{font-weight:bold;color:var(--chatroom-head-bg-color)}.conversejs .chatroom .box-flyout .chatroom-body .chat-info{color:var(--chat-info-color);line-height:normal}.conversejs .chatroom .box-flyout .chatroom-body .chat-info.badge{color:var(--chat-head-text-color)}.conversejs .chatroom .box-flyout .chatroom-body .chat-info.chat-msg--retracted{color:var(--subdued-color)}.conversejs .chatroom .box-flyout .chatroom-body .disconnect-container{margin:1em;width:100%}.conversejs .chatroom .box-flyout .chatroom-body .disconnect-container h3.disconnect-msg{padding-bottom:1em}.conversejs .chatroom .box-flyout .chatroom-body .chat-area{display:flex;flex-direction:column;flex:0 1 100%;justify-content:flex-end;min-width:25%;word-wrap:break-word}.conversejs .chatroom .box-flyout .chatroom-body .chat-area .new-msgs-indicator{background-color:var(--chatroom-color)}.conversejs .chatroom .box-flyout .chatroom-body .chat-area .chat-content{height:100%}.conversejs .chatroom .box-flyout .chatroom-body .chat-area .chat-content__help converse-chat-help{border-top:1px solid var(--chatroom-color)}.conversejs .chatroom .box-flyout .chatroom-body .chat-area .chat-content__help .close-chat-help svg{fill:var(--chatroom-color)}.conversejs .chatroom .room-invite .invited-contact{margin:-1px 0 0 -1px;width:100%;border:1px solid #999}converse-muc-disconnected,converse-muc-destroyed{padding:2em;width:100%;height:100%}.conversejs.converse-embedded .badge--muc,.conversejs .badge--muc{background-color:var(--groupchats-header-color)}.conversejs.converse-embedded .add-chatroom input[type=submit],.conversejs.converse-embedded .add-chatroom input[type=button],.conversejs .add-chatroom input[type=submit],.conversejs .add-chatroom input[type=button]{margin:.3em 0}.conversejs converse-chats.converse-overlayed .chatbox.chatroom{min-width:var(--chatroom-width) !important;width:var(--chatroom-width)}.conversejs converse-chats.converse-overlayed .chatbox.chatroom .box-flyout{min-width:var(--chatroom-width) !important;width:var(--chatroom-width)}.conversejs converse-chats.converse-overlayed .chatbox.chatroom .chatbox-title__text{flex:0 0 83.33333333%;max-width:83.33333333%}.conversejs converse-chats.converse-overlayed .chatbox.chatroom .chatbox-title__buttons{flex:0 0 16.66666667%;max-width:16.66666667%}.conversejs converse-chats.converse-overlayed .chatbox.chatroom .chat-head__desc{font-size:80%;margin-bottom:1em}.conversejs converse-chats.converse-overlayed .chatbox.chatroom .chatroom-body .occupants .occupants-heading{padding:0}.conversejs converse-chats.converse-overlayed .chatbox.chatroom .chatroom-body .occupants .occupant-list{border-bottom:none}.conversejs converse-chats.converse-overlayed .chatbox.chatroom .chatroom-body .occupants ul .occupant .occupant-nick-badge .occupant-badges{display:none}.conversejs converse-chats.converse-overlayed .chatbox.chatroom .chatroom-body .chat-area{min-width:var(--overlayed-chat-width)}.conversejs converse-chats.converse-embedded .chatroom .box-flyout,.conversejs converse-chats.converse-fullscreen .chatroom .box-flyout,.conversejs converse-chats.converse-mobile .chatroom .box-flyout{width:100%}.conversejs converse-chats.converse-embedded .chatroom .box-flyout .chatroom-body .chat-area.full .new-msgs-indicator,.conversejs converse-chats.converse-fullscreen .chatroom .box-flyout .chatroom-body .chat-area.full .new-msgs-indicator,.conversejs converse-chats.converse-mobile .chatroom .box-flyout .chatroom-body .chat-area.full .new-msgs-indicator{max-width:100%}.conversejs converse-chats.converse-embedded .chatroom .box-flyout .chatroom-body .occupants,.conversejs converse-chats.converse-fullscreen .chatroom .box-flyout .chatroom-body .occupants,.conversejs converse-chats.converse-mobile .chatroom .box-flyout .chatroom-body .occupants{padding:var(--occupants-padding)}.conversejs converse-chats.converse-embedded .chatroom .box-flyout .chatroom-body .occupants .occupants-heading,.conversejs converse-chats.converse-fullscreen .chatroom .box-flyout .chatroom-body .occupants .occupants-heading,.conversejs converse-chats.converse-mobile .chatroom .box-flyout .chatroom-body .occupants .occupants-heading{font-size:var(--font-size-large)}.conversejs converse-chats.converse-embedded .chatroom .box-flyout .chatroom-body .occupants ul.occupant-list li,.conversejs converse-chats.converse-fullscreen .chatroom .box-flyout .chatroom-body .occupants ul.occupant-list li,.conversejs converse-chats.converse-mobile .chatroom .box-flyout .chatroom-body .occupants ul.occupant-list li{font-size:var(--font-size-small)}.conversejs converse-chats.converse-embedded .chatroom .room-invite span .invited-contact,.conversejs converse-chats.converse-fullscreen .chatroom .room-invite span .invited-contact,.conversejs converse-chats.converse-mobile .chatroom .room-invite span .invited-contact{margin:0 0 .5em -1px}.conversejs converse-chats.converse-embedded .chatroom{margin:0;width:100%}.conversejs converse-chats.converse-embedded .chatroom .box-flyout .occupants-heading{font-size:120%}.conversejs converse-chats.converse-embedded .chatroom .box-flyout .chat-content .chat-message{margin:.5em;font-size:120%}.conversejs converse-chats.converse-embedded .chatroom .box-flyout .sendXMPPMessage .chat-textarea{padding:.5em;font-size:110%}.conversejs converse-chats.converse-embedded .chatroom .box-flyout .chatroom-body{height:100%}.conversejs converse-chats.converse-embedded .chatroom .box-flyout .chatroom-body .muc-form-container{height:100%;position:relative}.conversejs converse-chats.converse-embedded .chatroom .box-flyout .occupants .occupant-list{padding-left:.3em} +.conversejs converse-chats.converse-overlayed converse-minimized-chats{order:100}.conversejs converse-chats.converse-overlayed #minimized-chats{width:var(--minimized-chats-width);margin-bottom:0;border-top-left-radius:var(--chatbox-border-radius);border-top-right-radius:var(--chatbox-border-radius);color:var(--inverse-link-color);margin-right:var(--chat-gutter);padding:0}.conversejs converse-chats.converse-overlayed #minimized-chats .badge{bottom:8px;border:1px solid var(--overlayed-badge-color)}.conversejs converse-chats.converse-overlayed #minimized-chats #toggle-minimized-chats{border-top-left-radius:var(--chatbox-border-radius);border-top-right-radius:var(--chatbox-border-radius);background-color:var(--subdued-color);padding:1em 0 0 0;text-align:center;color:#fff;white-space:nowrap;overflow-y:hidden;text-overflow:ellipsis;display:block;height:45px;width:9em}.conversejs converse-chats.converse-overlayed #minimized-chats a.restore-chat{cursor:pointer;padding:1px 0 1px 5px;color:var(--chat-head-text-color);line-height:15px;display:block;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.conversejs converse-chats.converse-overlayed #minimized-chats a.restore-chat:hover{text-decoration:none}.conversejs converse-chats.converse-overlayed #minimized-chats a.restore-chat:visited{color:var(--chat-head-text-color)}.conversejs converse-chats.converse-overlayed #minimized-chats .minimized-chats-flyout{flex-direction:column-reverse;bottom:45px;width:var(--minimized-chats-width)}.conversejs converse-chats.converse-overlayed #minimized-chats .minimized-chats-flyout .chat-head{min-height:0;padding:.3em;border-radius:var(--chatbox-border-radius);height:35px;margin-bottom:.2em;width:100%;max-width:9em;flex-wrap:nowrap;background-color:var(--chat-head-color)}.conversejs converse-chats.converse-overlayed #minimized-chats .minimized-chats-flyout .chat-head-chatroom{background-color:var(--chatroom-head-bg-color)}.conversejs converse-chats.converse-overlayed #minimized-chats .minimized-chats-flyout .chat-head-chatroom a.restore-chat{color:var(--chatroom-head-color)}.conversejs converse-chats.converse-overlayed #minimized-chats .minimized-chats-flyout .chat-head-headline{background-color:var(--headlines-head-bg-color)}.conversejs converse-chats.converse-overlayed #minimized-chats .minimized-chats-flyout .chat-head-headline a.restore-chat{color:var(--headlines-head-text-color)}.conversejs converse-chats.converse-overlayed #minimized-chats .minimized-chats-flyout.minimized{height:auto}.conversejs converse-chats.converse-overlayed #minimized-chats .unread-message-count{font-weight:bold;background-color:#fff;border:1px solid;text-shadow:1px 1px 0 var(--text-shadow-color);color:var(--warning-color);border-radius:5px;padding:2px 4px;font-size:16px;text-align:center;position:absolute;right:116px;bottom:10px}.conversejs converse-chats.converse-overlayed #minimized-chats .unread-message-count-hidden,.conversejs converse-chats.converse-overlayed #minimized-chats .chat-head-message-count-hidden{display:none} +converse-register-panel .alert{margin:auto;max-width:50vw}#converse-register{opacity:0;animation-name:fadein;animation-fill-mode:forwards;animation-duration:.5s;animation-timing-function:ease;background-color:var(--controlbox-pane-background-color)}#converse-register .title{font-weight:bold}#converse-register .input-group input{height:auto}#converse-register .input-group .input-group-text{color:var(--text-color);background-color:var(--controlbox-pane-background-color)}#converse-register .info{color:green;font-size:90%;margin:1.5em 0}#converse-register .form-errors{color:var(--error-color);margin:1em 0}#converse-register .provider-title{font-size:var(--font-size-huge);margin:0}#converse-register .provider-score{width:178px;margin-bottom:8px}#converse-register .form-help .url{font-weight:bold;color:var(--link-color)}#converse-register .instructions{color:gray;font-size:85%}#converse-register .instructions:hover{color:var(--controlbox-text-color)} +converse-add-muc-modal .add-chatroom converse-autocomplete .suggestion-box__results--below{height:10em;overflow:auto}converse-add-muc-modal .add-chatroom converse-autocomplete .suggestion-box ul li{display:block} +converse-root.converse-js.converse-fullpage,converse-root.converse-js.converse-overlayed,converse-root.converse-js.converse-mobile{bottom:0;height:100%;padding-left:env(safe-area-inset-left);padding-right:env(safe-area-inset-right);position:fixed;z-index:1031}converse-root.converse-js.converse-embedded{position:relative} +.conversejs #controlbox .open-contacts-toggle,.conversejs #controlbox .open-contacts-toggle .fa{color:var(--chat-color) !important}.conversejs #controlbox .open-contacts-toggle:hover,.conversejs #controlbox .open-contacts-toggle .fa:hover{color:var(--chat-color) !important}.conversejs #controlbox .open-contacts-toggle{white-space:nowrap}.conversejs #converse-roster{text-align:left;width:100%;position:relative;margin:0;height:var(--roster-height);padding:0;overflow:hidden;height:calc(100% - 70px)}.conversejs #converse-roster #online-count{display:none}.conversejs #converse-roster .search-xmpp ul li.chat-info{padding-left:10px}.conversejs #converse-roster .roster-filter-form{width:100%}.conversejs #converse-roster .roster-filter-form .button-group{padding:.2em}.conversejs #converse-roster .roster-filter-form converse-icon{padding:.25em}.conversejs #converse-roster .roster-filter-form .roster-filter{width:100%;margin:.2em;font-size:calc(var(--font-size) - 2px)}.conversejs #converse-roster .roster-filter-form .state-type{font-size:calc(var(--font-size) - 2px);width:100%}.conversejs #converse-roster .roster-contacts{padding:0;margin:0 0 .2em 0;height:100%;overflow-x:hidden;overflow-y:auto;color:var(--text-color)}.conversejs #converse-roster .roster-contacts .roster-group-contacts .list-item:hover .list-item-action{opacity:1}.conversejs #converse-roster .roster-contacts converse-roster-contact{width:100%;overflow:hidden;white-space:nowrap;text-overflow:ellipsis;display:flex;justify-content:space-between}.conversejs #converse-roster .roster-contacts converse-roster-contact .list-item-action{line-height:2em}.conversejs #converse-roster .roster-contacts converse-roster-contact:hover .list-item-action{opacity:1}.conversejs #converse-roster .roster-contacts .group-toggle{font-family:var(--heading-font);display:block;width:100%;margin:.75em 0 .25em 0}.conversejs #converse-roster .roster-contacts .group-toggle,.conversejs #converse-roster .roster-contacts .group-toggle .fa{color:var(--chat-head-color-dark) !important}.conversejs #converse-roster .roster-contacts .group-toggle:hover,.conversejs #converse-roster .roster-contacts .group-toggle .fa:hover{color:var(--chat-head-color-darker) !important}.conversejs #converse-roster .roster-contacts .current-xmpp-contact{margin:.25em 0}.conversejs #converse-roster .roster-contacts .list-item.requesting-xmpp-contact a{line-height:var(--line-height)}.conversejs #converse-roster .roster-contacts .list-item.requesting-xmpp-contact .req-contact-name{padding:0 .2em 0 0}.conversejs #converse-roster .roster-contacts .list-item .open-chat{margin:0;padding:0}.conversejs #converse-roster .roster-contacts .list-item .open-chat.unread-msgs{font-weight:bold;color:var(--unread-msgs-color)}.conversejs #converse-roster .roster-contacts .list-item .open-chat.unread-msgs .contact-name{width:70%}.conversejs #converse-roster .roster-contacts .list-item .open-chat .msgs-indicator{color:var(--text-color-invert);background-color:var(--chat-color);opacity:1;border-radius:10%;padding:.2em .4em;font-size:var(--font-size-small);margin-right:0}.conversejs #converse-roster .roster-contacts .list-item .open-chat .contact-name{padding:0;margin:0;max-width:85%;float:none;height:100%}.conversejs #converse-roster .roster-contacts .list-item .open-chat .contact-name.unread-msgs{max-width:60%}.conversejs #converse-roster .roster-contacts .list-item .open-chat .contact-name.contact-name--offline{margin-left:.25em}.conversejs #converse-roster .roster-contacts .list-item.odd{background-color:#dceac5}.conversejs #converse-roster .roster-contacts .list-item a,.conversejs #converse-roster .roster-contacts .list-item span{white-space:nowrap;text-overflow:ellipsis}.conversejs #converse-roster .roster-contacts .list-item .span{display:inline-block}.conversejs #converse-roster .roster-contacts .list-item .decline-xmpp-request{margin-left:5px}.conversejs #converse-roster .roster-contacts .list-item:hover{background-color:var(--controlbox-pane-bg-hover-color)}.conversejs #converse-roster span.pending-contact-name{line-height:var(--line-height);width:100%} +.media{display:flex;align-items:flex-start}.media-body{flex:1}.conversejs,.conversejs-bg,#conversejs-bg,body.converse-fullscreen{--avatar-border-radius: 10%;--message-avatar-width: 36px;--message-avatar-height: 36px;--chatroom-width: 500px;--send-button-height: 27px;--send-button-margin: 3px;--inline-action-margin: 0.75em;--roster-height: 194px;--button-border-radius: 5px;--chatbox-border-radius: 4px;--normal-font: "Helvetica", "Arial", sans-serif;--heading-font: "Muli", normal;--branding-font: "Baumans", cursive;--font-size-tiny: 10px;--font-size-small: 12px;--font-size: 14px;--font-size-large: 16px;--font-size-huge: 20px;--message-font-size: var(--font-size);--line-height-small: 14px;--line-height: 16px;--line-height-large: 20px;--line-height-huge: 27px;--embedded-emoji-picker-height: 300px;--chat-gutter: 0.5em;--occupants-padding: 1em;--minimized-chats-width: 130px;--mobile-chat-width: 100%;--mobile-chat-height: 400px;--overlayed-chat-head-height: 55px;--overlayed-chat-height: 450px;--overlayed-chat-width: 300px;--overlayed-chatbox-hover-height: 1em;--overlayed-emoji-picker-height: 200px;--overlayed-max-chat-textarea-height: 200px;--list-toggle-font-weight: normal}.conversejs converse-chats.converse-embedded.converse-singleton .flyout,.conversejs converse-chats.converse-fullscreen.converse-singleton .flyout{border:none !important}.conversejs converse-chats.converse-embedded.converse-singleton .chat-head,.conversejs converse-chats.converse-fullscreen.converse-singleton .chat-head{padding:.5em}.conversejs converse-chats.converse-embedded.converse-singleton .chatbox,.conversejs converse-chats.converse-fullscreen.converse-singleton .chatbox{margin:0;position:relative;margin-left:-15px}@media screen and (max-width: 480px){.conversejs converse-chats.converse-embedded.converse-singleton .chatbox,.conversejs converse-chats.converse-fullscreen.converse-singleton .chatbox{margin-left:0}}@media(max-width: 767.98px){.conversejs converse-chats.converse-embedded.converse-singleton .chatbox,.conversejs converse-chats.converse-fullscreen.converse-singleton .chatbox{margin-left:0}}.conversejs converse-chats.converse-fullscreen.converse-singleton .chatbox{position:relative;width:100%;padding-right:15px;padding-left:15px}@media(min-width: 768px){.conversejs converse-chats.converse-fullscreen.converse-singleton .chatbox{flex:0 0 100%;max-width:100%}}@media(min-width: 992px){.conversejs converse-chats.converse-fullscreen.converse-singleton .chatbox{flex:0 0 100%;max-width:100%}}@media(min-width: 1200px){.conversejs converse-chats.converse-fullscreen.converse-singleton .chatbox{flex:0 0 100%;max-width:100%}} +body.converse-fullscreen{margin:0;background-color:var(--global-background-color);overflow:hidden} + +/*# sourceMappingURL=converse.min.css.map*/ \ No newline at end of file diff --git a/xmppchat/vendor/converse.min.js b/xmppchat/vendor/converse.min.js new file mode 100644 index 00000000..01d471f8 --- /dev/null +++ b/xmppchat/vendor/converse.min.js @@ -0,0 +1,10 @@ +/*! For license information please see converse.min.js.LICENSE.txt */ +(()=>{var e,t,n,s,i={1588:function(e,t,n){!function(e,t){"use strict";function n(e){return n.result?n.result:e&&"function"==typeof e.getSerializer?(n.result=e.getSerializer(),n.result):Promise.reject(new Error("localforage.getSerializer() was not available! localforage v1.4+ is required!"))}function s(e,t){return t&&e.then((function(e){t(null,e)}),(function(e){t(e)})),e}function i(e,t){var n=this.getItem(e).then((function(t){return{key:e,value:t}}));return s(n,t),n}function r(e){var t=this;return new Promise((function(n,s){for(var r=[],o=0,a=e.length;ot?1:0}return new Promise((function(s,i){t.ready().then((function(){var r,o=t._dbInfo,a=o.db.transaction(o.storeName,"readonly").objectStore(o.storeName),l=e.sort(n),d=c.bound(e[0],e[e.length-1],!1,!1);if("getAll"in a)(r=a.getAll(d)).onsuccess=function(){var e=r.result;void 0===e&&(e=null),s(e)};else{r=a.openCursor(d);var u={},h=0;r.onsuccess=function(){var e=r.result;if(e){for(var t=e.key;t>l[h];)if(++h===l.length)return void s(u);if(t===l[h]){var n=e.value;void 0===n&&(n=null),u[t]=n,e.continue()}else e.continue(l[h])}else s(u)}}r.onerror=function(){i(r.error)}})).catch(i)}))}function d(e){var t=this;return new Promise((function(s,i){t.ready().then((function(){return n(t)})).then((function(n){var r=t._dbInfo;r.db.transaction((function(t){for(var o=new Array(e.length),a=0,c=e.length;a{var s;!function(){"use strict";var i={not_string:/[^s]/,not_bool:/[^t]/,not_type:/[^T]/,not_primitive:/[^v]/,number:/[diefg]/,numeric_arg:/[bcdiefguxX]/,json:/[j]/,not_json:/[^j]/,text:/^[^\x25]+/,modulo:/^\x25{2}/,placeholder:/^\x25(?:([1-9]\d*)\$|\(([^)]+)\))?(\+)?(0|'[^$])?(-)?(\d+)?(?:\.(\d+))?([b-gijostTuvxX])/,key:/^([a-z_][a-z_\d]*)/i,key_access:/^\.([a-z_][a-z_\d]*)/i,index_access:/^\[(\d+)\]/,sign:/^[+-]/};function r(e){return function(e,t){var n,s,o,a,c,l,d,u,h,m=1,g=e.length,f="";for(s=0;s=0),a.type){case"b":n=parseInt(n,10).toString(2);break;case"c":n=String.fromCharCode(parseInt(n,10));break;case"d":case"i":n=parseInt(n,10);break;case"j":n=JSON.stringify(n,null,a.width?parseInt(a.width):0);break;case"e":n=a.precision?parseFloat(n).toExponential(a.precision):parseFloat(n).toExponential();break;case"f":n=a.precision?parseFloat(n).toFixed(a.precision):parseFloat(n);break;case"g":n=a.precision?String(Number(n.toPrecision(a.precision))):parseFloat(n);break;case"o":n=(parseInt(n,10)>>>0).toString(8);break;case"s":n=String(n),n=a.precision?n.substring(0,a.precision):n;break;case"t":n=String(!!n),n=a.precision?n.substring(0,a.precision):n;break;case"T":n=Object.prototype.toString.call(n).slice(8,-1).toLowerCase(),n=a.precision?n.substring(0,a.precision):n;break;case"u":n=parseInt(n,10)>>>0;break;case"v":n=n.valueOf(),n=a.precision?n.substring(0,a.precision):n;break;case"x":n=(parseInt(n,10)>>>0).toString(16);break;case"X":n=(parseInt(n,10)>>>0).toString(16).toUpperCase()}i.json.test(a.type)?f+=n:(!i.number.test(a.type)||u&&!a.sign?h="":(h=u?"+":"-",n=n.toString().replace(i.sign,"")),l=a.pad_char?"0"===a.pad_char?"0":a.pad_char.charAt(1):" ",d=a.width-(h+n).length,c=a.width&&d>0?l.repeat(d):"",f+=a.align?h+n+c:"0"===l?h+c+n:c+h+n)}return f}(function(e){if(a[e])return a[e];var t,n=e,s=[],r=0;for(;n;){if(null!==(t=i.text.exec(n)))s.push(t[0]);else if(null!==(t=i.modulo.exec(n)))s.push("%");else{if(null===(t=i.placeholder.exec(n)))throw new SyntaxError("[sprintf] unexpected placeholder");if(t[2]){r|=1;var o=[],c=t[2],l=[];if(null===(l=i.key.exec(c)))throw new SyntaxError("[sprintf] failed to parse named argument key");for(o.push(l[1]);""!==(c=c.substring(l[0].length));)if(null!==(l=i.key_access.exec(c)))o.push(l[1]);else{if(null===(l=i.index_access.exec(c)))throw new SyntaxError("[sprintf] failed to parse named argument key");o.push(l[1])}t[2]=o}else r|=2;if(3===r)throw new Error("[sprintf] mixing positional and named placeholders is not (yet) supported");s.push({placeholder:t[0],param_no:t[1],keys:t[2],sign:t[3],pad_char:t[4],align:t[5],width:t[6],precision:t[7],type:t[8]})}n=n.substring(t[0].length)}return a[e]=s}(e),arguments)}function o(e,t){return r.apply(null,[e].concat(t||[]))}var a=Object.create(null);t.sprintf=r,t.vsprintf=o,"undefined"!=typeof window&&(window.sprintf=r,window.vsprintf=o,void 0===(s=function(){return{sprintf:r,vsprintf:o}}.call(t,n,t,e))||(e.exports=s))}()},7949:function(e,t,n){var s,i;!function(r,o){"use strict";e.exports?e.exports=o():void 0===(i="function"==typeof(s=o)?s.call(t,n,t,e):s)||(e.exports=i)}(0,(function(e){"use strict";var t=e&&e.IPv6;return{best:function(e){var t,n,s=e.toLowerCase().split(":"),i=s.length,r=8;for(""===s[0]&&""===s[1]&&""===s[2]?(s.shift(),s.shift()):""===s[0]&&""===s[1]?s.shift():""===s[i-1]&&""===s[i-2]&&s.pop(),-1!==s[(i=s.length)-1].indexOf(".")&&(r=7),t=0;t1);a++)n.splice(0,1);s[o]=n.join("")}var c=-1,l=0,d=0,u=-1,h=!1;for(o=0;ol&&(c=u,l=d)):"0"===s[o]&&(h=!0,u=o,d=1);d>l&&(c=u,l=d),l>1&&s.splice(c,l,""),i=s.length;var m="";for(""===s[0]&&(m=":"),o=0;o=e.length-1)return!1;var s=e.lastIndexOf(".",t-1);if(s<=0||s>=t-1)return!1;var i=n.list[e.slice(t+1)];return!!i&&i.indexOf(" "+e.slice(s+1,t)+" ")>=0},is:function(e){var t=e.lastIndexOf(".");if(t<=0||t>=e.length-1)return!1;if(e.lastIndexOf(".",t-1)>=0)return!1;var s=n.list[e.slice(t+1)];return!!s&&s.indexOf(" "+e.slice(0,t)+" ")>=0},get:function(e){var t=e.lastIndexOf(".");if(t<=0||t>=e.length-1)return null;var s=e.lastIndexOf(".",t-1);if(s<=0||s>=t-1)return null;var i=n.list[e.slice(t+1)];return i?i.indexOf(" "+e.slice(s+1,t)+" ")<0?null:e.slice(s+1):null},noConflict:function(){return e.SecondLevelDomains===this&&(e.SecondLevelDomains=t),this}};return n}))},5168:function(e,t,n){var s,i,r;!function(o,a){"use strict";e.exports?e.exports=a(n(3658),n(7949),n(7341)):(i=[n(3658),n(7949),n(7341)],void 0===(r="function"==typeof(s=a)?s.apply(t,i):s)||(e.exports=r))}(0,(function(e,t,n,s){"use strict";var i=s&&s.URI;function r(e,t){var n=arguments.length>=1;if(!(this instanceof r))return n?arguments.length>=2?new r(e,t):new r(e):new r;if(void 0===e){if(n)throw new TypeError("undefined is not a valid argument for URI");e="undefined"!=typeof location?location.href+"":""}if(null===e&&n)throw new TypeError("null is not a valid argument for URI");return this.href(e),void 0!==t?this.absoluteTo(t):this}r.version="1.19.11";var o=r.prototype,a=Object.prototype.hasOwnProperty;function c(e){return e.replace(/([.*+?^=!:${}()|[\]\/\\])/g,"\\$1")}function l(e){return void 0===e?"Undefined":String(Object.prototype.toString.call(e)).slice(8,-1)}function d(e){return"Array"===l(e)}function u(e,t){var n,s,i={};if("RegExp"===l(t))i=null;else if(d(t))for(n=0,s=t.length;n]+|\(([^\s()<>]+|(\([^\s()<>]+\)))*\))+(?:\(([^\s()<>]+|(\([^\s()<>]+\)))*\)|[^\s`!()\[\]{};:'".,<>?«»“”‘’]))/gi,r.findUri={start:/\b(?:([a-z][a-z0-9.+-]*:\/\/)|www\.)/gi,end:/[\s\r\n]|$/,trim:/[`!()\[\]{};:'".,<>?«»“”„‘’]+$/,parens:/(\([^\)]*\)|\[[^\]]*\]|\{[^}]*\}|<[^>]*>)/g},r.leading_whitespace_expression=/^[\x00-\x20\u00a0\u1680\u2000-\u200a\u2028\u2029\u202f\u205f\u3000\ufeff]+/,r.ascii_tab_whitespace=/[\u0009\u000A\u000D]+/g,r.defaultPorts={http:"80",https:"443",ftp:"21",gopher:"70",ws:"80",wss:"443"},r.hostProtocols=["http","https"],r.invalid_hostname_characters=/[^a-zA-Z0-9\.\-:_]/,r.domAttributes={a:"href",blockquote:"cite",link:"href",base:"href",script:"src",form:"action",img:"src",area:"href",iframe:"src",embed:"src",source:"src",track:"src",input:"src",audio:"src",video:"src"},r.getDomAttribute=function(e){if(e&&e.nodeName){var t=e.nodeName.toLowerCase();if("input"!==t||"image"===e.type)return r.domAttributes[t]}},r.encode=p,r.decode=decodeURIComponent,r.iso8859=function(){r.encode=escape,r.decode=unescape},r.unicode=function(){r.encode=p,r.decode=decodeURIComponent},r.characters={pathname:{encode:{expression:/%(24|26|2B|2C|3B|3D|3A|40)/gi,map:{"%24":"$","%26":"&","%2B":"+","%2C":",","%3B":";","%3D":"=","%3A":":","%40":"@"}},decode:{expression:/[\/\?#]/g,map:{"/":"%2F","?":"%3F","#":"%23"}}},reserved:{encode:{expression:/%(21|23|24|26|27|28|29|2A|2B|2C|2F|3A|3B|3D|3F|40|5B|5D)/gi,map:{"%3A":":","%2F":"/","%3F":"?","%23":"#","%5B":"[","%5D":"]","%40":"@","%21":"!","%24":"$","%26":"&","%27":"'","%28":"(","%29":")","%2A":"*","%2B":"+","%2C":",","%3B":";","%3D":"="}}},urnpath:{encode:{expression:/%(21|24|27|28|29|2A|2B|2C|3B|3D|40)/gi,map:{"%21":"!","%24":"$","%27":"'","%28":"(","%29":")","%2A":"*","%2B":"+","%2C":",","%3B":";","%3D":"=","%40":"@"}},decode:{expression:/[\/\?#:]/g,map:{"/":"%2F","?":"%3F","#":"%23",":":"%3A"}}}},r.encodeQuery=function(e,t){var n=r.encode(e+"");return void 0===t&&(t=r.escapeQuerySpace),t?n.replace(/%20/g,"+"):n},r.decodeQuery=function(e,t){e+="",void 0===t&&(t=r.escapeQuerySpace);try{return r.decode(t?e.replace(/\+/g,"%20"):e)}catch(t){return e}};var v,y={encode:"encode",decode:"decode"},_=function(e,t){return function(n){try{return r[t](n+"").replace(r.characters[e][t].expression,(function(n){return r.characters[e][t].map[n]}))}catch(e){return n}}};for(v in y)r[v+"PathSegment"]=_("pathname",y[v]),r[v+"UrnPathSegment"]=_("urnpath",y[v]);var b=function(e,t,n){return function(s){var i;i=n?function(e){return r[t](r[n](e))}:r[t];for(var o=(s+"").split(e),a=0,c=o.length;a-1&&(t.fragment=e.substring(n+1)||null,e=e.substring(0,n)),(n=e.indexOf("?"))>-1&&(t.query=e.substring(n+1)||null,e=e.substring(0,n)),"//"===(e=(e=e.replace(/^(https?|ftp|wss?)?:+[/\\]*/i,"$1://")).replace(/^[/\\]{2,}/i,"//")).substring(0,2)?(t.protocol=null,e=e.substring(2),e=r.parseAuthority(e,t)):(n=e.indexOf(":"))>-1&&(t.protocol=e.substring(0,n)||null,t.protocol&&!t.protocol.match(r.protocol_expression)?t.protocol=void 0:"//"===e.substring(n+1,n+3).replace(/\\/g,"/")?(e=e.substring(n+3),e=r.parseAuthority(e,t)):(e=e.substring(n+1),t.urn=!0)),t.path=e,t},r.parseHost=function(e,t){e||(e="");var n,s,i=(e=e.replace(/\\/g,"/")).indexOf("/");if(-1===i&&(i=e.length),"["===e.charAt(0))n=e.indexOf("]"),t.hostname=e.substring(1,n)||null,t.port=e.substring(n+2,i)||null,"/"===t.port&&(t.port=null);else{var o=e.indexOf(":"),a=e.indexOf("/"),c=e.indexOf(":",o+1);-1!==c&&(-1===a||c-1?i:e.length-1);return o>-1&&(-1===i||o-1?m.slice(0,g)+m.slice(g).replace(o,""):m.replace(o,"")).length<=l[0].length||n.ignore&&n.ignore.test(m))){var v=t(m,d,h=d+m.length,e);void 0!==v?(v=String(v),e=e.slice(0,d)+v+e.slice(h),s.lastIndex=d+v.length):s.lastIndex=h}}return s.lastIndex=0,e},r.ensureValidHostname=function(t,n){var s=!!t,i=!1;if(!!n&&(i=h(r.hostProtocols,n)),i&&!s)throw new TypeError("Hostname cannot be empty, if protocol is "+n);if(t&&t.match(r.invalid_hostname_characters)){if(!e)throw new TypeError('Hostname "'+t+'" contains characters other than [A-Z0-9.-:_] and Punycode.js is not available');if(e.toASCII(t).match(r.invalid_hostname_characters))throw new TypeError('Hostname "'+t+'" contains characters other than [A-Z0-9.-:_]')}},r.ensureValidPort=function(e){if(e){var t=Number(e);if(!(/^[0-9]+$/.test(t)&&t>0&&t<65536))throw new TypeError('Port "'+e+'" is not a valid port')}},r.noConflict=function(e){if(e){var t={URI:this.noConflict()};return s.URITemplate&&"function"==typeof s.URITemplate.noConflict&&(t.URITemplate=s.URITemplate.noConflict()),s.IPv6&&"function"==typeof s.IPv6.noConflict&&(t.IPv6=s.IPv6.noConflict()),s.SecondLevelDomains&&"function"==typeof s.SecondLevelDomains.noConflict&&(t.SecondLevelDomains=s.SecondLevelDomains.noConflict()),t}return s.URI===this&&(s.URI=i),this},o.build=function(e){return!0===e?this._deferred_build=!0:(void 0===e||this._deferred_build)&&(this._string=r.build(this._parts),this._deferred_build=!1),this},o.clone=function(){return new r(this)},o.valueOf=o.toString=function(){return this.build(!1)._string},o.protocol=w("protocol"),o.username=w("username"),o.password=w("password"),o.hostname=w("hostname"),o.port=w("port"),o.query=S("query","?"),o.fragment=S("fragment","#"),o.search=function(e,t){var n=this.query(e,t);return"string"==typeof n&&n.length?"?"+n:n},o.hash=function(e,t){var n=this.fragment(e,t);return"string"==typeof n&&n.length?"#"+n:n},o.pathname=function(e,t){if(void 0===e||!0===e){var n=this._parts.path||(this._parts.hostname?"/":"");return e?(this._parts.urn?r.decodeUrnPath:r.decodePath)(n):n}return this._parts.urn?this._parts.path=e?r.recodeUrnPath(e):"":this._parts.path=e?r.recodePath(e):"/",this.build(!t),this},o.path=o.pathname,o.href=function(e,t){var n;if(void 0===e)return this.toString();this._string="",this._parts=r._parts();var s=e instanceof r,i="object"==typeof e&&(e.hostname||e.path||e.pathname);e.nodeName&&(e=e[r.getDomAttribute(e)]||"",i=!1);if(!s&&i&&void 0!==e.pathname&&(e=e.toString()),"string"==typeof e||e instanceof String)this._parts=r.parse(String(e),this._parts);else{if(!s&&!i)throw new TypeError("invalid input");var o=s?e._parts:e;for(n in o)"query"!==n&&a.call(this._parts,n)&&(this._parts[n]=o[n]);o.query&&this.query(o.query,!1)}return this.build(!t),this},o.is=function(e){var t=!1,s=!1,i=!1,o=!1,a=!1,c=!1,l=!1,d=!this._parts.urn;switch(this._parts.hostname&&(d=!1,s=r.ip4_expression.test(this._parts.hostname),i=r.ip6_expression.test(this._parts.hostname),a=(o=!(t=s||i))&&n&&n.has(this._parts.hostname),c=o&&r.idn_expression.test(this._parts.hostname),l=o&&r.punycode_expression.test(this._parts.hostname)),e.toLowerCase()){case"relative":return d;case"absolute":return!d;case"domain":case"name":return o;case"sld":return a;case"ip":return t;case"ip4":case"ipv4":case"inet4":return s;case"ip6":case"ipv6":case"inet6":return i;case"idn":return c;case"url":return!this._parts.urn;case"urn":return!!this._parts.urn;case"punycode":return l}return null};var x=o.protocol,A=o.port,E=o.hostname;o.protocol=function(e,t){if(e&&!(e=e.replace(/:(\/\/)?$/,"")).match(r.protocol_expression))throw new TypeError('Protocol "'+e+"\" contains characters other than [A-Z0-9.+-] or doesn't start with [A-Z]");return x.call(this,e,t)},o.scheme=o.protocol,o.port=function(e,t){return this._parts.urn?void 0===e?"":this:(void 0!==e&&(0===e&&(e=null),e&&(":"===(e+="").charAt(0)&&(e=e.substring(1)),r.ensureValidPort(e))),A.call(this,e,t))},o.hostname=function(e,t){if(this._parts.urn)return void 0===e?"":this;if(void 0!==e){var n={preventInvalidHostname:this._parts.preventInvalidHostname};if("/"!==r.parseHost(e,n))throw new TypeError('Hostname "'+e+'" contains characters other than [A-Z0-9.-]');e=n.hostname,this._parts.preventInvalidHostname&&r.ensureValidHostname(e,this._parts.protocol)}return E.call(this,e,t)},o.origin=function(e,t){if(this._parts.urn)return void 0===e?"":this;if(void 0===e){var n=this.protocol();return this.authority()?(n?n+"://":"")+this.authority():""}var s=r(e);return this.protocol(s.protocol()).authority(s.authority()).build(!t),this},o.host=function(e,t){if(this._parts.urn)return void 0===e?"":this;if(void 0===e)return this._parts.hostname?r.buildHost(this._parts):"";if("/"!==r.parseHost(e,this._parts))throw new TypeError('Hostname "'+e+'" contains characters other than [A-Z0-9.-]');return this.build(!t),this},o.authority=function(e,t){if(this._parts.urn)return void 0===e?"":this;if(void 0===e)return this._parts.hostname?r.buildAuthority(this._parts):"";if("/"!==r.parseAuthority(e,this._parts))throw new TypeError('Hostname "'+e+'" contains characters other than [A-Z0-9.-]');return this.build(!t),this},o.userinfo=function(e,t){if(this._parts.urn)return void 0===e?"":this;if(void 0===e){var n=r.buildUserinfo(this._parts);return n?n.substring(0,n.length-1):n}return"@"!==e[e.length-1]&&(e+="@"),r.parseUserinfo(e,this._parts),this.build(!t),this},o.resource=function(e,t){var n;return void 0===e?this.path()+this.search()+this.hash():(n=r.parse(e),this._parts.path=n.path,this._parts.query=n.query,this._parts.fragment=n.fragment,this.build(!t),this)},o.subdomain=function(e,t){if(this._parts.urn)return void 0===e?"":this;if(void 0===e){if(!this._parts.hostname||this.is("IP"))return"";var n=this._parts.hostname.length-this.domain().length-1;return this._parts.hostname.substring(0,n)||""}var s=this._parts.hostname.length-this.domain().length,i=this._parts.hostname.substring(0,s),o=new RegExp("^"+c(i));if(e&&"."!==e.charAt(e.length-1)&&(e+="."),-1!==e.indexOf(":"))throw new TypeError("Domains cannot contain colons");return e&&r.ensureValidHostname(e,this._parts.protocol),this._parts.hostname=this._parts.hostname.replace(o,e),this.build(!t),this},o.domain=function(e,t){if(this._parts.urn)return void 0===e?"":this;if("boolean"==typeof e&&(t=e,e=void 0),void 0===e){if(!this._parts.hostname||this.is("IP"))return"";var n=this._parts.hostname.match(/\./g);if(n&&n.length<2)return this._parts.hostname;var s=this._parts.hostname.length-this.tld(t).length-1;return s=this._parts.hostname.lastIndexOf(".",s-1)+1,this._parts.hostname.substring(s)||""}if(!e)throw new TypeError("cannot set domain empty");if(-1!==e.indexOf(":"))throw new TypeError("Domains cannot contain colons");if(r.ensureValidHostname(e,this._parts.protocol),!this._parts.hostname||this.is("IP"))this._parts.hostname=e;else{var i=new RegExp(c(this.domain())+"$");this._parts.hostname=this._parts.hostname.replace(i,e)}return this.build(!t),this},o.tld=function(e,t){if(this._parts.urn)return void 0===e?"":this;if("boolean"==typeof e&&(t=e,e=void 0),void 0===e){if(!this._parts.hostname||this.is("IP"))return"";var s=this._parts.hostname.lastIndexOf("."),i=this._parts.hostname.substring(s+1);return!0!==t&&n&&n.list[i.toLowerCase()]&&n.get(this._parts.hostname)||i}var r;if(!e)throw new TypeError("cannot set TLD empty");if(e.match(/[^a-zA-Z0-9-]/)){if(!n||!n.is(e))throw new TypeError('TLD "'+e+'" contains characters other than [A-Z0-9]');r=new RegExp(c(this.tld())+"$"),this._parts.hostname=this._parts.hostname.replace(r,e)}else{if(!this._parts.hostname||this.is("IP"))throw new ReferenceError("cannot set TLD on non-domain host");r=new RegExp(c(this.tld())+"$"),this._parts.hostname=this._parts.hostname.replace(r,e)}return this.build(!t),this},o.directory=function(e,t){if(this._parts.urn)return void 0===e?"":this;if(void 0===e||!0===e){if(!this._parts.path&&!this._parts.hostname)return"";if("/"===this._parts.path)return"/";var n=this._parts.path.length-this.filename().length-1,s=this._parts.path.substring(0,n)||(this._parts.hostname?"/":"");return e?r.decodePath(s):s}var i=this._parts.path.length-this.filename().length,o=this._parts.path.substring(0,i),a=new RegExp("^"+c(o));return this.is("relative")||(e||(e="/"),"/"!==e.charAt(0)&&(e="/"+e)),e&&"/"!==e.charAt(e.length-1)&&(e+="/"),e=r.recodePath(e),this._parts.path=this._parts.path.replace(a,e),this.build(!t),this},o.filename=function(e,t){if(this._parts.urn)return void 0===e?"":this;if("string"!=typeof e){if(!this._parts.path||"/"===this._parts.path)return"";var n=this._parts.path.lastIndexOf("/"),s=this._parts.path.substring(n+1);return e?r.decodePathSegment(s):s}var i=!1;"/"===e.charAt(0)&&(e=e.substring(1)),e.match(/\.?\//)&&(i=!0);var o=new RegExp(c(this.filename())+"$");return e=r.recodePath(e),this._parts.path=this._parts.path.replace(o,e),i?this.normalizePath(t):this.build(!t),this},o.suffix=function(e,t){if(this._parts.urn)return void 0===e?"":this;if(void 0===e||!0===e){if(!this._parts.path||"/"===this._parts.path)return"";var n,s,i=this.filename(),o=i.lastIndexOf(".");return-1===o?"":(n=i.substring(o+1),s=/^[a-z0-9%]+$/i.test(n)?n:"",e?r.decodePathSegment(s):s)}"."===e.charAt(0)&&(e=e.substring(1));var a,l=this.suffix();if(l)a=e?new RegExp(c(l)+"$"):new RegExp(c("."+l)+"$");else{if(!e)return this;this._parts.path+="."+r.recodePath(e)}return a&&(e=r.recodePath(e),this._parts.path=this._parts.path.replace(a,e)),this.build(!t),this},o.segment=function(e,t,n){var s=this._parts.urn?":":"/",i=this.path(),r="/"===i.substring(0,1),o=i.split(s);if(void 0!==e&&"number"!=typeof e&&(n=t,t=e,e=void 0),void 0!==e&&"number"!=typeof e)throw new Error('Bad segment "'+e+'", must be 0-based integer');if(r&&o.shift(),e<0&&(e=Math.max(o.length+e,0)),void 0===t)return void 0===e?o:o[e];if(null===e||void 0===o[e])if(d(t)){o=[];for(var a=0,c=t.length;a= 0x80 (not a basic code point)","invalid-input":"Invalid input"},b=c-l,w=Math.floor,S=String.fromCharCode;function x(e){throw new RangeError(_[e])}function A(e,t){for(var n=e.length,s=[];n--;)s[n]=t(e[n]);return s}function E(e,t){var n=e.split("@"),s="";return n.length>1&&(s=n[0]+"@",e=n[1]),s+A((e=e.replace(y,".")).split("."),t).join(".")}function $(e){for(var t,n,s=[],i=0,r=e.length;i=55296&&t<=56319&&i65535&&(t+=S((e-=65536)>>>10&1023|55296),e=56320|1023&e),t+=S(e)})).join("")}function k(e,t){return e+22+75*(e<26)-((0!=t)<<5)}function j(e,t,n){var s=0;for(e=n?w(e/h):e>>1,e+=w(e/t);e>b*d>>1;s+=c)e=w(e/b);return w(s+(b+1)*e/(e+u))}function T(e){var t,n,s,i,r,o,u,h,p,v,y,_=[],b=e.length,S=0,A=g,E=m;for((n=e.lastIndexOf(f))<0&&(n=0),s=0;s=128&&x("not-basic"),_.push(e.charCodeAt(s));for(i=n>0?n+1:0;i=b&&x("invalid-input"),((h=(y=e.charCodeAt(i++))-48<10?y-22:y-65<26?y-65:y-97<26?y-97:c)>=c||h>w((a-S)/o))&&x("overflow"),S+=h*o,!(h<(p=u<=E?l:u>=E+d?d:u-E));u+=c)o>w(a/(v=c-p))&&x("overflow"),o*=v;E=j(S-r,t=_.length+1,0==r),w(S/t)>a-A&&x("overflow"),A+=w(S/t),S%=t,_.splice(S++,0,A)}return C(_)}function I(e){var t,n,s,i,r,o,u,h,p,v,y,_,b,A,E,C=[];for(_=(e=$(e)).length,t=g,n=0,r=m,o=0;o<_;++o)(y=e[o])<128&&C.push(S(y));for(s=i=C.length,i&&C.push(f);s<_;){for(u=a,o=0;o<_;++o)(y=e[o])>=t&&yw((a-n)/(b=s+1))&&x("overflow"),n+=(u-t)*b,t=u,o=0;o<_;++o)if((y=e[o])a&&x("overflow"),y==t){for(h=n,p=c;!(h<(v=p<=r?l:p>=r+d?d:p-r));p+=c)E=h-v,A=c-v,C.push(S(k(v+E%A,0))),h=w(E/A);C.push(S(k(h,0))),r=j(n,b,s==i),n=0,++s}++n,++t}return C.join("")}o={version:"1.3.2",ucs2:{decode:$,encode:C},decode:T,encode:I,toASCII:function(e){return E(e,(function(e){return v.test(e)?"xn--"+I(e):e}))},toUnicode:function(e){return E(e,(function(e){return p.test(e)?T(e.slice(4).toLowerCase()):e}))}},void 0===(s=function(){return o}.call(t,n,t,e))||(e.exports=s)}()},3937:(e,t,n)=>{"use strict";n.r(t),n.d(t,{default:()=>OT});var s={};n.r(s),n.d(s,{DOMParser:()=>hr,WebSocket:()=>ur,getDummyXMLDOMDocument:()=>mr});var i={};n.r(i),n.d(i,{addCookies:()=>Tr,arrayBufToBase64:()=>Cr,base64ToArrayBuf:()=>kr,copyElement:()=>Br,createHtml:()=>Ur,default:()=>eo,escapeNode:()=>Zr,forEachChild:()=>Gr,getBareJidFromJid:()=>Xr,getDomainFromJid:()=>Kr,getFirstElementChild:()=>Dr,getNodeFromJid:()=>Jr,getParserError:()=>Rr,getResourceFromJid:()=>Yr,getText:()=>Vr,handleError:()=>Ar,isTagEqual:()=>Wr,stringToArrayBuf:()=>jr,toElement:()=>xr,unescapeNode:()=>Qr,utf16to8:()=>Er,validAttribute:()=>Lr,validCSS:()=>Fr,validTag:()=>Pr,xmlElement:()=>zr,xmlGenerator:()=>Nr,xmlHtmlNode:()=>Or,xmlTextNode:()=>Mr,xmlescape:()=>qr,xmlunescape:()=>Hr,xorArrayBuffers:()=>$r});const r="object"==typeof global&&global&&global.Object===Object&&global;var o="object"==typeof self&&self&&self.Object===Object&&self;const a=r||o||Function("return this")();const c=a.Symbol;var l=Object.prototype,d=l.hasOwnProperty,u=l.toString,h=c?c.toStringTag:void 0;const m=function(e){var t=d.call(e,h),n=e[h];try{e[h]=void 0;var s=!0}catch(e){}var i=u.call(e);return s&&(t?e[h]=n:delete e[h]),i};var g=Object.prototype.toString;const f=function(e){return g.call(e)};var p=c?c.toStringTag:void 0;const v=function(e){return null==e?void 0===e?"[object Undefined]":"[object Null]":p&&p in Object(e)?m(e):f(e)};const y=function(e){var t=typeof e;return null!=e&&("object"==t||"function"==t)};const _=function(e){if(!y(e))return!1;var t=v(e);return"[object Function]"==t||"[object GeneratorFunction]"==t||"[object AsyncFunction]"==t||"[object Proxy]"==t};const b=a["__core-js_shared__"];var w,S=(w=/[^.]+$/.exec(b&&b.keys&&b.keys.IE_PROTO||""))?"Symbol(src)_1."+w:"";const x=function(e){return!!S&&S in e};var A=Function.prototype.toString;const E=function(e){if(null!=e){try{return A.call(e)}catch(e){}try{return e+""}catch(e){}}return""};var $=/^\[object .+?Constructor\]$/,C=Function.prototype,k=Object.prototype,j=C.toString,T=k.hasOwnProperty,I=RegExp("^"+j.call(T).replace(/[\\^$.*+?()[\]{}|]/g,"\\$&").replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g,"$1.*?")+"$");const N=function(e){return!(!y(e)||x(e))&&(_(e)?I:$).test(E(e))};const M=function(e,t){return null==e?void 0:e[t]};const O=function(e,t){var n=M(e,t);return N(n)?n:void 0};const R=function(){try{var e=O(Object,"defineProperty");return e({},"",{}),e}catch(e){}}();const D=function(e,t,n){"__proto__"==t&&R?R(e,t,{configurable:!0,enumerable:!0,value:n,writable:!0}):e[t]=n};const z=function(e,t){return e===t||e!=e&&t!=t};var P=Object.prototype.hasOwnProperty;const L=function(e,t,n){var s=e[t];P.call(e,t)&&z(s,n)&&(void 0!==n||t in e)||D(e,t,n)};const F=function(e,t,n,s){var i=!n;n||(n={});for(var r=-1,o=t.length;++r-1&&e%1==0&&e-1&&e%1==0&&e<=9007199254740991};var se={};se["[object Float32Array]"]=se["[object Float64Array]"]=se["[object Int8Array]"]=se["[object Int16Array]"]=se["[object Int32Array]"]=se["[object Uint8Array]"]=se["[object Uint8ClampedArray]"]=se["[object Uint16Array]"]=se["[object Uint32Array]"]=!0,se["[object Arguments]"]=se["[object Array]"]=se["[object ArrayBuffer]"]=se["[object Boolean]"]=se["[object DataView]"]=se["[object Date]"]=se["[object Error]"]=se["[object Function]"]=se["[object Map]"]=se["[object Number]"]=se["[object Object]"]=se["[object RegExp]"]=se["[object Set]"]=se["[object String]"]=se["[object WeakMap]"]=!1;const ie=function(e){return B(e)&&ne(e.length)&&!!se[v(e)]};const re=function(e){return function(t){return e(t)}};var oe="object"==typeof exports&&exports&&!exports.nodeType&&exports,ae=oe&&"object"==typeof module&&module&&!module.nodeType&&module,ce=ae&&ae.exports===oe&&r.process;const le=function(){try{var e=ae&&ae.require&&ae.require("util").types;return e||ce&&ce.binding&&ce.binding("util")}catch(e){}}();var de=le&&le.isTypedArray;const ue=de?re(de):ie;var he=Object.prototype.hasOwnProperty;const me=function(e,t){var n=Z(e),s=!n&&V(e),i=!n&&!s&&X(e),r=!n&&!s&&!i&&ue(e),o=n||s||i||r,a=o?U(e.length,String):[],c=a.length;for(var l in e)!t&&!he.call(e,l)||o&&("length"==l||i&&("offset"==l||"parent"==l)||r&&("buffer"==l||"byteLength"==l||"byteOffset"==l)||te(l,c))||a.push(l);return a};var ge=Object.prototype;const fe=function(e){var t=e&&e.constructor;return e===("function"==typeof t&&t.prototype||ge)};const pe=function(e,t){return function(n){return e(t(n))}};const ve=pe(Object.keys,Object);var ye=Object.prototype.hasOwnProperty;const _e=function(e){if(!fe(e))return ve(e);var t=[];for(var n in Object(e))ye.call(e,n)&&"constructor"!=n&&t.push(n);return t};const be=function(e){return null!=e&&ne(e.length)&&!_(e)};const we=function(e){return be(e)?me(e):_e(e)};const Se=function(e,t){return e&&F(t,we(t),e)};var xe=Object.create,Ae=function(){function e(){}return function(t){if(!y(t))return{};if(xe)return xe(t);e.prototype=t;var n=new e;return e.prototype=void 0,n}}();const Ee=Ae;const $e=function(e,t){var n=Ee(e);return null==t?n:Se(n,t)};const Ce=function(e){return e};const ke=function(e,t,n){switch(n.length){case 0:return e.call(t);case 1:return e.call(t,n[0]);case 2:return e.call(t,n[0],n[1]);case 3:return e.call(t,n[0],n[1],n[2])}return e.apply(t,n)};var je=Math.max;const Te=function(e,t,n){return t=je(void 0===t?e.length-1:t,0),function(){for(var s=arguments,i=-1,r=je(s.length-t,0),o=Array(r);++i0){if(++t>=800)return arguments[0]}else t=0;return e.apply(void 0,arguments)}}(Ne);const Re=function(e,t){return Oe(Te(e,t,Ce),e+"")};const De=function(e,t,n){if(!y(n))return!1;var s=typeof t;return!!("number"==s?be(n)&&te(t,n.length):"string"==s&&t in n)&&z(n[t],e)};const ze=function(e){return Re((function(t,n){var s=-1,i=n.length,r=i>1?n[i-1]:void 0,o=i>2?n[2]:void 0;for(r=e.length>3&&"function"==typeof r?(i--,r):void 0,o&&De(n[0],n[1],o)&&(r=i<3?void 0:r,i=1),t=Object(t);++s-1};const ut=function(e,t){var n=this.__data__,s=ot(n,e);return s<0?(++this.size,n.push([e,t])):n[s][1]=t,this};function ht(e){var t=-1,n=null==e?0:e.length;for(this.clear();++t{e.resolve=t,e.reject=n}));return Object.assign(t,e),t.then((function(e){return t.isResolved=!0,t.isPending=!1,t.isRejected=!1,e}),(function(e){throw t.isResolved=!1,t.isPending=!1,t.isRejected=!0,e})),t}function Ht(){throw new Error('A "url" property or function must be specified')}function Gt(e,t){const n=t.error;t.error=function(s){n&&n.call(t.context,e,s,t),e.trigger("error",e,s,t)}}const Wt={create:"POST",update:"PUT",patch:"PATCH",delete:"DELETE",read:"GET"};function Vt(e){const t=Ft(e,"browserStorage")||Ft(e.collection,"browserStorage");return t?t.sync():Zt}function Zt(e,t){let n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{};const s={type:Wt[e],dataType:"json"};n.url||(s.url=Ft(t,"url")||Ht()),null!=n.data||!t||"create"!==e&&"update"!==e&&"patch"!==e||(s.contentType="application/json",s.data=JSON.stringify(n.attrs||t.toJSON(n))),"GET"!==s.type&&(s.processData=!1);const i=n.error;n.error=function(e,t,s){n.textStatus=t,n.errorThrown=s,i&&i.call(n.context,e,t,s)};const r=n.xhr=function(){return fetch.apply(this,arguments)}(Be(s,n));return t.trigger("request",t,r,n),r}const Qt=O(a,"DataView");const Jt=O(a,"Promise");const Kt=O(a,"Set");const Yt=O(a,"WeakMap");var Xt="[object Map]",en="[object Promise]",tn="[object Set]",nn="[object WeakMap]",sn="[object DataView]",rn=E(Qt),on=E(gt),an=E(Jt),cn=E(Kt),ln=E(Yt),dn=v;(Qt&&dn(new Qt(new ArrayBuffer(1)))!=sn||gt&&dn(new gt)!=Xt||Jt&&dn(Jt.resolve())!=en||Kt&&dn(new Kt)!=tn||Yt&&dn(new Yt)!=nn)&&(dn=function(e){var t=v(e),n="[object Object]"==t?e.constructor:void 0,s=n?E(n):"";if(s)switch(s){case rn:return sn;case on:return Xt;case an:return en;case cn:return tn;case ln:return nn}return t});const un=dn;var hn=Object.prototype.hasOwnProperty;const mn=function(e){if(null==e)return!0;if(be(e)&&(Z(e)||"string"==typeof e||"function"==typeof e.splice||X(e)||ue(e)||V(e)))return!e.length;var t=un(e);if("[object Map]"==t||"[object Set]"==t)return!e.size;if(fe(e))return!_e(e).length;for(var n in e)if(hn.call(e,n))return!1;return!0};var gn=/\s/;const fn=function(e){for(var t=e.length;t--&&gn.test(e.charAt(t)););return t};var pn=/^\s+/;const vn=function(e){return e?e.slice(0,fn(e)+1).replace(pn,""):e};var yn=/^[-+]0x[0-9a-f]+$/i,_n=/^0b[01]+$/i,bn=/^0o[0-7]+$/i,wn=parseInt;const Sn=function(e){if("number"==typeof e)return e;if(Ge(e))return NaN;if(y(e)){var t="function"==typeof e.valueOf?e.valueOf():e;e=y(t)?t+"":t}if("string"!=typeof e)return 0===e?e:+e;e=vn(e);var n=_n.test(e);return n||bn.test(e)?wn(e.slice(2),n?2:8):yn.test(e)?NaN:+e};var xn=1/0;const An=function(e){return e?(e=Sn(e))===xn||e===-1/0?17976931348623157e292*(e<0?-1:1):e==e?e:0:0===e?e:0};const En=function(e){var t=An(e),n=t%1;return t==t?n?t-n:t:0};const $n=function(e,t){var n;if("function"!=typeof t)throw new TypeError("Expected a function");return e=En(e),function(){return--e>0&&(n=t.apply(this,arguments)),e<=1&&(t=void 0),n}};const Cn=function(e){return $n(2,e)};var kn=0;const jn=function(e){var t=++kn;return Rt(e)+t},Tn={},In=/\s+/;let Nn;const Mn=function(e,t,n,s,i){let r,o=0;if(n&&"object"==typeof n){void 0!==s&&"context"in i&&void 0===i.context&&(i.context=s);for(r=we(n);o2?t[2]:void 0;for(i&&De(t[0],t[1],i)&&(s=1);++n":">",'"':""","'":"'"});var Qs=/[&<>"']/g,Js=RegExp(Qs.source);const Ks=function(e){return(e=Rt(e))&&Js.test(e)?e.replace(Qs,Zs):e};const Ys=function(e){return function(t,n,s){for(var i=-1,r=Object(t),o=s(t),a=o.length;a--;){var c=o[e?a:++i];if(!1===n(r[c],c,r))break}return t}};const Xs=Ys();const ei=function(e,t){return e&&Xs(e,t,we)};const ti=function(e,t,n,s){return ei(e,(function(e,i,r){t(s,n(e),i,r)})),s};const ni=function(e,t){return function(n,s){return ti(n,e,t(s),{})}};var si=Object.prototype.toString,ii=ni((function(e,t,n){null!=t&&"function"!=typeof t.toString&&(t=si.call(t)),e[t]=n}),Ie(Ce));const ri=ii;const oi=function(e){return this.__data__.set(e,"__lodash_hash_undefined__"),this};const ai=function(e){return this.__data__.has(e)};function ci(e){var t=-1,n=null==e?0:e.length;for(this.__data__=new xt;++ta))return!1;var l=r.get(e),d=r.get(t);if(l&&d)return l==t&&d==e;var u=-1,h=!0,m=2&n?new li:void 0;for(r.set(e,t),r.set(t,e);++ui?0:i+t),(n=n>i?i:n)<0&&(n+=i),i=t>n?0:n-t>>>0,t>>>=0;for(var r=Array(i);++s0&&s(c)?n>1?e(c,n-1,s,i,r):cs(r,c):i||(r[r.length]=c)}return r};const nr=function(e){return(null==e?0:e.length)?tr(e,1):[]};const sr=function(e){return Oe(Te(e,void 0,nr),e+"")};var ir=sr((function(e,t){var n={};if(null==e)return n;var s=!1;t=It(t,(function(t){return t=Dt(t,e),s||(s=t.length>1),t})),F(e,fs(e),n),s&&(n=Ls(n,7,Yi));for(var i=t.length;i--;)Gi(n,t[i]);return n}));const rr=ir;const or=function(e,t,n,s){if(!y(e))return e;for(var i=-1,r=(t=Dt(t,e)).length,o=r-1,a=e;null!=a&&++i_r.FATAL)throw new Error("Invalid log level supplied to setLogLevel");wr=e},log(e,t){e=_r.ERROR?console?.error(t):e===_r.INFO?console?.info(t):e===_r.WARN?console?.warn(t):e===_r.DEBUG&&console?.debug(t))},debug(e){this.log(_r.DEBUG,e)},info(e){this.log(_r.INFO,e)},warn(e){this.log(_r.WARN,e)},error(e){this.log(_r.ERROR,e)},fatal(e){this.log(_r.FATAL,e)}};function xr(e,t){const n=Or(e),s=Rr(n);if(s)throw new Error(`Parser Error: ${s}`);const i=Dr(n);if(["message","iq","presence"].includes(i.nodeName.toLowerCase())&&"jabber:client"!==i.namespaceURI&&"jabber:server"!==i.namespaceURI){const e=`Invalid namespaceURI ${i.namespaceURI}`;if(t)throw new Error(e);Sr.error(e)}return i}function Ar(e){void 0!==e.stack&&Sr.fatal(e.stack),Sr.fatal("error: "+e.message)}function Er(e){let t="";const n=e.length;for(let s=0;s=0&&n<=127?t+=e.charAt(s):n>2047?(t+=String.fromCharCode(224|n>>12&15),t+=String.fromCharCode(128|n>>6&63),t+=String.fromCharCode(128|n>>0&63)):(t+=String.fromCharCode(192|n>>6&31),t+=String.fromCharCode(128|n>>0&63))}return t}function $r(e,t){const n=new Uint8Array(e),s=new Uint8Array(t),i=new Uint8Array(e.byteLength);for(let t=0;te.charCodeAt(0)))?.buffer}function jr(e){return(new TextEncoder).encode(e).buffer}function Tr(e){"undefined"==typeof document&&Sr.error("addCookies: not adding any cookies, since there's no document object"),e=e||{};for(const t in e)if(Object.prototype.hasOwnProperty.call(e,t)){let n="",s="",i="";const r=e[t],o="object"==typeof r,a=escape(unescape(o?r.value:r));o&&(n=r.expires?";expires="+r.expires:"",s=r.domain?";domain="+r.domain:"",i=r.path?";path="+r.path:""),document.cookie=t+"="+a+n+s+i}}let Ir=null;function Nr(){return Ir||(Ir=mr()),Ir}function Mr(e){return Nr().createTextNode(e)}function Or(e){return(new hr).parseFromString(e,"text/xml")}function Rr(e){const t="parsererror"===e.firstElementChild?.nodeName?e.firstElementChild:e.getElementsByTagNameNS(fr,"parsererror")[0];return"parsererror"===t?.nodeName?t?.textContent:null}function Dr(e){if(e.firstElementChild)return e.firstElementChild;let t,n=0;const s=e.childNodes;for(;t=s[n++];)if(1===t.nodeType)return t;return null}function zr(e,t,n){if(!e)return null;const s=Nr().createElement(e);if(!n||"string"!=typeof n&&"number"!=typeof n){if("string"==typeof t||"number"==typeof t)return s.appendChild(Mr(t.toString())),s}else s.appendChild(Mr(n.toString()));if(!t)return s;if(Array.isArray(t))for(const e of t)Array.isArray(e)&&null!=e[0]&&null!=e[1]&&s.setAttribute(e[0],e[1]);else if("object"==typeof t)for(const e of Object.keys(t))e&&null!=t[e]&&s.setAttribute(e,t[e].toString());return s}function Pr(e){for(let t=0;t0)for(let e=0;e0&&(r=e.join("; "),t.setAttribute(i,r))}else t.setAttribute(i,r)}for(let n=0;n/g,">")).replace(/'/g,"'")).replace(/"/g,""")}function Hr(e){return e=(e=(e=(e=(e=e.replace(/\&/g,"&")).replace(/</g,"<")).replace(/>/g,">")).replace(/'/g,"'")).replace(/"/g,'"')}function Gr(e,t,n){for(let s=0;s/g,"\\3e").replace(/@/g,"\\40")}function Qr(e){return"string"!=typeof e?e:e.replace(/\\20/g," ").replace(/\\22/g,'"').replace(/\\26/g,"&").replace(/\\27/g,"'").replace(/\\2f/g,"/").replace(/\\3a/g,":").replace(/\\3c/g,"<").replace(/\\3e/g,">").replace(/\\40/g,"@").replace(/\\5c/g,"\\")}function Jr(e){return e.indexOf("@")<0?null:e.split("@")[0]}function Kr(e){const t=Xr(e);if(t.indexOf("@")<0)return t;{const e=t.split("@");return e.splice(0,1),e.join("@")}}function Yr(e){if(!e)return null;const t=e.split("/");return t.length<2?null:(t.splice(0,1),t.join("/"))}function Xr(e){return e?e.split("/")[0]:null}const eo={utf16to8:Er,xorArrayBuffers:$r,arrayBufToBase64:Cr,base64ToArrayBuf:kr,stringToArrayBuf:jr,addCookies:Tr};function to(e,t){return new ro(e,t)}function no(e){return new ro("message",e)}function so(e){return new ro("iq",e)}function io(e){return new ro("presence",e)}class ro{#e;#t;#n;#s;constructor(e,t){"presence"!==e&&"message"!==e&&"iq"!==e||(t&&!t.xmlns?t.xmlns=gr.CLIENT:t||(t={xmlns:gr.CLIENT})),this.#n=e,this.#s=t}static fromString(e){const t=xr(e,!0),n=new ro("");return n.#e=t,n}buildTree(){return zr(this.#n,this.#s)}get nodeTree(){return this.#e||(this.#e=this.buildTree()),this.#e}get node(){return this.#t||(this.#t=this.tree()),this.#t}set node(e){this.#t=e}static serialize(e){if(!e)return null;const t=e instanceof ro?e.tree():e,n=[...Array(t.attributes.length).keys()].map((e=>t.attributes[e].nodeName));n.sort();let s=n.reduce(((e,n)=>`${e} ${n}="${qr(t.attributes.getNamedItem(n).value)}"`),`<${t.nodeName}`);if(t.childNodes.length>0){s+=">";for(let e=0;e"}}s+=""}else s+="/>";return s}tree(){return this.nodeTree}toString(){return ro.serialize(this.tree())}up(){return this.node=this.node.parentElement?this.node.parentElement:this.node.parentNode,this}root(){return this.node=this.tree(),this}attrs(e){for(const t in e)Object.prototype.hasOwnProperty.call(e,t)&&(null!=e[t]?this.node.setAttribute(t,e[t].toString()):this.node.removeAttribute(t));return this}c(e,t,n){const s=zr(e,t,n);return this.node.appendChild(s),"string"!=typeof n&&"number"!=typeof n&&(this.node=s),this}cnode(e){let t;const n=Nr();try{t=void 0!==n.importNode}catch(e){t=!1}const s=t?n.importNode(e,!0):Br(e);return this.node.appendChild(s),this.node=s,this}t(e){const t=Mr(e);return this.node.appendChild(t),this}h(e){const t=Nr().createElement("body");t.innerHTML=e;const n=Ur(t);for(;n.childNodes.length>0;)this.node.appendChild(n.childNodes[0]);return this}}const oo=ro;let ao=0;const co=class{constructor(e,t,n){let s=arguments.length>3&&void 0!==arguments[3]?arguments[3]:0;this.id=++ao,this.xmlData=e,this.data=oo.serialize(e),this.origFunc=t,this.func=t,this.rid=n,this.date=NaN,this.sends=s,this.abort=!1,this.dead=null,this.age=()=>this.date?((new Date).valueOf()-this.date.valueOf())/1e3:0,this.timeDead=()=>this.dead?((new Date).valueOf()-this.dead.valueOf())/1e3:0,this.xhr=this._newXHR()}getResponse(){const e=this.xhr.responseXML?.documentElement;if(e){if("parsererror"===e.tagName)throw Sr.error("invalid response received"),Sr.error("responseText: "+this.xhr.responseText),Sr.error("responseXML: "+oo.serialize(e)),new Error("parsererror")}else if(this.xhr.responseText){Sr.debug("Got responseText but no responseXML; attempting to parse it with DOMParser...");const e=Or(this.xhr.responseText),t=Rr(e);if(!e||t){t&&(Sr.error("invalid response received: "+t),Sr.error("responseText: "+this.xhr.responseText));const e=new Error;throw e.name=yr.BAD_FORMAT,e}}return e}_newXHR(){const e=new XMLHttpRequest;return e.overrideMimeType&&e.overrideMimeType("text/xml; charset=utf-8"),e.onreadystatechange=this.func.bind(null,this),e}};let lo=1.1,uo=.1;class ho{constructor(e){this._conn=e,this.rid=Math.floor(4294967295*Math.random()),this.sid=null,this.hold=1,this.wait=60,this.window=5,this.errors=0,this.inactivity=null,this.strip=ho.prototype.strip??!1,this.lastResponseHeaders=null,this._requests=[]}static setTimeoutMultiplier(e){lo=e}static getTimeoutMultplier(){return lo}static setSecondaryTimeoutMultiplier(e){uo=e}static getSecondaryTimeoutMultplier(){return uo}_buildBody(){const e=to("body",{rid:this.rid++,xmlns:gr.HTTPBIND});return null!==this.sid&&e.attrs({sid:this.sid}),this._conn.options.keepalive&&this._conn._sessionCachingSupported()&&this._cacheSession(),e}_reset(){this.rid=Math.floor(4294967295*Math.random()),this.sid=null,this.errors=0,this._conn._sessionCachingSupported()&&sessionStorage.removeItem("strophe-bosh-session"),this._conn.nextValidRid(this.rid)}_connect(e,t,n){this.wait=e||this.wait,this.hold=t||this.hold,this.errors=0;const s=this._buildBody().attrs({to:this._conn.domain,"xml:lang":"en",wait:this.wait,hold:this.hold,content:"text/xml; charset=utf-8",ver:"1.6","xmpp:version":"1.0","xmlns:xmpp":gr.BOSH});n&&s.attrs({route:n});const i=this._conn._connect_cb;this._requests.push(new co(s.tree(),this._onRequestStateChange.bind(this,i.bind(this._conn)),Number(s.tree().getAttribute("rid")))),this._throttledRequestHandler()}_attach(e,t,n,s,i,r,o){this._conn.jid=e,this.sid=t,this.rid=n,this._conn.connect_callback=s,this._conn.domain=Kr(this._conn.jid),this._conn.authenticated=!0,this._conn.connected=!0,this.wait=i||this.wait,this.hold=r||this.hold,this.window=o||this.window,this._conn._changeConnectStatus(vr.ATTACHED,null)}_restore(e,t,n,s,i){const r=JSON.parse(sessionStorage.getItem("strophe-bosh-session"));if(!(null!=r&&r.rid&&r.sid&&r.jid&&(null==e||Xr(r.jid)===Xr(e)||null===Jr(e)&&Kr(r.jid)===e))){const e=new Error("_restore: no restoreable session.");throw e.name="StropheSessionError",e}this._conn.restored=!0,this._attach(r.jid,r.sid,r.rid,t,n,s,i)}_cacheSession(){this._conn.authenticated?this._conn.jid&&this.rid&&this.sid&&sessionStorage.setItem("strophe-bosh-session",JSON.stringify({jid:this._conn.jid,rid:this.rid,sid:this.sid})):sessionStorage.removeItem("strophe-bosh-session")}_connect_cb(e){const t=e.getAttribute("type");if(null!==t&&"terminate"===t){let t=e.getAttribute("condition");Sr.error("BOSH-Connection failed: "+t);const n=e.getElementsByTagName("conflict");return null!==t?("remote-stream-error"===t&&n.length>0&&(t="conflict"),this._conn._changeConnectStatus(vr.CONNFAIL,t)):this._conn._changeConnectStatus(vr.CONNFAIL,"unknown"),this._conn._doDisconnect(t),vr.CONNFAIL}this.sid||(this.sid=e.getAttribute("sid"));const n=e.getAttribute("requests");n&&(this.window=parseInt(n,10));const s=e.getAttribute("hold");s&&(this.hold=parseInt(s,10));const i=e.getAttribute("wait");i&&(this.wait=parseInt(i,10));const r=e.getAttribute("inactivity");r&&(this.inactivity=parseInt(r,10))}_disconnect(e){this._sendTerminate(e)}_doDisconnect(){this.sid=null,this.rid=Math.floor(4294967295*Math.random()),this._conn._sessionCachingSupported()&&sessionStorage.removeItem("strophe-bosh-session"),this._conn.nextValidRid(this.rid)}_emptyQueue(){return 0===this._requests.length}_callProtocolErrorHandlers(e){const t=ho._getRequestStatus(e),n=this._conn.protocolErrorHandlers.HTTP[t];n&&n.call(this,t)}_hitError(e){this.errors++,Sr.warn("request errored, status: "+e+", number of errors: "+this.errors),this.errors>4&&this._conn._onDisconnectTimeout()}_no_auth_received(e){Sr.warn("Server did not yet offer a supported authentication mechanism. Sending a blank poll request."),e=e?e.bind(this._conn):this._conn._connect_cb.bind(this._conn);const t=this._buildBody();this._requests.push(new co(t.tree(),this._onRequestStateChange.bind(this,e),Number(t.tree().getAttribute("rid")))),this._throttledRequestHandler()}_onDisconnectTimeout(){this._abortAllRequests()}_abortAllRequests(){for(;this._requests.length>0;){const e=this._requests.pop();e.abort=!0,e.xhr.abort(),e.xhr.onreadystatechange=function(){}}}_onIdle(){const e=this._conn._data;if(this._conn.authenticated&&0===this._requests.length&&0===e.length&&!this._conn.disconnecting&&(Sr.debug("no requests during idle cycle, sending blank request"),e.push(null)),!this._conn.paused){if(this._requests.length<2&&e.length>0){const t=this._buildBody();for(let n=0;n0){const e=this._requests[0].age();null!==this._requests[0].dead&&this._requests[0].timeDead()>Math.floor(lo*this.wait)&&this._throttledRequestHandler(),e>Math.floor(lo*this.wait)&&(Sr.warn("Request "+this._requests[0].id+" timed out, over "+Math.floor(lo*this.wait)+" seconds since last activity"),this._throttledRequestHandler())}}}static _getRequestStatus(e,t){let n;if(4===e.xhr.readyState)try{n=e.xhr.status}catch(e){Sr.error(`Caught an error while retrieving a request's status, reqStatus: ${n}, message: ${e.message}`)}return void 0===n&&(n="number"==typeof t?t:0),n}_onRequestStateChange(e,t){if(Sr.debug("request id "+t.id+"."+t.sends+" state changed to "+t.xhr.readyState),t.abort)return void(t.abort=!1);if(4!==t.xhr.readyState)return;const n=ho._getRequestStatus(t);if(this.lastResponseHeaders=t.xhr.getAllResponseHeaders(),this._conn.disconnecting&&n>=400)return this._hitError(n),void this._callProtocolErrorHandlers(t);const s=this._requests[0]===t,i=this._requests[1]===t,r=n>0&&n<500,o=t.sends>this._conn.maxRetries;(r||o)&&(this._removeRequest(t),Sr.debug("request id "+t.id+" should now be removed")),200===n?((i||s&&this._requests.length>0&&this._requests[0].age()>Math.floor(lo*this.wait))&&this._restartRequest(0),this._conn.nextValidRid(t.rid+1),Sr.debug("request id "+t.id+"."+t.sends+" got 200"),e(t),this.errors=0):0===n||n>=400&&n<600||n>=12e3?(Sr.error("request id "+t.id+"."+t.sends+" error "+n+" happened"),this._hitError(n),this._callProtocolErrorHandlers(t),n>=400&&n<500&&(this._conn._changeConnectStatus(vr.DISCONNECTING,null),this._conn._doDisconnect())):Sr.error("request id "+t.id+"."+t.sends+" error "+n+" happened"),r||o?o&&!this._conn.connected&&this._conn._changeConnectStatus(vr.CONNFAIL,"giving-up"):this._throttledRequestHandler()}_processRequest(e){let t=this._requests[e];const n=ho._getRequestStatus(t,-1);if(t.sends>this._conn.maxRetries)return void this._conn._onDisconnectTimeout();const s=t.age(),i=!isNaN(s)&&s>Math.floor(lo*this.wait),r=null!==t.dead&&t.timeDead()>Math.floor(uo*this.wait),o=4===t.xhr.readyState&&(n<1||n>=500);if((i||r||o)&&(r&&Sr.error(`Request ${this._requests[e].id} timed out (secondary), restarting`),t.abort=!0,t.xhr.abort(),t.xhr.onreadystatechange=function(){},this._requests[e]=new co(t.xmlData,t.origFunc,t.rid,t.sends),t=this._requests[e]),0===t.xhr.readyState){Sr.debug("request id "+t.id+"."+t.sends+" posting");try{const e=this._conn.options.contentType||"text/xml; charset=utf-8";t.xhr.open("POST",this._conn.service,!this._conn.options.sync),void 0!==t.xhr.setRequestHeader&&t.xhr.setRequestHeader("Content-Type",e),this._conn.options.withCredentials&&(t.xhr.withCredentials=!0)}catch(e){return Sr.error("XHR open failed: "+e.toString()),this._conn.connected||this._conn._changeConnectStatus(vr.CONNFAIL,"bad-service"),void this._conn.disconnect()}const e=()=>{if(t.date=(new Date).valueOf(),this._conn.options.customHeaders){const e=this._conn.options.customHeaders;for(const n in e)Object.prototype.hasOwnProperty.call(e,n)&&t.xhr.setRequestHeader(n,e[n])}t.xhr.send(t.data)};if(t.sends>1){const n=1e3*Math.min(Math.floor(lo*this.wait),Math.pow(t.sends,3));setTimeout((function(){e()}),n)}else e();t.sends++,this.strip&&"body"===t.xmlData.nodeName&&t.xmlData.childNodes.length?this._conn.xmlOutput?.(t.xmlData.children[0]):this._conn.xmlOutput?.(t.xmlData),this._conn.rawOutput?.(t.data)}else Sr.debug("_processRequest: "+(0===e?"first":"second")+" request has readyState of "+t.xhr.readyState)}_removeRequest(e){Sr.debug("removing request");for(let t=this._requests.length-1;t>=0;t--)e===this._requests[t]&&this._requests.splice(t,1);e.xhr.onreadystatechange=function(){},this._throttledRequestHandler()}_restartRequest(e){const t=this._requests[e];null===t.dead&&(t.dead=new Date),this._processRequest(e)}_reqToData(e){try{return e.getResponse()}catch(e){if("parsererror"!==e.message)throw e;this._conn.disconnect("strophe-parsererror")}}_sendTerminate(e){Sr.debug("_sendTerminate was called");const t=this._buildBody().attrs({type:"terminate"}),n=e instanceof oo?e.tree():e;e&&t.cnode(n);const s=new co(t.tree(),this._onRequestStateChange.bind(this,this._conn._dataRecv.bind(this._conn)),Number(t.tree().getAttribute("rid")));this._requests.push(s),this._throttledRequestHandler()}_send(){clearTimeout(this._conn._idleTimeout),this._throttledRequestHandler(),this._conn._idleTimeout=setTimeout((()=>this._conn._onIdle()),100)}_sendRestart(){this._throttledRequestHandler(),clearTimeout(this._conn._idleTimeout)}_throttledRequestHandler(){this._requests?Sr.debug("_throttledRequestHandler called with "+this._requests.length+" requests"):Sr.debug("_throttledRequestHandler called with undefined requests"),this._requests&&0!==this._requests.length&&(this._requests.length>0&&this._processRequest(0),this._requests.length>1&&Math.abs(this._requests[0].rid-this._requests[1].rid)0&&void 0!==arguments[0]?arguments[0]:"ANONYMOUS",arguments.length>1&&void 0!==arguments[1]&&arguments[1],arguments.length>2&&void 0!==arguments[2]?arguments[2]:20)}test(e){return null===e.authcid}};const yo=class extends po{constructor(){super(arguments.length>0&&void 0!==arguments[0]?arguments[0]:"EXTERNAL",!(arguments.length>1&&void 0!==arguments[1])||arguments[1],arguments.length>2&&void 0!==arguments[2]?arguments[2]:10)}onChallenge(e){return e.authcid===e.authzid?"":e.authzid}};const _o=class extends po{constructor(){super(arguments.length>0&&void 0!==arguments[0]?arguments[0]:"OAUTHBEARER",!(arguments.length>1&&void 0!==arguments[1])||arguments[1],arguments.length>2&&void 0!==arguments[2]?arguments[2]:40)}test(e){return null!==e.pass}onChallenge(e){let t="n,";return null!==e.authcid&&(t=t+"a="+e.authzid),t+=",",t+="",t+="auth=Bearer ",t+=e.pass,t+="",t+="",eo.utf16to8(t)}};const bo=class extends po{constructor(){super(arguments.length>0&&void 0!==arguments[0]?arguments[0]:"PLAIN",!(arguments.length>1&&void 0!==arguments[1])||arguments[1],arguments.length>2&&void 0!==arguments[2]?arguments[2]:50)}test(e){return null!==e.authcid}onChallenge(e){const{authcid:t,authzid:n,domain:s,pass:i}=e;if(!s)throw new Error("SASLPlain onChallenge: domain is not defined!");let r=n!==`${t}@${s}`?n:"";return r+="\0",r+=t,r+="\0",r+=i,eo.utf16to8(r)}};const wo={async scramResponse(e,t,n,s){const i=e._sasl_data.cnonce,r=function(e){let t,n,s;const i=/([a-z]+)=([^,]+)(,|$)/;for(;e.match(i);){const r=e.match(i);switch(e=e.replace(r[0],""),r[1]){case"r":t=r[2];break;case"s":n=eo.base64ToArrayBuf(r[2]);break;case"i":s=parseInt(r[2],10);break;case"m":return}}if(isNaN(s)||s<4096)Sr.warn("Failing SCRAM authentication because server supplied iteration count < 4096.");else{if(n)return{nonce:t,salt:n,iter:s};Sr.warn("Failing SCRAM authentication because server supplied incorrect salt.")}}(t);if(!r&&r?.nonce.slice(0,i.length)!==i)return Sr.warn("Failing SCRAM authentication because server supplied incorrect nonce."),e._sasl_data={},e._sasl_failure_cb();let o,a;const{pass:c}=e;if("string"==typeof e.pass||e.pass instanceof String){const e=await async function(e,t,n,s,i){const r=await crypto.subtle.deriveBits({name:"PBKDF2",salt:t,iterations:n,hash:{name:s}},await crypto.subtle.importKey("raw",eo.stringToArrayBuf(e),"PBKDF2",!1,["deriveBits"]),i),o=await crypto.subtle.importKey("raw",r,{name:"HMAC",hash:s},!1,["sign"]);return{ck:await crypto.subtle.sign("HMAC",o,eo.stringToArrayBuf("Client Key")),sk:await crypto.subtle.sign("HMAC",o,eo.stringToArrayBuf("Server Key"))}}(c,r.salt,r.iter,n,s);o=e.ck,a=e.sk}else{if(c?.name!==n||c?.salt!==eo.arrayBufToBase64(r.salt)||c?.iter!==r.iter)return e._sasl_failure_cb();{const{ck:e,sk:t}=c;o=eo.base64ToArrayBuf(e),a=eo.base64ToArrayBuf(t)}}const l=e._sasl_data["client-first-message-bare"],d=t,u=`c=biws,r=${r.nonce}`,h=`${l},${d},${u}`,m=await async function(e,t,n){const s=await crypto.subtle.importKey("raw",await crypto.subtle.digest(n,t),{name:"HMAC",hash:n},!1,["sign"]),i=await crypto.subtle.sign("HMAC",s,eo.stringToArrayBuf(e));return eo.xorArrayBuffers(t,i)}(h,o,n),g=await async function(e,t,n){const s=await crypto.subtle.importKey("raw",t,{name:"HMAC",hash:n},!1,["sign"]);return crypto.subtle.sign("HMAC",s,eo.stringToArrayBuf(e))}(h,a,n);return e._sasl_data["server-signature"]=eo.arrayBufToBase64(g),e._sasl_data.keys={name:n,iter:r.iter,salt:eo.arrayBufToBase64(r.salt),ck:eo.arrayBufToBase64(o),sk:eo.arrayBufToBase64(a)},`${u},p=${eo.arrayBufToBase64(m)}`},clientChallenge(e,t){const n=t||function(){const e=new Uint8Array(16);return eo.arrayBufToBase64(crypto.getRandomValues(e).buffer)}(),s=`n=${e.authcid},r=${n}`;return e._sasl_data.cnonce=n,e._sasl_data["client-first-message-bare"]=s,`n,,${s}`}};const So=class extends po{constructor(){super(arguments.length>0&&void 0!==arguments[0]?arguments[0]:"SCRAM-SHA-1",!(arguments.length>1&&void 0!==arguments[1])||arguments[1],arguments.length>2&&void 0!==arguments[2]?arguments[2]:60)}test(e){return null!==e.authcid}async onChallenge(e,t){return await wo.scramResponse(e,t,"SHA-1",160)}clientChallenge(e,t){return wo.clientChallenge(e,t)}};const xo=class extends po{constructor(){super(arguments.length>0&&void 0!==arguments[0]?arguments[0]:"SCRAM-SHA-256",!(arguments.length>1&&void 0!==arguments[1])||arguments[1],arguments.length>2&&void 0!==arguments[2]?arguments[2]:70)}test(e){return null!==e.authcid}async onChallenge(e,t){return await wo.scramResponse(e,t,"SHA-256",256)}clientChallenge(e,t){return wo.clientChallenge(e,t)}};const Ao=class extends po{constructor(){super(arguments.length>0&&void 0!==arguments[0]?arguments[0]:"SCRAM-SHA-384",!(arguments.length>1&&void 0!==arguments[1])||arguments[1],arguments.length>2&&void 0!==arguments[2]?arguments[2]:71)}test(e){return null!==e.authcid}async onChallenge(e,t){return await wo.scramResponse(e,t,"SHA-384",384)}clientChallenge(e,t){return wo.clientChallenge(e,t)}};const Eo=class extends po{constructor(){super(arguments.length>0&&void 0!==arguments[0]?arguments[0]:"SCRAM-SHA-512",!(arguments.length>1&&void 0!==arguments[1])||arguments[1],arguments.length>2&&void 0!==arguments[2]?arguments[2]:72)}test(e){return null!==e.authcid}async onChallenge(e,t){return await wo.scramResponse(e,t,"SHA-512",512)}clientChallenge(e,t){return wo.clientChallenge(e,t)}};const $o=class extends po{constructor(){super(arguments.length>0&&void 0!==arguments[0]?arguments[0]:"X-OAUTH2",!(arguments.length>1&&void 0!==arguments[1])||arguments[1],arguments.length>2&&void 0!==arguments[2]?arguments[2]:30)}test(e){return null!==e.pass}onChallenge(e){let t="\0";return null!==e.authcid&&(t+=e.authzid),t+="\0",t+=e.pass,eo.utf16to8(t)}};class Co extends Error{constructor(e){super(e),this.name="StropheSessionError"}}const ko=class{constructor(e){this._conn=e,this.strip="wrapper";const t=e.service;if(0!==t.indexOf("ws:")&&0!==t.indexOf("wss:")){let n="";"ws"===e.options.protocol&&"https:"!==location.protocol?n+="ws":n+="wss",n+="://"+location.host,0!==t.indexOf("/")?n+=location.pathname+t:n+=t,e.service=n}}_buildStream(){return to("open",{xmlns:gr.FRAMING,to:this._conn.domain,version:"1.0"})}_checkStreamError(e,t){let n;if(n=e.getElementsByTagNameNS?e.getElementsByTagNameNS(gr.STREAM,"error"):e.getElementsByTagName("stream:error"),0===n.length)return!1;const s=n[0];let i="",r="";for(let e=0;ethis._onOpen(),this.socket.onerror=e=>this._onError(e),this.socket.onclose=e=>this._onClose(e),this.socket.onmessage=e=>this._onInitialMessage(e)}_connect_cb(e){if(this._checkStreamError(e,vr.CONNFAIL))return vr.CONNFAIL}_handleStreamStart(e){let t=null;const n=e.getAttribute("xmlns");"string"!=typeof n?t="Missing xmlns in ":n!==gr.FRAMING&&(t="Wrong xmlns in : "+n);const s=e.getAttribute("version");return"string"!=typeof s?t="Missing version in ":"1.0"!==s&&(t="Wrong version in : "+s),!t||(this._conn._changeConnectStatus(vr.CONNFAIL,t),this._conn._doDisconnect(),!1)}_onInitialMessage(e){if(0===e.data.indexOf("\s*)*/,"");if(""===t)return;const n=(new hr).parseFromString(t,"text/xml").documentElement;this._conn.xmlInput(n),this._conn.rawInput(e.data),this._handleStreamStart(n)&&this._connect_cb(n)}else if(0===e.data.indexOf("=0&&n.indexOf("wss:")>=0||e.indexOf("ws:")>=0)&&(this._conn._changeConnectStatus(vr.REDIRECT,"Received see-other-uri, resetting connection"),this._conn.reset(),this._conn.service=n,this._connect())}else this._conn._changeConnectStatus(vr.CONNFAIL,"Received closing stream"),this._conn._doDisconnect()}else{this._replaceMessageHandler();const t=this._streamWrap(e.data),n=(new hr).parseFromString(t,"text/xml").documentElement;this._conn._connect_cb(n,null,e.data)}}_replaceMessageHandler(){this.socket.onmessage=e=>this._onMessage(e)}_disconnect(e){if(this.socket&&this.socket.readyState!==ur.CLOSED){e&&this._conn.send(e);const t=to("close",{xmlns:gr.FRAMING});this._conn.xmlOutput(t.tree());const n=oo.serialize(t);this._conn.rawOutput(n);try{this.socket.send(n)}catch(e){Sr.warn(`Couldn't send tag. "${e.message}"`)}}setTimeout((()=>this._conn._doDisconnect()),0)}_doDisconnect(){Sr.debug("WebSockets _doDisconnect was called"),this._closeSocket()}_streamWrap(e){return""+e+""}_closeSocket(){if(this.socket)try{this.socket.onclose=null,this.socket.onerror=null,this.socket.onmessage=null,this.socket.close()}catch(e){Sr.debug(e.message)}this.socket=null}_emptyQueue(){return!0}_onClose(e){this._conn.connected&&!this._conn.disconnecting?(Sr.error("Websocket closed unexpectedly"),this._conn._doDisconnect()):e&&1006===e.code&&!this._conn.connected&&this.socket?(Sr.error("Websocket closed unexcectedly"),this._conn._changeConnectStatus(vr.CONNFAIL,"The WebSocket connection could not be established or was disconnected."),this._conn._doDisconnect()):Sr.debug("Websocket closed")}_no_auth_received(e){Sr.error("Server did not offer a supported authentication mechanism"),this._conn._changeConnectStatus(vr.CONNFAIL,yr.NO_AUTH_MECH),e?.call(this._conn),this._conn._doDisconnect()}_onDisconnectTimeout(){}_abortAllRequests(){}_onError(e){Sr.error("Websocket error "+JSON.stringify(e)),this._conn._changeConnectStatus(vr.CONNFAIL,"The WebSocket connection could not be established or was disconnected."),this._disconnect()}_onIdle(){const e=this._conn._data;if(e.length>0&&!this._conn.paused){for(let t=0;t{console?.error(e),Sr.error(`Shared Worker Error: ${e}`)}}_setSocket(){this.socket={send:e=>this.worker.port.postMessage(["send",e]),close:()=>this.worker.port.postMessage(["_closeSocket"]),onopen:()=>{},onerror:e=>this._onError(e),onclose:e=>this._onClose(e),onmessage:()=>{},readyState:null}}_connect(){this._setSocket(),this._messageHandler=e=>this._onInitialMessage(e),this.worker.port.start(),this.worker.port.onmessage=e=>this._onWorkerMessage(e),this.worker.port.postMessage(["_connect",this._conn.service,this._conn.jid])}_attach(e){this._setSocket(),this._messageHandler=e=>this._onMessage(e),this._conn.connect_callback=e,this.worker.port.start(),this.worker.port.onmessage=e=>this._onWorkerMessage(e),this.worker.port.postMessage(["_attach",this._conn.service])}_attachCallback(e,t){e===vr.ATTACHED?(this._conn.jid=t,this._conn.authenticated=!0,this._conn.connected=!0,this._conn.restored=!0,this._conn._changeConnectStatus(vr.ATTACHED)):e===vr.ATTACHFAIL&&(this._conn.authenticated=!1,this._conn.connected=!1,this._conn.restored=!1,this._conn._changeConnectStatus(vr.ATTACHFAIL))}_disconnect(e){e&&this._conn.send(e);const t=to("close",{xmlns:gr.FRAMING});this._conn.xmlOutput(t.tree());const n=oo.serialize(t);this._conn.rawOutput(n),this.worker.port.postMessage(["send",n]),this._conn._doDisconnect()}_closeSocket(){this.socket.close()}_replaceMessageHandler(){this._messageHandler=e=>this._onMessage(e)}_onWorkerMessage(e){const{data:t}=e,n=t[0];if("_onMessage"===n)this._messageHandler(t[1]);else if(n in this)try{this[n].apply(this,e.data.slice(1))}catch(e){Sr.error(e)}else if("log"===n){const e={debug:_r.DEBUG,info:_r.INFO,warn:_r.WARN,error:_r.ERROR,fatal:_r.FATAL},n=t[1],s=t[2];Sr.log(e[n],s)}else Sr.error(`Found unhandled service worker message: ${t}`)}},To={};class Io{constructor(e){let t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};this.service=e,this.options=t,this.setProtocol(),this.jid="",this.domain=null,this.features=null,this._sasl_data={},this.do_bind=!1,this.do_session=!1,this.mechanisms={},this.timedHandlers=[],this.handlers=[],this.removeTimeds=[],this.removeHandlers=[],this.addTimeds=[],this.addHandlers=[],this.protocolErrorHandlers={HTTP:{},websocket:{}},this._idleTimeout=null,this._disconnectTimeout=null,this.authenticated=!1,this.connected=!1,this.disconnecting=!1,this.do_authentication=!0,this.paused=!1,this.restored=!1,this._data=[],this._uniqueId=0,this._sasl_success_handler=null,this._sasl_failure_handler=null,this._sasl_challenge_handler=null,this.maxRetries=5,this._idleTimeout=setTimeout((()=>this._onIdle()),100),Tr(this.options.cookies),this.registerSASLMechanisms(this.options.mechanisms),this.iqFallbackHandler=new go((e=>this.send(so({type:"error",id:e.getAttribute("id")}).c("error",{type:"cancel"}).c("service-unavailable",{xmlns:gr.STANZAS}))),null,"iq",["get","set"]);for(const e in To)if(Object.prototype.hasOwnProperty.call(To,e)){const t=function(){};t.prototype=To[e],this[e]=new t,this[e].init(this)}}static addConnectionPlugin(e,t){To[e]=t}setProtocol(){const e=this.options.protocol||"";this.options.worker?this._proto=new jo(this):0===this.service.indexOf("ws:")||0===this.service.indexOf("wss:")||0===e.indexOf("ws")?this._proto=new ko(this):this._proto=new mo(this)}reset(){this._proto._reset(),this.do_session=!1,this.do_bind=!1,this.timedHandlers=[],this.handlers=[],this.removeTimeds=[],this.removeHandlers=[],this.addTimeds=[],this.addHandlers=[],this.authenticated=!1,this.connected=!1,this.disconnecting=!1,this.restored=!1,this._data=[],this._requests=[],this._uniqueId=0}pause(){this.paused=!0}resume(){this.paused=!1}getUniqueId(e){const t="xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g,(function(e){const t=16*Math.random()|0;return("x"===e?t:3&t|8).toString(16)}));return"string"==typeof e||"number"==typeof e?t+":"+e:t+""}addProtocolErrorHandler(e,t,n){this.protocolErrorHandlers[e][t]=n}connect(e,t,n,s,i,r,o){let a=arguments.length>7&&void 0!==arguments[7]?arguments[7]:3e3;this.jid=e,this.authzid=Xr(this.jid),this.authcid=o||Jr(this.jid),this.pass=t,this.scram_keys=null,this.connect_callback=n,this.disconnecting=!1,this.connected=!1,this.authenticated=!1,this.restored=!1,this.disconnection_timeout=a,this.domain=Kr(this.jid),this._changeConnectStatus(vr.CONNECTING,null),this._proto._connect(s,i,r)}attach(e,t,n,s,i,r,o){if(this._proto instanceof mo&&"string"==typeof e)return this._proto._attach(e,t,n,s,i,r,o);if(this._proto instanceof jo&&"function"==typeof e){const t=e;return this._proto._attach(t)}throw new Co('The "attach" method is not available for your connection protocol')}restore(e,t,n,s,i){if(!(this._proto instanceof mo&&this._sessionCachingSupported()))throw new Co('The "restore" method can only be used with a BOSH connection.');this._sessionCachingSupported()&&this._proto._restore(e,t,n,s,i)}_sessionCachingSupported(){if(this._proto instanceof mo){if(!JSON)return!1;try{sessionStorage.setItem("_strophe_","_strophe_"),sessionStorage.removeItem("_strophe_")}catch(e){return!1}return!0}return!1}xmlInput(e){}xmlOutput(e){}rawInput(e){}rawOutput(e){}nextValidRid(e){}send(e){if(null!==e){if(Array.isArray(e))e.forEach((e=>this._queueData(e instanceof oo?e.tree():e)));else{const t=e instanceof oo?e.tree():e;this._queueData(t)}this._proto._send()}}flush(){clearTimeout(this._idleTimeout),this._onIdle()}sendPresence(e,t,n,s){let i=null;const r=e instanceof oo?e.tree():e;let o=r.getAttribute("id");if(o||(o=this.getUniqueId("sendPresence"),r.setAttribute("id",o)),"function"==typeof t||"function"==typeof n){const e=this.addHandler((e=>{i&&this.deleteTimedHandler(i),"error"===e.getAttribute("type")?n?.(e):t&&t(e)}),null,"presence",null,o);s&&(i=this.addTimedHandler(s,(()=>(this.deleteHandler(e),n?.(null),!1))))}return this.send(r),o}sendIQ(e,t,n,s){let i=null;const r=e instanceof oo?e.tree():e;let o=r.getAttribute("id");if(o||(o=this.getUniqueId("sendIQ"),r.setAttribute("id",o)),"function"==typeof t||"function"==typeof n){const e=this.addHandler((e=>{i&&this.deleteTimedHandler(i);const s=e.getAttribute("type");if("result"===s)t?.(e);else{if("error"!==s){const e=new Error(`Got bad IQ type of ${s}`);throw e.name="StropheError",e}n?.(e)}}),null,"iq",["error","result"],o);s&&(i=this.addTimedHandler(s,(()=>(this.deleteHandler(e),n?.(null),!1))))}return this.send(r),o}_queueData(e){if(null===e||!e.tagName||!e.childNodes){const e=new Error("Cannot queue non-DOMElement.");throw e.name="StropheError",e}this._data.push(e)}_sendRestart(){this._data.push("restart"),this._proto._sendRestart(),this._idleTimeout=setTimeout((()=>this._onIdle()),100)}addTimedHandler(e,t){const n=new fo(e,t);return this.addTimeds.push(n),n}deleteTimedHandler(e){this.removeTimeds.push(e)}addHandler(e,t,n,s,i,r,o){const a=new go(e,t,n,s,i,r,o);return this.addHandlers.push(a),a}deleteHandler(e){this.removeHandlers.push(e);const t=this.addHandlers.indexOf(e);t>=0&&this.addHandlers.splice(t,1)}registerSASLMechanisms(e){this.mechanisms={},(e||[vo,yo,_o,$o,bo,So,xo,Ao,Eo]).forEach((e=>this.registerSASLMechanism(e)))}registerSASLMechanism(e){const t=new e;this.mechanisms[t.mechname]=t}disconnect(e){if(this._changeConnectStatus(vr.DISCONNECTING,e),e?Sr.info("Disconnect was called because: "+e):Sr.debug("Disconnect was called"),this.connected){let e=null;this.disconnecting=!0,this.authenticated&&(e=io({xmlns:gr.CLIENT,type:"unavailable"})),this._disconnectTimeout=this._addSysTimedHandler(this.disconnection_timeout,this._onDisconnectTimeout.bind(this)),this._proto._disconnect(e)}else Sr.debug("Disconnect was called before Strophe connected to the server"),this._proto._abortAllRequests(),this._doDisconnect()}_changeConnectStatus(e,t,n){for(const n in To)if(Object.prototype.hasOwnProperty.call(To,n)){const s=this[n];if(s.statusChanged)try{s.statusChanged(e,t)}catch(e){Sr.error(`${n} plugin caused an exception changing status: ${e}`)}}if(this.connect_callback)try{this.connect_callback(e,t,n)}catch(e){Ar(e),Sr.error(`User connection callback caused an exception: ${e}`)}}_doDisconnect(e){"number"==typeof this._idleTimeout&&clearTimeout(this._idleTimeout),null!==this._disconnectTimeout&&(this.deleteTimedHandler(this._disconnectTimeout),this._disconnectTimeout=null),Sr.debug("_doDisconnect was called"),this._proto._doDisconnect(),this.authenticated=!1,this.disconnecting=!1,this.restored=!1,this.handlers=[],this.timedHandlers=[],this.removeTimeds=[],this.removeHandlers=[],this.addTimeds=[],this.addHandlers=[],this._changeConnectStatus(vr.DISCONNECTED,e),this.connected=!1}_dataRecv(e,t){const n="_reqToData"in this._proto?this._proto._reqToData(e):e;if(null===n)return;for(this.xmlInput!==Io.prototype.xmlInput&&(n.nodeName===this._proto.strip&&n.childNodes.length?this.xmlInput(n.childNodes[0]):this.xmlInput(n)),this.rawInput!==Io.prototype.rawInput&&(t?this.rawInput(t):this.rawInput(oo.serialize(n)));this.removeHandlers.length>0;){const e=this.removeHandlers.pop(),t=this.handlers.indexOf(e);t>=0&&this.handlers.splice(t,1)}for(;this.addHandlers.length>0;)this.handlers.push(this.addHandlers.pop());if(this.disconnecting&&this._proto._emptyQueue())return void this._doDisconnect();const s=n.getAttribute("type");if(null!==s&&"terminate"===s){if(this.disconnecting)return;let e=n.getAttribute("condition");const t=n.getElementsByTagName("conflict");return null!==e?("remote-stream-error"===e&&t.length>0&&(e="conflict"),this._changeConnectStatus(vr.CONNFAIL,e)):this._changeConnectStatus(vr.CONNFAIL,yr.UNKNOWN_REASON),void this._doDisconnect(e)}Gr(n,null,(e=>{const t=[];this.handlers=this.handlers.reduce(((n,s)=>{try{!s.isMatch(e)||!this.authenticated&&s.user?n.push(s):(s.run(e)&&n.push(s),t.push(s))}catch(e){Sr.warn("Removing Strophe handlers due to uncaught exception: "+e.message)}return n}),[]),!t.length&&this.iqFallbackHandler.isMatch(e)&&this.iqFallbackHandler.run(e)}))}_connect_cb(e,t,n){let s;Sr.debug("_connect_cb was called"),this.connected=!0;try{s="_reqToData"in this._proto?this._proto._reqToData(e):e}catch(e){if(e.name!==yr.BAD_FORMAT)throw e;this._changeConnectStatus(vr.CONNFAIL,yr.BAD_FORMAT),this._doDisconnect(yr.BAD_FORMAT)}if(!s)return;this.xmlInput!==Io.prototype.xmlInput&&(s.nodeName===this._proto.strip&&s.childNodes.length?this.xmlInput(s.childNodes[0]):this.xmlInput(s)),this.rawInput!==Io.prototype.rawInput&&(n?this.rawInput(n):this.rawInput(oo.serialize(s)));if(this._proto._connect_cb(s)===vr.CONNFAIL)return;let i;if(i=s.getElementsByTagNameNS?s.getElementsByTagNameNS(gr.STREAM,"features").length>0:s.getElementsByTagName("stream:features").length>0||s.getElementsByTagName("features").length>0,!i)return void this._proto._no_auth_received(t);const r=Array.from(s.getElementsByTagName("mechanism")).map((e=>this.mechanisms[e.textContent])).filter((e=>e));0!==r.length||0!==s.getElementsByTagName("auth").length?!1!==this.do_authentication&&this.authenticate(r):this._proto._no_auth_received(t)}sortMechanismsByPriority(e){for(let t=0;te[n].priority&&(n=s);if(n!==t){const s=e[t];e[t]=e[n],e[n]=s}}return e}authenticate(e){this._attemptSASLAuth(e)||this._attemptLegacyAuth()}_attemptSASLAuth(e){e=this.sortMechanismsByPriority(e||[]);let t=!1;for(let n=0;n{for(;e.length;)this.deleteHandler(e.pop());return this._onStreamFeaturesAfterSASL(t),!1};return t.push(this._addSysHandler((e=>n(t,e)),null,"stream:features",null,null)),t.push(this._addSysHandler((e=>n(t,e)),gr.STREAM,"features",null,null)),this._sendRestart(),!1}_onStreamFeaturesAfterSASL(e){this.features=e;for(let t=0;t0&&(t=yr.CONFLICT),this._changeConnectStatus(vr.AUTHFAIL,t,e),!1}const t=e.getElementsByTagName("bind");if(!(t.length>0))return Sr.warn("Resource binding failed."),this._changeConnectStatus(vr.AUTHFAIL,null,e),!1;{const e=t[0].getElementsByTagName("jid");e.length>0&&(this.authenticated=!0,this.jid=Vr(e[0]),this.do_session?this._establishSession():this._changeConnectStatus(vr.CONNECTED,null))}}_establishSession(){if(!this.do_session)throw new Error(`Connection.prototype._establishSession called but apparently ${gr.SESSION} wasn't advertised by the server`);this._addSysHandler(this._onSessionResultIQ.bind(this),null,null,null,"_session_auth_2"),this.send(so({type:"set",id:"_session_auth_2"}).c("session",{xmlns:gr.SESSION}).tree())}_onSessionResultIQ(e){if("result"===e.getAttribute("type"))this.authenticated=!0,this._changeConnectStatus(vr.CONNECTED,null);else if("error"===e.getAttribute("type"))return this.authenticated=!1,Sr.warn("Session creation failed."),this._changeConnectStatus(vr.AUTHFAIL,null,e),!1;return!1}_sasl_failure_cb(e){return this._sasl_success_handler&&(this.deleteHandler(this._sasl_success_handler),this._sasl_success_handler=null),this._sasl_challenge_handler&&(this.deleteHandler(this._sasl_challenge_handler),this._sasl_challenge_handler=null),this._sasl_mechanism&&this._sasl_mechanism.onFailure(),this._changeConnectStatus(vr.AUTHFAIL,null,e),!1}_auth2_cb(e){return"result"===e.getAttribute("type")?(this.authenticated=!0,this._changeConnectStatus(vr.CONNECTED,null)):"error"===e.getAttribute("type")&&(this._changeConnectStatus(vr.AUTHFAIL,null,e),this.disconnect("authentication failed")),!1}_addSysTimedHandler(e,t){const n=new fo(e,t);return n.user=!1,this.addTimeds.push(n),n}_addSysHandler(e,t,n,s,i){const r=new go(e,t,n,s,i);return r.user=!1,this.addHandlers.push(r),r}_onDisconnectTimeout(){return Sr.debug("_onDisconnectTimeout was called"),this._changeConnectStatus(vr.CONNTIMEOUT,null),this._proto._onDisconnectTimeout(),this._doDisconnect(),!1}_onIdle(){for(;this.addTimeds.length>0;)this.timedHandlers.push(this.addTimeds.pop());for(;this.removeTimeds.length>0;){const e=this.removeTimeds.pop(),t=this.timedHandlers.indexOf(e);t>=0&&this.timedHandlers.splice(t,1)}const e=(new Date).getTime(),t=[];for(let n=0;nthis._onIdle()),100))}}const No=Io;class Mo extends oo{#i;#r;#o;constructor(e,t){super("stanza"),this.#r=e,this.#o=t}static unsafeXML(e){return oo.fromString(e)}static toElement(e,t){const n=Or(e),s=Rr(n);if(s)throw new Error(`Parser Error: ${s}`);const i=Dr(n);if(["message","iq","presence"].includes(i.nodeName.toLowerCase())&&"jabber:client"!==i.namespaceURI&&"jabber:server"!==i.namespaceURI){const e=`Invalid namespaceURI ${i.namespaceURI}`;if(t)throw new Error(e);Sr.error(e)}return i}buildTree(){return Mo.toElement(this.toString(),!0)}toString(){return this.#i=this.#i||this.#r.reduce(((e,t)=>{const n=this.#r.indexOf(t),s=this.#o.length>n?this.#o[n]:"";return e+t+(Array.isArray(s)?s.map((e=>e instanceof Mo||e instanceof oo?e:qr(e.toString()))).join(""):s instanceof Mo||s instanceof oo?s:qr(s.toString()))}),"").trim(),this.#i}}const Oo={VERSION:"3.0.0",get TIMEOUT(){return mo.getTimeoutMultplier()},set TIMEOUT(e){mo.setTimeoutMultiplier(e)},get SECONDARY_TIMEOUT(){return mo.getSecondaryTimeoutMultplier()},set SECONDARY_TIMEOUT(e){mo.setSecondaryTimeoutMultiplier(e)},...i,...Sr,shims:s,Request:co,Bosh:mo,Websocket:ko,WorkerWebsocket:jo,Connection:No,Handler:go,SASLAnonymous:vo,SASLPlain:bo,SASLSHA1:So,SASLSHA256:xo,SASLSHA384:Ao,SASLSHA512:Eo,SASLOAuthBearer:_o,SASLExternal:yo,SASLXOAuth2:$o,Stanza:Mo,Builder:oo,ElementType:br,ErrorCondition:yr,LogLevel:_r,NS:gr,SASLMechanism:po,Status:vr,TimedHandler:fo,XHTML:{...pr,validTag:Pr,validCSS:Fr,validAttribute:Lr},serialize:e=>oo.serialize(e),setLogLevel(e){Sr.setLogLevel(e)},addNamespace(e,t){Oo.NS[e]=t},addConnectionPlugin(e,t){No.addConnectionPlugin(e,t)}};globalThis.$build=to,globalThis.$iq=so,globalThis.$msg=no,globalThis.$pres=io,globalThis.Strophe=Oo,globalThis.stx=function(e){for(var t=arguments.length,n=new Array(t>1?t-1:0),s=1;s{e.resolve=t,e.reject=n}));return Object.assign(t,e),t.then((function(e){return t.isResolved=!0,t.isPending=!1,t.isRejected=!1,e}),(function(e){throw t.isResolved=!1,t.isPending=!1,t.isRejected=!0,e})),t}const ea={allow_non_roster_messaging:!1,allow_url_history_change:!0,assets_path:"/dist",authentication:"login",auto_login:!1,reuse_scram_keys:!1,auto_reconnect:!0,blacklisted_plugins:[],clear_cache_on_logout:!1,connection_options:{},credentials_url:null,discover_connection_methods:!0,geouri_regex:/https\:\/\/www.openstreetmap.org\/.*#map=[0-9]+\/([\-0-9.]+)\/([\-0-9.]+)\S*/g,geouri_replacement:"https://www.openstreetmap.org/?mlat=$1&mlon=$2#map=18/$1/$2",i18n:void 0,jid:void 0,keepalive:!0,loglevel:"info",locales:["af","ar","bg","ca","cs","da","de","el","en","eo","es","eu","fa","fi","fr","gl","he","hi","hu","id","it","ja","lt","mr","nb","nl","oc","pl","pt","pt_BR","ro","ru","sv","th","tr","ug","uk","vi","zh_CN","zh_TW"],nickname:void 0,password:void 0,persistent_store:"IndexedDB",rid:void 0,root:window.document,sid:void 0,singleton:!1,strict_plugin_dependencies:!1,stanza_timeout:2e4,view_mode:"overlayed",websocket_url:void 0,whitelisted_plugins:[]};var ta=n(7686);const na=function(e){return Ls(e,5)};const sa=function(e){return"string"==typeof e||!Z(e)&&B(e)&&"[object String]"==v(e)};const ia=function(){try{if("undefined"!=typeof indexedDB)return indexedDB;if("undefined"!=typeof webkitIndexedDB)return webkitIndexedDB;if("undefined"!=typeof mozIndexedDB)return mozIndexedDB;if("undefined"!=typeof OIndexedDB)return OIndexedDB;if("undefined"!=typeof msIndexedDB)return msIndexedDB}catch(e){return}}();const ra=function(){try{if(!ia||!ia.open)return!1;var e="undefined"!=typeof openDatabase&&/(Safari|iPhone|iPad|iPod)/.test(navigator.userAgent)&&!/Chrome/.test(navigator.userAgent)&&!/BlackBerry/.test(navigator.platform),t="function"==typeof fetch&&-1!==fetch.toString().indexOf("[native code");return(!e||t)&&"undefined"!=typeof indexedDB&&"undefined"!=typeof IDBKeyRange}catch(e){return!1}};const oa=function(e,t){e=e||[],t=t||{};try{return new Blob(e,t)}catch(i){if("TypeError"!==i.name)throw i;for(var n=new("undefined"!=typeof BlobBuilder?BlobBuilder:"undefined"!=typeof MSBlobBuilder?MSBlobBuilder:"undefined"!=typeof MozBlobBuilder?MozBlobBuilder:WebKitBlobBuilder),s=0;s=43)}})).catch((function(){return!1}))}(e).then((function(e){return ma=e,ma}))}function _a(e){var t=ga[e.name],n={};n.promise=new aa((function(e,t){n.resolve=e,n.reject=t})),t.deferredOperations.push(n),t.dbReady?t.dbReady=t.dbReady.then((function(){return n.promise})):t.dbReady=n.promise}function ba(e){var t=ga[e.name].deferredOperations.pop();if(t)return t.resolve(),t.promise}function wa(e,t){var n=ga[e.name].deferredOperations.pop();if(n)return n.reject(t),n.promise}function Sa(e,t){return new aa((function(n,s){if(ga[e.name]=ga[e.name]||{forages:[],db:null,dbReady:null,deferredOperations:[]},e.db){if(!t)return n(e.db);_a(e),e.db.close()}var i=[e.name];t&&i.push(e.version);var r=ia.open.apply(ia,i);t&&(r.onupgradeneeded=function(t){var n=r.result;try{n.createObjectStore(e.storeName),t.oldVersion<=1&&n.createObjectStore(ha)}catch(n){if("ConstraintError"!==n.name)throw n;console.warn('The database "'+e.name+'" has been upgraded from version '+t.oldVersion+" to version "+t.newVersion+', but the storage "'+e.storeName+'" already exists.')}}),r.onerror=function(e){e.preventDefault(),s(r.error)},r.onsuccess=function(){var t=r.result;t.onversionchange=function(e){e.target.close()},n(t),ba(e)}}))}function xa(e){return Sa(e,!1)}function Aa(e){return Sa(e,!0)}function Ea(e,t){if(!e.db)return!0;var n=!e.db.objectStoreNames.contains(e.storeName),s=e.versione.db.version;if(s&&(e.version!==t&&console.warn('The database "'+e.name+"\" can't be downgraded from version "+e.db.version+" to version "+e.version+"."),e.version=e.db.version),i||n){if(n){var r=e.db.version+1;r>e.version&&(e.version=r)}return!0}return!1}function $a(e){var t=function(e){for(var t=e.length,n=new ArrayBuffer(t),s=new Uint8Array(n),i=0;i0&&(!e.db||"InvalidStateError"===i.name||"NotFoundError"===i.name))return aa.resolve().then((()=>{if(!e.db||"NotFoundError"===i.name&&!e.db.objectStoreNames.contains(e.storeName)&&e.version<=e.db.version)return e.db&&(e.version=e.db.version+1),Aa(e)})).then((()=>function(e){_a(e);for(var t=ga[e.name],n=t.forages,s=0;s(e.db=t,Ea(e)?Aa(e):t))).then((s=>{e.db=t.db=s;for(var i=0;i{throw wa(e,t),t}))}(e).then((function(){ja(e,t,n,s-1)})))).catch(n);n(i)}}var Ta={_driver:"asyncStorage",_initStorage:function(e){var t=this,n={db:null};if(e)for(var s in e)n[s]=e[s];var i=ga[n.name];i||(i={forages:[],db:null,dbReady:null,deferredOperations:[]},ga[n.name]=i),i.forages.push(t),t._initReady||(t._initReady=t.ready,t.ready=ka);var r=[];function o(){return aa.resolve()}for(var a=0;a{const n=ga[e.name],s=n.forages;n.db=t;for(var i=0;i{if(!t.objectStoreNames.contains(e.storeName))return;const n=t.version+1;_a(e);const s=ga[e.name],i=s.forages;t.close();for(let e=0;e{const i=ia.open(e.name,n);i.onerror=e=>{i.result.close(),s(e)},i.onupgradeneeded=()=>{i.result.deleteObjectStore(e.storeName)},i.onsuccess=()=>{const e=i.result;e.close(),t(e)}}));return r.then((e=>{s.db=e;for(let t=0;t{throw(wa(e,t)||aa.resolve()).catch((()=>{})),t}))})):t.then((t=>{_a(e);const n=ga[e.name],s=n.forages;t.close();for(var i=0;i{var s=ia.deleteDatabase(e.name);s.onerror=()=>{const e=s.result;e&&e.close(),n(s.error)},s.onblocked=()=>{console.warn('dropInstance blocked for database "'+e.name+'" until all open connections are closed')},s.onsuccess=()=>{const e=s.result;e&&e.close(),t(e)}}));return r.then((e=>{n.db=e;for(var t=0;t{throw(wa(e,t)||aa.resolve()).catch((()=>{})),t}))}))}else n=aa.reject("Invalid arguments");return ca(n,t),n}};const Ia=Ta;const Na=function(){return"function"==typeof openDatabase};var Ma="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",Oa=/^~~local_forage_type~([^~]+)~/,Ra="__lfsc__:",Da="arbf",za="blob",Pa="si08",La="ui08",Fa="uic8",Ua="si16",Ba="si32",qa="ur16",Ha="ui32",Ga="fl32",Wa="fl64",Va=Object.prototype.toString;function Za(e){var t,n,s,i,r,o=.75*e.length,a=e.length,c=0;"="===e[e.length-1]&&(o--,"="===e[e.length-2]&&o--);var l=new ArrayBuffer(o),d=new Uint8Array(l);for(t=0;t>4,d[c++]=(15&s)<<4|i>>2,d[c++]=(3&i)<<6|63&r;return l}function Qa(e){var t,n=new Uint8Array(e),s="";for(t=0;t>2],s+=Ma[(3&n[t])<<4|n[t+1]>>4],s+=Ma[(15&n[t+1])<<2|n[t+2]>>6],s+=Ma[63&n[t+2]];return n.length%3==2?s=s.substring(0,s.length-1)+"=":n.length%3==1&&(s=s.substring(0,s.length-2)+"=="),s}var Ja={serialize:function(e,t){var n="";if(e&&(n=Va.call(e)),e&&("[object ArrayBuffer]"===n||e.buffer&&"[object ArrayBuffer]"===Va.call(e.buffer))){var s,i=Ra;e instanceof ArrayBuffer?(s=e,i+=Da):(s=e.buffer,"[object Int8Array]"===n?i+=Pa:"[object Uint8Array]"===n?i+=La:"[object Uint8ClampedArray]"===n?i+=Fa:"[object Int16Array]"===n?i+=Ua:"[object Uint16Array]"===n?i+=qa:"[object Int32Array]"===n?i+=Ba:"[object Uint32Array]"===n?i+=Ha:"[object Float32Array]"===n?i+=Ga:"[object Float64Array]"===n?i+=Wa:t(new Error("Failed to get type for BinaryArray"))),t(i+Qa(s))}else if("[object Blob]"===n){var r=new FileReader;r.onload=function(){var n="~~local_forage_type~"+e.type+"~"+Qa(this.result);t(Ra+za+n)},r.readAsArrayBuffer(e)}else try{t(JSON.stringify(e))}catch(n){console.error("Couldn't convert value into a JSON string: ",e),t(null,n)}},deserialize:function(e){if(e.substring(0,9)!==Ra)return JSON.parse(e);var t,n=e.substring(13),s=e.substring(9,13);if(s===za&&Oa.test(n)){var i=n.match(Oa);t=i[1],n=n.substring(i[0].length)}var r=Za(n);switch(s){case Da:return r;case za:return oa([r],{type:t});case Pa:return new Int8Array(r);case La:return new Uint8Array(r);case Fa:return new Uint8ClampedArray(r);case Ua:return new Int16Array(r);case qa:return new Uint16Array(r);case Ba:return new Int32Array(r);case Ha:return new Uint32Array(r);case Ga:return new Float32Array(r);case Wa:return new Float64Array(r);default:throw new Error("Unkown type: "+s)}},stringToBuffer:Za,bufferToString:Qa};const Ka=Ja;function Ya(e,t,n,s){e.executeSql(`CREATE TABLE IF NOT EXISTS ${t.storeName} (id INTEGER PRIMARY KEY, key unique, value)`,[],n,s)}function Xa(e,t,n,s,i,r){e.executeSql(n,s,i,(function(e,o){o.code===o.SYNTAX_ERR?e.executeSql("SELECT name FROM sqlite_master WHERE type='table' AND name = ?",[t.storeName],(function(e,a){a.rows.length?r(e,o):Ya(e,t,(function(){e.executeSql(n,s,i,r)}),r)}),r):r(e,o)}),r)}function ec(e,t,n,s){var i=this;e=da(e);var r=new aa((function(r,o){i.ready().then((function(){void 0===t&&(t=null);var a=t,c=i._dbInfo;c.serializer.serialize(t,(function(t,l){l?o(l):c.db.transaction((function(n){Xa(n,c,`INSERT OR REPLACE INTO ${c.storeName} (key, value) VALUES (?, ?)`,[e,t],(function(){r(a)}),(function(e,t){o(t)}))}),(function(t){if(t.code===t.QUOTA_ERR){if(s>0)return void r(ec.apply(i,[e,a,n,s-1]));o(t)}}))}))})).catch(o)}));return ca(r,n),r}var tc={_driver:"webSQLStorage",_initStorage:function(e){var t=this,n={db:null};if(e)for(var s in e)n[s]="string"!=typeof e[s]?e[s].toString():e[s];var i=new aa((function(e,s){try{n.db=openDatabase(n.name,String(n.version),n.description,n.size)}catch(e){return s(e)}n.db.transaction((function(i){Ya(i,n,(function(){t._dbInfo=n,e()}),(function(e,t){s(t)}))}),s)}));return n.serializer=Ka,i},_support:Na(),iterate:function(e,t){var n=this,s=new aa((function(t,s){n.ready().then((function(){var i=n._dbInfo;i.db.transaction((function(n){Xa(n,i,`SELECT * FROM ${i.storeName}`,[],(function(n,s){for(var r=s.rows,o=r.length,a=0;a '__WebKitDatabaseInfoTable__'",[],(function(n,s){for(var i=[],r=0;r0}var rc={_driver:"localStorageWrapper",_initStorage:function(e){var t={};if(e)for(var n in e)t[n]=e[n];return t.keyPrefix=sc(e,this._defaultConfig),ic()?(this._dbInfo=t,t.serializer=Ka,aa.resolve()):aa.reject()},_support:function(){try{return"undefined"!=typeof localStorage&&"setItem"in localStorage&&!!localStorage.setItem}catch(e){return!1}}(),iterate:function(e,t){var n=this,s=n.ready().then((function(){for(var t=n._dbInfo,s=t.keyPrefix,i=s.length,r=localStorage.length,o=1,a=0;a=0;n--){var s=localStorage.key(n);0===s.indexOf(e)&&localStorage.removeItem(s)}}));return ca(n,e),n},length:function(e){var t=this.keys().then((function(e){return e.length}));return ca(t,e),t},key:function(e,t){var n=this,s=n.ready().then((function(){var t,s=n._dbInfo;try{t=localStorage.key(e)}catch(e){t=null}return t&&(t=t.substring(s.keyPrefix.length)),t}));return ca(s,t),s},keys:function(e){var t=this,n=t.ready().then((function(){for(var e=t._dbInfo,n=localStorage.length,s=[],i=0;i=0;t--){var n=localStorage.key(t);0===n.indexOf(e)&&localStorage.removeItem(n)}})):aa.reject("Invalid arguments"),ca(s,t),s}};const oc=rc,ac=(e,t)=>e===t||"number"==typeof e&&"number"==typeof t&&isNaN(e)&&isNaN(t),cc=(e,t)=>{const n=e.length;let s=0;for(;s{}))}config(e){if("object"==typeof e){if(this._ready)return new Error("Can't call config() after localforage has been used.");for(let t in e){if("storeName"===t&&(e[t]=e[t].replace(/\W/g,"_")),"version"===t&&"number"!=typeof e[t])return new Error("Database version must be a number.");this._config[t]=e[t]}return!("driver"in e)||!e.driver||this.setDriver(this._config.driver)}return"string"==typeof e?this._config[e]:this._config}defineDriver(e,t,n){const s=new aa((function(t,n){try{const s=e._driver,i=new Error("Custom driver not compliant; see https://mozilla.github.io/localForage/#definedriver");if(!e._driver)return void n(i);const r=fc.concat("_initStorage");for(let t=0,s=r.length;t(null===t._ready&&(t._ready=t._initDriver()),t._ready)));return la(n,e,e),n}setDriver(e,t,n){const s=this;lc(e)||(e=[e]);const i=this._getSupportedDrivers(e);function r(){s._config.driver=s.driver()}function o(e){return s._extend(e),r(),s._ready=s._initStorage(s._config),s._ready}const a=null!==this._driverSet?this._driverSet.catch((()=>aa.resolve())):aa.resolve();return this._driverSet=a.then((()=>{const e=i[0];return s._dbInfo=null,s._ready=null,s.getDriver(e).then((e=>{s._driver=e._driver,r(),s._wrapLibraryMethodsWithReady(),s._initDriver=function(e){return function(){let t=0;return function n(){for(;t{r();const e=new Error("No available storage method found.");return s._driverSet=aa.reject(e),s._driverSet})),la(this._driverSet,t,n),this._driverSet}supports(e){return!!uc[e]}_extend(e){yc(this,e)}_getSupportedDrivers(e){const t=[];for(let n=0,s=e.length;n2&&void 0!==arguments[2]?arguments[2]:{},l=0,d=!1,u=c.promise?Xo():null;if("function"!=typeof e)throw new TypeError("Expected a function");function h(t){const i=n,o=s,a=u;return n=s=void 0,l=t,r=e.apply(o,i),c.promise&&(a.resolve(r),u=Xo()),c.promise?a:r}function m(e){const n=e-a;return void 0===a||n>=t||n<0||d&&e-l>=i}function g(){const e=jc();if(m(e))return f(e);o=setTimeout(g,function(e){const n=t-(e-a);return d?Ic(n,i-(e-l)):n}(e))}function f(e){return o=void 0,n?h(e):(n=s=void 0,c.promise?u:r)}function p(e,t){if(Array.isArray(e)&&Array.isArray(t))return c?.dedupeArrays?e.concat(t.filter((t=>-1===e.indexOf(t)))):e.concat(t)}function v(){const e=jc(),i=m(e);var f;if(f=Array.from(arguments),n=n?.length?f.length?c?.concatArrays||c?.dedupeArrays?kc(n,f,p):Cc(n,f):n:f||[],s=this,a=e,i){if(void 0===o)return function(e){return l=e,o=setTimeout(g,t),c.promise?u:r}(a);if(d)return clearTimeout(o),o=setTimeout(g,t),h(a)}return void 0===o&&(o=setTimeout(g,t)),c.promise?u:r}return t=Sn(t)||0,y(c)&&(d="maxWait"in c,i=d?Tc(Sn(c.maxWait)||0,t):i),v.cancel=function(){void 0!==o&&clearTimeout(o),l=0,n=a=s=o=void 0},v.flush=function(){return void 0===o?r:f(jc())},v};function Mc(e,t){let n=e.name+"/";return e.storeName!==t.storeName&&(n+=e.storeName+"/"),n}const Oc={serializer:{serialize:Ka.serialize,deserialize:Ka.deserialize}};const Rc={_driver:"sessionStorageWrapper",_initStorage:function(e){if(Oc.keyPrefix=Mc(e,this._defaultConfig),e)for(const t in e)Oc[t]=e[t]},_support:function(){try{if(sessionStorage&&"setItem"in sessionStorage)return!0}catch(e){console.log(e)}return!1}(),iterate:function(e,t){const n=this.ready().then((function(){const t=Oc.keyPrefix,n=t.length,s=sessionStorage.length;let i=1;for(let r=0;r{if(i)throw i;try{sessionStorage.setItem(Oc.keyPrefix+e,t),ca(Promise.resolve(s),n)}catch(e){if("QuotaExceededError"===e.name||"NS_ERROR_DOM_QUOTA_REACHED"===e.name)throw console.error("Your sesionStorage capacity is used up."),e;throw e}}))},removeItem:function(e,t){e=da(e);const n=this.ready().then((function(){sessionStorage.removeItem(Oc.keyPrefix+e)}));return ca(n,t),n},clear:function(e){const t=this.ready().then((function(){const e=Oc.keyPrefix;for(let t=sessionStorage.length-1;t>=0;t--){const n=sessionStorage.key(t);0===n.indexOf(e)&&sessionStorage.removeItem(n)}}));return ca(t,e),t},length:function(e){const t=this.keys().then((function(e){return e.length}));return ca(t,e),t},key:function(e,t){const n=this.ready().then((function(){let t;try{t=sessionStorage.key(e)}catch(e){t=null}return t&&(t=t.substring(Oc.keyPrefix.length)),t}));return ca(n,t),n},keys:function(e){const t=this.ready().then((function(){const e=sessionStorage.length,t=[];for(let n=0;n=0;t--){const n=sessionStorage.key(t);0===n.indexOf(e)&&sessionStorage.removeItem(n)}})):Promise.reject(new Error("Invalid arguments")),ca(s,t),s}},Dc=Rc;var zc=n(7284),Pc=n(1588);const Lc=ta._driver;bc.defineDriver(ta),(0,zc.extendPrototype)(bc),(0,Pc.extendPrototype)(bc);class Fc{constructor(e,t){let n=arguments.length>2&&void 0!==arguments[2]&&arguments[2];if("local"===t&&!window.localStorage)throw new Error("Skeletor.storage: Environment does not support localStorage.");if("session"===t&&!window.sessionStorage)throw new Error("Skeletor.storage: Environment does not support sessionStorage.");sa(t)?this.storeInitialized=this.initStore(t,n):(this.store=t,n&&(this.store.debouncedSetItems=Nc((e=>this.store.setItems(e)),50,{promise:!0})),this.storeInitialized=Promise.resolve()),this.name=e}async initStore(e,t){if("session"===e)bc.setDriver(Dc._driver);else if("local"===e)await bc.config({driver:bc.LOCALSTORAGE});else if("in_memory"===e)bc.config({driver:Lc});else if("indexed"!==e)throw new Error("Skeletor.storage: No storage type was specified");this.store=bc,t&&(this.store.debouncedSetItems=Nc((e=>this.store.setItems(e)),50,{promise:!0}))}flush(){return this.store.debouncedSetItems?.flush()}async clear(){await this.store.removeItem(this.name).catch((e=>console.error(e)));const e=new RegExp(`^${this.name}-`),t=(await this.store.keys()).filter((t=>e.test(t)));await Promise.all(t.map((e=>this.store.removeItem(e).catch((e=>console.error(e))))))}sync(){const e=this;async function t(t,n,s){let i,r,o,a;const c=n.collection;["patch","update"].includes(t)&&(a=na(n.attributes)),await e.storeInitialized;try{const r=n.attributes;switch(t){case"read":i=void 0!==n.id?await e.find(n):await e.findAll();break;case"create":i=await e.create(n,s);break;case"patch":case"update":s.wait&&(n.attributes=a),o=e.update(n,s),s.wait&&(n.attributes=r),i=await o;break;case"delete":i=await e.destroy(n,c)}}catch(t){r=22===t.code&&0===e.getStorageSize()?"Private browsing is unsupported":t.message}if(i){if(s&&s.success){const e="read"===t?i:null;s.success(e,s)}}else r=r||"Record Not Found",s&&s.error&&s.error(r)}return t.__name__="localSync",t}removeCollectionReference(e,t){if(!t)return;const n=t.filter((t=>t.id!==e.id)).map((e=>this.getItemName(e.id)));return this.store.setItem(this.name,n)}addCollectionReference(e,t){if(!t)return;const n=t.map((e=>this.getItemName(e.id))),s=this.getItemName(e.id);return n.includes(s)||n.push(s),this.store.setItem(this.name,n)}getCollectionReferenceData(e){if(!e.collection)return{};const t=e.collection.map((e=>this.getItemName(e.id))),n=this.getItemName(e.id);t.includes(n)||t.push(n);const s={};return s[this.name]=t,s}async save(e){if(this.store.setItems){const t={};return t[this.getItemName(e.id)]=e.toJSON(),Object.assign(t,this.getCollectionReferenceData(e)),this.store.debouncedSetItems?this.store.debouncedSetItems(t):this.store.setItems(t)}{const t=this.getItemName(e.id),n=await this.store.setItem(t,e.toJSON());return await this.addCollectionReference(e,e.collection),n}}create(e,t){return e.id||(e.id=Ut()+Ut()+"-"+Ut()+"-"+Ut()+"-"+Ut()+"-"+Ut()+Ut()+Ut(),e.set(e.idAttribute,e.id,t)),this.save(e)}update(e){return this.save(e)}find(e){return this.store.getItem(this.getItemName(e.id))}async findAll(){const e=await this.store.getItem(this.name);if(e?.length){const t=await this.store.getItems(e);return Object.values(t)}return[]}async destroy(e,t){return await this.flush(),await this.store.removeItem(this.getItemName(e.id)),await this.removeCollectionReference(e,t),e}getStorageSize(){return this.store.length}getItemName(e){return this.name+"-"+e}}Fc.sessionStorageInitialized=bc.defineDriver(Dc),Fc.localForage=bc;const Uc=Fc;function Bc(){if(Zl.config.get("trusted")){return"sessionStorage"===wd.settings.get("persistent_store")?"session":"persistent"}return"session"}function qc(e){return"persistent"===e&&"IndexedDB"===wd.settings.get("persistent_store")}function Hc(e,t){const n=t||Bc(),s=Zl.storage[n];if(void 0===s)throw new TypeError(`createStore: Could not find store for ${e}`);return new Uc(e,s,qc(t))}function Gc(e,t,n){const s=n||Bc();if(e.browserStorage=Hc(t,s),qc(s)){const t=()=>e.browserStorage.flush();window.addEventListener(Zl.unloadevent,t),e.on("destroy",(()=>window.removeEventListener(Zl.unloadevent,t))),e.listenTo(Zl,"beforeLogout",t)}}let Wc,Vc,Zc={};function Qc(){return Wc}function Jc(){if(!Zl.bare_jid){const e="No JID to fetch user settings for";throw $l.error(e),Error(e)}if(!Vc?.fetched){const e=`converse.user-settings.${Zl.bare_jid}`;Vc=new dr({id:e}),Gc(Vc,e),Vc.fetched=Vc.fetch({promise:!0})}return Vc.fetched}async function Kc(){return await Jc(),Vc}async function Yc(e,t){return await Jc(),Vc.save(e,t)}const Xc={extend:e=>function(e){xl.merge(ea,e);const t=Object.keys(lr(e,Object.keys(ea))),n=lr(Zc,t),s=Be(lr(e,t),n);xl.merge(Wc,s)}(e),update(e){return $l.warn("The api.settings.update method has been deprecated and will be removed. Please use api.settings.extend instead."),this.extend(e)},get:e=>function(e){if(Object.keys(ea).includes(e))return Wc[e]}(e),set(e,t){!function(e,t){if(null==e)return this;let n;y(e)?n=e:"string"==typeof e&&(n={},n[e]=t);const s=Object.keys(lr(n,Object.keys(ea))),i={};s.forEach((e=>{const t=n[e];$i(Wc[e],t)||(i[e]=t,Wc[e]=t)})),Object.keys(i).forEach((e=>Wc.trigger("change:"+e,i[e]))),Wc.trigger("change",i)}(e,t)},listen:{on(e,t,n){!function(e,t,n){Wc.on(e,t,n)}(e,t,n)},not(e,t){!function(e,t){Wc.off(e,t)}(e,t)}}},el={getModel:()=>Kc(),async get(e,t){const n=await Kc();return void 0===n.get(e)?t:n.get(e)},set(e,t){if(y(e))return Yc(e,{promise:!0});{const n={};return n[e]=t,Yc(n,{promise:!0})}},clear:()=>async function(){return await Jc(),Vc.clear()}()};function tl(e,t){const n=Oo.xmlHtmlNode(e);if(n.getElementsByTagNameNS("http://www.w3.org/1999/xhtml","parsererror").length)throw new Error(`Parser Error: ${e}`);const s=n.firstElementChild;if(["message","iq","presence"].includes(s.nodeName.toLowerCase())&&"jabber:client"!==s.namespaceURI&&"jabber:server"!==s.namespaceURI){const e=`Invalid namespaceURI ${s.namespaceURI}`;if($l.error(e),t)throw new Error(e)}return s}class nl{constructor(e,t){this.strings=e,this.values=t}toString(){return this.string=this.string||this.strings.reduce(((e,t)=>{const n=this.strings.indexOf(t);return e+t+(this.values.length>n?this.values[n].toString():"")}),""),this.string}tree(){return this.node=this.node??tl(this.toString(),!0),this.node}}function sl(e){for(var t=arguments.length,n=new Array(t>1?t-1:0),s=1;st.begin-e.begin)).forEach((e=>{t=`${t.slice(0,e.begin)}@${t.slice(e.begin)}`})),t}function hl(e){return"string"==typeof e&&(2===Jo(e.split("@")).length&&!e.startsWith("@")&&!e.endsWith("@"))}function ml(e){return e instanceof Error}function gl(e,t,n){il.isPersistableModel(e)?e.save(t,n):e.set(t,n)}function fl(e){return Math.random()*e|0}function pl(e){const t=crypto.randomUUID?.()??"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g,(e=>{const t=fl(16);return("x"===e?t:3&t|8).toString(16)}));return"string"==typeof e||"number"==typeof e?t+":"+e:t}function vl(e,t){clearTimeout(e),clearInterval(t)}function yl(e){let t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:300,n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:3;try{const t=e();if(t)return Promise.resolve(t)}catch(e){return Promise.reject(e)}const s=Xo(),i=new Error;const r=setInterval((function(){try{const t=e();t&&(vl(o,r),s.resolve(t))}catch(e){vl(o,r),s.reject(e)}}),n);const o=setTimeout((function(){vl(o,r);const e=`Wait until promise timed out: \n\n${i.stack}`;console.trace(),$l.error(e),s.reject(new Error(e))}),t);return s}function _l(e){const t=Zl.promises[e];if(!t)throw new Error(`Tried to replace non-existing promise: ${e}`);if(t.replace){const n=Xo();n.replace=t.replace,Zl.promises[e]=n}else $l.debug(`Not replacing promise "${e}"`)}il.isTagEqual=function(e,t){if(e.tree?.())return il.isTagEqual(e.tree(),t);if(e instanceof Element)return Oo.isTagEqual(e,t);throw Error("isTagEqual called with value which isn't an element or Strophe.Builder instance")},il.getJIDFromURI=function(e){return e.startsWith("xmpp:")&&e.endsWith("?join")?e.replace(/^xmpp:/,"").replace(/\?join$/,""):e},il.getLongestSubstring=function(e,t){return t.reduce((function(t,n){return e.startsWith(n)&&n.length>t.length?n:t}),"")},il.isValidMUCJID=function(e){return!e.startsWith("@")&&!e.endsWith("@")},il.isSameBareJID=function(e,t){return"string"==typeof e&&"string"==typeof t&&Oo.getBareJidFromJid(e).toLowerCase()===Oo.getBareJidFromJid(t).toLowerCase()},il.isSameDomain=function(e,t){return"string"==typeof e&&"string"==typeof t&&Oo.getDomainFromJid(e).toLowerCase()===Oo.getDomainFromJid(t).toLowerCase()},il.isNewMessage=function(e){return e instanceof Element?!(Yo()(`result[xmlns="${Oo.NS.MAM}"]`,e).length&&Yo()(`delay[xmlns="${Oo.NS.DELAY}"]`,e).length):(e instanceof dr&&(e=e.attributes),!(e.is_delayed&&e.is_archived))},il.shouldCreateMessage=function(e){return e.retracted||!ol(e)},il.shouldCreateGroupchatMessage=function(e){return e.nick&&(il.shouldCreateMessage(e)||e.is_tombstone)},il.isChatRoom=function(e){return e&&"chatroom"===e.get("type")},il.isErrorStanza=function(e){return!!rl(e)&&"error"===e.getAttribute("type")},il.isForbiddenError=function(e){return!!rl(e)&&Yo()(`error[type="auth"] forbidden[xmlns="${Oo.NS.STANZAS}"]`,e).length>0},il.isServiceUnavailableError=function(e){return!!rl(e)&&Yo()(`error[type="cancel"] service-unavailable[xmlns="${Oo.NS.STANZAS}"]`,e).length>0},il.getOuterWidth=function(e){let t=arguments.length>1&&void 0!==arguments[1]&&arguments[1],n=e.offsetWidth;if(!t)return n;const s=window.getComputedStyle(e);return n+=parseInt(s.marginLeft?s.marginLeft:0,10)+parseInt(s.marginRight?s.marginRight:0,10),n},il.stringToElement=function(e){var t=document.createElement("div");return t.innerHTML=e,t.firstElementChild},il.matchesSelector=function(e,t){const n=e.matches||e.matchesSelector||e.msMatchesSelector||e.mozMatchesSelector||e.webkitMatchesSelector||e.oMatchesSelector;return!!n&&n.call(e,t)},il.queryChildren=function(e,t){return Array.from(e.childNodes).filter((e=>il.matchesSelector(e,t)))},il.contains=function(e,t){const n=(e,n)=>e.get(n).toLowerCase().includes(t.toLowerCase());return function(t){if("object"==typeof e)return Object.keys(e).reduce(((e,s)=>e||n(t,s)),!1);if("string"==typeof e)return n(t,e);throw new TypeError("contains: wrong attribute type. Must be string or array.")}},il.isOfType=function(e,t){return t.get("type")==e},il.isInstance=function(e,t){return t instanceof e},il.getAttribute=function(e,t){return t.get(e)},il.contains.not=function(e,t){return function(n){return!il.contains(e,t)(n)}},il.rootContains=function(e,t){return e!==document||e.contains?e.contains?e.contains(t):window.HTMLElement.prototype.contains.call(e,t):document.head.contains(t)||document.body.contains(t)},il.createFragmentFromText=function(e){var t,n=document.createDocumentFragment(),s=document.createElement("body");for(s.innerHTML=e;t=s.firstChild;)n.appendChild(t);return n},il.isPersistableModel=function(e){return e.collection&&e.collection.browserStorage},il.getResolveablePromise=Xo,il.getOpenPromise=Xo,il.interpolate=function(e,t){return e.replace(/{{{([^{}]*)}}}/g,((e,n)=>{var s=t[n];return"string"==typeof s||"number"==typeof s?s:e}))},il.onMultipleEvents=function(){let e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:[],t=arguments.length>1?arguments[1]:void 0,n=[];function s(s){n.push(s),e.length===n.length&&(t(n),n=[])}e.forEach((e=>e.object.on(e.event,s)))},il.safeSave=gl,il.siblingIndex=function(e){for(var t=0;e=e.previousElementSibling;t++);return t},il.getCurrentWord=function(e,t,n){t||(t=e.selectionEnd||void 0);let[s]=e.value.slice(0,t).split(/\s/).slice(-1);return n&&([s]=s.split(n).slice(-1)),s},il.isMentionBoundary=e=>"@"!==e&&RegExp("(\\p{Z}|\\p{P})","u").test(e),il.replaceCurrentWord=function(e,t){const n=e.selectionEnd||void 0,s=Bi(e.value.slice(0,n).split(/\s/)),i=e.value,r=il.isMentionBoundary(s[0])?s[0]:"";e.value=i.slice(0,n-s.length)+r+`${t} `+i.slice(n);const o=n-s.length+t.length+1;e.selectionEnd=r?o+1:o},il.triggerEvent=function(e,t){let n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:"Event",s=!(arguments.length>3&&void 0!==arguments[3])||arguments[3],i=!(arguments.length>4&&void 0!==arguments[4])||arguments[4];const r=document.createEvent(n);r.initEvent(t,s,i),e.dispatchEvent(r)},il.getSelectValues=function(e){const t=[],n=e&&e.options;for(var s=0,i=n.length;se.setSelectionRange(t,t)),1),this.scrollTop=999999};const bl=document.createElement("div");function wl(e){return e&&"string"==typeof e&&(bl.innerHTML=Qo().sanitize(e),e=bl.textContent,bl.textContent=""),e}function Sl(e){let t;const n={focus:"visible",focusin:"visible",pageshow:"visible",blur:"hidden",focusout:"hidden",pagehide:"hidden"};t=(e=e||document.createEvent("Events")).type in n?n[e.type]:document.hidden?"hidden":"visible",Zl.windowState=t,Zl.api.trigger("windowStateChanged",{state:t})}const xl=Object.assign({shouldClearCache:cl,waitUntil:yl,isErrorObject:ml,getRandomInt:fl,getUniqueId:pl,isElement:rl,isEmptyMessage:ol,isValidJID:hl,merge:function e(t,n){for(const s in n)Object.prototype.hasOwnProperty.call(n,s)&&"__proto__"!==s&&"constructor"!==s&&(y(t[s])?e(t[s],n[s]):t[s]=n[s])},prefixMentions:ul,saveWindowState:Sl,stx:sl,toStanza:tl},il),Al={debug:0,info:1,warn:2,error:3,fatal:4},El=Object.assign({debug:console?.log?console.log.bind(console):function(){},error:console?.log?console.log.bind(console):function(){},info:console?.log?console.log.bind(console):function(){},warn:console?.log?console.log.bind(console):function(){}},console),$l={setLogLevel(e){if(!["debug","info","warn","error","fatal"].includes(e))throw new Error(`Invalid loglevel: ${e}`);this.loglevel=e},log(e,t){let n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:"";if(Al[t]4?i-4:0),o=4;o{const n=this.plugins[t];if(n){if(n.dependencies?.includes(e.__name__))throw'Found a circular dependency between the plugins "'+e.__name__+'" and "'+t+'"';this.initializePlugin(n)}else this.throwUndefinedDependencyError('Could not find dependency "'+t+'" for the plugin "'+e.__name__+"\". If it's needed, make sure it's loaded by require.js")}))}throwUndefinedDependencyError(e){if(this.plugged.strict_plugin_dependencies)throw e;console.warn?console.warn(e):console.log(e)}applyOverrides(e){Object.keys(e.overrides||{}).forEach((t=>{const n=e.overrides[t];"object"==typeof n?void 0===this.plugged[t]?this.throwUndefinedDependencyError(`Plugin "${e.__name__}" tried to override "${t}" but it's not found.`):this._extendObject(this.plugged[t],n):this._overrideAttribute(t,e)}))}initializePlugin(e){Object.keys(this.allowed_plugins).includes(e.__name__)&&(this.initialized_plugins.includes(e.__name__)||("boolean"==typeof e.enabled&&e.enabled||e.enabled?.(this.plugged)||null==e.enabled)&&(Object.assign(e,this.properties),e.dependencies&&this.loadPluginDependencies(e),this.applyOverrides(e),"function"==typeof e.initialize&&e.initialize.bind(e)(this),this.initialized_plugins.push(e.__name__)))}registerPlugin(e,t){if(e in this.plugins)throw new Error("Error: Plugin name "+e+" is already taken");t.__name__=e,this.plugins[e]=t}initializePlugins(){let e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:[],n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:[];if(Object.keys(this.plugins).length){this.properties=e,this.allowed_plugins={};for(const[e,s]of Object.entries(this.plugins))t.length&&!t.includes(e)||n.includes(e)||(this.allowed_plugins[e]=s);Object.values(this.allowed_plugins).forEach((e=>this.initializePlugin(e)))}}}const jl={enable:function(e,t,n){return void 0===n&&(n="pluginSocket"),void 0===t&&(t="plugged"),e[n]=new kl(e,t),e}};const Tl=function(e,t){return function(n,s){if(null==n)return n;if(!be(n))return e(n,s);for(var i=n.length,r=t?i:-1,o=Object(n);(t?r--:++r7),this._useHashChange=this._wantsHashChange&&this._hasHashChange,this._wantsPushState=!!this.options.pushState,this._hasPushState=!(!this.history||!this.history.pushState),this._usePushState=this._wantsPushState&&this._hasPushState,this.fragment=this.getFragment(),this.root=("/"+this.root+"/").replace(Dl,"/"),this._wantsHashChange&&this._wantsPushState){if(!this._hasPushState&&!this.atRoot()){const e=this.root.slice(0,-1)||"/";return this.location.replace(e+"#"+this.getPath()),!0}this._hasPushState&&this.atRoot()&&this.navigate(this.getHash(),{replace:!0})}if(!this._hasHashChange&&this._wantsHashChange&&!this._usePushState){this.iframe=document.createElement("iframe"),this.iframe.src="javascript:0",this.iframe.style.display="none",this.iframe.tabIndex=-1;const e=document.body,t=e.insertBefore(this.iframe,e.firstChild).contentWindow;t.document.open(),t.document.close(),t.location.hash="#"+this.fragment}if(this._usePushState?addEventListener("popstate",this.checkUrl,!1):this._useHashChange&&!this.iframe?addEventListener("hashchange",this.checkUrl,!1):this._wantsHashChange&&(this._checkUrlInterval=setInterval(this.checkUrl,this.interval)),!this.options.silent)return this.loadUrl()},stop:function(){this._usePushState?removeEventListener("popstate",this.checkUrl,!1):this._useHashChange&&!this.iframe&&removeEventListener("hashchange",this.checkUrl,!1),this.iframe&&(document.body.removeChild(this.iframe),this.iframe=null),this._checkUrlInterval&&clearInterval(this._checkUrlInterval),Ol.started=!1},route:function(e,t){this.handlers.unshift({route:e,callback:t})},checkUrl:function(e){let t=this.getFragment();if(t===this.fragment&&this.iframe&&(t=this.getHash(this.iframe.contentWindow)),t===this.fragment)return!1;this.iframe&&this.navigate(t),this.loadUrl()},loadUrl:function(e){return!!this.matchRoot()&&(e=this.fragment=this.getFragment(e),Ml(this.handlers,(function(t){if(t.route.test(e))return t.callback(e),!0})))},navigate:function(e,t){if(!Ol.started)return!1;t&&!0!==t||(t={trigger:!!t}),e=this.getFragment(e||"");let n=this.root;""!==e&&"?"!==e.charAt(0)||(n=n.slice(0,-1)||"/");const s=n+e;e=e.replace(zl,"");const i=this.decodeFragment(e);if(this.fragment!==i){if(this.fragment=i,this._usePushState)this.history[t.replace?"replaceState":"pushState"]({},document.title,s);else{if(!this._wantsHashChange)return this.location.assign(s);if(this._updateHash(this.location,e,t.replace),this.iframe&&e!==this.getHash(this.iframe.contentWindow)){const n=this.iframe.contentWindow;t.replace||(n.document.open(),n.document.close()),this._updateHash(n.location,e,t.replace)}}return t.trigger?this.loadUrl(e):void 0}},_updateHash:function(e,t,n){if(n){const n=e.href.replace(/(javascript:|#).*$/,"");e.replace(n+"#"+t)}else e.hash="#"+t}});const Pl=Ol;const Ll=function(e){return B(e)&&"[object RegExp]"==v(e)};var Fl=le&&le.isRegExp;const Ul=Fl?re(Fl):Ll,Bl=function(){let e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};this.history=e.history||new Pl,this.preinitialize.apply(this,arguments),e.routes&&(this.routes=e.routes),this._bindRoutes(),this.initialize.apply(this,arguments)};Bl.extend=Bt;const ql=/\((.*?)\)/g,Hl=/(\(\?)?:\w+/g,Gl=/\*\w+/g,Wl=/[\-{}\[\]+?.,\\\^$|#\s]/g;Object.assign(Bl.prototype,Tn,{preinitialize:function(){},initialize:function(){},route:function(e,t,n){return Ul(e)||(e=this._routeToRegExp(e)),_(t)&&(n=t,t=""),n||(n=this[t]),this.history.route(e,(s=>{const i=this._extractParameters(e,s);!1!==this.execute(n,i,t)&&(this.trigger.apply(this,["route:"+t].concat(i)),this.trigger("route",t,i),this.history.trigger("route",this,t,i))})),this},execute:function(e,t,n){e&&e.apply(this,t)},navigate:function(e,t){return this.history.navigate(e,t),this},_bindRoutes:function(){if(!this.routes)return;let e;this.routes=Ft(this,"routes");const t=we(this.routes);for(;null!=(e=t.pop());)this.route(e,this.routes[e])},_routeToRegExp:function(e){return e=e.replace(Wl,"\\$&").replace(ql,"(?:$1)?").replace(Hl,(function(e,t){return t?e:"([^/?]+)"})).replace(Gl,"([^?]*?)"),new RegExp("^"+e+"(?:\\?([\\s\\S]*))?$")},_extractParameters:function(e,t){const n=e.exec(t).slice(1);return n.map((function(e,t){return t===n.length-1?e||null:e?decodeURIComponent(e):null}))}});const Vl={log:$l,shouldClearCache:cl,VERSION_NAME:Ro,templates:{},promises:{initialized:Xo()},ANONYMOUS:zo,CLOSED:"closed",EXTERNAL:Po,LOGIN:Lo,LOGOUT:Fo,OPENED:"opened",PREBIND:Uo,SUCCESS:"success",FAILURE:"failure",DEFAULT_IMAGE_TYPE:"image/svg+xml",DEFAULT_IMAGE:"PD94bWwgdmVyc2lvbj0iMS4wIj8+CjxzdmcgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB3aWR0aD0iMTI4IiBoZWlnaHQ9IjEyOCI+CiA8cmVjdCB3aWR0aD0iMTI4IiBoZWlnaHQ9IjEyOCIgZmlsbD0iIzU1NSIvPgogPGNpcmNsZSBjeD0iNjQiIGN5PSI0MSIgcj0iMjQiIGZpbGw9IiNmZmYiLz4KIDxwYXRoIGQ9Im0yOC41IDExMiB2LTEyIGMwLTEyIDEwLTI0IDI0LTI0IGgyMyBjMTQgMCAyNCAxMiAyNCAyNCB2MTIiIGZpbGw9IiNmZmYiLz4KPC9zdmc+Cg==",INACTIVE:"inactive",ACTIVE:"active",COMPOSING:"composing",PAUSED:"paused",GONE:"gone",PRIVATE_CHAT_TYPE:"chatbox",CHATROOMS_TYPE:"chatroom",HEADLINES_TYPE:"headline",CONTROLBOX_TYPE:"controlbox",TIMEOUTS:{PAUSED:1e4,INACTIVE:9e4},default_connection_options:{explicitResourceBinding:!0},router:new Bl,isTestEnv:()=>"montague.lit/http-bind"===Zc.bosh_service_url,getDefaultStore:Bc,createStore:Hc,__:function(){return Vo.__(...arguments)},___:e=>e};Object.assign(Vl,Tn),jl.enable(Vl,"_converse","pluggable");const Zl=Vl;var Ql=n(9479),Jl=n.n(Ql);const Kl={authenticated:()=>Zl?.connection?.authenticated&&!0,connected:()=>Zl?.connection?.connected&&!0,disconnect(){Zl.connection&&Zl.connection.disconnect()},reconnect(){const{__:e,connection:t}=Zl;return t.setConnectionStatus(Oo.Status.RECONNECTING,e("The connection has dropped, attempting to reconnect.")),t?.reconnecting?t.debouncedReconnect():t.reconnect()},isType:e=>Zl.connection.isType(e)},Yl={async trigger(e){if(!Zl._events)return;const t=Array.from(arguments),n=t.pop();if(n&&n.synchronous){const n=Zl._events[e]||[],s=t.splice(1);await Promise.all(n.map((e=>e.callback.apply(e.ctx,s))))}else Zl.trigger.apply(Zl,arguments);const s=Zl.promises[e];void 0!==s&&s.resolve()},hook(e,t,n){const s=Zl._events[e]||[];return s.length?s.reduce(((e,n)=>e.then((e=>n.callback(t,e)))),Promise.resolve(n)):n},listen:{once:Zl.once.bind(Zl),on:Zl.on.bind(Zl),not:Zl.off.bind(Zl),stanza(e,t,n){xl(t)?(n=t,t={}):t=t||{},Zl.connection.addHandler(n,t.ns,e,t.type,t.id,t.from,t)}}},Xl={promises:{add(e){let t=!(arguments.length>1&&void 0!==arguments[1])||arguments[1];(e=Array.isArray(e)?e:[e]).forEach((e=>{const n=Xo();n.replace=t,Zl.promises[e]=n}))}},waitUntil(e){if("function"==typeof e)return yl(e);{const t=Zl.promises[e];return void 0===t?null:t}}};class ed extends Error{}const td={send(e){const{api:t}=Zl;return t.connection.connected()?("string"==typeof e?e=tl(e):e?.tree&&(e=e.tree()),"iq"===e.tagName?t.sendIQ(e):(Zl.connection.send(e),void t.trigger("send",e))):($l.warn("Not sending stanza because we're not connected!"),void $l.warn(Oo.serialize(e)))},sendIQ(e,t){let n=!(arguments.length>2&&void 0!==arguments[2])||arguments[2];const{api:s,connection:i}=Zl;let r;return e=e.tree?.()??e,["get","set"].includes(e.getAttribute("type"))?(t=t||s.settings.get("stanza_timeout"),n?(r=new Promise(((n,s)=>i.sendIQ(e,n,s,t))),r.catch((n=>{if(null===n)throw new ed(`Timeout error after ${t}ms for the following IQ stanza: ${Oo.serialize(e)}`)}))):r=new Promise((n=>i.sendIQ(e,n,n,t)))):(Zl.connection.sendIQ(e),r=Promise.resolve()),s.trigger("send",e),r}},nd={presence:{async send(e,t,n,s){await wd.waitUntil("statusInitialized"),s&&!Array.isArray(s)&&(s=[s]);const i=Zl.xmppstatus,r=await i.constructPresence(e,t,n);if(s?.map((e=>e?.tree()??e)).forEach((e=>r.cnode(e).up())),wd.send(r),["away","chat","dnd","online","xa",void 0].includes(e)){(await wd.rooms.get()).forEach((t=>t.sendStatusPresence(e,n,s)))}}}};var sd=Math.max,id=Math.min;const rd=function(e,t,n){var s,i,r,o,a,c,l=0,d=!1,u=!1,h=!0;if("function"!=typeof e)throw new TypeError("Expected a function");function m(t){var n=s,r=i;return s=i=void 0,l=t,o=e.apply(r,n)}function g(e){var n=e-c;return void 0===c||n>=t||n<0||u&&e-l>=r}function f(){var e=jc();if(g(e))return p(e);a=setTimeout(f,function(e){var n=t-(e-c);return u?id(n,r-(e-l)):n}(e))}function p(e){return a=void 0,h&&s?m(e):(s=i=void 0,o)}function v(){var e=jc(),n=g(e);if(s=arguments,i=this,c=e,n){if(void 0===a)return function(e){return l=e,a=setTimeout(f,t),d?m(e):o}(c);if(u)return clearTimeout(a),a=setTimeout(f,t),m(c)}return void 0===a&&(a=setTimeout(f,t)),o}return t=Sn(t)||0,y(n)&&(d=!!n.leading,r=(u="maxWait"in n)?sd(Sn(n.maxWait)||0,t):r,h="trailing"in n?!!n.trailing:h),v.cancel=function(){void 0!==a&&clearTimeout(a),l=0,s=c=i=a=void 0},v.flush=function(){return void 0===a?o:p(jc())},v};var od=n(4013),ad=n(6528);const cd=Object.keys(Oo.Status).reduce(((e,t)=>Math.max(e,Oo.Status[t])),0);Oo.Status.RECONNECTING=cd+1;class ld extends Oo.Connection{constructor(e,t){super(e,t),this.debouncedReconnect=rd(this.reconnect,3e3)}static generateResource(){return`/converse.js-${Math.floor(139749528*Math.random()).toString()}`}async bind(){await wd.trigger("beforeResourceBinding",{synchronous:!0}),super.bind()}async onDomainDiscovered(e){const t=await e.text(),n=(new window.DOMParser).parseFromString(t,"text/xml").firstElementChild;if("XRD"!=n.nodeName||"http://docs.oasis-open.org/ns/xri/xrd-1.0"!=n.namespaceURI)return $l.warn("Could not discover XEP-0156 connection methods");const s=Yo()('Link[rel="urn:xmpp:alt-connections:xbosh"]',n),i=Yo()('Link[rel="urn:xmpp:alt-connections:websocket"]',n),r=s.map((e=>e.getAttribute("href"))),o=i.map((e=>e.getAttribute("href")));0===r.length&&0===o.length?$l.warn("Neither BOSH nor WebSocket connection methods have been specified with XEP-0156."):(wd.settings.set("websocket_url",o.pop()),wd.settings.set("bosh_service_url",r.pop()),this.service=wd.settings.get("websocket_url")||wd.settings.get("bosh_service_url"),this.setProtocol())}async discoverConnectionMethods(e){const t={mode:"cors",headers:{Accept:"application/xrd+xml, text/xml"}},n=`https://${e}/.well-known/host-meta`;let s;try{s=await fetch(n,t)}catch(e){return $l.error(`Failed to discover alternative connection methods at ${n}`),void $l.error(e)}s.status>=200&&s.status<400?await this.onDomainDiscovered(s):$l.warn("Could not discover XEP-0156 connection methods")}async connect(e,t,n){if(wd.settings.get("discover_connection_methods")){const t=Oo.getDomainFromJid(e);await this.discoverConnectionMethods(t)}if(!wd.settings.get("bosh_service_url")&&!wd.settings.get("websocket_url"))throw new Error("You must supply a value for either the bosh_service_url or websocket_url or both.");super.connect(e,t,n||this.onConnectStatusChanged,59)}async switchTransport(){wd.connection.isType("websocket")&&wd.settings.get("bosh_service_url")?(await gd(Zl.bare_jid),this._proto._doDisconnect(),this._proto=new Oo.Bosh(this),this.service=wd.settings.get("bosh_service_url")):wd.connection.isType("bosh")&&wd.settings.get("websocket_url")&&(wd.settings.get("authentication")===zo?await gd(wd.settings.get("jid")):await gd(Zl.bare_jid),this._proto._doDisconnect(),this._proto=new Oo.Websocket(this),this.service=wd.settings.get("websocket_url"))}async reconnect(){$l.debug("RECONNECTING: the connection has dropped, attempting to reconnect."),this.reconnecting=!0,await ll();const e=Zl.connfeedback.get("connection_status");return e===Oo.Status.CONNFAIL?this.switchTransport():e===Oo.Status.AUTHFAIL&&wd.settings.get("authentication")===zo&&await gd(wd.settings.get("jid")),wd.trigger("will-reconnect"),wd.settings.get("authentication")===zo&&await dl(),wd.user.login()}async onConnected(e){delete this.reconnecting,this.flush(),await gd(this.jid),Zl.config.get("trusted")&&localStorage.setItem("conversejs-session-jid",Zl.bare_jid),await wd.trigger("afterResourceBinding",e,{synchronous:!0}),e?wd.trigger("reconnected"):wd.trigger("connected")}setDisconnectionCause(e,t,n){void 0===e?(delete this.disconnection_cause,delete this.disconnection_reason):(void 0===this.disconnection_cause||n)&&(this.disconnection_cause=e,this.disconnection_reason=t)}setConnectionStatus(e,t){this.status=e,Zl.connfeedback.set({connection_status:e,message:t})}async finishDisconnection(){$l.debug("DISCONNECTED"),delete this.reconnecting,this.reset(),ll(),await dl(),delete Zl.connection,wd.trigger("disconnected")}onDisconnected(){if(!wd.settings.get("auto_reconnect"))return this.finishDisconnection();{const e=this.disconnection_reason;if(this.disconnection_cause===Oo.Status.AUTHFAIL)return wd.settings.get("credentials_url")||wd.settings.get("authentication")===zo?wd.connection.reconnect():this.finishDisconnection();if(this.status===Oo.Status.CONNECTING){const{__:e}=Zl;return this.setConnectionStatus(Oo.Status.CONNFAIL,e("An error occurred while connecting to the chat server.")),this.finishDisconnection()}if(this.disconnection_cause===Fo||e===Oo.ErrorCondition.NO_AUTH_MECH||"host-unknown"===e||"remote-connection-failed"===e)return this.finishDisconnection();wd.connection.reconnect()}}onConnectStatusChanged(e,t){const{__:n}=Zl;if($l.debug(`Status changed to: ${Bo[e]}`),e===Oo.Status.ATTACHFAIL)this.setConnectionStatus(e),this.worker_attach_promise?.resolve(!1);else if(e===Oo.Status.CONNECTED||e===Oo.Status.ATTACHED){if(this.worker_attach_promise?.isResolved&&this.status===Oo.Status.ATTACHED)return;this.setConnectionStatus(e),this.worker_attach_promise?.resolve(!0),Zl.send_initial_presence=!0,this.setDisconnectionCause(),this.reconnecting?($l.debug(e===Oo.Status.CONNECTED?"Reconnected":"Reattached"),this.onConnected(!0)):($l.debug(e===Oo.Status.CONNECTED?"Connected":"Attached"),this.restored&&(Zl.send_initial_presence=!1),this.onConnected())}else if(e===Oo.Status.DISCONNECTED)this.setDisconnectionCause(e,t),this.onDisconnected();else if(e===Oo.Status.BINDREQUIRED)this.bind();else if(e===Oo.Status.ERROR)this.setConnectionStatus(e,n("An error occurred while connecting to the chat server."));else if(e===Oo.Status.CONNECTING)this.setConnectionStatus(e);else if(e===Oo.Status.AUTHENTICATING)this.setConnectionStatus(e);else if(e===Oo.Status.AUTHFAIL)t||(t=n("Your XMPP address and/or password is incorrect. Please try again.")),this.setConnectionStatus(e,t),this.setDisconnectionCause(e,t,!0),this.onDisconnected();else if(e===Oo.Status.CONNFAIL){let s=t;"host-unknown"===t||"remote-connection-failed"==t?s=n("Sorry, we could not connect to the XMPP host with domain: %1$s",`"${Oo.getDomainFromJid(this.jid)}"`):void 0!==t&&t===Oo?.ErrorCondition?.NO_AUTH_MECH&&(s=n("The XMPP server did not offer a supported authentication mechanism")),this.setConnectionStatus(e,s),this.setDisconnectionCause(e,t)}else e===Oo.Status.DISCONNECTING&&this.setDisconnectionCause(e,t)}isType(e){return"websocket"===e.toLowerCase()?this._proto instanceof Oo.Websocket:"bosh"===e.toLowerCase()?Oo.Bosh&&this._proto instanceof Oo.Bosh:void 0}hasResumed(){return wd.settings.get("connection_options")?.worker||this.isType("bosh")?Zl.connfeedback.get("connection_status")===Oo.Status.ATTACHED:!this.do_bind}restoreWorkerSession(){return this.attach(this.onConnectStatusChanged),this.worker_attach_promise=Xo(),this.worker_attach_promise}}class dd extends ld{constructor(e,t){super(e,t),this.sent_stanzas=[],this.IQ_stanzas=[],this.IQ_ids=[],this.features=Oo.xmlHtmlNode('').firstChild,this._proto._processRequest=()=>{},this._proto._disconnect=()=>this._onDisconnectTimeout(),this._proto._onDisconnectTimeout=()=>{},this._proto._connect=()=>{this.connected=!0,this.mock=!0,this.jid="romeo@montague.lit/orchard",this._changeConnectStatus(Oo.Status.BINDREQUIRED)}}_processRequest(){}sendIQ(e,t,n){e=e.tree?.()??e,this.IQ_stanzas.push(e);const s=super.sendIQ(e,t,n);return this.IQ_ids.push(s),s}send(e){return e=e.tree?.()??e,this.sent_stanzas.push(e),super.send(e)}async bind(){await wd.trigger("beforeResourceBinding",{synchronous:!0}),this.authenticated=!0,Zl.no_connection_on_bind||this._changeConnectStatus(Oo.Status.CONNECTED)}}function ud(){const{api:e}=Zl;return("WebSocket"in window||"MozWebSocket"in window)&&e.settings.get("websocket_url")?e.settings.get("websocket_url"):e.settings.get("bosh_service_url")?e.settings.get("bosh_service_url"):""}function hd(){const e=Zl.api;if(!e.settings.get("bosh_service_url")&&e.settings.get("authentication")===Uo)throw new Error("authentication is set to 'prebind' but we don't have a BOSH connection");const t=Zl.isTestEnv()?dd:ld;Zl.connection=new t(ud(),Object.assign(Zl.default_connection_options,e.settings.get("connection_options"),{keepalive:e.settings.get("keepalive")})),function(){const e={};e[Oo.LogLevel.DEBUG]="debug",e[Oo.LogLevel.INFO]="info",e[Oo.LogLevel.WARN]="warn",e[Oo.LogLevel.ERROR]="error",e[Oo.LogLevel.FATAL]="fatal",Oo.log=(t,n)=>$l.log(n,e[t]),Oo.error=e=>$l.error(e),Zl.connection.xmlInput=e=>$l.debug(e.outerHTML,"color: darkgoldenrod"),Zl.connection.xmlOutput=e=>$l.debug(e.outerHTML,"color: darkcyan")}(),e.trigger("connectionInitialized")}function md(e,t){t=e.session.get("jid")||t,e.api.settings.get("authentication")===zo||Oo.getResourceFromJid(t)||(t=t.toLowerCase()+ld.generateResource()),e.jid=t,e.bare_jid=Oo.getBareJidFromJid(t),e.resource=Oo.getResourceFromJid(t),e.domain=Oo.getDomainFromJid(t),e.session.save({jid:t,bare_jid:e.bare_jid,resource:e.resource,domain:e.domain,active:!0}),e.connection.jid=t}async function gd(e){return await async function(e,t){const n=e.api.settings.get("connection_options").worker,s=Oo.getBareJidFromJid(t).toLowerCase(),i=`converse.session-${s}`;e.session?.get("id")!==i?(!function(e,t){if("sessionStorage"===e.api.settings.get("persistent_store"))return;if("BrowserExtLocal"===e.api.settings.get("persistent_store"))return Uc.localForage.defineDriver(od.Z).then((()=>Uc.localForage.setDriver("webExtensionLocalStorage"))),void(e.storage.persistent=Uc.localForage);if("BrowserExtSync"===e.api.settings.get("persistent_store"))return Uc.localForage.defineDriver(ad.Z).then((()=>Uc.localForage.setDriver("webExtensionSyncStorage"))),void(e.storage.persistent=Uc.localForage);const n={name:e.isTestEnv()?"converse-test-persistent":"converse-persistent",storeName:t};"localStorage"===e.api.settings.get("persistent_store")?(n.description="localStorage instance",n.driver=[Uc.localForage.LOCALSTORAGE]):"IndexedDB"===e.api.settings.get("persistent_store")&&(n.description="indexedDB instance",n.driver=[Uc.localForage.INDEXEDDB]),e.storage.persistent=Uc.localForage.createInstance(n)}(e,s),e.session=new dr({id:i}),Gc(e.session,i,n?"persistent":"session"),await new Promise((t=>e.session.fetch({success:t,error:t}))),!n&&e.session.get("active")&&(e.session.clear(),e.session.save({id:i})),md(e,t),window.addEventListener(e.unloadevent,(()=>e.session?.save("active",!1))),e.api.trigger("userSessionInitialized")):md(e,t)}(Zl,e),Zl.api.trigger("setUserJID"),e}async function fd(e){const{api:t}=e;await t.trigger("cleanup",{synchronous:!0}),e.router.history.stop(),function(e){const{api:t}=e;document.removeEventListener("visibilitychange",Sl),t.trigger("unregisteredGlobalEventHandlers")}(e),e.connection?.reset(),e.stopListening(),e.off(),e.promises.initialized.isResolved&&t.promises.add("initialized")}function pd(){return new Promise(rd((async(e,t)=>{let n=new XMLHttpRequest;n.open("GET",Zl.api.settings.get("credentials_url"),!0),n.setRequestHeader("Accept","application/json, text/javascript"),n.onload=()=>{if(n.status>=200&&n.status<400){const t=JSON.parse(n.responseText);gd(t.jid).then((()=>{e({jid:t.jid,password:t.password})}))}else t(new Error(`${n.status}: ${n.responseText}`))},n.onerror=t,n=await Zl.api.hook("beforeFetchLoginCredentials",this,n),n.send()}),arguments.length>0&&void 0!==arguments[0]?arguments[0]:0))}async function vd(e,t){const{api:n}=Zl;if(n.settings.get("authentication")===Lo){if(e)return _d(e);if(n.settings.get("credentials_url"))return _d(await async function(){let e,t=0;for(;!e;){try{e=await pd(t)}catch(e){$l.error("Could not fetch login credentials"),$l.error(e)}t=2e3}return e}());if(Zl.jid&&(n.settings.get("password")||Zl.connection.pass))return _d();if(n.settings.get("reuse_scram_keys")){const e=await async function(){const e=localStorage.getItem("conversejs-session-jid");if(!e)return null;await gd(e);const t=(await yd(e)).get("scram_keys");return t?{jid:e,password:t}:null}();if(e)return _d(e)}if(!Zl.isTestEnv()&&"credentials"in navigator){const e=await async function(){if(!localStorage.getItem("conversejs-session-jid"))return null;try{const e=await navigator.credentials.get({password:!0});if(e&&"password"==e.type&&hl(e.id))return await gd(e.id),{jid:e.id,password:e.password}}catch(e){return $l.error(e),null}}();if(e)return _d(e)}Zl.isTestEnv()||$l.warn("attemptNonPreboundSession: Couldn't find credentials to log in with")}else![zo,Po].includes(n.settings.get("authentication"))||t&&!n.settings.get("auto_login")||_d()}async function yd(e){const t=`converse.scram-keys-${Oo.getBareJidFromJid(e)}`,n=new dr({id:t});return Gc(n,t,"persistent"),await new Promise((e=>n.fetch({success:e,error:e}))),n}async function _d(e){const{api:t}=Zl;if([zo,Po].includes(t.settings.get("authentication"))){if(!Zl.jid)throw new Error("Config Error: when using anonymous login you need to provide the server's domain via the 'jid' option. Either when calling converse.initialize, or when calling _converse.api.user.login.");Zl.connection.reconnecting||Zl.connection.reset(),Zl.connection.connect(Zl.jid.toLowerCase())}else if(t.settings.get("authentication")===Lo){const n=e?.password??(Zl.connection?.pass||t.settings.get("password"));if(!n){if(t.settings.get("auto_login"))throw new Error("autoLogin: If you use auto_login and authentication='login' then you also need to provide a password.");return Zl.connection.setDisconnectionCause(Oo.Status.AUTHFAIL,void 0,!0),void t.connection.disconnect()}let s;if(Zl.connection.reconnecting||(Zl.connection.reset(),Zl.connection.service=ud()),Zl.config.get("trusted")&&Zl.jid&&t.settings.get("reuse_scram_keys")&&!n?.ck){const e=await yd(Zl.jid);s=t=>{const{scram_keys:n}=Zl.connection;n&&e.save({scram_keys:n}),Zl.connection.onConnectStatusChanged(t)}}Zl.connection.connect(Zl.jid,n,s)}}const bd={user:{settings:el,...nd,jid:()=>Zl.connection.jid,async login(e,t){let n=arguments.length>2&&void 0!==arguments[2]&&arguments[2];const{api:s}=Zl;if(e=e||s.settings.get("jid"),(!Zl.connection?.jid||e&&!xl.isSameDomain(Zl.connection.jid,e))&&hd(),s.settings.get("connection_options")?.worker&&await Zl.connection.restoreWorkerSession())return;e&&(e=await gd(e));const i=Zl.pluggable.plugins["converse-bosh"];if(i?.enabled()){if(await Zl.restoreBOSHSession())return;if(s.settings.get("authentication")===Uo&&(!n||s.settings.get("auto_login")))return Zl.startNewPreboundBOSHSession()}t=t||s.settings.get("password");vd(e&&t?{jid:e,password:t}:null,n)},async logout(){const{api:e}=Zl;await e.trigger("beforeLogout",{synchronous:!0});const t=Xo(),n=()=>{Object.keys(Zl.promises).forEach(_l),delete Zl.jid,localStorage.removeItem("conversejs-session-jid"),e.trigger("logout"),t.resolve()};return Zl.connection.setDisconnectionCause(Fo,void 0,!0),void 0!==Zl.connection?(e.listen.once("disconnected",(()=>n())),Zl.connection.disconnect()):n(),t}}},wd=Zl.api={connection:Kl,settings:Xc,...td,...bd,...Yl,...Xl};var Sd=n(4794),xd=n.n(Sd);const Ad=dr.extend({defaults:{connection_status:Oo.Status.DISCONNECTED,message:""},initialize(){const{api:e}=Zl;this.on("change",(()=>e.trigger("connfeedback",Zl.connfeedback)))}});var Ed=n(5168),$d=n.n(Ed);const Cd=function(e,t,n,s){for(var i=-1,r=null==e?0:e.length;++i-1};const Pd=function(e,t,n){for(var s=-1,i=null==e?0:e.length;++s=200&&(r=ui,o=!1,t=new li(t));e:for(;++it||r&&o&&c&&!a&&!l||s&&o&&c||!n&&c||!i)return 1;if(!s&&!r&&!l&&e=a?c:c*("desc"==n[s]?-1:1)}return e.index-t.index};const du=function(e,t,n){t=t.length?It(t,(function(e){return Z(e)?function(t){return Ni(t,1===e.length?e[0]:e)}:e})):[Ce];var s=-1;t=It(t,re(Fi));var i=ou(e,(function(e,n,i){var r=It(t,(function(t){return t(e)}));return{criteria:r,index:++s,value:e}}));return au(i,(function(e,t){return lu(e,t,n)}))};var uu=Re((function(e,t){if(null==e)return[];var n=t.length;return n>1&&De(e,t[0],t[1])?t=[]:n>2&&De(t[0],t[1],t[2])&&(t=[t[0]]),du(e,tr(t,1),[])}));const hu=uu,mu=Array.prototype.slice,gu=function(e,t){t||(t={}),this.preinitialize.apply(this,arguments),t.model&&(this.model=t.model),void 0!==t.comparator&&(this.comparator=t.comparator),this._reset(),this.initialize.apply(this,arguments),e&&this.reset(e,Be({silent:!0},t))};gu.extend=Bt;const fu={add:!0,remove:!0,merge:!0},pu={add:!0,remove:!1},vu=function(e,t,n){n=Math.min(Math.max(n,0),e.length);const s=Array(e.length-n),i=t.length;let r;for(r=0;rthis.length&&(s=this.length),s<0&&(s+=this.length+1);const i=[],r=[],o=[],a=[],c={},l=t.add,d=t.merge,u=t.remove;let h=!1;const m=this.comparator&&null==s&&!1!==t.sort,g=sa(this.comparator)?this.comparator:null;let f,p;for(p=0;pe!==i[t])),this.models.length=0,vu(this.models,i,0),this.length=this.models.length):r.length&&(m&&(h=!0),vu(this.models,r,null==s?this.length:s),this.length=this.models.length),h&&this.sort({silent:!0}),!t.silent){for(p=0;p0&&void 0!==arguments[0]?arguments[0]:{},t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:e=>e;await Promise.all(this.models.filter(t).map((t=>new Promise((n=>{t.destroy(Object.assign(e,{success:n,error:(e,t)=>{console.error(t),n()}}))}))))),await this.browserStorage.clear(),this.reset()},reset:function(e,t){t=t?Fs(t):{};for(let e=0;et.matches(e),t)},every:function(e){return qd(this.models.map((e=>e.attributes)),e)},difference:function(e){return Fd(this.models,e)},max:function(){return Math.max.apply(Math,this.models)},min:function(){return Math.min.apply(Math,this.models)},drop:function(){let e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:1;return this.models.slice(e)},some:function(e){return Ml(this.models.map((e=>e.attributes)),e)},sortBy:function(e){return hu(this.models,_(e)?e:t=>sa(e)?t.get(e):t.matches(e))},isEmpty:function(){return mn(this.models)},keyBy:function(e){return tu(this.models,e)},each:function(e,t){return this.forEach(e,t)},forEach:function(e,t){return this.models.forEach(e,t)},includes:function(e){return this.models.includes(e)},size:function(){return this.models.length},countBy:function(e){return Nd(this.models,_(e)?e:t=>sa(e)?t.get(e):t.matches(e))},groupBy:function(e){return Kd(this.models,_(e)?e:t=>sa(e)?t.get(e):t.matches(e))},indexOf:function(e){return Xd(this.models,e)},findLastIndex:function(e,t){return Zd(this.models,_(e)?e:t=>sa(e)?t.get(e):t.matches(e),t)},lastIndexOf:function(e){return ru(this.models,e)},findIndex:function(e){return Gd(this.models,_(e)?e:t=>sa(e)?t.get(e):t.matches(e))},last:function(){const e=null==this.models?0:this.models.length;return e?this.models[e-1]:void 0},head:function(){return this.models[0]},first:function(){return this.head()},map:function(e,t){return this.models.map(_(e)?e:t=>sa(e)?t.get(e):t.matches(e),t)},reduce:function(e,t){return this.models.reduce(e,t||this.models[0])},reduceRight:function(e,t){return this.models.reduceRight(e,t||this.models[0])},toArray:function(){return Array.from(this.models)},get:function(e){if(null!=e)return this._byId[e]||this._byId[this.modelId(this._isModel(e)?e.attributes:e)]||e.cid&&this._byId[e.cid]},has:function(e){return null!=this.get(e)},at:function(e){return e<0&&(e+=this.length),this.models[e]},where:function(e,t){return this[t?"find":"filter"](e)},findWhere:function(e){return this.where(e,!0)},find:function(e,t){const n=_(e)?e:t=>t.matches(e);return this.models.find(n,t)},sort:function(e){let t=this.comparator;if(!t)throw new Error("Cannot sort a set without a comparator");e||(e={});const n=t.length;return _(t)&&(t=t.bind(this)),1===n||sa(t)?this.models=this.sortBy(t):this.models.sort(t),e.silent||this.trigger("sort",this,e),this},pluck:function(e){return this.map(e+"")},fetch:function(e){const t=(e=Be({parse:!0},e)).success,n=this,s=e.promise&&qt();return e.success=function(i){const r=e.reset?"reset":"set";n[r](i,e),t&&t.call(e.context,n,i,e),s&&s.resolve(),n.trigger("sync",n,i,e)},Gt(this,e),s||this.sync("read",this,e)},create:function(e,t){const n=(t=t?Fs(t):{}).wait,s=t.promise,i=s&&qt();if(!(e=this._prepareModel(e,t)))return!1;n||this.add(e,t);const r=this,o=t.success,a=t.error;return t.success=function(e,t,a){n&&r.add(e,a),o&&o.call(a.context,e,t,a),s&&i.resolve(e)},t.error=function(e,t,n){a&&a.call(n.context,e,t,n),s&&i.reject(t)},e.save(null,Object.assign(t,{promise:!1})),s?i:e},parse:function(e,t){return e},clone:function(){return new this.constructor(this.models,{model:this.model,comparator:this.comparator})},modelId:function(e){return e[this.model.prototype?.idAttribute||"id"]},values:function(){return new _u(this,bu)},keys:function(){return new _u(this,wu)},entries:function(){return new _u(this,Su)},_reset:function(){this.length=0,this.models=[],this._byId={}},_prepareModel:function(e,t){if(this._isModel(e))return e.collection||(e.collection=this),e;(t=t?Fs(t):{}).collection=this;const n=new this.model(e,t);return n.validationError?(this.trigger("invalid",this,n.validationError,t),!1):n},_removeModels:function(e,t){const n=[];for(let s=0;s0?s=(d=d===Iu?Iu:Ou)===Iu?2:10:d=10===(s=2===s?2:10)||d===Ou?Ou:Iu;const S=10===s?1e3:1024,x=!0===h,A=y<0,E=Math[f];if("bigint"!=typeof e&&isNaN(e))throw new TypeError(Nu);if(typeof E!==Tu)throw new TypeError(Mu);if(A&&(y=-y),(-1===v||isNaN(v))&&(v=Math.floor(Math.log(y)/Math.log(S)),v<0&&(v=0)),v>8&&(p>0&&(p+=8-v),v=8),u===ju)return v;if(0===y)_[0]=0,w=_[1]=Hu.symbol[d][t?Eu:Cu][v];else{b=y/(2===s?Math.pow(2,10*v):Math.pow(1e3,v)),t&&(b*=8,b>=S&&v<8&&(b/=S,v++));const e=Math.pow(10,v>0?i:0);_[0]=E(b*e)/e,_[0]===S&&v<8&&-1===g&&(_[0]=1,v++),w=_[1]=10===s&&1===v?t?Lu:Fu:Hu.symbol[d][t?Eu:Cu][v]}if(A&&(_[0]=-_[0]),p>0&&(_[0]=_[0].toPrecision(p)),_[1]=l[_[1]]||_[1],!0===r?_[0]=_[0].toLocaleString():r.length>0?_[0]=_[0].toLocaleString(r,o):a.length>0&&(_[0]=_[0].toString().replace(Du,a)),n&&!1===Number.isInteger(_[0])&&i>0){const e=a||Du,t=_[0].toString().split(e),n=t[1]||ku,s=n.length,r=i-s;_[0]=`${t[0]}${e}${n.padEnd(s+r,qu)}`}return x&&(_[1]=m[v]?m[v]:Hu.fullform[d][v]+(t?Au:$u)+(1===_[0]?ku:Pu)),u===xu?_:u===Ru?{value:_[0],symbol:_[1],exponent:v,unit:w}:_.join(c)}const Wu=globalThis,Vu=Wu.ShadowRoot&&(void 0===Wu.ShadyCSS||Wu.ShadyCSS.nativeShadow)&&"adoptedStyleSheets"in Document.prototype&&"replace"in CSSStyleSheet.prototype,Zu=Symbol(),Qu=new WeakMap;class Ju{constructor(e,t,n){if(this._$cssResult$=!0,n!==Zu)throw Error("CSSResult is not constructable. Use `unsafeCSS` or `css` instead.");this.cssText=e,this.t=t}get styleSheet(){let e=this.o;const t=this.t;if(Vu&&void 0===e){const n=void 0!==t&&1===t.length;n&&(e=Qu.get(t)),void 0===e&&((this.o=e=new CSSStyleSheet).replaceSync(this.cssText),n&&Qu.set(t,e))}return e}toString(){return this.cssText}}const Ku=(e,t)=>{if(Vu)e.adoptedStyleSheets=t.map((e=>e instanceof CSSStyleSheet?e:e.styleSheet));else for(const n of t){const t=document.createElement("style"),s=Wu.litNonce;void 0!==s&&t.setAttribute("nonce",s),t.textContent=n.cssText,e.appendChild(t)}},Yu=Vu?e=>e:e=>e instanceof CSSStyleSheet?(e=>{let t="";for(const n of e.cssRules)t+=n.cssText;return(e=>new Ju("string"==typeof e?e:e+"",void 0,Zu))(t)})(e):e,{is:Xu,defineProperty:eh,getOwnPropertyDescriptor:th,getOwnPropertyNames:nh,getOwnPropertySymbols:sh,getPrototypeOf:ih}=Object,rh=globalThis,oh=rh.trustedTypes,ah=oh?oh.emptyScript:"",ch=rh.reactiveElementPolyfillSupport,lh=(e,t)=>e,dh={toAttribute(e,t){switch(t){case Boolean:e=e?ah:null;break;case Object:case Array:e=null==e?e:JSON.stringify(e)}return e},fromAttribute(e,t){let n=e;switch(t){case Boolean:n=null!==e;break;case Number:n=null===e?null:Number(e);break;case Object:case Array:try{n=JSON.parse(e)}catch(e){n=null}}return n}},uh=(e,t)=>!Xu(e,t),hh={attribute:!0,type:String,converter:dh,reflect:!1,hasChanged:uh};Symbol.metadata??=Symbol("metadata"),rh.litPropertyMetadata??=new WeakMap;class mh extends HTMLElement{static addInitializer(e){this._$Ei(),(this.l??=[]).push(e)}static get observedAttributes(){return this.finalize(),this._$Eh&&[...this._$Eh.keys()]}static createProperty(e,t=hh){if(t.state&&(t.attribute=!1),this._$Ei(),this.elementProperties.set(e,t),!t.noAccessor){const n=Symbol(),s=this.getPropertyDescriptor(e,n,t);void 0!==s&&eh(this.prototype,e,s)}}static getPropertyDescriptor(e,t,n){const{get:s,set:i}=th(this.prototype,e)??{get(){return this[t]},set(e){this[t]=e}};return{get(){return s?.call(this)},set(t){const r=s?.call(this);i.call(this,t),this.requestUpdate(e,r,n)},configurable:!0,enumerable:!0}}static getPropertyOptions(e){return this.elementProperties.get(e)??hh}static _$Ei(){if(this.hasOwnProperty(lh("elementProperties")))return;const e=ih(this);e.finalize(),void 0!==e.l&&(this.l=[...e.l]),this.elementProperties=new Map(e.elementProperties)}static finalize(){if(this.hasOwnProperty(lh("finalized")))return;if(this.finalized=!0,this._$Ei(),this.hasOwnProperty(lh("properties"))){const e=this.properties,t=[...nh(e),...sh(e)];for(const n of t)this.createProperty(n,e[n])}const e=this[Symbol.metadata];if(null!==e){const t=litPropertyMetadata.get(e);if(void 0!==t)for(const[e,n]of t)this.elementProperties.set(e,n)}this._$Eh=new Map;for(const[e,t]of this.elementProperties){const n=this._$Eu(e,t);void 0!==n&&this._$Eh.set(n,e)}this.elementStyles=this.finalizeStyles(this.styles)}static finalizeStyles(e){const t=[];if(Array.isArray(e)){const n=new Set(e.flat(1/0).reverse());for(const e of n)t.unshift(Yu(e))}else void 0!==e&&t.push(Yu(e));return t}static _$Eu(e,t){const n=t.attribute;return!1===n?void 0:"string"==typeof n?n:"string"==typeof e?e.toLowerCase():void 0}constructor(){super(),this._$Ep=void 0,this.isUpdatePending=!1,this.hasUpdated=!1,this._$Em=null,this._$Ev()}_$Ev(){this._$ES=new Promise((e=>this.enableUpdating=e)),this._$AL=new Map,this._$E_(),this.requestUpdate(),this.constructor.l?.forEach((e=>e(this)))}addController(e){(this._$EO??=new Set).add(e),void 0!==this.renderRoot&&this.isConnected&&e.hostConnected?.()}removeController(e){this._$EO?.delete(e)}_$E_(){const e=new Map,t=this.constructor.elementProperties;for(const n of t.keys())this.hasOwnProperty(n)&&(e.set(n,this[n]),delete this[n]);e.size>0&&(this._$Ep=e)}createRenderRoot(){const e=this.shadowRoot??this.attachShadow(this.constructor.shadowRootOptions);return Ku(e,this.constructor.elementStyles),e}connectedCallback(){this.renderRoot??=this.createRenderRoot(),this.enableUpdating(!0),this._$EO?.forEach((e=>e.hostConnected?.()))}enableUpdating(e){}disconnectedCallback(){this._$EO?.forEach((e=>e.hostDisconnected?.()))}attributeChangedCallback(e,t,n){this._$AK(e,n)}_$EC(e,t){const n=this.constructor.elementProperties.get(e),s=this.constructor._$Eu(e,n);if(void 0!==s&&!0===n.reflect){const i=(void 0!==n.converter?.toAttribute?n.converter:dh).toAttribute(t,n.type);this._$Em=e,null==i?this.removeAttribute(s):this.setAttribute(s,i),this._$Em=null}}_$AK(e,t){const n=this.constructor,s=n._$Eh.get(e);if(void 0!==s&&this._$Em!==s){const e=n.getPropertyOptions(s),i="function"==typeof e.converter?{fromAttribute:e.converter}:void 0!==e.converter?.fromAttribute?e.converter:dh;this._$Em=s,this[s]=i.fromAttribute(t,e.type),this._$Em=null}}requestUpdate(e,t,n){if(void 0!==e){if(n??=this.constructor.getPropertyOptions(e),!(n.hasChanged??uh)(this[e],t))return;this.P(e,t,n)}!1===this.isUpdatePending&&(this._$ES=this._$ET())}P(e,t,n){this._$AL.has(e)||this._$AL.set(e,t),!0===n.reflect&&this._$Em!==e&&(this._$Ej??=new Set).add(e)}async _$ET(){this.isUpdatePending=!0;try{await this._$ES}catch(e){Promise.reject(e)}const e=this.scheduleUpdate();return null!=e&&await e,!this.isUpdatePending}scheduleUpdate(){return this.performUpdate()}performUpdate(){if(!this.isUpdatePending)return;if(!this.hasUpdated){if(this.renderRoot??=this.createRenderRoot(),this._$Ep){for(const[e,t]of this._$Ep)this[e]=t;this._$Ep=void 0}const e=this.constructor.elementProperties;if(e.size>0)for(const[t,n]of e)!0!==n.wrapped||this._$AL.has(t)||void 0===this[t]||this.P(t,this[t],n)}let e=!1;const t=this._$AL;try{e=this.shouldUpdate(t),e?(this.willUpdate(t),this._$EO?.forEach((e=>e.hostUpdate?.())),this.update(t)):this._$EU()}catch(t){throw e=!1,this._$EU(),t}e&&this._$AE(t)}willUpdate(e){}_$AE(e){this._$EO?.forEach((e=>e.hostUpdated?.())),this.hasUpdated||(this.hasUpdated=!0,this.firstUpdated(e)),this.updated(e)}_$EU(){this._$AL=new Map,this.isUpdatePending=!1}get updateComplete(){return this.getUpdateComplete()}getUpdateComplete(){return this._$ES}shouldUpdate(e){return!0}update(e){this._$Ej&&=this._$Ej.forEach((e=>this._$EC(e,this[e]))),this._$EU()}updated(e){}firstUpdated(e){}}mh.elementStyles=[],mh.shadowRootOptions={mode:"open"},mh[lh("elementProperties")]=new Map,mh[lh("finalized")]=new Map,ch?.({ReactiveElement:mh}),(rh.reactiveElementVersions??=[]).push("2.0.4");const gh=globalThis,fh=gh.trustedTypes,ph=fh?fh.createPolicy("lit-html",{createHTML:e=>e}):void 0,vh="$lit$",yh=`lit$${Math.random().toFixed(9).slice(2)}$`,_h="?"+yh,bh=`<${_h}>`,wh=document,Sh=()=>wh.createComment(""),xh=e=>null===e||"object"!=typeof e&&"function"!=typeof e,Ah=Array.isArray,Eh=e=>Ah(e)||"function"==typeof e?.[Symbol.iterator],$h="[ \t\n\f\r]",Ch=/<(?:(!--|\/[^a-zA-Z])|(\/?[a-zA-Z][^>\s]*)|(\/?$))/g,kh=/-->/g,jh=/>/g,Th=RegExp(`>|${$h}(?:([^\\s"'>=/]+)(${$h}*=${$h}*(?:[^ \t\n\f\r"'\`<>=]|("|')|))|$)`,"g"),Ih=/'/g,Nh=/"/g,Mh=/^(?:script|style|textarea|title)$/i,Oh=e=>function(t){for(var n=arguments.length,s=new Array(n>1?n-1:0),i=1;i{const n=e.length-1,s=[];let i,r=2===t?"":3===t?"":"",o=Ch;for(let t=0;t"===c[0]?(o=i??Ch,l=-1):void 0===c[1]?l=-2:(l=o.lastIndex-c[2].length,a=c[1],o=void 0===c[3]?Th:'"'===c[3]?Nh:Ih):o===Nh||o===Ih?o=Th:o===kh||o===jh?o=Ch:(o=Th,i=void 0);const u=o===Th&&e[t+1].startsWith("/>")?" ":"";r+=o===Ch?n+bh:l>=0?(s.push(a),n.slice(0,l)+vh+n.slice(l)+yh+u):n+yh+(-2===l?t:u)}return[Fh(e,r+(e[n]||"")+(2===t?"":3===t?"":"")),s]};class Bh{constructor(e,t){let n,{strings:s,_$litType$:i}=e;this.parts=[];let r=0,o=0;const a=s.length-1,c=this.parts,[l,d]=Uh(s,i);if(this.el=Bh.createElement(l,t),Lh.currentNode=this.el.content,2===i||3===i){const e=this.el.content.firstChild;e.replaceWith(...e.childNodes)}for(;null!==(n=Lh.nextNode())&&c.length0){n.textContent=fh?fh.emptyScript:"";for(let s=0;s2&&void 0!==arguments[2]?arguments[2]:e,s=arguments.length>3?arguments[3]:void 0;if(t===Dh)return t;let i=void 0!==s?n._$Co?.[s]:n._$Cl;const r=xh(t)?void 0:t._$litDirective$;return i?.constructor!==r&&(i?._$AO?.(!1),void 0===r?i=void 0:(i=new r(e),i._$AT(e,n,s)),void 0!==s?(n._$Co??=[])[s]=i:n._$Cl=i),void 0!==i&&(t=qh(e,i._$AS(e,t.values),i,s)),t}class Hh{constructor(e,t){this._$AV=[],this._$AN=void 0,this._$AD=e,this._$AM=t}get parentNode(){return this._$AM.parentNode}get _$AU(){return this._$AM._$AU}u(e){const{el:{content:t},parts:n}=this._$AD,s=(e?.creationScope??wh).importNode(t,!0);Lh.currentNode=s;let i=Lh.nextNode(),r=0,o=0,a=n[0];for(;void 0!==a;){if(r===a.index){let t;2===a.type?t=new Gh(i,i.nextSibling,this,e):1===a.type?t=new a.ctor(i,a.name,a.strings,this,e):6===a.type&&(t=new Jh(i,this,e)),this._$AV.push(t),a=n[++o]}r!==a?.index&&(i=Lh.nextNode(),r++)}return Lh.currentNode=wh,s}p(e){let t=0;for(const n of this._$AV)void 0!==n&&(void 0!==n.strings?(n._$AI(e,n,t),t+=n.strings.length-2):n._$AI(e[t])),t++}}class Gh{get _$AU(){return this._$AM?._$AU??this._$Cv}constructor(e,t,n,s){this.type=2,this._$AH=zh,this._$AN=void 0,this._$AA=e,this._$AB=t,this._$AM=n,this.options=s,this._$Cv=s?.isConnected??!0}get parentNode(){let e=this._$AA.parentNode;const t=this._$AM;return void 0!==t&&11===e?.nodeType&&(e=t.parentNode),e}get startNode(){return this._$AA}get endNode(){return this._$AB}_$AI(e){e=qh(this,e,arguments.length>1&&void 0!==arguments[1]?arguments[1]:this),xh(e)?e===zh||null==e||""===e?(this._$AH!==zh&&this._$AR(),this._$AH=zh):e!==this._$AH&&e!==Dh&&this._(e):void 0!==e._$litType$?this.$(e):void 0!==e.nodeType?this.T(e):Eh(e)?this.k(e):this._(e)}O(e){return this._$AA.parentNode.insertBefore(e,this._$AB)}T(e){this._$AH!==e&&(this._$AR(),this._$AH=this.O(e))}_(e){this._$AH!==zh&&xh(this._$AH)?this._$AA.nextSibling.data=e:this.T(wh.createTextNode(e)),this._$AH=e}$(e){const{values:t,_$litType$:n}=e,s="number"==typeof n?this._$AC(e):(void 0===n.el&&(n.el=Bh.createElement(Fh(n.h,n.h[0]),this.options)),n);if(this._$AH?._$AD===s)this._$AH.p(t);else{const e=new Hh(s,this),n=e.u(this.options);e.p(t),this.T(n),this._$AH=e}}_$AC(e){let t=Ph.get(e.strings);return void 0===t&&Ph.set(e.strings,t=new Bh(e)),t}k(e){Ah(this._$AH)||(this._$AH=[],this._$AR());const t=this._$AH;let n,s=0;for(const i of e)s===t.length?t.push(n=new Gh(this.O(Sh()),this.O(Sh()),this,this.options)):n=t[s],n._$AI(i),s++;s0&&void 0!==arguments[0]?arguments[0]:this._$AA.nextSibling,t=arguments.length>1?arguments[1]:void 0;for(this._$AP?.(!1,!0,t);e&&e!==this._$AB;){const t=e.nextSibling;e.remove(),e=t}}setConnected(e){void 0===this._$AM&&(this._$Cv=e,this._$AP?.(e))}}class Wh{get tagName(){return this.element.tagName}get _$AU(){return this._$AM._$AU}constructor(e,t,n,s,i){this.type=1,this._$AH=zh,this._$AN=void 0,this.element=e,this.name=t,this._$AM=s,this.options=i,n.length>2||""!==n[0]||""!==n[1]?(this._$AH=Array(n.length-1).fill(new String),this.strings=n):this._$AH=zh}_$AI(e){let t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:this,n=arguments.length>2?arguments[2]:void 0,s=arguments.length>3?arguments[3]:void 0;const i=this.strings;let r=!1;if(void 0===i)e=qh(this,e,t,0),r=!xh(e)||e!==this._$AH&&e!==Dh,r&&(this._$AH=e);else{const s=e;let o,a;for(e=i[0],o=0;o1&&void 0!==arguments[1]?arguments[1]:this,0)??zh)===Dh)return;const t=this._$AH,n=e===zh&&t!==zh||e.capture!==t.capture||e.once!==t.once||e.passive!==t.passive,s=e!==zh&&(t===zh||n);n&&this.element.removeEventListener(this.name,this,t),s&&this.element.addEventListener(this.name,this,e),this._$AH=e}handleEvent(e){"function"==typeof this._$AH?this._$AH.call(this.options?.host??this.element,e):this._$AH.handleEvent(e)}}class Jh{constructor(e,t,n){this.element=e,this.type=6,this._$AN=void 0,this._$AM=t,this.options=n}get _$AU(){return this._$AM._$AU}_$AI(e){qh(this,e)}}const Kh={M:vh,P:yh,A:_h,C:1,L:Uh,R:Hh,D:Eh,V:qh,I:Gh,H:Wh,N:Zh,U:Qh,B:Vh,F:Jh},Yh=gh.litHtmlPolyfillSupport;Yh?.(Bh,Gh),(gh.litHtmlVersions??=[]).push("3.2.1");const Xh=globalThis,em=Xh.trustedTypes,tm=em?em.createPolicy("lit-html",{createHTML:e=>e}):void 0,nm="$lit$",sm=`lit$${Math.random().toFixed(9).slice(2)}$`,im="?"+sm,rm=`<${im}>`,om=document,am=()=>om.createComment(""),cm=e=>null===e||"object"!=typeof e&&"function"!=typeof e,lm=Array.isArray,dm=e=>lm(e)||"function"==typeof e?.[Symbol.iterator],um="[ \t\n\f\r]",hm=/<(?:(!--|\/[^a-zA-Z])|(\/?[a-zA-Z][^>\s]*)|(\/?$))/g,mm=/-->/g,gm=/>/g,fm=RegExp(`>|${um}(?:([^\\s"'>=/]+)(${um}*=${um}*(?:[^ \t\n\f\r"'\`<>=]|("|')|))|$)`,"g"),pm=/'/g,vm=/"/g,ym=/^(?:script|style|textarea|title)$/i,_m=e=>function(t){for(var n=arguments.length,s=new Array(n>1?n-1:0),i=1;i{const n=e.length-1,s=[];let i,r=2===t?"":3===t?"":"",o=hm;for(let t=0;t"===c[0]?(o=i??hm,l=-1):void 0===c[1]?l=-2:(l=o.lastIndex-c[2].length,a=c[1],o=void 0===c[3]?fm:'"'===c[3]?vm:pm):o===vm||o===pm?o=fm:o===mm||o===gm?o=hm:(o=fm,i=void 0);const u=o===fm&&e[t+1].startsWith("/>")?" ":"";r+=o===hm?n+rm:l>=0?(s.push(a),n.slice(0,l)+nm+n.slice(l)+sm+u):n+sm+(-2===l?t:u)}return[Em(e,r+(e[n]||"")+(2===t?"":3===t?"":"")),s]};class Cm{constructor(e,t){let n,{strings:s,_$litType$:i}=e;this.parts=[];let r=0,o=0;const a=s.length-1,c=this.parts,[l,d]=$m(s,i);if(this.el=Cm.createElement(l,t),Am.currentNode=this.el.content,2===i||3===i){const e=this.el.content.firstChild;e.replaceWith(...e.childNodes)}for(;null!==(n=Am.nextNode())&&c.length0){n.textContent=em?em.emptyScript:"";for(let s=0;s2&&void 0!==arguments[2]?arguments[2]:e,s=arguments.length>3?arguments[3]:void 0;if(t===wm)return t;let i=void 0!==s?n._$Co?.[s]:n._$Cl;const r=cm(t)?void 0:t._$litDirective$;return i?.constructor!==r&&(i?._$AO?.(!1),void 0===r?i=void 0:(i=new r(e),i._$AT(e,n,s)),void 0!==s?(n._$Co??=[])[s]=i:n._$Cl=i),void 0!==i&&(t=km(e,i._$AS(e,t.values),i,s)),t}class jm{constructor(e,t){this._$AV=[],this._$AN=void 0,this._$AD=e,this._$AM=t}get parentNode(){return this._$AM.parentNode}get _$AU(){return this._$AM._$AU}u(e){const{el:{content:t},parts:n}=this._$AD,s=(e?.creationScope??om).importNode(t,!0);Am.currentNode=s;let i=Am.nextNode(),r=0,o=0,a=n[0];for(;void 0!==a;){if(r===a.index){let t;2===a.type?t=new Tm(i,i.nextSibling,this,e):1===a.type?t=new a.ctor(i,a.name,a.strings,this,e):6===a.type&&(t=new Rm(i,this,e)),this._$AV.push(t),a=n[++o]}r!==a?.index&&(i=Am.nextNode(),r++)}return Am.currentNode=om,s}p(e){let t=0;for(const n of this._$AV)void 0!==n&&(void 0!==n.strings?(n._$AI(e,n,t),t+=n.strings.length-2):n._$AI(e[t])),t++}}class Tm{get _$AU(){return this._$AM?._$AU??this._$Cv}constructor(e,t,n,s){this.type=2,this._$AH=Sm,this._$AN=void 0,this._$AA=e,this._$AB=t,this._$AM=n,this.options=s,this._$Cv=s?.isConnected??!0}get parentNode(){let e=this._$AA.parentNode;const t=this._$AM;return void 0!==t&&11===e?.nodeType&&(e=t.parentNode),e}get startNode(){return this._$AA}get endNode(){return this._$AB}_$AI(e){e=km(this,e,arguments.length>1&&void 0!==arguments[1]?arguments[1]:this),cm(e)?e===Sm||null==e||""===e?(this._$AH!==Sm&&this._$AR(),this._$AH=Sm):e!==this._$AH&&e!==wm&&this._(e):void 0!==e._$litType$?this.$(e):void 0!==e.nodeType?this.T(e):dm(e)?this.k(e):this._(e)}O(e){return this._$AA.parentNode.insertBefore(e,this._$AB)}T(e){this._$AH!==e&&(this._$AR(),this._$AH=this.O(e))}_(e){this._$AH!==Sm&&cm(this._$AH)?this._$AA.nextSibling.data=e:this.T(om.createTextNode(e)),this._$AH=e}$(e){const{values:t,_$litType$:n}=e,s="number"==typeof n?this._$AC(e):(void 0===n.el&&(n.el=Cm.createElement(Em(n.h,n.h[0]),this.options)),n);if(this._$AH?._$AD===s)this._$AH.p(t);else{const e=new jm(s,this),n=e.u(this.options);e.p(t),this.T(n),this._$AH=e}}_$AC(e){let t=xm.get(e.strings);return void 0===t&&xm.set(e.strings,t=new Cm(e)),t}k(e){lm(this._$AH)||(this._$AH=[],this._$AR());const t=this._$AH;let n,s=0;for(const i of e)s===t.length?t.push(n=new Tm(this.O(am()),this.O(am()),this,this.options)):n=t[s],n._$AI(i),s++;s0&&void 0!==arguments[0]?arguments[0]:this._$AA.nextSibling,t=arguments.length>1?arguments[1]:void 0;for(this._$AP?.(!1,!0,t);e&&e!==this._$AB;){const t=e.nextSibling;e.remove(),e=t}}setConnected(e){void 0===this._$AM&&(this._$Cv=e,this._$AP?.(e))}}class Im{get tagName(){return this.element.tagName}get _$AU(){return this._$AM._$AU}constructor(e,t,n,s,i){this.type=1,this._$AH=Sm,this._$AN=void 0,this.element=e,this.name=t,this._$AM=s,this.options=i,n.length>2||""!==n[0]||""!==n[1]?(this._$AH=Array(n.length-1).fill(new String),this.strings=n):this._$AH=Sm}_$AI(e){let t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:this,n=arguments.length>2?arguments[2]:void 0,s=arguments.length>3?arguments[3]:void 0;const i=this.strings;let r=!1;if(void 0===i)e=km(this,e,t,0),r=!cm(e)||e!==this._$AH&&e!==wm,r&&(this._$AH=e);else{const s=e;let o,a;for(e=i[0],o=0;o1&&void 0!==arguments[1]?arguments[1]:this,0)??Sm)===wm)return;const t=this._$AH,n=e===Sm&&t!==Sm||e.capture!==t.capture||e.once!==t.once||e.passive!==t.passive,s=e!==Sm&&(t===Sm||n);n&&this.element.removeEventListener(this.name,this,t),s&&this.element.addEventListener(this.name,this,e),this._$AH=e}handleEvent(e){"function"==typeof this._$AH?this._$AH.call(this.options?.host??this.element,e):this._$AH.handleEvent(e)}}class Rm{constructor(e,t,n){this.element=e,this.type=6,this._$AN=void 0,this._$AM=t,this.options=n}get _$AU(){return this._$AM._$AU}_$AI(e){km(this,e)}}const Dm=Xh.litHtmlPolyfillSupport;Dm?.(Cm,Tm),(Xh.litHtmlVersions??=[]).push("3.2.1");const zm=(e,t,n)=>{const s=n?.renderBefore??t;let i=s._$litPart$;if(void 0===i){const e=n?.renderBefore??null;s._$litPart$=i=new Tm(t.insertBefore(am(),e),e,void 0,n??{})}return i._$AI(e),i};class Pm extends mh{constructor(){super(...arguments),this.renderOptions={host:this},this._$Do=void 0}createRenderRoot(){const e=super.createRenderRoot();return this.renderOptions.renderBefore??=e.firstChild,e}update(e){const t=this.render();this.hasUpdated||(this.renderOptions.isConnected=this.isConnected),super.update(e),this._$Do=zm(t,this.renderRoot,this.renderOptions)}connectedCallback(){super.connectedCallback(),this._$Do?.setConnected(!0)}disconnectedCallback(){super.disconnectedCallback(),this._$Do?.setConnected(!1)}render(){return wm}}Pm._$litElement$=!0,Pm.finalized=!0,globalThis.litElementHydrateSupport?.({LitElement:Pm});const Lm=globalThis.litElementPolyfillSupport;Lm?.({LitElement:Pm});(globalThis.litElementVersions??=[]).push("4.1.1");const Fm=Object.assign(window.converse||{},{CHAT_STATES:["active","composing","gone","inactive","paused"],keycodes:Go,async initialize(e){const{api:t}=Zl;if(await fd(Zl),"onpagehide"in window?Zl.unloadevent="pagehide":"onbeforeunload"in window?Zl.unloadevent="beforeunload":"onunload"in window&&(Zl.unloadevent="unload"),function(e){Zc=e,Wc={},Object.assign(Wc,Tn);const t=lr(e,Object.keys(ea));Be(Wc,ea,t)}(e),Zl.strict_plugin_dependencies=e.strict_plugin_dependencies,$l.setLogLevel(t.settings.get("loglevel")),t.settings.get("authentication")===zo&&t.settings.get("auto_login")&&!t.settings.get("jid"))throw new Error("Config Error: you need to provide the server's domain via the 'jid' option when using anonymous authentication with auto_login.");Zl.router.route(/^converse\?loglevel=(debug|info|warn|error|fatal)$/,"loglevel",(e=>$l.setLogLevel(e))),Zl.connfeedback=new Ad,Zl.send_initial_presence=!0,await async function(e){await Uc.sessionStorageInitialized,e.storage={session:Uc.localForage.createInstance({name:e.isTestEnv()?"converse-test-session":"converse-session",description:"sessionStorage instance",driver:["sessionStorageWrapper"]})}}(Zl),await async function(e){const t="converse.client-config";e.config=new dr({id:t,trusted:!0}),e.config.browserStorage=Hc(t,"session"),await new Promise((t=>e.config.fetch({success:t,error:t}))),e.api.trigger("clientConfigInitialized")}(Zl),await Vo.initialize(),function(e){e.pluggable.initialized_plugins=[];const t=qo.concat(e.api.settings.get("whitelisted_plugins"));e.api.settings.get("singleton")&&["converse-bookmarks","converse-controlbox","converse-headline","converse-register"].forEach((t=>e.api.settings.get("blacklisted_plugins").push(t))),e.pluggable.initializePlugins({_converse:e},t,e.api.settings.get("blacklisted_plugins")),e.api.trigger("pluginsInitialized")}(Zl),t.elements?.register(),function(e){document.addEventListener("visibilitychange",Sl),Sl({type:document.hidden?"blur":"focus"}),e.api.trigger("registeredGlobalEventHandlers")}(Zl);try{!History.started&&Zl.router.history.start()}catch(e){$l.error(e)}const n=Zl.pluggable.plugins;if((t.settings.get("auto_login")||t.settings.get("keepalive")&&n["converse-bosh"]?.enabled())&&await t.user.login(null,null,!0),t.trigger("initialized"),Zl.isTestEnv())return Zl},plugins:{add(e,t){if(t.__name__=e,void 0!==Zl.pluggable.plugins[e])throw new TypeError(`Error: plugin with name "${e}" has already been registered!`);Zl.pluggable.plugins[e]=t}},env:{$build:to,$iq:so,$msg:no,$pres:io,utils:xl,Collection:gu,Model:dr,Promise,Strophe:Oo,TimeoutError:ed,URI:$d(),VERSION_NAME:Ro,dayjs:xd(),filesize:Gu,html:bm,log:$l,sizzle:Yo(),sprintf:Wo.sprintf,stx:sl,u:xl}});xd().extend(Jl());const Um=dr.extend({initialize(){this.rosterContactAdded=Xo()},async setRosterContact(e){const t=await wd.contacts.get(e);t&&(this.contact=t,this.set("nickname",t.get("nickname")),this.rosterContactAdded.resolve())}}),Bm=Um;const qm=function(e,t){return e===t||Ci(e,t,ji(t))},{u:Hm}=Fm.env;function Gm(e,t){let n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:0;return e.map((e=>{const s=e.start-n,i=e.end-n;return s<0||s>=t.length?null:Object.assign({},e,{start:s,end:i,url:t.substring(e.start-n,e.end-n)})})).filter((e=>e))}async function Wm(e,t){if(!t.replace_id||!t.from)return;const n="groupchat"===t.type&&t.occupant_id?e=>{let{attributes:n}=e;return n.msgid===t.replace_id&&n.occupant_id==t.occupant_id}:e=>{let{attributes:n}=e;return n.msgid===t.replace_id&&n.from===t.from&&null==n.occupant_id},s=e.messages.models.find(n);if(!s)return t.older_versions={},await e.createMessage(t);const i=s.get("older_versions")||{};return t.timet){const n=e.messages.filter((e=>!Hm.isEmptyMessage(e)));if(n.length>t){for(;n.length>t;)n.shift().destroy();wd.trigger("historyPruned",e)}}}),500),Zm=Fm.env.utils;function Qm(e,t){wd.send(no({to:e.getAttribute("from"),type:"error",id:e.getAttribute("id")}).c("error",{type:"cancel"}).c("not-allowed",{xmlns:"urn:ietf:params:xml:ns:xmpp-stanzas"}).up().c("text",{xmlns:"urn:ietf:params:xml:ns:xmpp-stanzas"}).t(t)),$l.warn(`Rejecting message stanza with the following reason: ${t}`),$l.warn(e)}function Jm(e,t,n,s){const i=no({from:Zl.connection.jid,id:Zm.getUniqueId(),to:e,type:s||"chat"}).c(n,{xmlns:Oo.NS.MARKERS,id:t});wd.send(i)}const{u:Km}=Fm.env;function Ym(e){const t=Xm(e),{protocol:n}=window.location;return!!["chrome-extension:","file:"].includes(n)||("http:"===n||"https:"===n&&["https","aesgcm"].includes(t.protocol().toLowerCase()))}function Xm(e){try{return e instanceof $d()?e:new($d())(e)}catch(e){return $l.debug(e),null}}function eg(e,t){const n=Xm(t);if(null===n)throw new Error(`checkFileTypes: could not parse url ${t}`);const s=n.filename().toLowerCase();return!!e.filter((e=>s.endsWith(e))).length}function tg(e,t){const n=Xm(t),s=n.subdomain(),i=n.domain(),r=`${s?`${s}.`:""}${i}`;return e.includes(i)||e.includes(r)}function ng(e,t){if(!Ym(e))return!1;const n=wd.settings.get("render_media"),s=ig(e,`allowed_${t}_domains`);return Array.isArray(n)?s&&tg(n,e):s&&n}function sg(e){const t=wd.settings.get("filter_url_query_params");if(!t)return e;return Xm(e).removeQuery(t).toString()}function ig(e,t){const n=wd.settings.get(t);if(!Array.isArray(n))return!0;try{return tg(n,e)}catch(e){return $l.debug(e),!1}}function rg(e){return e.is_audio&&ig(e.url,"allowed_audio_domains")||e.is_video&&ig(e.url,"allowed_video_domains")||e.is_image&&ig(e.url,"allowed_image_domains")}function og(e){return eg([".jpg",".jpeg",".png",".gif",".bmp",".tiff",".svg"],e)}function ag(e){return eg([".gif"],e)}function cg(e){return eg([".ogg",".mp3",".m4a"],e)}function lg(e){return eg([".mp4",".webm"],e)}function dg(e){const t=wd.settings.get("image_urls_regex");return t?.test(e)||og(e)}Object.assign(Km,{isAudioURL:cg,isGIFURL:ag,isVideoURL:lg,isImageURL:dg,isURLWithImageExtension:og,checkFileTypes:eg,getURI:Xm,shouldRenderMediaFromURL:ng,isAllowedProtocolForMedia:Ym});const{NS:ug}=Oo;class hg extends Error{constructor(e,t){super(e,t),this.name="StanzaParseError",this.stanza=t}}function mg(e,t){const n={},s=Yo()(`stanza-id[xmlns="${Oo.NS.SID}"]`,e).reduce(((e,t)=>(e[`stanza_id ${t.getAttribute("by")}`]=t.getAttribute("id"),e)),{});Object.assign(n,s);const i=Yo()(`message > result[xmlns="${Oo.NS.MAM}"]`,t).pop();if(i){n[`stanza_id ${t.getAttribute("from")||Zl.bare_jid}`]=i.getAttribute("id")}const r=Yo()(`origin-id[xmlns="${Oo.NS.SID}"]`,e).pop();return r&&(n.origin_id=r.getAttribute("id")),n}function gg(e){const t=Yo()(`encryption[xmlns="${Oo.NS.EME}"]`,e).pop(),n=t?.getAttribute("namespace"),s={};return n?(s.is_encrypted=!0,s.encryption_namespace=n):Yo()(`encrypted[xmlns="${Oo.NS.OMEMO}"]`,e).pop()&&(s.is_encrypted=!0,s.encryption_namespace=Oo.NS.OMEMO),s}function fg(e,t){const n=Yo()(`> apply-to[xmlns="${Oo.NS.FASTEN}"]`,e).pop();if(n){const e=n.getAttribute("id");if(Yo()(`> retract[xmlns="${Oo.NS.RETRACT}"]`,n).pop()){const n=Yo()(`delay[xmlns="${Oo.NS.DELAY}"]`,t).pop();return{editable:!1,retracted:n?xd()(n.getAttribute("stamp")).toISOString():(new Date).toISOString(),retracted_id:e}}}else{const t=Yo()(`> retracted[xmlns="${Oo.NS.RETRACT}"]`,e).pop();if(t)return{editable:!1,is_tombstone:!0,retracted:t.getAttribute("stamp")}}return{}}function pg(e,t){const n=Yo()(`replace[xmlns="${Oo.NS.MESSAGE_CORRECT}"]`,e).pop();if(n){const e=n.getAttribute("id");if(e){const n=Yo()(`delay[xmlns="${Oo.NS.DELAY}"]`,t).pop();return{replace_id:e,edited:n?xd()(n.getAttribute("stamp")).toISOString():(new Date).toISOString()}}}return{}}function vg(e){let t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:0;const n=[];if(!e)return{};try{$d().withinString(e,((e,s,i)=>(e.startsWith("_")&&(e=e.slice(1),s+=1),e.endsWith("_")&&(e=e.slice(0,e.length-1),i-=1),n.push({url:e,start:s+t,end:i+t}),e)),Ho)}catch(e){$l.debug(e)}const s=n.map((e=>{return{end:e.end,is_audio:cg(e.url),is_image:dg(e.url),is_video:lg(e.url),is_encrypted:(t=e.url,t.startsWith("aesgcm://")),start:e.start};var t}));return s.length?{media_urls:s}:{}}function yg(e){const t=Yo()(`spoiler[xmlns="${Oo.NS.SPOILER}"]`,e).pop();return{is_spoiler:!!t,spoiler_hint:t?.textContent}}function _g(e){const t=Yo()(`x[xmlns="${Oo.NS.OUTOFBAND}"]`,e).pop();return t?{oob_url:t.querySelector("url")?.textContent,oob_desc:t.querySelector("desc")?.textContent}:{}}function bg(e){if("error"===e.getAttribute("type")){const t=e.querySelector("error"),n=Yo()(`text[xmlns="${Oo.NS.STANZAS}"]`,t).pop();return{is_error:!0,error_text:n?.textContent,error_type:t.getAttribute("type"),error_condition:t.firstElementChild.nodeName}}return{}}function wg(e){return Yo()(`reference[xmlns="${Oo.NS.REFERENCE}"]`,e).map((t=>{const n=t.getAttribute("anchor"),s=e.querySelector(n?`#${n}`:"body")?.textContent;if(!s)return $l.warn(`Could not find referenced text for ${t}`),null;const i=t.getAttribute("begin"),r=t.getAttribute("end");return{begin:i,end:r,type:t.getAttribute("type"),value:s.slice(i,r),uri:t.getAttribute("uri")}})).filter((e=>e))}function Sg(e){const t=Yo()(`received[xmlns="${Oo.NS.RECEIPTS}"]`,e).pop();return t?.getAttribute("id")}function xg(e){const t=Oo.NS.CARBONS;return Yo()(`message > received[xmlns="${t}"]`,e).length>0||Yo()(`message > sent[xmlns="${t}"]`,e).length>0}function Ag(e){return Yo()(`\n composing[xmlns="${ug.CHATSTATES}"],\n paused[xmlns="${ug.CHATSTATES}"],\n inactive[xmlns="${ug.CHATSTATES}"],\n active[xmlns="${ug.CHATSTATES}"],\n gone[xmlns="${ug.CHATSTATES}"]`,e).pop()?.nodeName}function Eg(e,t){return"me"!==t.sender&&!t.is_carbon&&!t.is_archived&&Yo()(`request[xmlns="${Oo.NS.RECEIPTS}"]`,e).length}function $g(e){if(Yo()(`message > forwarded[xmlns="${Oo.NS.FORWARD}"]`,e).length){Qm(e,"Forwarded messages not part of an encapsulating protocol are not supported");const t=e.getAttribute("from");throw new hg(`Ignoring unencapsulated forwarded message from ${t}`,e)}}function Cg(e){return Yo()(`\n acknowledged[xmlns="${Oo.NS.MARKERS}"],\n displayed[xmlns="${Oo.NS.MARKERS}"],\n received[xmlns="${Oo.NS.MARKERS}"]`,e).pop()}function kg(e){return"headline"===e.getAttribute("type")}function jg(e){if(Yo()(`mentions[xmlns="${Oo.NS.MENTIONS}"]`,e).pop())return!1;const t=e.getAttribute("from");return!("error"===e.getAttribute("type")||!t||t.includes("@"))}function Tg(e){return!!Yo()(`message > result[xmlns="${Oo.NS.MAM}"]`,e).pop()}function Ig(e){return e.getAttributeNames().reduce(((t,n)=>(t[n]=Oo.xmlunescape(e.getAttribute(n)),t)),{})}const{Strophe:Ng,sizzle:Mg}=Fm.env;async function Og(e){$g(e);let t=e.getAttribute("to");const n=Ng.getResourceFromJid(t);if(wd.settings.get("filter_by_resource")&&n&&n!==Zl.resource)return new hg(`Ignoring incoming message intended for a different resource: ${t}`,e);const s=e;let i=e.getAttribute("from")||Zl.bare_jid;if(xg(e)){if(i!==Zl.bare_jid)return Qm(e,"Rejecting carbon from invalid JID"),new hg(`Rejecting carbon from invalid JID ${t}`,e);{const n=`[xmlns="${Ng.NS.CARBONS}"] > forwarded[xmlns="${Ng.NS.FORWARD}"] > message`;t=(e=Mg(n,e).pop()).getAttribute("to"),i=e.getAttribute("from")}}const r=Tg(e);if(r){if(i!==Zl.bare_jid)return new hg(`Invalid Stanza: alleged MAM message from ${e.getAttribute("from")}`,e);{const n=`[xmlns="${Ng.NS.MAM}"] > forwarded[xmlns="${Ng.NS.FORWARD}"] > message`;t=(e=Mg(n,e).pop()).getAttribute("to"),i=e.getAttribute("from")}}const o=Ng.getBareJidFromJid(i),a=o===Zl.bare_jid;if(a&&null===t)return new hg(`Don't know how to handle message stanza without 'to' attribute. ${e.outerHTML}`,e);const c=kg(e),l=jg(e);let d,u;if(!c&&!l&&(u=a?Ng.getBareJidFromJid(t):o,d=await wd.contacts.get(u),void 0===d&&!wd.settings.get("allow_non_roster_messaging")))return $l.error(e),new hg("Blocking messaging with a JID not in our roster because allow_non_roster_messaging is false.",e);const h=Mg(`delay[xmlns="${Ng.NS.DELAY}"]`,s).pop(),m=Cg(e),g=(new Date).toISOString();let f=Object.assign({contact_jid:u,is_archived:r,is_headline:c,is_server_message:l,body:e.querySelector("body")?.textContent?.trim(),chat_state:Ag(e),from:Ng.getBareJidFromJid(e.getAttribute("from")),is_carbon:xg(s),is_delayed:!!h,is_markable:!!Mg(`markable[xmlns="${Ng.NS.MARKERS}"]`,e).length,is_marker:!!m,is_unstyled:!!Mg(`unstyled[xmlns="${Ng.NS.STYLING}"]`,e).length,marker_id:m&&m.getAttribute("id"),msgid:e.getAttribute("id")||s.getAttribute("id"),nick:d?.attributes?.nickname,receipt_id:Sg(e),received:(new Date).toISOString(),references:wg(e),sender:a?"me":"them",subject:e.querySelector("subject")?.textContent,thread:e.querySelector("thread")?.textContent,time:h?xd()(h.getAttribute("stamp")).toISOString():g,to:e.getAttribute("to"),type:e.getAttribute("type")||"normal"},bg(e),_g(e),yg(e),pg(e,s),mg(e,s),fg(e,s),gg(e));if(f.is_archived){const t=s.getAttribute("from");if(t&&t!==Zl.bare_jid)return new hg(`Invalid Stanza: Forged MAM message from ${t}`,e)}return await wd.emojis.initialize(),f=Object.assign({message:f.body||f.error,is_only_emojis:!!f.body&&xl.isOnlyEmojis(f.body),is_valid_receipt_request:Eg(e,f)},f),f.id=f.origin_id||f[`stanza_id ${f.from}`]||xl.getUniqueId(),f=await wd.hook("parseMessage",e,f),Object.assign(f,vg(f.is_encrypted?f.plaintext:f.body))}const{Strophe:Rg,$msg:Dg}=Fm.env,zg=Fm.env.utils,Pg=Bm.extend({defaults(){return{bookmarked:!1,chat_state:void 0,hidden:al()&&!wd.settings.get("singleton"),message_type:"chat",nickname:void 0,num_unread:0,time_opened:this.get("time_opened")||(new Date).getTime(),time_sent:new Date(0).toISOString(),type:Zl.PRIVATE_CHAT_TYPE,url:""}},async initialize(){this.initialized=Xo(),Bm.prototype.initialize.apply(this,arguments);const e=this.get("jid");e&&(this.set({box_id:`box-${e}`}),this.initNotifications(),this.initUI(),this.initMessages(),this.get("type")===Zl.PRIVATE_CHAT_TYPE&&(this.presence=Zl.presences.get(e)||Zl.presences.create({jid:e}),await this.setRosterContact(e),this.presence.on("change:show",(e=>this.onPresenceChanged(e)))),this.on("change:chat_state",this.sendChatState,this),this.ui.on("change:scrolled",this.onScrolledChanged,this),await this.fetchMessages(),await wd.trigger("chatBoxInitialized",this,{Synchronous:!0}),this.initialized.resolve())},getMessagesCollection:()=>new Zl.Messages,getMessagesCacheKey(){return`converse.messages-${this.get("jid")}-${Zl.bare_jid}`},initMessages(){this.messages=this.getMessagesCollection(),this.messages.fetched=Xo(),this.messages.chatbox=this,Gc(this.messages,this.getMessagesCacheKey()),this.listenTo(this.messages,"change:upload",this.onMessageUploadChanged,this),this.listenTo(this.messages,"add",this.onMessageAdded,this)},initUI(){this.ui=new dr},initNotifications(){this.notifications=new dr},getNotificationsText(){const{__:e}=Zl;return this.notifications?.get("chat_state")===Zl.COMPOSING?e("%1$s is typing",this.getDisplayName()):this.notifications?.get("chat_state")===Zl.PAUSED?e("%1$s has stopped typing",this.getDisplayName()):this.notifications?.get("chat_state")===Zl.GONE?e("%1$s has gone away",this.getDisplayName()):""},afterMessagesFetched(){this.pruneHistoryWhenScrolledDown(),wd.trigger("afterMessagesFetched",this)},fetchMessages(){if(this.messages.fetched_flag)return void $l.info(`Not re-fetching messages for ${this.get("jid")}`);this.messages.fetched_flag=!0;const e=this.messages.fetched.resolve;return this.messages.fetch({add:!0,success:t=>{this.afterMessagesFetched(t),e()},error:()=>{this.afterMessagesFetched(),e()}}),this.messages.fetched},async handleErrorMessageStanza(e){const{__:t}=Zl,n=await Og(e);if(!await this.shouldShowErrorMessage(n))return;const s=this.getMessageReferencedByError(n);if(s){const e={error:n.error,error_condition:n.error_condition,error_text:n.error_text,error_type:n.error_type,editable:!1};n.msgid===s.get("retraction_id")?(e.retraction_id=void 0,n.error||("forbidden"===n.error_condition?e.error=t("You're not allowed to retract your message."):e.error=t("Sorry, an error occurred while trying to retract your message."))):n.error||("forbidden"===n.error_condition?e.error=t("You're not allowed to send a message."):e.error=t("Sorry, an error occurred while trying to send your message.")),s.save(e)}else this.createMessage(n)},queueMessage(e){return this.msg_chain=(this.msg_chain||this.messages.fetched).then((()=>this.onMessage(e))).catch((e=>$l.error(e))),this.msg_chain},async onMessage(e){if(e=await e,zg.isErrorObject(e))return e.stanza&&$l.error(e.stanza),$l.error(e.message);const t=this.getDuplicateMessage(e);if(t)this.updateMessage(t,e);else if(!this.handleReceipt(e)&&!this.handleChatMarker(e)&&!await this.handleRetraction(e)&&(this.setEditable(e,e.time),e.chat_state&&"them"===e.sender&&this.notifications.set("chat_state",e.chat_state),zg.shouldCreateMessage(e))){const t=await Wm(this,e)||await this.createMessage(e);this.notifications.set({chat_state:null}),this.handleUnreadMessage(t)}},async onMessageUploadChanged(e){if(e.get("upload")===Zl.SUCCESS){const t={body:e.get("body"),spoiler_hint:e.get("spoiler_hint"),oob_url:e.get("oob_url")};await this.sendMessage(t),e.destroy()}},onMessageAdded(e){!wd.settings.get("prune_messages_above")||"scrolled"!==wd.settings.get("pruning_behavior")&&this.ui.get("scrolled")||ol(e)||Vm(this)},async clearMessages(){try{await this.messages.clearStore()}catch(e){this.messages.trigger("reset"),$l.error(e)}finally{this.messages.fetched.resolve()}},async close(){wd.connection.connected()&&(this.setChatState(Zl.INACTIVE),this.sendChatState());try{await new Promise(((e,t)=>this.destroy({success:e,error:(e,n)=>t(n)})))}catch(e){$l.error(e)}finally{wd.settings.get("clear_messages_on_reconnection")&&await this.clearMessages()}wd.trigger("chatBoxClosed",this)},announceReconnection(){wd.trigger("chatReconnected",this)},async onReconnection(){wd.settings.get("clear_messages_on_reconnection")&&await this.clearMessages(),this.announceReconnection()},onPresenceChanged(e){const{__:t}=Zl,n=e.get("show"),s=this.getDisplayName();let i;"offline"===n?i=t("%1$s has gone offline",s):"away"===n?i=t("%1$s has gone away",s):"dnd"===n?i=t("%1$s is busy",s):"online"===n&&(i=t("%1$s is online",s)),i&&this.createMessage({message:i,type:"info"})},onScrolledChanged(){this.ui.get("scrolled")||(this.clearUnreadMsgCounter(),this.pruneHistoryWhenScrolledDown())},pruneHistoryWhenScrolledDown(){wd.settings.get("prune_messages_above")&&"unscrolled"===wd.settings.get("pruning_behavior")&&!this.ui.get("scrolled")&&Vm(this)},validate(e){if(!e.jid)return"Ignored ChatBox without JID";const t=wd.settings.get("auto_join_rooms").map((e=>y(e)?e.jid:e)),n=wd.settings.get("auto_join_private_chats").concat(t);if(wd.settings.get("singleton")&&!n.includes(e.jid)&&!wd.settings.get("auto_join_on_invite")){const t=`${e.jid} is not allowed because singleton is true and it's not being auto_joined`;return $l.warn(t),t}},getDisplayName(){return this.contact?this.contact.getDisplayName():this.vcard?this.vcard.getDisplayName():this.get("jid")},async createMessageFromError(e){if(e instanceof ed){(await this.createMessage({type:"error",message:e.message,retry_event_id:e.retry_event_id,is_ephemeral:3e4})).error=e}},editEarlierMessage(){let e,t=this.messages.findLastIndex("correcting");if(t>=0)for(this.messages.at(t).save("correcting",!1);t>0;){t-=1;const n=this.messages.at(t);if(n.get("editable")){e=n;break}}e=e||this.messages.filter({sender:"me"}).reverse().find((e=>e.get("editable"))),e&&e.save("correcting",!0)},editLaterMessage(){let e,t=this.messages.findLastIndex("correcting");if(t>=0)for(this.messages.at(t).save("correcting",!1);t=0;e--){const t=this.messages.at(e);if(t.get("type")===this.get("message_type"))return t}},getUpdatedMessageAttributes:(e,t)=>t.error_type||"Decryption"!==e.get("error_type")?{is_archived:t.is_archived}:Object.assign({},t,{error_condition:void 0,error_message:void 0,error_text:void 0,error_type:void 0,is_archived:t.is_archived,is_ephemeral:!1,is_error:!1}),updateMessage(e,t){const n=this.getUpdatedMessageAttributes(e,t);n&&e.save(n)},setChatState(e,t){return void 0!==this.chat_state_timeout&&(window.clearTimeout(this.chat_state_timeout),delete this.chat_state_timeout),e===Zl.COMPOSING?this.chat_state_timeout=window.setTimeout(this.setChatState.bind(this),Zl.TIMEOUTS.PAUSED,Zl.PAUSED):e===Zl.PAUSED&&(this.chat_state_timeout=window.setTimeout(this.setChatState.bind(this),Zl.TIMEOUTS.INACTIVE,Zl.INACTIVE)),this.set("chat_state",e,t),this},getMessageReferencedByError(e){const t=e.msgid;return t&&this.messages.models.find((e=>[e.get("msgid"),e.get("retraction_id")].includes(t)))},shouldShowErrorMessage(e){if(this.getMessageReferencedByError(e)||!e.chat_state)return!0},isSameUser:(e,t)=>zg.isSameBareJID(e,t),findDanglingRetraction(e){if(!e.origin_id||!this.messages.length)return null;if(this.messages.last().get("time")>e.time){const t=Array.from(this.messages.models);return t.reverse(),t.find((t=>{let{attributes:n}=t;return n.retracted_id===e.origin_id&&n.from===e.from&&!n.moderated_by}))}},async handleRetraction(e){const t=["retracted","retracted_id","editable"];if(e.retracted){if(e.is_tombstone)return!1;const n=this.messages.findWhere({origin_id:e.retracted_id,from:e.from});return n?(n.save(lr(e,t)),!0):(e.dangling_retraction=!0,await this.createMessage(e),!0)}{const n=this.findDanglingRetraction(e);if(n){const s=lr(n.attributes,t),i=Object.assign({dangling_retraction:!1},e,s);return delete i.id,n.save(i),!0}}return!1},getDuplicateMessage(e){const t=[...this.getStanzaIdQueryAttrs(e),this.getOriginIdQueryAttrs(e),this.getMessageBodyQueryAttrs(e)].filter((e=>e));return this.messages.models.find((e=>t.reduce(((t,n)=>t||qm(e.attributes,n)),!1)))},getOriginIdQueryAttrs:e=>e.origin_id&&{origin_id:e.origin_id,from:e.from},getStanzaIdQueryAttrs(e){const t=Object.keys(e).filter((e=>e.startsWith("stanza_id ")));return t.map((t=>{const n={};return n[`stanza_id ${t.replace(/^stanza_id /,"")}`]=e[t],n}))},getMessageBodyQueryAttrs(e){if(e.msgid){const t={from:e.from,msgid:e.msgid};return!e.is_encrypted&&e.body&&(t.body=e.body),t}},retractOwnMessage(e){this.sendRetractionMessage(e),e.save({retracted:(new Date).toISOString(),retracted_id:e.get("origin_id"),retraction_id:e.get("id"),is_ephemeral:!0,editable:!1})},sendRetractionMessage(e){const t=e.get("origin_id");if(!t)throw new Error("Can't retract message without a XEP-0359 Origin ID");const n=Dg({id:zg.getUniqueId(),to:this.get("jid"),type:"chat"}).c("store",{xmlns:Rg.NS.HINTS}).up().c("apply-to",{id:t,xmlns:Rg.NS.FASTEN}).c("retract",{xmlns:Rg.NS.RETRACT});return Zl.connection.send(n)},sendMarkerForLastMessage(){let e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:"displayed",t=arguments.length>1&&void 0!==arguments[1]&&arguments[1];const n=Array.from(this.messages.models);n.reverse();const s=n.find((e=>"them"===e.get("sender")&&(t||e.get("is_markable"))));s&&this.sendMarkerForMessage(s,e,t)},sendMarkerForMessage(e){let t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:"displayed",n=arguments.length>2&&void 0!==arguments[2]&&arguments[2];if(e&&wd.settings.get("send_chat_markers").includes(t)&&(e?.get("is_markable")||n)){Jm(Rg.getBareJidFromJid(e.get("from")),e.get("msgid"),t,e.get("type"))}},handleChatMarker(e){if(Rg.getBareJidFromJid(e.to)!==Zl.bare_jid)return!1;if(e.is_markable)return!this.contact||e.is_archived||e.is_carbon||Jm(e.from,e.msgid,"received"),!1;if(e.marker_id){const t=this.messages.findWhere({msgid:e.marker_id}),n=`marker_${e.marker}`;return t&&!t.get(n)&&t.save({field_name:(new Date).toISOString()}),!0}},sendReceiptStanza(e,t){const n=Dg({from:Zl.connection.jid,id:zg.getUniqueId(),to:e,type:"chat"}).c("received",{xmlns:Rg.NS.RECEIPTS,id:t}).up().c("store",{xmlns:Rg.NS.HINTS}).up();wd.send(n)},handleReceipt(e){if("them"===e.sender)if(e.is_valid_receipt_request)this.sendReceiptStanza(e.from,e.msgid);else if(e.receipt_id){const t=this.messages.findWhere({msgid:e.receipt_id});return t&&!t.get("received")&&t.save({received:(new Date).toISOString()}),!0}return!1},async createMessageStanza(e){const t=Dg({from:Zl.connection.jid,to:this.get("jid"),type:this.get("message_type"),id:e.get("edited")&&zg.getUniqueId()||e.get("msgid")}).c("body").t(e.get("body")).up().c(Zl.ACTIVE,{xmlns:Rg.NS.CHATSTATES}).root();"chat"===e.get("type")&&t.c("request",{xmlns:Rg.NS.RECEIPTS}).root(),e.get("is_encrypted")||(e.get("is_spoiler")&&(e.get("spoiler_hint")?t.c("spoiler",{xmlns:Rg.NS.SPOILER},e.get("spoiler_hint")).root():t.c("spoiler",{xmlns:Rg.NS.SPOILER}).root()),(e.get("references")||[]).forEach((e=>{const n={xmlns:Rg.NS.REFERENCE,begin:e.begin,end:e.end,type:e.type};e.uri&&(n.uri=e.uri),t.c("reference",n).root()})),e.get("oob_url")&&t.c("x",{xmlns:Rg.NS.OUTOFBAND}).c("url").t(e.get("oob_url")).root()),e.get("edited")&&t.c("replace",{xmlns:Rg.NS.MESSAGE_CORRECT,id:e.get("msgid")}).root(),e.get("origin_id")&&t.c("origin-id",{xmlns:Rg.NS.SID,id:e.get("origin_id")}).root(),t.root();return(await wd.hook("createMessageStanza",this,{message:e,stanza:t})).stanza},async getOutgoingMessageAttributes(e){await wd.emojis.initialize();const t=!!this.get("composing_spoiler"),n=zg.getUniqueId(),s=e?.body,i=s?zg.shortnamesToUnicode(s):void 0;return e=Object.assign({},e,{from:Zl.bare_jid,fullname:Zl.xmppstatus.get("fullname"),id:n,is_only_emojis:!!s&&zg.isOnlyEmojis(s),jid:this.get("jid"),message:i,msgid:n,nickname:this.get("nickname"),sender:"me",time:(new Date).toISOString(),type:this.get("message_type"),body:i,is_spoiler:t,origin_id:n},vg(s)),e=await wd.hook("getOutgoingMessageAttributes",this,e)},setEditable(e,t){e.is_headline||ol(e)||"me"!==e.sender||("all"===wd.settings.get("allow_message_corrections")?e.editable=!(e.file||e.retracted||"oob_url"in e):"last"===wd.settings.get("allow_message_corrections")&&t>this.get("time_sent")&&(this.set({time_sent:t}),this.messages.findWhere({editable:!0})?.save({editable:!1}),e.editable=!(e.file||e.retracted||"oob_url"in e)))},async createMessage(e,t){return e.time=e.time||(new Date).toISOString(),await this.messages.fetched,this.messages.create(e,t)},async sendMessage(e){e=await this.getOutgoingMessageAttributes(e);let t=this.messages.findWhere("correcting");if(t){const n=t.get("older_versions")||{};n[t.get("edited")||t.get("time")]=t.getMessageText(),t.save({...lr(e,["body","is_only_emojis","media_urls","references","is_encrypted"]),correcting:!1,edited:(new Date).toISOString(),message:e.body,ogp_metadata:[],origin_id:zg.getUniqueId(),received:void 0,older_versions:n,plaintext:e.is_encrypted?e.message:void 0})}else this.setEditable(e,(new Date).toISOString()),t=await this.createMessage(e);try{const e=await this.createMessageStanza(t);wd.send(e)}catch(e){return t.destroy(),void $l.error(e)}return wd.trigger("sendMessage",{chatbox:this,message:t}),t},sendChatState(){if(wd.settings.get("send_chat_state_notifications")&&this.get("chat_state")){const e=wd.settings.get("send_chat_state_notifications");if(Array.isArray(e)&&!e.includes(this.get("chat_state")))return;wd.send(Dg({id:zg.getUniqueId(),to:this.get("jid"),type:"chat"}).c(this.get("chat_state"),{xmlns:Rg.NS.CHATSTATES}).up().c("no-store",{xmlns:Rg.NS.HINTS}).up().c("no-permanent-store",{xmlns:Rg.NS.HINTS}))}},async sendFiles(e){const{__:t}=Zl,n=(await wd.disco.features.get(Rg.NS.HTTPUPLOAD,Zl.domain)).pop();if(!n)return void this.createMessage({message:t("Sorry, looks like file upload is not supported by your server."),type:"error",is_ephemeral:!0});const s=n.dataforms.where({FORM_TYPE:{value:Rg.NS.HTTPUPLOAD,type:"hidden"}}).pop(),i=window.parseInt((s?.attributes||{})["max-file-size"]?.value),r=n?.id;r?Array.from(e).forEach((async e=>{if(e=await wd.hook("beforeFileUpload",this,e),!window.isNaN(i)&&window.parseInt(e.size)>i)return this.createMessage({message:t("The size of your file, %1$s, exceeds the maximum allowed by your server, which is %2$s.",e.name,Gu(i)),type:"error",is_ephemeral:!0});{const t=await this.getOutgoingMessageAttributes(),n=Object.assign(t,{file:!0,progress:0,slot_request_url:r});this.setEditable(n,(new Date).toISOString());const s=await this.createMessage(n,{silent:!0});s.file=e,this.messages.trigger("add",s),s.getRequestSlotURL()}})):this.createMessage({message:t("Sorry, looks like file upload is not supported by your server."),type:"error",is_ephemeral:!0})},maybeShow(e){if(!al())return zg.safeSave(this,{hidden:!1}),this.trigger("show"),this;{const t=e=>!e.get("hidden")&&e.get("jid")!==this.get("jid")&&"controlbox"!==e.get("id"),n=Zl.chatboxes.filter(t);(e||0===n.length)&&(n.forEach((e=>zg.safeSave(e,{hidden:!0}))),zg.safeSave(this,{hidden:!1}))}},isHidden(){return this.get("hidden")||this.isScrolledUp()||"hidden"===Zl.windowState},handleUnreadMessage(e){e?.get("body")&&zg.isNewMessage(e)&&("me"===e.get("sender")?this.ui.set("scrolled",!1):this.isHidden()?this.incrementUnreadMsgsCounter(e):this.sendMarkerForMessage(e))},incrementUnreadMsgsCounter(e){const t={num_unread:this.get("num_unread")+1};0===this.get("num_unread")&&(t.first_unread_id=e.get("id")),this.save(t)},clearUnreadMsgCounter(){this.get("num_unread")>0&&this.sendMarkerForMessage(this.messages.last()),zg.safeSave(this,{num_unread:0})},isScrolledUp(){return this.ui.get("scrolled")}}),Lg=Pg,{Strophe:Fg,sizzle:Ug,u:Bg}=Fm.env,qg={defaults:()=>({msgid:Bg.getUniqueId(),time:(new Date).toISOString(),is_ephemeral:!1}),async initialize(){this.checkValidity()&&(this.initialized=Xo(),this.get("file")&&this.on("change:put",(()=>this.uploadFile())),this.on("change:type",(()=>this.setContact())),this.on("change:is_ephemeral",(()=>this.setTimerForEphemeralMessage())),await this.setContact(),this.setTimerForEphemeralMessage(),await wd.trigger("messageInitialized",this,{Synchronous:!0}),this.initialized.resolve())},setContact(){["chat","normal"].includes(this.get("type"))&&(Bm.prototype.initialize.apply(this,arguments),this.setRosterContact(Fg.getBareJidFromJid(this.get("from"))))},setTimerForEphemeralMessage(){this.ephemeral_timer&&clearTimeout(this.ephemeral_timer);const e=this.isEphemeral();if(e){const t="number"==typeof e?e:1e4;this.ephemeral_timer=window.setTimeout((()=>this.safeDestroy()),t)}},checkValidity(){return 3!==Object.keys(this.attributes).length||(this.validationError="Empty message",this.safeDestroy(),!1)},mayBeRetracted(){const e="me"===this.get("sender"),t="cancel"!==this.get("error_type");return e&&t&&["all","own"].includes(wd.settings.get("allow_message_retraction"))},safeDestroy(){try{this.destroy()}catch(e){$l.warn(`safeDestroy: ${e}`)}},isEphemeral(){return this.get("is_ephemeral")},isMeCommand(){const e=this.getMessageText();return!!e&&e.startsWith("/me ")},isFollowup(){const e=this.collection.models,t=e.indexOf(this),n=t?e[t-1]:null;if(null===n)return!1;const s=xd()(this.get("time"));return this.get("from")===n.get("from")&&!this.isMeCommand()&&!n.isMeCommand()&&!!this.get("is_encrypted")==!!n.get("is_encrypted")&&this.get("type")===n.get("type")&&"info"!==this.get("type")&&s.isBefore(xd()(n.get("time")).add(10,"minutes"))&&("groupchat"!==this.get("type")||this.get("occupant_id")===n.get("occupant_id"))},getDisplayName(){return this.contact?this.contact.getDisplayName():this.vcard?this.vcard.getDisplayName():this.get("from")},getMessageText(){if(this.get("is_encrypted")){const{__:e}=Zl;return this.get("plaintext")||this.get("body")||e("Undecryptable OMEMO message")}return["groupchat","chat","normal"].includes(this.get("type"))?this.get("body"):this.get("message")},sendSlotRequestStanza(){if(!this.file)return Promise.reject(new Error("file is undefined"));const e=Fm.env.$iq({from:Zl.jid,to:this.get("slot_request_url"),type:"get"}).c("request",{xmlns:Fg.NS.HTTPUPLOAD,filename:this.file.name,size:this.file.size,"content-type":this.file.type});return wd.sendIQ(e)},getUploadRequestMetadata:e=>({headers:Ug(`slot[xmlns="${Fg.NS.HTTPUPLOAD}"] put header`,e).map((e=>({name:e.getAttribute("name"),value:e.textContent}))).filter((e=>["Authorization","Expires"].includes(e.name)))}),async getRequestSlotURL(){const{__:e}=Zl;let t;try{t=await this.sendSlotRequestStanza()}catch(t){return $l.error(t),this.save({type:"error",message:e("Sorry, could not determine upload URL."),is_ephemeral:!0})}const n=Ug(`slot[xmlns="${Fg.NS.HTTPUPLOAD}"]`,t).pop();if(!n)return this.save({type:"error",message:e("Sorry, could not determine file upload URL."),is_ephemeral:!0});this.upload_metadata=this.getUploadRequestMetadata(t),this.save({get:n.querySelector("get").getAttribute("url"),put:n.querySelector("put").getAttribute("url")})},uploadFile(){const e=new XMLHttpRequest;e.onreadystatechange=async()=>{if(e.readyState===XMLHttpRequest.DONE)if($l.info("Status: "+e.status),200===e.status||201===e.status){let e={upload:Zl.SUCCESS,oob_url:this.get("get"),message:this.get("get"),body:this.get("get")};e=await wd.hook("afterFileUploaded",this,e),this.save(e)}else e.onerror()},e.upload.addEventListener("progress",(e=>{e.lengthComputable&&this.set("progress",e.loaded/e.total)}),!1),e.onerror=()=>{const{__:t}=Zl;let n;n=e.responseText?t('Sorry, could not succesfully upload your file. Your server’s response: "%1$s"',e.responseText):t("Sorry, could not succesfully upload your file."),this.save({type:"error",upload:Zl.FAILURE,message:n,is_ephemeral:!0})},e.open("PUT",this.get("put"),!0),e.setRequestHeader("Content-type",this.file.type),this.upload_metadata.headers?.forEach((t=>e.setRequestHeader(t.name,t.value))),e.send(this.file)}},Hg=qg,Gg={chats:{async create(e,t){if("string"==typeof e){if(t&&!t?.fullname){const n=await wd.contacts.get(e);t.fullname=n?.attributes?.fullname}const n=wd.chats.get(e,t,!0);return n||void $l.error("Could not open chatbox for JID: "+e)}return Array.isArray(e)?Promise.all(e.forEach((async n=>{const s=await wd.contacts.get(e);return t.fullname=s?.attributes?.fullname,wd.chats.get(n,t,!0).maybeShow()}))):($l.error("chats.create: You need to provide at least one JID"),null)},async open(e,t,n){if("string"==typeof e){const s=await wd.chats.get(e,t,!0);return s?s.maybeShow(n):s}if(Array.isArray(e))return Promise.all(e.map((e=>wd.chats.get(e,t,!0).then((e=>e&&e.maybeShow(n))))).filter((e=>e)));const s="chats.open: You need to provide at least one JID";throw $l.error(s),new Error(s)},async get(e){let t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},n=arguments.length>2&&void 0!==arguments[2]&&arguments[2];async function s(e){let s=await wd.chatboxes.get(e);return!s&&n?s=await wd.chatboxes.create(e,t,Zl.ChatBox):(s=s&&s.get("type")===Zl.PRIVATE_CHAT_TYPE?s:null,s&&Object.keys(t).length&&s.save(t)),s}if(await wd.waitUntil("chatBoxesFetched"),void 0===e){return(await wd.chatboxes.get()).filter((e=>e.get("type")===Zl.PRIVATE_CHAT_TYPE))}return"string"==typeof e?s(e):Promise.all(e.map((e=>s(e))))}}},{Strophe:Wg,u:Vg}=Fm.env;function Zg(e){if(!Vg.isValidJID(e))return $l.warn(`Invalid JID "${e}" provided in URL fragment`);wd.chats.open(e)}async function Qg(){if(cl()){await Promise.all(Zl.chatboxes.map((e=>e.messages&&e.messages.clearStore({silent:!0}))));const e=e=>e.get("type")!==Zl.CONTROLBOX_TYPE;Zl.chatboxes.clearStore({silent:!0},e)}}function Jg(){wd.settings.get("auto_join_private_chats").forEach((e=>{Zl.chatboxes.where({jid:e}).length||("string"==typeof e?wd.chats.open(e):$l.error('Invalid jid criteria specified for "auto_join_private_chats"'))})),wd.trigger("privateChatsAutoJoined")}function Kg(){Zl.connection.addHandler((e=>!!(["groupchat","error"].includes(e.getAttribute("type"))||kg(e)||jg(e)||Tg(e))||(Zl.handleMessageStanza(e)||!0)),null,"message"),Zl.connection.addHandler((e=>async function(e){const t=Wg.getBareJidFromJid(e.getAttribute("from"));if(Vg.isSameBareJID(t,Zl.bare_jid))return;const n=await wd.chatboxes.get(t);n?.get("type")===Zl.PRIVATE_CHAT_TYPE&&n?.handleErrorMessageStanza(e)}(e)||!0),null,"message","error")}async function Yg(e){if(jg(e=e.tree?.()??e)){const t=e.getAttribute("from");return $l.info(`handleMessageStanza: Ignoring incoming server message from JID: ${t}`)}let t;try{t=await Og(e)}catch(e){return $l.error(e)}if(Vg.isErrorObject(t))return t.stanza&&$l.error(t.stanza),$l.error(t.message);const n=!(!t.body&&!t.plaintext),s=await wd.chats.get(t.contact_jid,{nickname:t.nick},n);await(s?.queueMessage(t));const i={stanza:e,attrs:t,chatbox:s};wd.trigger("message",i)}async function Xg(){const e=Wg.getDomainFromJid(Zl.bare_jid);if(!await wd.disco.supports(Wg.NS.CARBONS,e))return void $l.warn("Not enabling carbons because it's not supported!");const t=new Wg.Builder("iq",{from:Zl.connection.jid,type:"set"}).c("enable",{xmlns:Wg.NS.CARBONS}),n=await wd.sendIQ(t,null,!1);null===n?$l.warn("A timeout occurred while trying to enable carbons"):Vg.isErrorStanza(n)?($l.warn("An error occurred while trying to enable message carbons."),$l.error(n)):$l.debug("Message carbons have been enabled.")}Fm.plugins.add("converse-chat",{dependencies:["converse-chatboxes","converse-disco"],initialize(){wd.settings.extend({allow_message_corrections:"all",allow_message_retraction:"all",allow_message_styling:!0,auto_join_private_chats:[],clear_messages_on_reconnection:!1,filter_by_resource:!1,prune_messages_above:void 0,pruning_behavior:"unscrolled",send_chat_markers:["received","displayed","acknowledged"],send_chat_state_notifications:!0}),Zl.Message=Bm.extend(Hg),Zl.Messages=gu.extend({model:Zl.Message,comparator:"time"}),Object.assign(Zl,{ChatBox:Lg,handleMessageStanza:Yg}),Object.assign(wd,Gg),Zl.router.route("converse/chat?jid=:jid",Zg),wd.listen.on("chatBoxesFetched",Jg),wd.listen.on("presencesInitialized",Kg),wd.listen.on("clearSession",Qg),wd.listen.on("connected",(()=>Xg())),wd.listen.on("reconnected",(()=>Xg()))}});const{Strophe:ef}=Fm.env,tf=dr.extend({idAttribute:"jid",initialize(e,t){this.waitUntilFeaturesDiscovered=Xo(),this.dataforms=new gu;let n=`converse.dataforms-${this.get("jid")}`;this.dataforms.browserStorage=Zl.createStore(n,"session"),this.features=new gu,n=`converse.features-${this.get("jid")}`,this.features.browserStorage=Zl.createStore(n,"session"),this.listenTo(this.features,"add",this.onFeatureAdded),this.fields=new gu,n=`converse.fields-${this.get("jid")}`,this.fields.browserStorage=Zl.createStore(n,"session"),this.listenTo(this.fields,"add",this.onFieldAdded),this.identities=new gu,n=`converse.identities-${this.get("jid")}`,this.identities.browserStorage=Zl.createStore(n,"session"),this.fetchFeatures(t)},async getIdentity(e,t){return await this.waitUntilFeaturesDiscovered,this.identities.findWhere({category:e,type:t})},async getFeature(e){if(await this.waitUntilFeaturesDiscovered,this.features.findWhere({var:e}))return this},onFeatureAdded(e){e.entity=this,wd.trigger("serviceDiscovered",e)},onFieldAdded(e){e.entity=this,wd.trigger("discoExtensionFieldDiscovered",e)},async fetchFeatures(e){if(e.ignore_cache)this.queryInfo();else{const e=this.features.browserStorage.name,t=await this.features.browserStorage.store.getItem(e);t&&0===t.length||null===t?this.queryInfo():(this.features.fetch({add:!0,success:()=>{this.waitUntilFeaturesDiscovered.resolve(this),this.trigger("featuresDiscovered")}}),this.identities.fetch({add:!0}))}},async queryInfo(){let e;try{e=await wd.disco.info(this.get("jid"),null)}catch(e){return null===e?$l.error(`Timeout for disco#info query for ${this.get("jid")}`):$l.error(e),void this.waitUntilFeaturesDiscovered.resolve(this)}this.onInfo(e)},onDiscoItems(e){Yo()(`query[xmlns="${ef.NS.DISCO_ITEMS}"] item`,e).forEach((e=>{if(e.getAttribute("node"))return;const t=e.getAttribute("jid"),n=Zl.disco_entities.get(t);n?n.set({parent_jids:[this.get("jid")]}):wd.disco.entities.create({jid:t,parent_jids:[this.get("jid")],name:e.getAttribute("name")})}))},async queryForItems(){if(0===this.identities.where({category:"server"}).length)return;const e=await wd.disco.items(this.get("jid"));this.onDiscoItems(e)},async onInfo(e){Array.from(e.querySelectorAll("identity")).forEach((e=>{this.identities.create({category:e.getAttribute("category"),type:e.getAttribute("type"),name:e.getAttribute("name")})})),Yo()(`x[type="result"][xmlns="${ef.NS.XFORM}"]`,e).forEach((e=>{const t={};Yo()("field",e).forEach((e=>{t[e.getAttribute("var")]={value:e.querySelector("value")?.textContent,type:e.getAttribute("type")}})),this.dataforms.create(t)})),e.querySelector(`feature[var="${ef.NS.DISCO_ITEMS}"]`)&&await this.queryForItems(),Array.from(e.querySelectorAll("feature")).forEach((t=>{this.features.create({var:t.getAttribute("var"),from:e.getAttribute("from")})})),Yo()('x[type="result"][xmlns="jabber:x:data"] field',e).forEach((t=>{this.fields.create({var:t.getAttribute("var"),value:t.querySelector("value")?.textContent,from:e.getAttribute("from")})})),this.waitUntilFeaturesDiscovered.resolve(this),this.trigger("featuresDiscovered")}}),nf=tf,sf=gu.extend({model:nf,fetchEntities(){return new Promise(((e,t)=>{this.fetch({add:!0,success:e,error(e,n){$l.error(n),t(new Error("Could not fetch disco entities"))}})}))}}),rf=sf,{Strophe:of,$iq:af}=Fm.env;async function cf(){wd.disco.own.identities.add("client","web","Converse"),wd.disco.own.features.add(of.NS.CHATSTATES),wd.disco.own.features.add(of.NS.DISCO_INFO),wd.disco.own.features.add(of.NS.ROSTERX),wd.disco.own.features.add(of.NS.CARBONS),wd.trigger("addClientFeatures"),Zl.connection.addHandler((e=>function(e){const t=e.getElementsByTagName("query")[0].getAttribute("node"),n={xmlns:of.NS.DISCO_INFO};t&&(n.node=t);const s=af({type:"result",id:e.getAttribute("id")}),i=e.getAttribute("from");return null!==i&&s.attrs({to:i}),s.c("query",n),Zl.disco._identities.forEach((e=>{const t={category:e.category,type:e.type};e.name&&(t.name=e.name),e.lang&&(t["xml:lang"]=e.lang),s.c("identity",t).up()})),Zl.disco._features.forEach((e=>s.c("feature",{var:e}).up())),wd.send(s.tree()),!0}(e)),of.NS.DISCO_INFO,"iq","get",null,null),Zl.disco_entities=new Zl.DiscoEntities;const e=`converse.disco-entities-${Zl.bare_jid}`;Zl.disco_entities.browserStorage=Zl.createStore(e,"session");const t=await Zl.disco_entities.fetchEntities();0!==t.length&&t.get(Zl.domain)||wd.disco.entities.create({jid:Zl.domain},{ignore_cache:!0}),wd.trigger("discoInitialized")}function lf(){if(!Zl.stream_features){const e=`converse.stream-features-${of.getBareJidFromJid(Zl.jid)}`;wd.promises.add("streamFeaturesAdded"),Zl.stream_features=new gu,Zl.stream_features.browserStorage=Zl.createStore(e,"session")}}function df(){wd.trigger("streamFeaturesAdded")}function uf(){lf(),Array.from(Zl.connection.features.childNodes).forEach((e=>{Zl.stream_features.create({name:e.nodeName,xmlns:e.getAttribute("xmlns")})})),df()}function hf(){Zl.disco_entities?.forEach((e=>e.features.clearStore())),Zl.disco_entities?.forEach((e=>e.identities.clearStore())),Zl.disco_entities?.forEach((e=>e.dataforms.clearStore())),Zl.disco_entities?.forEach((e=>e.fields.clearStore())),Zl.disco_entities?.clearStore(),delete Zl.disco_entities}const{Strophe:mf,$iq:gf}=Fm.env,ff={disco:{stream:{async getFeature(e,t){if(await wd.waitUntil("streamFeaturesAdded"),!e||!t)throw new Error("name and xmlns need to be provided when calling disco.stream.getFeature");if(void 0!==Zl.stream_features||wd.connection.connected())return Zl.stream_features.findWhere({name:e,xmlns:t});{const n=`Tried to get feature ${e} ${t} but _converse.stream_features has been torn down`;$l.warn(n)}}},own:{identities:{add(e,t,n,s){for(var i=0;iZl.disco._identities},features:{add(e){for(var t=0;tZl.disco._features}},info(e,t){const n={xmlns:mf.NS.DISCO_INFO};t&&(n.node=t);const s=gf({from:Zl.connection.jid,to:e,type:"get"}).c("query",n);return wd.sendIQ(s)},items(e,t){const n={xmlns:mf.NS.DISCO_ITEMS};return t&&(n.node=t),wd.sendIQ(gf({from:Zl.connection.jid,to:e,type:"get"}).c("query",n))},entities:{async get(e){let t=arguments.length>1&&void 0!==arguments[1]&&arguments[1];if(await wd.waitUntil("discoInitialized"),!e)return Zl.disco_entities;if(void 0===Zl.disco_entities)return void $l.warn(`Tried to look up entity ${e} but _converse.disco_entities has been torn down`);const n=Zl.disco_entities.get(e);return n||!t?n:wd.disco.entities.create({jid:e})},items:e=>Zl.disco_entities.filter((t=>t.get("parent_jids")?.includes(e))),create:(e,t)=>Zl.disco_entities.create(e,t)},features:{async get(e,t){if(!t)throw new TypeError("You need to provide an entity JID");const n=await wd.disco.entities.get(t,!0);if(void 0===Zl.disco_entities&&!wd.connection.connected())return $l.warn(`Tried to get feature ${e} for ${t} but _converse.disco_entities has been torn down`),[];const s=[n.getFeature(e),...wd.disco.entities.items(t).map((t=>t.getFeature(e)))];return(await Promise.all(s)).filter(y)},async has(e,t){if(!t)throw new TypeError("You need to provide an entity JID");const n=await wd.disco.entities.get(t,!0);if(void 0===Zl.disco_entities&&!wd.connection.connected())return $l.warn(`Tried to check if ${t} supports feature ${e}`),!1;if(await n.getFeature(e))return!0;const s=await Promise.all(wd.disco.entities.items(t).map((t=>t.getFeature(e))));return s.map(y).includes(!0)}},supports:(e,t)=>wd.disco.features.has(e,t),async refresh(e){if(!e)throw new TypeError("api.disco.refresh: You need to provide an entity JID");await wd.waitUntil("discoInitialized");let t=await wd.disco.entities.get(e);return t?(t.features.reset(),t.fields.reset(),t.identities.reset(),t.waitUntilFeaturesDiscovered.isPending||(t.waitUntilFeaturesDiscovered=Xo()),t.queryInfo()):t=await wd.disco.entities.create({jid:e},{ignore_cache:!0}),t.waitUntilFeaturesDiscovered},refreshFeatures:e=>wd.refresh(e),async getFeatures(e){if(!e)throw new TypeError("api.disco.getFeatures: You need to provide an entity JID");await wd.waitUntil("discoInitialized");let t=await wd.disco.entities.get(e,!0);return t=await t.waitUntilFeaturesDiscovered,t.features},async getFields(e){if(!e)throw new TypeError("api.disco.getFields: You need to provide an entity JID");await wd.waitUntil("discoInitialized");let t=await wd.disco.entities.get(e,!0);return t=await t.waitUntilFeaturesDiscovered,t.fields},async getIdentity(e,t,n){const s=await wd.disco.entities.get(n,!0);if(void 0!==s||wd.connection.connected())return s.getIdentity(e,t);{const t=`Tried to look up category ${e} for ${n} but _converse.disco_entities has been torn down`;$l.warn(t)}}}},{Strophe:pf}=Fm.env;Fm.plugins.add("converse-disco",{initialize(){Object.assign(wd,ff),wd.promises.add("discoInitialized"),wd.promises.add("streamFeaturesAdded"),Zl.DiscoEntity=nf,Zl.DiscoEntities=rf,Zl.disco={_identities:[],_features:[]},wd.listen.on("userSessionInitialized",(async()=>{lf(),Zl.connfeedback.get("connection_status")===pf.Status.ATTACHED&&(await new Promise(((e,t)=>Zl.stream_features.fetch({success:e,error:t}))),df())})),wd.listen.on("beforeResourceBinding",uf),wd.listen.on("reconnected",cf),wd.listen.on("connected",cf),wd.listen.on("beforeTearDown",(async()=>{wd.promises.add("streamFeaturesAdded"),Zl.stream_features&&(await Zl.stream_features.clearStore(),delete Zl.stream_features)})),wd.listen.on("will-reconnect",hf),wd.listen.on("clearSession",hf)}});const vf=new RegExp("]*>.*?|]*>.*?|<(?:object|embed|svg|img|div|span|p|a)[^>]*>|((\\s|^)(\\*\\\\0\\/\\*|\\*\\\\O\\/\\*|\\-___\\-|\\:'\\-\\)|'\\:\\-\\)|'\\:\\-D|\\>\\:\\-\\)|>\\:\\-\\)|'\\:\\-\\(|\\>\\:\\-\\(|>\\:\\-\\(|\\:'\\-\\(|O\\:\\-\\)|0\\:\\-3|0\\:\\-\\)|0;\\^\\)|O;\\-\\)|0;\\-\\)|O\\:\\-3|\\-__\\-|\\:\\-Þ|\\:\\-Þ|\\<\\/3|<\\/3|\\:'\\)|\\:\\-D|'\\:\\)|'\\=\\)|'\\:D|'\\=D|\\>\\:\\)|>\\:\\)|\\>;\\)|>;\\)|\\>\\=\\)|>\\=\\)|;\\-\\)|\\*\\-\\)|;\\-\\]|;\\^\\)|'\\:\\(|'\\=\\(|\\:\\-\\*|\\:\\^\\*|\\>\\:P|>\\:P|X\\-P|\\>\\:\\[|>\\:\\[|\\:\\-\\(|\\:\\-\\[|\\>\\:\\(|>\\:\\(|\\:'\\(|;\\-\\(|\\>\\.\\<|>\\.<|#\\-\\)|%\\-\\)|X\\-\\)|\\\\0\\/|\\\\O\\/|0\\:3|0\\:\\)|O\\:\\)|O\\=\\)|O\\:3|B\\-\\)|8\\-\\)|B\\-D|8\\-D|\\-_\\-|\\>\\:\\\\|>\\:\\\\|\\>\\:\\/|>\\:\\/|\\:\\-\\/|\\:\\-\\.|\\:\\-P|\\:Þ|\\:Þ|\\:\\-b|\\:\\-O|O_O|\\>\\:O|>\\:O|\\:\\-X|\\:\\-#|\\:\\-\\)|\\(y\\)|\\<3|<3|\\:D|\\=D|;\\)|\\*\\)|;\\]|;D|\\:\\*|\\=\\*|\\:\\(|\\:\\[|\\=\\(|\\:@|;\\(|D\\:|\\:\\$|\\=\\$|#\\)|%\\)|X\\)|B\\)|8\\)|\\:\\/|\\:\\\\|\\=\\/|\\=\\\\|\\:L|\\=L|\\:P|\\=P|\\:b|\\:O|\\:X|\\:#|\\=X|\\=#|\\:\\)|\\=\\]|\\=\\)|\\:\\])(?=\\s|$|[!,.?]))","gi"),yf=/(?:\ud83d\udc68\ud83c\udffb\u200d\ud83e\udd1d\u200d\ud83d\udc68\ud83c[\udffc-\udfff]|\ud83d\udc68\ud83c\udffc\u200d\ud83e\udd1d\u200d\ud83d\udc68\ud83c[\udffb\udffd-\udfff]|\ud83d\udc68\ud83c\udffd\u200d\ud83e\udd1d\u200d\ud83d\udc68\ud83c[\udffb\udffc\udffe\udfff]|\ud83d\udc68\ud83c\udffe\u200d\ud83e\udd1d\u200d\ud83d\udc68\ud83c[\udffb-\udffd\udfff]|\ud83d\udc68\ud83c\udfff\u200d\ud83e\udd1d\u200d\ud83d\udc68\ud83c[\udffb-\udffe]|\ud83d\udc69\ud83c\udffb\u200d\ud83e\udd1d\u200d\ud83d\udc68\ud83c[\udffc-\udfff]|\ud83d\udc69\ud83c\udffb\u200d\ud83e\udd1d\u200d\ud83d\udc69\ud83c[\udffc-\udfff]|\ud83d\udc69\ud83c\udffc\u200d\ud83e\udd1d\u200d\ud83d\udc68\ud83c[\udffb\udffd-\udfff]|\ud83d\udc69\ud83c\udffc\u200d\ud83e\udd1d\u200d\ud83d\udc69\ud83c[\udffb\udffd-\udfff]|\ud83d\udc69\ud83c\udffd\u200d\ud83e\udd1d\u200d\ud83d\udc68\ud83c[\udffb\udffc\udffe\udfff]|\ud83d\udc69\ud83c\udffd\u200d\ud83e\udd1d\u200d\ud83d\udc69\ud83c[\udffb\udffc\udffe\udfff]|\ud83d\udc69\ud83c\udffe\u200d\ud83e\udd1d\u200d\ud83d\udc68\ud83c[\udffb-\udffd\udfff]|\ud83d\udc69\ud83c\udffe\u200d\ud83e\udd1d\u200d\ud83d\udc69\ud83c[\udffb-\udffd\udfff]|\ud83d\udc69\ud83c\udfff\u200d\ud83e\udd1d\u200d\ud83d\udc68\ud83c[\udffb-\udffe]|\ud83d\udc69\ud83c\udfff\u200d\ud83e\udd1d\u200d\ud83d\udc69\ud83c[\udffb-\udffe]|\ud83e\uddd1\ud83c\udffb\u200d\ud83e\udd1d\u200d\ud83e\uddd1\ud83c[\udffb-\udfff]|\ud83e\uddd1\ud83c\udffc\u200d\ud83e\udd1d\u200d\ud83e\uddd1\ud83c[\udffb-\udfff]|\ud83e\uddd1\ud83c\udffd\u200d\ud83e\udd1d\u200d\ud83e\uddd1\ud83c[\udffb-\udfff]|\ud83e\uddd1\ud83c\udffe\u200d\ud83e\udd1d\u200d\ud83e\uddd1\ud83c[\udffb-\udfff]|\ud83e\uddd1\ud83c\udfff\u200d\ud83e\udd1d\u200d\ud83e\uddd1\ud83c[\udffb-\udfff]|\ud83e\uddd1\u200d\ud83e\udd1d\u200d\ud83e\uddd1|\ud83d\udc6b\ud83c[\udffb-\udfff]|\ud83d\udc6c\ud83c[\udffb-\udfff]|\ud83d\udc6d\ud83c[\udffb-\udfff]|\ud83d[\udc6b-\udc6d])|(?:\ud83d[\udc68\udc69]|\ud83e\uddd1)(?:\ud83c[\udffb-\udfff])?\u200d(?:\u2695\ufe0f|\u2696\ufe0f|\u2708\ufe0f|\ud83c[\udf3e\udf73\udf93\udfa4\udfa8\udfeb\udfed]|\ud83d[\udcbb\udcbc\udd27\udd2c\ude80\ude92]|\ud83e[\uddaf-\uddb3\uddbc\uddbd])|(?:\ud83c[\udfcb\udfcc]|\ud83d[\udd74\udd75]|\u26f9)((?:\ud83c[\udffb-\udfff]|\ufe0f)\u200d[\u2640\u2642]\ufe0f)|(?:\ud83c[\udfc3\udfc4\udfca]|\ud83d[\udc6e\udc71\udc73\udc77\udc81\udc82\udc86\udc87\ude45-\ude47\ude4b\ude4d\ude4e\udea3\udeb4-\udeb6]|\ud83e[\udd26\udd35\udd37-\udd39\udd3d\udd3e\uddb8\uddb9\uddcd-\uddcf\uddd6-\udddd])(?:\ud83c[\udffb-\udfff])?\u200d[\u2640\u2642]\ufe0f|(?:\ud83d\udc68\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d\udc68|\ud83d\udc68\u200d\ud83d\udc68\u200d\ud83d\udc66\u200d\ud83d\udc66|\ud83d\udc68\u200d\ud83d\udc68\u200d\ud83d\udc67\u200d\ud83d[\udc66\udc67]|\ud83d\udc68\u200d\ud83d\udc69\u200d\ud83d\udc66\u200d\ud83d\udc66|\ud83d\udc68\u200d\ud83d\udc69\u200d\ud83d\udc67\u200d\ud83d[\udc66\udc67]|\ud83d\udc69\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d[\udc68\udc69]|\ud83d\udc69\u200d\ud83d\udc69\u200d\ud83d\udc66\u200d\ud83d\udc66|\ud83d\udc69\u200d\ud83d\udc69\u200d\ud83d\udc67\u200d\ud83d[\udc66\udc67]|\ud83d\udc68\u200d\u2764\ufe0f\u200d\ud83d\udc68|\ud83d\udc68\u200d\ud83d\udc66\u200d\ud83d\udc66|\ud83d\udc68\u200d\ud83d\udc67\u200d\ud83d[\udc66\udc67]|\ud83d\udc68\u200d\ud83d\udc68\u200d\ud83d[\udc66\udc67]|\ud83d\udc68\u200d\ud83d\udc69\u200d\ud83d[\udc66\udc67]|\ud83d\udc69\u200d\u2764\ufe0f\u200d\ud83d[\udc68\udc69]|\ud83d\udc69\u200d\ud83d\udc66\u200d\ud83d\udc66|\ud83d\udc69\u200d\ud83d\udc67\u200d\ud83d[\udc66\udc67]|\ud83d\udc69\u200d\ud83d\udc69\u200d\ud83d[\udc66\udc67]|\ud83c\udff3\ufe0f\u200d\u26a7\ufe0f|\ud83c\udff3\ufe0f\u200d\ud83c\udf08|\ud83c\udff4\u200d\u2620\ufe0f|\ud83d\udc15\u200d\ud83e\uddba|\ud83d\udc41\u200d\ud83d\udde8|\ud83d\udc68\u200d\ud83d[\udc66\udc67]|\ud83d\udc69\u200d\ud83d[\udc66\udc67]|\ud83d\udc6f\u200d\u2640\ufe0f|\ud83d\udc6f\u200d\u2642\ufe0f|\ud83e\udd3c\u200d\u2640\ufe0f|\ud83e\udd3c\u200d\u2642\ufe0f|\ud83e\uddde\u200d\u2640\ufe0f|\ud83e\uddde\u200d\u2642\ufe0f|\ud83e\udddf\u200d\u2640\ufe0f|\ud83e\udddf\u200d\u2642\ufe0f)|[#*0-9]\ufe0f?\u20e3|(?:[©®\u2122\u265f]\ufe0f)|(?:\ud83c[\udc04\udd70\udd71\udd7e\udd7f\ude02\ude1a\ude2f\ude37\udf21\udf24-\udf2c\udf36\udf7d\udf96\udf97\udf99-\udf9b\udf9e\udf9f\udfcd\udfce\udfd4-\udfdf\udff3\udff5\udff7]|\ud83d[\udc3f\udc41\udcfd\udd49\udd4a\udd6f\udd70\udd73\udd76-\udd79\udd87\udd8a-\udd8d\udda5\udda8\uddb1\uddb2\uddbc\uddc2-\uddc4\uddd1-\uddd3\udddc-\uddde\udde1\udde3\udde8\uddef\uddf3\uddfa\udecb\udecd-\udecf\udee0-\udee5\udee9\udef0\udef3]|[\u203c\u2049\u2139\u2194-\u2199\u21a9\u21aa\u231a\u231b\u2328\u23cf\u23ed-\u23ef\u23f1\u23f2\u23f8-\u23fa\u24c2\u25aa\u25ab\u25b6\u25c0\u25fb-\u25fe\u2600-\u2604\u260e\u2611\u2614\u2615\u2618\u2620\u2622\u2623\u2626\u262a\u262e\u262f\u2638-\u263a\u2640\u2642\u2648-\u2653\u2660\u2663\u2665\u2666\u2668\u267b\u267f\u2692-\u2697\u2699\u269b\u269c\u26a0\u26a1\u26a7\u26aa\u26ab\u26b0\u26b1\u26bd\u26be\u26c4\u26c5\u26c8\u26cf\u26d1\u26d3\u26d4\u26e9\u26ea\u26f0-\u26f5\u26f8\u26fa\u26fd\u2702\u2708\u2709\u270f\u2712\u2714\u2716\u271d\u2721\u2733\u2734\u2744\u2747\u2757\u2763\u2764\u27a1\u2934\u2935\u2b05-\u2b07\u2b1b\u2b1c\u2b50\u2b55\u3030\u303d\u3297\u3299])(?:\ufe0f|(?!\ufe0e))|(?:(?:\ud83c[\udfcb\udfcc]|\ud83d[\udd74\udd75\udd90]|[\u261d\u26f7\u26f9\u270c\u270d])(?:\ufe0f|(?!\ufe0e))|(?:\ud83c[\udf85\udfc2-\udfc4\udfc7\udfca]|\ud83d[\udc42\udc43\udc46-\udc50\udc66-\udc69\udc6e\udc70-\udc78\udc7c\udc81-\udc83\udc85-\udc87\udcaa\udd7a\udd95\udd96\ude45-\ude47\ude4b-\ude4f\udea3\udeb4-\udeb6\udec0\udecc]|\ud83e[\udd0f\udd18-\udd1c\udd1e\udd1f\udd26\udd30-\udd39\udd3d\udd3e\uddb5\uddb6\uddb8\uddb9\uddbb\uddcd-\uddcf\uddd1-\udddd]|[\u270a\u270b]))(?:\ud83c[\udffb-\udfff])?|(?:\ud83c\udff4\udb40\udc67\udb40\udc62\udb40\udc65\udb40\udc6e\udb40\udc67\udb40\udc7f|\ud83c\udff4\udb40\udc67\udb40\udc62\udb40\udc73\udb40\udc63\udb40\udc74\udb40\udc7f|\ud83c\udff4\udb40\udc67\udb40\udc62\udb40\udc77\udb40\udc6c\udb40\udc73\udb40\udc7f|\ud83c\udde6\ud83c[\udde8-\uddec\uddee\uddf1\uddf2\uddf4\uddf6-\uddfa\uddfc\uddfd\uddff]|\ud83c\udde7\ud83c[\udde6\udde7\udde9-\uddef\uddf1-\uddf4\uddf6-\uddf9\uddfb\uddfc\uddfe\uddff]|\ud83c\udde8\ud83c[\udde6\udde8\udde9\uddeb-\uddee\uddf0-\uddf5\uddf7\uddfa-\uddff]|\ud83c\udde9\ud83c[\uddea\uddec\uddef\uddf0\uddf2\uddf4\uddff]|\ud83c\uddea\ud83c[\udde6\udde8\uddea\uddec\udded\uddf7-\uddfa]|\ud83c\uddeb\ud83c[\uddee-\uddf0\uddf2\uddf4\uddf7]|\ud83c\uddec\ud83c[\udde6\udde7\udde9-\uddee\uddf1-\uddf3\uddf5-\uddfa\uddfc\uddfe]|\ud83c\udded\ud83c[\uddf0\uddf2\uddf3\uddf7\uddf9\uddfa]|\ud83c\uddee\ud83c[\udde8-\uddea\uddf1-\uddf4\uddf6-\uddf9]|\ud83c\uddef\ud83c[\uddea\uddf2\uddf4\uddf5]|\ud83c\uddf0\ud83c[\uddea\uddec-\uddee\uddf2\uddf3\uddf5\uddf7\uddfc\uddfe\uddff]|\ud83c\uddf1\ud83c[\udde6-\udde8\uddee\uddf0\uddf7-\uddfb\uddfe]|\ud83c\uddf2\ud83c[\udde6\udde8-\udded\uddf0-\uddff]|\ud83c\uddf3\ud83c[\udde6\udde8\uddea-\uddec\uddee\uddf1\uddf4\uddf5\uddf7\uddfa\uddff]|\ud83c\uddf4\ud83c\uddf2|\ud83c\uddf5\ud83c[\udde6\uddea-\udded\uddf0-\uddf3\uddf7-\uddf9\uddfc\uddfe]|\ud83c\uddf6\ud83c\udde6|\ud83c\uddf7\ud83c[\uddea\uddf4\uddf8\uddfa\uddfc]|\ud83c\uddf8\ud83c[\udde6-\uddea\uddec-\uddf4\uddf7-\uddf9\uddfb\uddfd-\uddff]|\ud83c\uddf9\ud83c[\udde6\udde8\udde9\uddeb-\udded\uddef-\uddf4\uddf7\uddf9\uddfb\uddfc\uddff]|\ud83c\uddfa\ud83c[\udde6\uddec\uddf2\uddf3\uddf8\uddfe\uddff]|\ud83c\uddfb\ud83c[\udde6\udde8\uddea\uddec\uddee\uddf3\uddfa]|\ud83c\uddfc\ud83c[\uddeb\uddf8]|\ud83c\uddfd\ud83c\uddf0|\ud83c\uddfe\ud83c[\uddea\uddf9]|\ud83c\uddff\ud83c[\udde6\uddf2\uddfc]|\ud83c[\udccf\udd8e\udd91-\udd9a\udde6-\uddff\ude01\ude32-\ude36\ude38-\ude3a\ude50\ude51\udf00-\udf20\udf2d-\udf35\udf37-\udf7c\udf7e-\udf84\udf86-\udf93\udfa0-\udfc1\udfc5\udfc6\udfc8\udfc9\udfcf-\udfd3\udfe0-\udff0\udff4\udff8-\udfff]|\ud83d[\udc00-\udc3e\udc40\udc44\udc45\udc51-\udc65\udc6a\udc6f\udc79-\udc7b\udc7d-\udc80\udc84\udc88-\udca9\udcab-\udcfc\udcff-\udd3d\udd4b-\udd4e\udd50-\udd67\udda4\uddfb-\ude44\ude48-\ude4a\ude80-\udea2\udea4-\udeb3\udeb7-\udebf\udec1-\udec5\uded0-\uded2\uded5\udeeb\udeec\udef4-\udefa\udfe0-\udfeb]|\ud83e[\udd0d\udd0e\udd10-\udd17\udd1d\udd20-\udd25\udd27-\udd2f\udd3a\udd3c\udd3f-\udd45\udd47-\udd71\udd73-\udd76\udd7a-\udda2\udda5-\uddaa\uddae-\uddb4\uddb7\uddba\uddbc-\uddca\uddd0\uddde-\uddff\ude70-\ude73\ude78-\ude7a\ude80-\ude82\ude90-\ude95]|[\u23e9-\u23ec\u23f0\u23f3\u267e\u26ce\u2705\u2728\u274c\u274e\u2753-\u2755\u2795-\u2797\u27b0\u27bf\ue50a])|\ufe0f/g,{u:_f}=Fm.env,bf={},wf={"*\\0/*":"1f646","*\\O/*":"1f646","-___-":"1f611",":'-)":"1f602","':-)":"1f605","':-D":"1f605",">:-)":"1f606","':-(":"1f613",">:-(":"1f620",":'-(":"1f622","O:-)":"1f607","0:-3":"1f607","0:-)":"1f607","0;^)":"1f607","O;-)":"1f607","0;-)":"1f607","O:-3":"1f607","-__-":"1f611",":-Þ":"1f61b",":)":"1f606",">;)":"1f606",">=)":"1f606",";-)":"1f609","*-)":"1f609",";-]":"1f609",";^)":"1f609","':(":"1f613","'=(":"1f613",":-*":"1f618",":^*":"1f618",">:P":"1f61c","X-P":"1f61c",">:[":"1f61e",":-(":"1f61e",":-[":"1f61e",">:(":"1f620",":'(":"1f622",";-(":"1f622",">.<":"1f623","#-)":"1f635","%-)":"1f635","X-)":"1f635","\\0/":"1f646","\\O/":"1f646","0:3":"1f607","0:)":"1f607","O:)":"1f607","O=)":"1f607","O:3":"1f607","B-)":"1f60e","8-)":"1f60e","B-D":"1f60e","8-D":"1f60e","-_-":"1f611",">:\\":"1f615",">:/":"1f615",":-/":"1f615",":-.":"1f615",":-P":"1f61b",":Þ":"1f61b",":-b":"1f61b",":-O":"1f62e",O_O:"1f62e",">:O":"1f62e",":-X":"1f636",":-#":"1f636",":-)":"1f642","(y)":"1f44d","<3":"2764",":D":"1f603","=D":"1f603",";)":"1f609","*)":"1f609",";]":"1f609",";D":"1f609",":*":"1f618","=*":"1f618",":(":"1f61e",":[":"1f61e","=(":"1f61e",":@":"1f620",";(":"1f622","D:":"1f628",":$":"1f633","=$":"1f633","#)":"1f635","%)":"1f635","X)":"1f635","B)":"1f60e","8)":"1f60e",":/":"1f615",":\\":"1f615","=/":"1f615","=\\":"1f615",":L":"1f615","=L":"1f615",":P":"1f61b","=P":"1f61b",":b":"1f61b",":O":"1f62e",":X":"1f636",":#":"1f636","=X":"1f636","=#":"1f636",":)":"1f642","=]":"1f642","=)":"1f642",":]":"1f642"};function Sf(e){if(e.indexOf("-")>-1){const t=[],n=e.split("-");for(let e=0;e=65536&&s<=1114111){const e=Math.floor((s-65536)/1024)+55296,t=(s-65536)%1024+56320;s=String.fromCharCode(e)+String.fromCharCode(t)}else s=String.fromCharCode(s);t.push(s)}return t.join("")}return function(e){let t="string"==typeof e?parseInt(e,16):e;return t<65536?String.fromCharCode(t):(t-=65536,String.fromCharCode(55296+(t>>10),56320+(1023&t)))}(e)}function xf(e){return e.replace(vf,((e,t,n,s)=>{if(void 0===s||""===s||!(_f.unescapeHTML(s)in wf))return e;s=_f.unescapeHTML(s);return n+Sf(wf[s].toUpperCase())}))}function Af(e){if(!Fm.emojis.initialized)throw new Error("getShortnameReferences called before emojis are initialized. To avoid this problem, first await the converse.emojis.initialized_promise");return[...e.matchAll(Fm.emojis.shortnames_regex)].filter((e=>e[0].length>0)).map((e=>{const t=Fm.emojis.by_sn[e[0]].cp;return{cp:t,begin:e.index,end:e.index+e[0].length,shortname:e[0],emoji:t?Sf(t):null}}))}function Ef(e){const t=[];return function(e,t){const n=/\uFE0F/g,s=String.fromCharCode(8205);String(e).replace(yf,((e,i,r)=>{const o=function(e){const t=[];let n=0,s=0;for(;s{t.push({begin:s,cp:e,emoji:n,end:s+n.length,shortname:$f("cp")[e]?.sn||""})})),t}function $f(e){if(bf[e])return bf[e];if("category"===e)return Fm.emojis.json;const t=Fm.emojis.list.map((t=>t[e])).filter(((e,t,n)=>n.indexOf(e)==t));return bf[e]={},t.forEach((t=>bf[e][t]=Fm.emojis.list.find((n=>n[e]===t)))),bf[e]}Object.assign(_f,{getEmojisByAtrribute:$f,isOnlyEmojis:function(e){const t=e.trim().split(/\s+/);if(0===t.length||t.length>3)return!1;return t.filter((e=>{const t=Ef(_f.shortnamesToUnicode(e));return 1===t.length&&(e===t[0].shortname||e===t[0].emoji)})).length===t.length},shortnamesToUnicode:function(e){return function(e){let t=[e];return[...Af(e),...Ef(e)].sort(((e,t)=>t.begin-e.begin)).forEach((e=>{const n=t.shift(),s=e.emoji||e.shortname;t=[n.slice(0,e.begin)+s+n.slice(e.end),...t]})),t}(xf(e)).pop()}}),Fm.emojis={initialized:!1,initialized_promise:Xo()},Fm.plugins.add("converse-emoji",{initialize(){const{___:e}=Zl;wd.settings.extend({emoji_image_path:"https://twemoji.maxcdn.com/v/12.1.6/",emoji_categories:{smileys:":grinning:",people:":thumbsup:",activity:":soccer:",travel:":motorcycle:",objects:":bomb:",nature:":rainbow:",food:":hotdog:",symbols:":musical_note:",flags:":flag_ac:",custom:null},emoji_category_labels:{smileys:e("Smileys and emotions"),people:e("People"),activity:e("Activities"),travel:e("Travel"),objects:e("Objects"),nature:e("Animals and nature"),food:e("Food and drink"),symbols:e("Symbols"),flags:e("Flags"),custom:e("Stickers")}}),Zl.EmojiPicker=dr.extend({defaults:{current_category:"smileys",current_skintone:"",scroll_position:0}}),Object.assign(wd,{emojis:{async initialize(){if(!Fm.emojis.initialized){Fm.emojis.initialized=!0;const e=await n.e(4610).then(n.t.bind(n,5175,19)),t=Fm.emojis.json=e.default;Fm.emojis.by_sn=Object.keys(t).reduce(((e,n)=>Object.assign(e,t[n])),{}),Fm.emojis.list=Object.values(Fm.emojis.by_sn),Fm.emojis.list.sort(((e,t)=>e.snt.sn?1:0)),Fm.emojis.shortnames=Fm.emojis.list.map((e=>e.sn));const s=()=>Fm.emojis.shortnames.map((e=>e.replace(/[+]/g,"\\$&"))).join("|");Fm.emojis.shortnames_regex=new RegExp(s(),"gi"),Fm.emojis.initialized_promise.resolve()}return Fm.emojis.initialized_promise}}})}});const Cf={initialize(){this.checkValidity()&&(this.get("file")&&this.on("change:put",(()=>this.uploadFile())),this.on("change:type",(()=>this.setOccupant())),this.on("change:is_ephemeral",(()=>this.setTimerForEphemeralMessage())),this.chatbox=this.collection?.chatbox,this.setTimerForEphemeralMessage(),this.setOccupant(),wd.trigger("chatRoomMessageInitialized",this))},getDisplayName(){return this.occupant?.getDisplayName()||this.get("nick")},mayBeModerated(){if(void 0!==this.get("from_muc"))return["all","moderator"].includes(wd.settings.get("allow_message_retraction"))&&this.get(`stanza_id ${this.get("from_muc")}`)&&this.chatbox.canModerateMessages()},checkValidity(){const e=Zl.Message.prototype.checkValidity.call(this);return!e&&this.chatbox.debouncedRejoin(),e},onOccupantRemoved(){this.stopListening(this.occupant),delete this.occupant,this.listenTo(this.chatbox.occupants,"add",this.onOccupantAdded)},onOccupantAdded(e){if(this.get("occupant_id")){if(e.get("occupant_id")!==this.get("occupant_id"))return}else if(e.get("nick")!==Oo.getResourceFromJid(this.get("from")))return;this.occupant=e,e.get("jid")&&this.save("from_real_jid",e.get("jid")),this.trigger("occupantAdded"),this.listenTo(this.occupant,"destroy",this.onOccupantRemoved),this.stopListening(this.chatbox.occupants,"add",this.onOccupantAdded)},getOccupant(){return this.occupant||this.setOccupant(),this.occupant},setOccupant(){if("groupchat"!==this.get("type")||this.isEphemeral()||this.occupant)return;const e=Oo.getResourceFromJid(this.get("from")),t=this.get("occupant_id");if(this.occupant=this.chatbox.occupants.findOccupant({nick:e,occupant_id:t}),!this.occupant&&(this.occupant=this.chatbox.occupants.create({nick:e,occupant_id:t,jid:this.get("from_real_jid")}),wd.settings.get("muc_send_probes"))){const t=`${this.chatbox.get("jid")}/${e}`;wd.user.presence.send("probe",t)}this.listenTo(this.occupant,"destroy",this.onOccupantRemoved)}},kf=Cf;const jf=function(e){return B(e)&&1===e.nodeType&&!Ki(e)},Tf={},If=(e,t)=>e.replace(RegExp("\\"+t,"ig"),"\\"+t);Tf.escapeCharacters=e=>t=>e.split("").reduce(If,t),Tf.escapeRegexString=Tf.escapeCharacters("[\\^$.?*+(){}|"),Tf.findFirstMatchInArray=e=>t=>{for(let n=0;n{let[s,i]=e,r=s,{begin:o,end:a}=t;const{value:c}=t;return o-=n,a=a-n-1,r=`${r.slice(0,o)}${c}${r.slice(a+1)}`,[r,[...i,{...t,begin:o,end:a}]]};Tf.reduceTextFromReferences=(e,t)=>t.reduce(Nf,[e,[]]);const Mf=Tf,Of=["moderator","participant","visitor"],Rf=["owner","admin","member","outcast","none"],Df={moderator:1,participant:2,visitor:3,none:2},zf={OWNER:"owner",ADMIN:"admin",MEMBER:"member",EXADMIN:"exadmin",EXOWNER:"exowner",EXOUTCAST:"exoutcast",EXMEMBER:"exmember"},Pf=Object.values(zf),Lf={ENTERED:"entered",EXITED:"exited"},Ff=Object.values(Lf),Uf={OP:"op",DEOP:"deop",VOICE:"voice",MUTE:"mute"},Bf=Object.values(Uf),qf={visibility_changes:["100","102","103","172","173","174"],self:["110"],non_privacy_changes:["104","201"],muc_logging_changes:["170","171"],nickname_changes:["210","303"],disconnected:["301","307","321","322","332","333"],affiliation_changes:[...Pf],join_leave_events:[...Ff],role_changes:[...Bf]},Hf={CONNECTED:0,CONNECTING:1,NICKNAME_REQUIRED:2,PASSWORD_REQUIRED:3,DISCONNECTED:4,ENTERED:5,DESTROYED:6,BANNED:7,CLOSING:8},{Strophe:Gf,sizzle:Wf,u:Vf}=Fm.env,{NS:Zf}=Gf;function Qf(e){const t=Wf(`items[node="${Gf.NS.CONFINFO}"]`,e).pop();if(!t)return null;const n=e.getAttribute("from"),s=e.getAttribute("id"),i=`item conference-info[xmlns="${Gf.NS.CONFINFO}"] activity[xmlns="${Gf.NS.ACTIVITY}"]`;return Wf(i,t).map((t=>{const i=t.querySelector("text")?.textContent;if(i){const r=wg(e),o=t.querySelector("reason")?.textContent;return{from:n,msgid:s,message:i,reason:o,references:r,type:"mep"}}return{}}))}function Jf(e,t){if(t.features.get(Gf.NS.OCCUPANTID))return Wf(`occupant-id[xmlns="${Gf.NS.OCCUPANTID}"]`,e).pop()?.getAttribute("id")}function Kf(e,t){let n;const s=t.get("occupant_id");return n=s?e.occupant_id===s:e.from_real_jid?Gf.getBareJidFromJid(e.from_real_jid)===Zl.bare_jid:e.nick===t.get("nick"),n?"me":"them"}async function Yf(e,t){$g(e);const n=`[xmlns="${Zf.MAM}"] > forwarded[xmlns="${Zf.FORWARD}"] > message`,s=e;if(e=Wf(n,e).pop()||e,Wf(`message > forwarded[xmlns="${Gf.NS.FORWARD}"]`,e).length)return new hg(`Invalid Stanza: Forged MAM groupchat message from ${e.getAttribute("from")}`,e);const i=Wf(`delay[xmlns="${Gf.NS.DELAY}"]`,s).pop(),r=e.getAttribute("from"),o=Cg(e);let a=Object.assign({from:r,activities:Qf(e),body:e.querySelector(":scope > body")?.textContent?.trim(),chat_state:Ag(e),from_muc:Gf.getBareJidFromJid(r),is_archived:Tg(s),is_carbon:xg(s),is_delayed:!!i,is_forwarded:!!e.querySelector("forwarded"),is_headline:kg(e),is_markable:!!Wf(`markable[xmlns="${Gf.NS.MARKERS}"]`,e).length,is_marker:!!o,is_unstyled:!!Wf(`unstyled[xmlns="${Gf.NS.STYLING}"]`,e).length,marker_id:o&&o.getAttribute("id"),msgid:e.getAttribute("id")||s.getAttribute("id"),nick:Gf.unescapeNode(Gf.getResourceFromJid(r)),occupant_id:Jf(e,t),receipt_id:Sg(e),received:(new Date).toISOString(),references:wg(e),subject:e.querySelector("subject")?.textContent,thread:e.querySelector("thread")?.textContent,time:i?xd()(i.getAttribute("stamp")).toISOString():(new Date).toISOString(),to:e.getAttribute("to"),type:e.getAttribute("type")},bg(e),_g(e),yg(e),pg(e,s),mg(e,s),function(e){const t=Yo()(`> apply-to[xmlns="${Oo.NS.FASTEN}"]`,e).pop();if(t){const e=t.getAttribute("id"),n=Yo()(`> meta[xmlns="${Oo.NS.XHTML}"]`,t);if(n.length){const t=wd.settings.get("message_limit"),s=n.reduce(((e,n)=>{const s=n.getAttribute("property");if(s){let i=wl(n.getAttribute("content")||"");t&&"og:description"===s&&i.length>=t&&(i=`${i.slice(0,t)}${wl("…")}`),e[s]=i}return e}),{ogp_for_id:e});if("og:description"in s||"og:title"in s||"og:image"in s)return s}}return{}}(e),fg(e,s),function(e){const t=Wf(`apply-to[xmlns="${Gf.NS.FASTEN}"]`,e).pop();if(t){const e=t.getAttribute("id"),n=Wf(`moderated[xmlns="${Gf.NS.MODERATE}"]`,t).pop();if(n&&Wf(`retract[xmlns="${Gf.NS.RETRACT}"]`,n).pop())return{editable:!1,moderated:"retracted",moderated_by:n.getAttribute("by"),moderated_id:e,moderation_reason:n.querySelector("reason")?.textContent}}else{const t=Wf(`> moderated[xmlns="${Gf.NS.MODERATE}"]`,e).pop();if(t&&Wf(`retracted[xmlns="${Gf.NS.RETRACT}"]`,t).pop())return{editable:!1,is_tombstone:!0,moderated_by:t.getAttribute("by"),retracted:t.getAttribute("stamp"),moderation_reason:t.querySelector("reason")?.textContent}}return{}}(e),gg(e));return await wd.emojis.initialize(),a.from_real_jid=a.is_archived&&function(e){const t=Wf(`x[xmlns="${Gf.NS.MUC_USER}"] item`,e).pop();return t?.getAttribute("jid")}(e)||t.occupants.findOccupant(a)?.get("jid"),a=Object.assign({is_only_emojis:!!a.body&&Vf.isOnlyEmojis(a.body),is_valid_receipt_request:Eg(e,a),message:a.body||a.error,sender:Kf(a,t)},a),a.is_archived&&s.getAttribute("from")!==a.from_muc?new hg(`Invalid Stanza: Forged MAM message from ${s.getAttribute("from")}`,e):a.is_archived&&s.getAttribute("from")!==t.get("jid")?new hg(`Invalid Stanza: Forged MAM groupchat message from ${e.getAttribute("from")}`,e):a.is_carbon?new hg("Invalid Stanza: MUC messages SHOULD NOT be XEP-0280 carbon copied",e):(a.id=a.origin_id||a[`stanza_id ${a.from_muc||a.from}`]||Vf.getUniqueId(),a=await wd.hook("parseMUCMessage",e,a),Object.assign(a,vg(a.is_encrypted?a.plaintext:a.body)))}const{Strophe:Xf,$iq:ep,u:tp}=Fm.env;async function np(e,t){const{__:n}=Zl,s=ep({to:t,type:"get"}).c("query",{xmlns:Xf.NS.MUC_ADMIN}).c("item",{affiliation:e}),i=await wd.sendIQ(s,null,!1);if(null===i){const s=n("Error: timeout while fetching %1s list for MUC %2s",e,t),i=new Error(s);return $l.warn(s),i}if(tp.isErrorStanza(i)){const s=n("Error: not allowed to fetch %1s list for MUC %2s",e,t),r=new Error(s);return $l.warn(s),$l.warn(i),r}return function(e){return Wf(`query[xmlns="${Gf.NS.MUC_ADMIN}"] item`,e).map((e=>{const t={affiliation:e.getAttribute("affiliation")},n=e.getAttribute("jid");Vf.isValidJID(n)?t.jid=n:t.nick=n;const s=e.getAttribute("nick");return s&&(t.nick=s),e.getAttribute("role")&&(t.role=s),t}))}(i).filter((e=>e)).sort(((e,t)=>e.nickt.nick?1:0))}function sp(e){let t=wd.settings.get("modtools_disable_assign");return Array.isArray(t)||(t=t?Fp:[]),"owner"===e?.get("affiliation")?Fp.filter((e=>!t.includes(e))):"admin"===e?.get("affiliation")?Fp.filter((e=>!["owner","admin",...t].includes(e))):[]}function ip(e,t){const n=[...new Set(t.map((e=>e.affiliation)))];return Promise.all(n.map((n=>rp(n,e,t))))}function rp(e,t,n){return Array.isArray(t)||(t=[t]),n=n.filter((t=>[void 0,e].includes(t.affiliation))),Promise.all(t.reduce(((t,s)=>[...t,...n.map((t=>function(e,t,n){const s=ep({to:t,type:"set"}).c("query",{xmlns:Xf.NS.MUC_ADMIN}).c("item",{affiliation:n.affiliation||e,nick:n.nick,jid:n.jid});void 0!==n.reason&&s.c("reason",n.reason);return wd.sendIQ(s)}(e,s,t)))]),[]))}function op(e,t,n,s){const i=n.map((e=>e.jid)),r=s.map((e=>e.jid));let o=Fd(i,r).map((e=>n[Xd(i,e)]));return e||(o=o.concat(n.filter((e=>{const t=Xd(r,e.jid);return t>=0&&e.affiliation!==s[t].affiliation})))),t&&(o=o.concat(Fd(r,i).map((e=>({jid:e,affiliation:"none"}))))),o}Zl.getAssignableAffiliations=sp;const{u:ap}=Fm.env,cp=["owner"],lp=["admin","ban","deop","destroy","member","op","revoke"],dp=["kick","mute","voice","modtools"],up=["nick"],hp=["og:article:author","og:article:published_time","og:description","og:image","og:image:height","og:image:width","og:site_name","og:title","og:type","og:url","og:video:height","og:video:secure_url","og:video:tag","og:video:type","og:video:url","og:video:width"],mp=["301","303","333","307","321","322"],gp=dr.extend({defaults:()=>({connection_status:Hf.DISCONNECTED})}),fp={defaults(){return{bookmarked:!1,chat_state:void 0,has_activity:!1,hidden:al()&&!wd.settings.get("singleton"),hidden_occupants:!!wd.settings.get("hide_muc_participants"),message_type:"groupchat",name:"",num_unread_general:0,num_unread:0,roomconfig:{},time_opened:this.get("time_opened")||(new Date).getTime(),time_sent:new Date(0).toISOString(),type:Zl.CHATROOMS_TYPE}},async initialize(){this.initialized=Xo(),this.debouncedRejoin=rd(this.rejoin,250),this.set("box_id",`box-${this.get("jid")}`),this.initNotifications(),this.initMessages(),this.initUI(),this.initOccupants(),this.initDiscoModels(),this.registerHandlers(),this.on("change:chat_state",this.sendChatState,this),this.on("change:hidden",this.onHiddenChange,this),this.on("destroy",this.removeHandlers,this),this.ui.on("change:scrolled",this.onScrolledChanged,this),await this.restoreSession(),this.session.on("change:connection_status",this.onConnectionStatusChanged,this),this.listenTo(this.occupants,"add",this.onOccupantAdded),this.listenTo(this.occupants,"remove",this.onOccupantRemoved),this.listenTo(this.occupants,"change:show",this.onOccupantShowChanged),this.listenTo(this.occupants,"change:affiliation",this.createAffiliationChangeMessage),this.listenTo(this.occupants,"change:role",this.createRoleChangeMessage);await this.restoreFromCache()||this.join(),await wd.trigger("chatRoomInitialized",this,{Synchronous:!0}),this.initialized.resolve()},isEntered(){return this.session.get("connection_status")===Hf.ENTERED},isRAICandidate(){return this.get("hidden")&&wd.settings.get("muc_subscribe_to_rai")&&"none"!==this.getOwnAffiliation()},async restoreFromCache(){if(this.isEntered()){if(await this.fetchOccupants().catch((e=>$l.error(e))),this.isRAICandidate())return this.session.save("connection_status",Hf.DISCONNECTED),this.enableRAI(),!0;if(await this.isJoined())return await new Promise((e=>this.config.fetch({success:e,error:e}))),await new Promise((e=>this.features.fetch({success:e,error:e}))),await this.fetchMessages().catch((e=>$l.error(e))),!0}return this.session.save("connection_status",Hf.DISCONNECTED),this.clearOccupantsCache(),!1},async join(e,t){return this.isEntered()?this:(this.session.save("connection_status",Hf.CONNECTING),await this.refreshDiscoInfo(),(e=await this.getAndPersistNickname(e))?(wd.send(await this.constructJoinPresence(t)),this):(gl(this.session,{connection_status:Hf.NICKNAME_REQUIRED}),wd.settings.get("muc_show_logs_before_join")&&await this.fetchMessages(),this))},rejoin(){return this.session.save("connection_status",Hf.DISCONNECTED),this.registerHandlers(),this.clearOccupantsCache(),this.join()},async constructJoinPresence(e){let t=io({id:pl(),from:Zl.connection.jid,to:this.getRoomJIDAndNick()}).c("x",{xmlns:Oo.NS.MUC}).c("history",{maxstanzas:this.features.get("mam_enabled")?0:wd.settings.get("muc_history_max_stanzas")}).up();return(e=e||this.get("password"))&&t.cnode(Oo.xmlElement("password",[],e)),t.up(),t=await wd.hook("constructedMUCPresence",this,t),t},clearOccupantsCache(){this.occupants.length?this.occupants.filter((e=>!e.isMember())).forEach((e=>e.destroy())):this.occupants.clearStore()},sendMarkerForMessage(e){let t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:"displayed",n=arguments.length>2&&void 0!==arguments[2]&&arguments[2];if(e&&wd.settings.get("send_chat_markers").includes(t)&&"groupchat"===e?.get("type")&&(e?.get("is_markable")||n)){const n=`stanza_id ${this.get("jid")}`,s=e.get(n);if(!s)return void $l.error(`Can't send marker for message without stanza ID: ${n}`);Jm(Oo.getBareJidFromJid(e.get("from")),s,t,e.get("type"))}},enableRAI(){if(wd.settings.get("muc_subscribe_to_rai")){const e=Oo.getDomainFromJid(this.get("jid"));wd.user.presence.send(null,e,null,to("rai",{xmlns:Oo.NS.RAI}))}},async onHiddenChange(){const e=Hf,t=this.session.get("connection_status");this.get("hidden")?t===e.ENTERED&&this.isRAICandidate()&&(this.sendMarkerForLastMessage("received",!0),await this.leave(),this.enableRAI()):(t===e.DISCONNECTED&&this.rejoin(),this.clearUnreadMsgCounter())},onOccupantAdded(e){Zl.isInfoVisible(Fm.MUC_TRAFFIC_STATES.ENTERED)&&this.session.get("connection_status")===Hf.ENTERED&&"online"===e.get("show")&&this.updateNotifications(e.get("nick"),Fm.MUC_TRAFFIC_STATES.ENTERED)},onOccupantRemoved(e){Zl.isInfoVisible(Fm.MUC_TRAFFIC_STATES.EXITED)&&this.isEntered()&&"online"===e.get("show")&&this.updateNotifications(e.get("nick"),Fm.MUC_TRAFFIC_STATES.EXITED)},onOccupantShowChanged(e){e.get("states").includes("303")||("offline"===e.get("show")&&Zl.isInfoVisible(Fm.MUC_TRAFFIC_STATES.EXITED)?this.updateNotifications(e.get("nick"),Fm.MUC_TRAFFIC_STATES.EXITED):"online"===e.get("show")&&Zl.isInfoVisible(Fm.MUC_TRAFFIC_STATES.ENTERED)&&this.updateNotifications(e.get("nick"),Fm.MUC_TRAFFIC_STATES.ENTERED))},async onRoomEntered(){await this.occupants.fetchMembers(),wd.settings.get("clear_messages_on_reconnection")?await this.clearMessages():await this.fetchMessages(),wd.trigger("enteredNewRoom",this),wd.settings.get("auto_register_muc_nickname")&&await wd.disco.supports(Oo.NS.MUC_REGISTER,this.get("jid"))&&this.registerNickname()},async onConnectionStatusChanged(){if(this.isEntered())if(this.isRAICandidate()){try{await this.leave()}catch(e){$l.error(e)}this.enableRAI()}else await this.onRoomEntered()},async onReconnection(){await this.rejoin(),this.announceReconnection()},getMessagesCollection:()=>new Zl.ChatRoomMessages,restoreSession(){const e=`muc.session-${Zl.bare_jid}-${this.get("jid")}`;return this.session=new gp({id:e}),Gc(this.session,e,"session"),new Promise((e=>this.session.fetch({success:e,error:e})))},initDiscoModels(){let e=`converse.muc-features-${Zl.bare_jid}-${this.get("jid")}`;this.features=new dr(Object.assign({id:e},Fm.ROOM_FEATURES.reduce(((e,t)=>(e[t]=!1,e)),{}))),this.features.browserStorage=Zl.createStore(e,"session"),this.features.listenTo(Zl,"beforeLogout",(()=>this.features.browserStorage.flush())),e=`converse.muc-config-${Zl.bare_jid}-${this.get("jid")}`,this.config=new dr({id:e}),this.config.browserStorage=Zl.createStore(e,"session"),this.config.listenTo(Zl,"beforeLogout",(()=>this.config.browserStorage.flush()))},initOccupants(){this.occupants=new Zl.ChatRoomOccupants;const e=`converse.occupants-${Zl.bare_jid}${this.get("jid")}`;this.occupants.browserStorage=Zl.createStore(e,"session"),this.occupants.chatroom=this,this.occupants.listenTo(Zl,"beforeLogout",(()=>this.occupants.browserStorage.flush()))},fetchOccupants(){return this.occupants.fetched=new Promise((e=>{this.occupants.fetch({add:!0,silent:!0,success:e,error:e})})),this.occupants.fetched},handleAffiliationChangedMessage(e){const t=Yo()(`x[xmlns="${Oo.NS.MUC_USER}"] item`,e).pop();if(t){const n=e.getAttribute("from"),s=e.getAttribute("type"),i=t.getAttribute("affiliation"),r=t.getAttribute("jid"),o={from:n,type:s,affiliation:i,states:[],show:"unavailable"==s?"offline":"online",role:t.getAttribute("role"),jid:Oo.getBareJidFromJid(r),resource:Oo.getResourceFromJid(r)},a=this.occupants.findOccupant({jid:o.jid});a?a.save(o):this.occupants.create(o)}},async handleErrorMessageStanza(e){const{__:t}=Zl,n=await Yf(e,this);if(!await this.shouldShowErrorMessage(n))return;const s=this.getMessageReferencedByError(n);if(s){const e={error:n.error,error_condition:n.error_condition,error_text:n.error_text,error_type:n.error_type,editable:!1};n.msgid===s.get("retraction_id")?(e.retracted=void 0,e.retraction_id=void 0,e.retracted_id=void 0,n.error||("forbidden"===n.error_condition?e.error=t("You're not allowed to retract your message."):"not-acceptable"===n.error_condition?e.error=t("Your retraction was not delivered because you're not present in the groupchat."):e.error=t("Sorry, an error occurred while trying to retract your message."))):n.error||("forbidden"===n.error_condition?e.error=t("Your message was not delivered because you weren't allowed to send it."):"not-acceptable"===n.error_condition?e.error=t("Your message was not delivered because you're not present in the groupchat."):e.error=t("Sorry, an error occurred while trying to send your message.")),s.save(e)}else this.createMessage(n)},handleMessageFromMUCHost(e){if(this.isEntered())return;const t=Yo()(`rai[xmlns="${Oo.NS.RAI}"]`,e).pop(),n=Array.from(t?.querySelectorAll("activity")||[]).map((e=>e.textContent));n.includes(this.get("jid"))&&this.save({has_activity:!0,num_unread_general:0})},handleForwardedMentions(e){if(this.isEntered())return;const t=Yo()(`mentions[xmlns="${Oo.NS.MENTIONS}"] forwarded[xmlns="${Oo.NS.FORWARD}"] message[type="groupchat"]`,e),n=this.get("jid"),s=t.filter((e=>Oo.getBareJidFromJid(e.getAttribute("from"))===n));s.length&&(this.save({has_activity:!0,num_unread:this.get("num_unread")+s.length}),s.forEach((async e=>{const t={stanza:e,attrs:await Yf(e,this),chatbox:this};wd.trigger("message",t)})))},async handleMessageStanza(e){const t=(e=e.tree?.()??e).getAttribute("type");if("error"===t)return this.handleErrorMessageStanza(e);if("groupchat"===t){if(Tg(e))return $l.warn('Received a MAM message with type "groupchat"');this.createInfoMessages(e),this.fetchFeaturesIfConfigurationChanged(e)}else if(!t)return this.handleForwardedMentions(e);let n;try{n=await Yf(e,this)}catch(e){return $l.error(e)}const s={stanza:e,attrs:n,chatbox:this};return wd.trigger("message",s),n&&this.queueMessage(n)},registerHandlers(){const e=this.get("jid"),t=Oo.getDomainFromJid(e);this.removeHandlers(),this.presence_handler=Zl.connection.addHandler((e=>this.onPresence(e)||!0),null,"presence",null,null,e,{ignoreNamespaceFragment:!0,matchBareFromJid:!0}),this.domain_presence_handler=Zl.connection.addHandler((e=>this.onPresenceFromMUCHost(e)||!0),null,"presence",null,null,t),this.message_handler=Zl.connection.addHandler((e=>!!this.handleMessageStanza(e)||!0),null,"message",null,null,e,{matchBareFromJid:!0}),this.domain_message_handler=Zl.connection.addHandler((e=>this.handleMessageFromMUCHost(e)||!0),null,"message",null,null,t),this.affiliation_message_handler=Zl.connection.addHandler((e=>this.handleAffiliationChangedMessage(e)||!0),Oo.NS.MUC_USER,"message",null,null,e)},removeHandlers(){return this.message_handler&&(Zl.connection&&Zl.connection.deleteHandler(this.message_handler),delete this.message_handler),this.domain_message_handler&&(Zl.connection&&Zl.connection.deleteHandler(this.domain_message_handler),delete this.domain_message_handler),this.presence_handler&&(Zl.connection&&Zl.connection.deleteHandler(this.presence_handler),delete this.presence_handler),this.domain_presence_handler&&(Zl.connection&&Zl.connection.deleteHandler(this.domain_presence_handler),delete this.domain_presence_handler),this.affiliation_message_handler&&(Zl.connection&&Zl.connection.deleteHandler(this.affiliation_message_handler),delete this.affiliation_message_handler),this},invitesAllowed(){return wd.settings.get("allow_muc_invitations")&&(this.features.get("open")||"owner"===this.getOwnAffiliation())},getDisplayName(){const e=this.get("name");return e||("hidden"===wd.settings.get("locked_muc_domain")?Oo.getNodeFromJid(this.get("jid")):this.get("jid"))},sendTimedMessage(e){"function"==typeof e.tree&&(e=e.tree());let t=e.getAttribute("id");t||(t=this.getUniqueId("sendIQ"),e.setAttribute("id",t));const n=Xo(),s=wd.settings.get("stanza_timeout"),i=Zl.connection.addTimedHandler(s,(()=>{Zl.connection.deleteHandler(r);const e=new ed("Timeout Error: No response from server");return n.resolve(e),!1})),r=Zl.connection.addHandler((e=>{i&&Zl.connection.deleteTimedHandler(i),n.resolve(e)}),null,"message",["error","groupchat"],t);return wd.send(e),n},async retractOwnMessage(e){const t=Zl.__,n=e.get("origin_id");if(!n)throw new Error("Can't retract message without a XEP-0359 Origin ID");const s=e.get("editable"),i=no({id:pl(),to:this.get("jid"),type:"groupchat"}).c("store",{xmlns:Oo.NS.HINTS}).up().c("apply-to",{id:n,xmlns:Oo.NS.FASTEN}).c("retract",{xmlns:Oo.NS.RETRACT});e.set({retracted:(new Date).toISOString(),retracted_id:n,retraction_id:i.tree().getAttribute("id"),editable:!1});const r=await this.sendTimedMessage(i);ap.isErrorStanza(r)?$l.error(r):r instanceof ed&&($l.error(r),e.save({editable:s,error_type:"timeout",error:t("A timeout happened while while trying to retract your message."),retracted:void 0,retracted_id:void 0,retraction_id:void 0}))},async retractOtherMessage(e,t){const n=e.get("editable");e.save({moderated:"retracted",moderated_by:Zl.bare_jid,moderated_id:e.get("msgid"),moderation_reason:t,editable:!1});const s=await this.sendRetractionIQ(e,t);return(null===s||ap.isErrorStanza(s))&&e.save({editable:n,moderated:void 0,moderated_by:void 0,moderated_id:void 0,moderation_reason:void 0}),s},sendRetractionIQ(e,t){const n=so({to:this.get("jid"),type:"set"}).c("apply-to",{id:e.get(`stanza_id ${this.get("jid")}`),xmlns:Oo.NS.FASTEN}).c("moderate",{xmlns:Oo.NS.MODERATE}).c("retract",{xmlns:Oo.NS.RETRACT}).up().c("reason").t(t||"");return wd.sendIQ(n,null,!1)},sendDestroyIQ(e,t){const n=to("destroy");t&&n.attrs({jid:t});const s=so({to:this.get("jid"),type:"set"}).c("query",{xmlns:Oo.NS.MUC_OWNER}).cnode(n.node);return e&&e.length>0&&s.c("reason",e),wd.sendIQ(s)},async leave(e){wd.connection.connected()&&wd.user.presence.send("unavailable",this.getRoomJIDAndNick(),e),this.features&&await new Promise((e=>this.features.destroy({success:e,error:(t,n)=>{$l.error(n),e()}})));const t=Zl.disco_entities?.get(this.get("jid"));t&&await new Promise((e=>t.destroy({success:e,error:(t,n)=>{$l.error(n),e()}}))),gl(this.session,{connection_status:Hf.DISCONNECTED})},async close(e){const{ENTERED:t,CLOSING:n}=Hf,s=this.session.get("connection_status")===t;return gl(this.session,{connection_status:n}),s&&this.sendMarkerForLastMessage("received",!0),await this.unregisterNickname(),await this.leave(),this.occupants.clearStore(),"closeAllChatBoxes"!==e?.name&&wd.settings.get("muc_clear_messages_on_leave")&&this.clearMessages(),await new Promise((e=>this.session.destroy({success:e,error:(t,n)=>{$l.error(n),e()}}))),Zl.ChatBox.prototype.close.call(this)},canModerateMessages(){const e=this.getOwnOccupant();return e&&e.isModerator()&&wd.disco.supports(Oo.NS.MODERATE,this.get("jid"))},getAllKnownNicknames(){return[...new Set([...this.occupants.map((e=>e.get("nick"))),...this.messages.map((e=>e.get("nick")))])].filter((e=>e))},getAllKnownNicknamesRegex(){const e=this.getAllKnownNicknames().map((e=>Mf.escapeRegexString(e))).join("|");return RegExp(`(?:\\p{P}|\\p{Z}|^)@(${e})(?![\\w@-])`,"uig")},getOccupantByJID(e){return this.occupants.findOccupant({jid:e})},getOccupantByNickname(e){return this.occupants.findOccupant({nick:e})},getReferenceURIFromNickname(e){const t=this.get("jid"),n=this.getOccupant(e),s=this.features.get("nonanonymous")&&n?.get("jid")||`${t}/${e}`;return encodeURI(`xmpp:${s}`)},parseTextForReferences(e){if(!e||!/(\p{P}|\p{Z}|^)([@][\w_-]+(?:\.\w+)*)/giu.test(e))return[e,[]];const t=Mf.findFirstMatchInArray(this.getAllKnownNicknames()),n=this.getAllKnownNicknamesRegex(),s=[...e.matchAll(n)].filter((e=>!e[0].startsWith("/"))),i=s.map((e=>{let n=e[0].indexOf("@");"@"===e[0][n+1]&&(n+=1);const s=e.index+n,i=s+e[0].length-n,r=t(e[1]);return{begin:s,end:i,value:r,type:"mention",uri:this.getReferenceURIFromNickname(r)}})),[r,o]=Mf.reduceTextFromReferences(e,i);return[r,o]},async getOutgoingMessageAttributes(e){await wd.emojis.initialize();const t=this.get("composing_spoiler");let n,s="";e?.body&&([s,n]=this.parseTextForReferences(e.body));const i=pl(),r=s?ap.shortnamesToUnicode(s):void 0;return e=Object.assign({},e,{body:r,is_spoiler:t,origin_id:i,references:n,id:i,msgid:i,from:`${this.get("jid")}/${this.get("nick")}`,fullname:this.get("nick"),is_only_emojis:!!s&&ap.isOnlyEmojis(s),message:r,nick:this.get("nick"),sender:"me",type:"groupchat"},vg(s)),e=await wd.hook("getOutgoingMessageAttributes",this,e)},getRoomJIDAndNick(){const e=this.get("nick");return Oo.getBareJidFromJid(this.get("jid"))+(null!==e?`/${e}`:"")},sendChatState(){if(!wd.settings.get("send_chat_state_notifications")||!this.get("chat_state")||!this.isEntered()||this.features.get("moderated")&&"visitor"===this.getOwnRole())return;const e=wd.settings.get("send_chat_state_notifications");if(Array.isArray(e)&&!e.includes(this.get("chat_state")))return;const t=this.get("chat_state");t!==Zl.GONE&&wd.send(no({to:this.get("jid"),type:"groupchat"}).c(t,{xmlns:Oo.NS.CHATSTATES}).up().c("no-store",{xmlns:Oo.NS.HINTS}).up().c("no-permanent-store",{xmlns:Oo.NS.HINTS}))},directInvite(e,t){this.features.get("membersonly")&&this.updateMemberLists([{jid:e,affiliation:"member",reason:t}]);const n={xmlns:"jabber:x:conference",jid:this.get("jid")};null!==t&&(n.reason=t),this.get("password")&&(n.password=this.get("password"));const s=no({from:Zl.connection.jid,to:e,id:pl()}).c("x",n);wd.send(s),wd.trigger("roomInviteSent",{room:this,recipient:e,reason:t})},refreshDiscoInfo(){return wd.disco.refresh(this.get("jid")).then((()=>this.getDiscoInfo())).catch((e=>$l.error(e)))},getDiscoInfo(){return wd.disco.getIdentity("conference","text",this.get("jid")).then((e=>this.save({name:e?.get("name")}))).then((()=>this.getDiscoInfoFields())).then((()=>this.getDiscoInfoFeatures())).catch((e=>$l.error(e)))},async getDiscoInfoFields(){const e=(await wd.disco.getFields(this.get("jid"))).reduce(((e,t)=>{const n=t.get("var");return n?.startsWith("muc#roominfo_")&&(e[n.replace("muc#roominfo_","")]=t.get("value")),e}),{});this.config.save(e)},async getDiscoInfoFeatures(){const e=await wd.disco.getFeatures(this.get("jid")),t=Fm.ROOM_FEATURES.reduce(((e,t)=>(e[t]=!1,e)),{fetched:(new Date).toISOString()});e.each((e=>{const n=e.get("var");n.startsWith("muc_")?t[n.replace("muc_","")]=!0:n===Oo.NS.MAM?t.mam_enabled=!0:t[n]=!0})),this.features.save(t)},addFieldValue(e){const t=e.getAttribute("type");if("fixed"===t)return e;const n=e.getAttribute("var").replace("muc#roomconfig_",""),s=this.get("roomconfig");if(n in s){let i;switch(t){case"boolean":i=[s[n]?1:0];break;case"list-multi":i=s[n];break;default:i=[s[n]]}e.innerHTML=i.map((e=>to("value").t(e))).join("")}return e},async autoConfigureChatRoom(){const e=await this.fetchRoomConfiguration(),t=Yo()("field",e).map((e=>this.addFieldValue(e)));if(t.length)return this.sendConfiguration(t)},fetchRoomConfiguration(){return wd.sendIQ(so({to:this.get("jid"),type:"get"}).c("query",{xmlns:Oo.NS.MUC_OWNER}))},sendConfiguration(){let e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:[];const t=so({to:this.get("jid"),type:"set"}).c("query",{xmlns:Oo.NS.MUC_OWNER}).c("x",{xmlns:Oo.NS.XFORM,type:"submit"});return e.forEach((e=>t.cnode(e).up())),wd.sendIQ(t)},onCommandError(e){const{__:t}=Zl;$l.fatal(e);const n=t("Sorry, an error happened while running the command.")+" "+t("Check your browser's developer console for details.");this.createMessage({message:n,type:"error"})},getNickOrJIDFromCommandArgs(e){const{__:t}=Zl;if(ap.isValidJID(e.trim()))return e.trim();e.startsWith("@")||(e="@"+e);const[n,s]=this.parseTextForReferences(e);if(!s.length){const e=t("Error: couldn't find a groupchat participant based on your arguments");return void this.createMessage({message:e,type:"error"})}if(s.length>1){const e=t("Error: found multiple groupchat participant based on your arguments");return void this.createMessage({message:e,type:"error"})}const i=s.pop().value,r=e.split(i,2)[1];if(!r||r.startsWith(" "))return i;{const e=t("Error: couldn't find a groupchat participant based on your arguments");this.createMessage({message:e,type:"error"})}},validateRoleOrAffiliationChangeArgs(e,t){const{__:n}=Zl;if(!t){const t=n('Error: the "%1$s" command takes two arguments, the user\'s nickname and optionally a reason.',e);return this.createMessage({message:t,type:"error"}),!1}return!0},getAllowedCommands(){let e=["clear","help","me","nick","register"];(this.config.get("changesubject")||["owner","admin"].includes(this.getOwnAffiliation()))&&(e=[...e,"subject","topic"]);const t=this.occupants.findWhere({jid:Zl.bare_jid});return this.verifyAffiliations(["owner"],t,!1)?e=e.concat(cp).concat(lp):this.verifyAffiliations(["admin"],t,!1)&&(e=e.concat(lp)),this.verifyRoles(["moderator"],t,!1)?e=e.concat(dp).concat(up):this.verifyRoles(["visitor","participant","moderator"],t,!1)||(e=e.concat(up)),e.sort(),Array.isArray(wd.settings.get("muc_disable_slash_commands"))?e.filter((e=>!wd.settings.get("muc_disable_slash_commands").includes(e))):e},verifyAffiliations(e,t){let n=!(arguments.length>2&&void 0!==arguments[2])||arguments[2];const{__:s}=Zl;if(!Array.isArray(e))throw new TypeError("affiliations must be an Array");if(!e.length)return!0;if(t=t||this.occupants.findWhere({jid:Zl.bare_jid})){const n=t.get("affiliation");if(e.includes(n))return!0}if(n){const e=s("Forbidden: you do not have the necessary affiliation in order to do that.");this.createMessage({message:e,type:"error"})}return!1},verifyRoles(e,t){let n=!(arguments.length>2&&void 0!==arguments[2])||arguments[2];const{__:s}=Zl;if(!Array.isArray(e))throw new TypeError("roles must be an Array");if(!e.length)return!0;if(t=t||this.occupants.findWhere({jid:Zl.bare_jid})){const n=t.get("role");if(e.includes(n))return!0}if(n){const e=s("Forbidden: you do not have the necessary role in order to do that.");this.createMessage({message:e,type:"error",is_ephemeral:2e4})}return!1},getOwnRole(){return this.getOwnOccupant()?.attributes?.role},getOwnAffiliation(){return this.getOwnOccupant()?.attributes?.affiliation||"none"},getOwnOccupant(){return this.occupants.getOwnOccupant()},async setNickname(e){if(wd.settings.get("auto_register_muc_nickname")&&await wd.disco.supports(Oo.NS.MUC_REGISTER,this.get("jid"))){const t=this.get("nick");this.set({nick:e});try{await this.registerNickname()}catch(e){const{__:n}=Zl;$l.error(e);const s=n("Error: couldn't register new nickname in members only room");return this.createMessage({message:s,type:"error",is_ephemeral:!0}),void this.set({nick:t})}}const t=Oo.getBareJidFromJid(this.get("jid"));wd.send(io({from:Zl.connection.jid,to:`${t}/${e}`,id:pl()}).tree())},setRole(e,t,n,s,i){const r=to("item",{nick:e.get("nick"),role:t}),o=so({to:this.get("jid"),type:"set"}).c("query",{xmlns:Oo.NS.MUC_ADMIN}).cnode(r.node);return null!==n&&o.c("reason",n),wd.sendIQ(o).then(s).catch(i)},getOccupant(e){return ap.isValidJID(e)?this.getOccupantByJID(e):this.getOccupantByNickname(e)},getOccupantsWithRole(e){return this.getOccupantsSortedBy("nick").filter((t=>t.get("role")===e)).map((e=>({jid:e.get("jid"),nick:e.get("nick"),role:e.get("role")})))},getOccupantsWithAffiliation(e){return this.getOccupantsSortedBy("nick").filter((t=>t.get("affiliation")===e)).map((e=>({jid:e.get("jid"),nick:e.get("nick"),affiliation:e.get("affiliation")})))},getOccupantsSortedBy(e){return Array.from(this.occupants.models).sort(((t,n)=>t.get(e)n.get(e)?1:0))},async updateMemberLists(e){const t=this.get("jid"),n=await Promise.all(["member","admin","owner"].map((e=>np(e,t)))),s=n.reduce(((e,t)=>ap.isErrorObject(t)?e:[...t,...e]),[]);await ip(t,op(!0,!1,e,s)),await this.occupants.fetchMembers()},async getAndPersistNickname(e){return(e=e||this.get("nick")||await this.getReservedNick()||Zl.getDefaultMUCNickname())&&gl(this,{nick:e},{silent:!0}),e},async getReservedNick(){const e=so({to:this.get("jid"),from:Zl.connection.jid,type:"get"}).c("query",{xmlns:Oo.NS.DISCO_INFO,node:"x-roomuser-item"}),t=await wd.sendIQ(e,null,!1);if(ap.isErrorObject(t))throw t;const n=t?.querySelector('query[node="x-roomuser-item"] identity');return n?n.getAttribute("name"):null},async registerNickname(){const{__:e}=Zl,t=this.get("nick"),n=this.get("jid");let s,i;try{s=await wd.sendIQ(so({to:n,type:"get"}).c("query",{xmlns:Oo.NS.MUC_REGISTER}))}catch(t){return Yo()(`not-allowed[xmlns="${Oo.NS.STANZAS}"]`,t).length?i=e("You're not allowed to register yourself in this groupchat."):Yo()(`registration-required[xmlns="${Oo.NS.STANZAS}"]`,t).length&&(i=e("You're not allowed to register in this groupchat because it's members-only.")),$l.error(t),i}const r=Yo()("field required",s).map((e=>e.parentElement));if(r.length>1&&"muc#register_roomnick"!==r[0].getAttribute("var"))return $l.error(`Can't register the user register in the groupchat ${n} due to the required fields`);try{await wd.sendIQ(so({to:n,type:"set"}).c("query",{xmlns:Oo.NS.MUC_REGISTER}).c("x",{xmlns:Oo.NS.XFORM,type:"submit"}).c("field",{var:"FORM_TYPE"}).c("value").t("http://jabber.org/protocol/muc#register").up().up().c("field",{var:"muc#register_roomnick"}).c("value").t(t))}catch(t){return Yo()(`service-unavailable[xmlns="${Oo.NS.STANZAS}"]`,t).length?i=e("Can't register your nickname in this groupchat, it doesn't support registration."):Yo()(`bad-request[xmlns="${Oo.NS.STANZAS}"]`,t).length&&(i=e("Can't register your nickname in this groupchat, invalid data form supplied.")),$l.error(i),$l.error(t),i}},async unregisterNickname(){if("unregister"===wd.settings.get("auto_register_muc_nickname"))try{await wd.disco.supports(Oo.NS.MUC_REGISTER,this.get("jid"))&&await this.sendUnregistrationIQ()}catch(e){$l.error(e)}},sendUnregistrationIQ(){const e=so({to:this.get("jid"),type:"set"}).c("query",{xmlns:Oo.NS.MUC_REGISTER}).c("remove");return wd.sendIQ(e).catch((e=>$l.error(e)))},updateOccupantsOnPresence(e){const t=function(e,t){const n=e.getAttribute("from"),s=e.getAttribute("type"),i={is_me:!!e.querySelector("status[code='110']"),from:n,occupant_id:Jf(e,t),nick:Gf.getResourceFromJid(n),type:s,states:[],hats:[],show:"unavailable"!==s?"online":"offline"};return Array.from(e.children).forEach((e=>{e.matches("status")?i.status=e.textContent||null:e.matches("show")?i.show=e.textContent||"online":e.matches("x")&&e.getAttribute("xmlns")===Gf.NS.MUC_USER?Array.from(e.children).forEach((e=>{"item"===e.nodeName?(i.affiliation=e.getAttribute("affiliation"),i.role=e.getAttribute("role"),i.jid=e.getAttribute("jid"),i.nick=e.getAttribute("nick")||i.nick):"status"==e.nodeName&&e.getAttribute("code")&&i.states.push(e.getAttribute("code"))})):e.matches("x")&&e.getAttribute("xmlns")===Gf.NS.VCARDUPDATE?i.image_hash=e.querySelector("photo")?.textContent:e.matches("hats")&&e.getAttribute("xmlns")===Gf.NS.MUC_HATS&&(i.hats=Array.from(e.children).map((e=>e.matches("hat")&&{title:e.getAttribute("title"),uri:e.getAttribute("uri")})))})),i}(e,this);if("error"===t.type||!t.jid&&!t.nick&&!t.occupant_id)return!0;const n=this.occupants.findOccupant(t);if("unavailable"===t.type&&n&&!t.states.includes(Fm.MUC_NICK_CHANGED_CODE)&&!["admin","owner","member"].includes(t.affiliation))return n.set(t),void n.destroy();const s=t.jid||"",i={...t,jid:Oo.getBareJidFromJid(s)||n?.attributes?.jid,resource:Oo.getResourceFromJid(s)||n?.attributes?.resource};if(t.is_me){let e=!1;t.states.includes(Fm.MUC_NICK_CHANGED_CODE)&&(e=!0,this.set("nick",t.nick)),this.features.get(Oo.NS.OCCUPANTID)&&this.get("occupant-id")!==t.occupant_id&&(e=!0,this.set("occupant_id",t.occupant_id)),e&&this.save()}n?n.save(i):this.occupants.create(i)},fetchFeaturesIfConfigurationChanged(e){const t=["104","170","171","172","173","174"];Yo()("status",e).filter((e=>t.includes(e.getAttribute("status")))).length&&this.refreshDiscoInfo()},isSameUser(e,t){const n=Oo.getBareJidFromJid(e),s=Oo.getBareJidFromJid(t),i=Oo.getResourceFromJid(e),r=Oo.getResourceFromJid(t);if(ap.isSameBareJID(e,t))return n!==this.get("jid")||i===r;return(n===this.get("jid")?this.occupants.findOccupant({nick:i}):this.occupants.findOccupant({jid:n}))===(s===this.get("jid")?this.occupants.findOccupant({nick:r}):this.occupants.findOccupant({jid:s}))},async isSubjectHidden(){return(await wd.user.settings.get("mucs_with_hidden_subject",[])).includes(this.get("jid"))},async toggleSubjectHiddenState(){const e=this.get("jid"),t=await wd.user.settings.get("mucs_with_hidden_subject",[]);t.includes(this.get("jid"))?wd.user.settings.set("mucs_with_hidden_subject",t.filter((t=>t!==e))):wd.user.settings.set("mucs_with_hidden_subject",[...t,e])},async handleSubjectChange(e){const t=Zl.__;if("string"==typeof e.subject&&!e.thread&&!e.message){const n=e.subject,s=e.nick;if(gl(this,{subject:{author:s,text:e.subject||""}}),!e.is_delayed&&s){const i=t(n?"Topic set by %1$s":"Topic cleared by %1$s",s),r=this.messages.last();r?.get("nick")===e.nick&&"info"===r?.get("type")&&r?.get("message")===i||this.createMessage({message:i,nick:e.nick,type:"info",is_ephemeral:!0}),await this.isSubjectHidden()&&this.toggleSubjectHiddenState()}return!0}return!1},setSubject(){let e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:"";wd.send(no({to:this.get("jid"),from:Zl.connection.jid,type:"groupchat"}).c("subject",{xmlns:"jabber:client"}).t(e).tree())},ignorableCSN(e){return e.chat_state&&!e.body&&(e.is_delayed||this.isOwnMessage(e))},isOwnMessage(e){let t;return t=jf(e)?e.getAttribute("from"):e instanceof Zl.Message?e.get("from"):e.from,Oo.getResourceFromJid(t)==this.get("nick")},getUpdatedMessageAttributes(e,t){const n={...Zl.ChatBox.prototype.getUpdatedMessageAttributes.call(this,e,t),...lr(t,["from_muc","occupant_id"])};if(this.isOwnMessage(t)){const s=Object.keys(t).filter((e=>e.startsWith("stanza_id")));Object.assign(n,lr(t,s)),e.get("received")||(n.received=(new Date).toISOString())}return n},async isJoined(){return this.isEntered()?(wd.connection.connected()||await new Promise((e=>wd.listen.once("reconnected",e))),wd.ping(`${this.get("jid")}/${this.get("nick")}`)):($l.info(`isJoined: not pinging MUC ${this.get("jid")} since we're not entered`),!1)},async sendStatusPresence(e,t,n){if(this.session.get("connection_status")===Hf.ENTERED){const s=await Zl.xmppstatus.constructPresence(e,this.getRoomJIDAndNick(),t);n?.map((e=>e?.tree()??e)).forEach((e=>s.cnode(e).up())),wd.send(s)}},async rejoinIfNecessary(){return this.isRAICandidate()?($l.debug(`rejoinIfNecessary: not rejoining hidden MUC "${this.get("jid")}" since we're using RAI`),!0):await this.isJoined()?void 0:(this.rejoin(),!0)},async shouldShowErrorMessage(e){if("Decryption"===e.error_type){if("Message key not found. The counter was repeated or the key was not filled."===e.error_message)return!1;if("not-encrypted-for-this-device"===e.error_condition)return!1}else if("not-acceptable"===e.error_condition&&await this.rejoinIfNecessary())return!1;return Zl.ChatBox.prototype.shouldShowErrorMessage.call(this,e)},findDanglingModeration(e){if(!this.messages.length)return null;if(this.messages.last().get("time")>e.time){const t=Array.from(this.messages.models),n=e[`stanza_id ${this.get("jid")}`];return n?(t.reverse(),t.find((e=>{let{attributes:t}=e;return"retracted"===t.moderated&&t.moderated_id===n&&t.moderated_by}))):null}},async handleModeration(e){const t=["editable","moderated","moderated_by","moderated_id","moderation_reason"];if("retracted"===e.moderated){const n={};n[`stanza_id ${this.get("jid")}`]=e.moderated_id;const s=this.messages.findWhere(n);return s?(s.save(lr(e,t)),!0):(e.dangling_moderation=!0,await this.createMessage(e),!0)}{const n=this.findDanglingModeration(e);if(n){const s=lr(n.attributes,t),i=Object.assign({dangling_moderation:!1},e,s);return delete i.id,n.save(i),!0}}return!1},getNotificationsText(){const{__:e}=Zl,t=this.notifications.toJSON(),n=wd.settings.get("muc_show_info_messages").filter((e=>Fm.MUC_ROLE_CHANGES_LIST.includes(e))),s=wd.settings.get("muc_show_info_messages").filter((e=>Fm.MUC_TRAFFIC_STATES_LIST.includes(e)));return[...Fm.CHAT_STATES,...s,...n].reduce(((n,s)=>{const i=t[s];if(!i?.length)return n;const r=i.map((e=>this.getOccupant(e)?.getDisplayName()||e));if(1===r.length){if("composing"===s)return`${n}${e("%1$s is typing",r[0])}\n`;if("paused"===s)return`${n}${e("%1$s has stopped typing",r[0])}\n`;if(s===Zl.GONE)return`${n}${e("%1$s has gone away",r[0])}\n`;if("entered"===s)return`${n}${e("%1$s has entered the groupchat",r[0])}\n`;if("exited"===s)return`${n}${e("%1$s has left the groupchat",r[0])}\n`;if("op"===s)return`${n}${e("%1$s is now a moderator",r[0])}\n`;if("deop"===s)return`${n}${e("%1$s is no longer a moderator",r[0])}\n`;if("voice"===s)return`${n}${e("%1$s has been given a voice",r[0])}\n`;if("mute"===s)return`${n}${e("%1$s has been muted",r[0])}\n`}else if(r.length>1){let t;if(r.length>3)t=`${Array.from(r).slice(0,2).join(", ")} and others`;else{const n=r.pop();t=e("%1$s and %2$s",r.join(", "),n)}if("composing"===s)return`${n}${e("%1$s are typing",t)}\n`;if("paused"===s)return`${n}${e("%1$s have stopped typing",t)}\n`;if(s===Zl.GONE)return`${n}${e("%1$s have gone away",t)}\n`;if("entered"===s)return`${n}${e("%1$s have entered the groupchat",t)}\n`;if("exited"===s)return`${n}${e("%1$s have left the groupchat",t)}\n`;if("op"===s)return`${n}${e("%1$s are now moderators",r[0])}\n`;if("deop"===s)return`${n}${e("%1$s are no longer moderators",r[0])}\n`;if("voice"===s)return`${n}${e("%1$s have been given voices",r[0])}\n`;if("mute"===s)return`${n}${e("%1$s have been muted",r[0])}\n`}return n}),"")},removeNotification(e,t){const n=this.notifications.toJSON();(t=Array.isArray(t)?t:[t]).forEach((t=>{const s=Array.from(n[t]||[]);if(s.includes(e)){const n=s.indexOf(e);s.splice(n,1),this.notifications.set(t,Array.from(s))}}))},updateNotifications(e,t){const n=this.notifications.toJSON(),s=n[t]||[];if(s.includes(e))return;const i=(i,r)=>(i[r]=r===t?[...s,e]:(n[r]||[]).filter((t=>t!==e)),i),r=Fm.CHAT_STATES.reduce(i,{}),o=Fm.MUC_TRAFFIC_STATES_LIST.reduce(i,{}),a=Fm.MUC_ROLE_CHANGES_LIST.reduce(i,{});this.notifications.set(Object.assign(r,o,a)),window.setTimeout((()=>this.removeNotification(e,t)),1e4)},handleMetadataFastening(e){if(e.ogp_for_id){if(e.from!==this.get("jid"))return!1;const t=this.messages.findWhere({origin_id:e.ogp_for_id});if(t){const n=t.get("ogp_metadata")||[];if(n.filter((t=>t["og:url"]===e["og:url"])).length)return!1;const s=[...n,lr(e,hp)];return t.save("ogp_metadata",s),!0}}return!1},handleMEPNotification(e){return!(e.from!==this.get("jid")||!e.activities)&&(e.activities?.forEach((t=>{const n=Object.assign(e,t);this.createMessage(n),wd.trigger("message",{attrs:n,chatbox:this})})),!!e.activities.length)},getDuplicateMessage(e){return e.activities?.length?this.messages.findWhere({type:"mep",msgid:e.msgid}):Zl.ChatBox.prototype.getDuplicateMessage.call(this,e)},async onMessage(e){if(e=await e,ap.isErrorObject(e))return e.stanza&&$l.error(e.stanza),$l.error(e.message);if("error"===e.type&&!await this.shouldShowErrorMessage(e))return;const t=this.getDuplicateMessage(e);if(t)"groupchat"===t.get("type")&&this.updateMessage(t,e);else if(!(e.receipt_id||e.is_marker||this.ignorableCSN(e)))if(this.handleMetadataFastening(e)||this.handleMEPNotification(e)||await this.handleRetraction(e)||await this.handleModeration(e)||await this.handleSubjectChange(e))e.nick&&this.removeNotification(e.nick,["composing","paused"]);else if(this.setEditable(e,e.time),e.chat_state&&this.updateNotifications(e.nick,e.chat_state),ap.shouldCreateGroupchatMessage(e)){const t=await Wm(this,e)||await this.createMessage(e);this.removeNotification(e.nick,["composing","paused"]),this.handleUnreadMessage(t)}},handleModifyError(e){const t=e.querySelector("error text")?.textContent;if(t)if(this.session.get("connection_status")===Hf.CONNECTING)this.setDisconnectionState(t);else{const e={type:"error",message:t,is_ephemeral:!0};this.createMessage(e)}},handleDisconnection(e){const t=null!==e.querySelector("status[code='110']"),n=Yo()(`x[xmlns="${Oo.NS.MUC_USER}"]`,e).pop();if(!n)return;const s=Object.keys(Zl.muc.disconnect_messages),i=Yo()("status",n).map((e=>e.getAttribute("code"))).filter((e=>s.includes(e)));if(!(t&&i.length>0))return;const r=n.querySelector("item"),o=r?r.querySelector("reason")?.textContent:void 0,a=r?r.querySelector("actor")?.getAttribute("nick"):void 0,c=Zl.muc.disconnect_messages[i[0]],l=i.includes("301")?Hf.BANNED:Hf.DISCONNECTED;this.setDisconnectionState(c,o,a,l)},getActionInfoMessage(e,t,n){const s=Zl.__;return"301"===e?n?s("%1$s has been banned by %2$s",t,n):s("%1$s has been banned",t):"303"===e?s("%1$s's nickname has changed",t):"307"===e?n?s("%1$s has been kicked out by %2$s",t,n):s("%1$s has been kicked out",t):"321"===e?s("%1$s has been removed because of an affiliation change",t):"322"===e?s("%1$s has been removed for not being a member",t):void 0},createAffiliationChangeMessage(e){const t=Zl.__,n=e._previousAttributes.affiliation;if(!n)return;const s=e.get("affiliation");"admin"===n&&Zl.isInfoVisible(Fm.AFFILIATION_CHANGES.EXADMIN)?this.createMessage({type:"info",message:t("%1$s is no longer an admin of this groupchat",e.get("nick"))}):"owner"===n&&Zl.isInfoVisible(Fm.AFFILIATION_CHANGES.EXOWNER)?this.createMessage({type:"info",message:t("%1$s is no longer an owner of this groupchat",e.get("nick"))}):"outcast"===n&&Zl.isInfoVisible(Fm.AFFILIATION_CHANGES.EXOUTCAST)&&this.createMessage({type:"info",message:t("%1$s is no longer banned from this groupchat",e.get("nick"))}),"none"===s&&"member"===n&&Zl.isInfoVisible(Fm.AFFILIATION_CHANGES.EXMEMBER)&&this.createMessage({type:"info",message:t("%1$s is no longer a member of this groupchat",e.get("nick"))}),"member"===s&&Zl.isInfoVisible(Fm.AFFILIATION_CHANGES.MEMBER)?this.createMessage({type:"info",message:t("%1$s is now a member of this groupchat",e.get("nick"))}):("admin"===s&&Zl.isInfoVisible(Fm.AFFILIATION_CHANGES.ADMIN)||"owner"==s&&Zl.isInfoVisible(Fm.AFFILIATION_CHANGES.OWNER))&&this.createMessage({type:"info",message:t("%1$s is now an %2$s of this groupchat",e.get("nick"),s)})},createRoleChangeMessage(e,t){if("none"===t||e.changed.affiliation)return;const n=e._previousAttributes.role;"moderator"===n&&Zl.isInfoVisible(Fm.MUC_ROLE_CHANGES.DEOP)?this.updateNotifications(e.get("nick"),Fm.MUC_ROLE_CHANGES.DEOP):"visitor"===n&&Zl.isInfoVisible(Fm.MUC_ROLE_CHANGES.VOICE)&&this.updateNotifications(e.get("nick"),Fm.MUC_ROLE_CHANGES.VOICE),"visitor"===e.get("role")&&Zl.isInfoVisible(Fm.MUC_ROLE_CHANGES.MUTE)?this.updateNotifications(e.get("nick"),Fm.MUC_ROLE_CHANGES.MUTE):"moderator"===e.get("role")&&!["owner","admin"].includes(e.get("affiliation"))&&Zl.isInfoVisible(Fm.MUC_ROLE_CHANGES.OP)&&this.updateNotifications(e.get("nick"),Fm.MUC_ROLE_CHANGES.OP)},createInfoMessage(e,t,n){const s=Zl.__,i={type:"info",is_ephemeral:!0};if(Zl.isInfoVisible(e)&&"110"!==e&&("100"!==e||n)){if(e in Zl.muc.info_messages)i.message=Zl.muc.info_messages[e];else if(!n&&mp.includes(e)){const n=Oo.getResourceFromJid(t.getAttribute("from")),s=Yo()(`x[xmlns="${Oo.NS.MUC_USER}"] item`,t).pop();i.actor=s?s.querySelector("actor")?.getAttribute("nick"):void 0,i.reason=s?s.querySelector("reason")?.textContent:void 0,i.message=this.getActionInfoMessage(e,n,i.actor)}else if(n&&e in Zl.muc.new_nickname_messages){let n;"210"===e?n=Oo.getResourceFromJid(t.getAttribute("from")):"303"===e&&(n=Yo()(`x[xmlns="${Oo.NS.MUC_USER}"] item`,t).pop().getAttribute("nick")),this.save("nick",n),i.message=s(Zl.muc.new_nickname_messages[e],n)}if(i.message){if("201"===e&&this.messages.findWhere(i))return;this.createMessage(i)}}},createInfoMessages(e){const t=Yo()(`x[xmlns="${Oo.NS.MUC_USER}"] status`,e).map((e=>e.getAttribute("code")));t.includes("333")&&t.includes("307")&&t.splice(t.indexOf("307"),1);const n=t.includes("110");t.forEach((t=>this.createInfoMessage(t,e,n)))},setDisconnectionState(e,t,n){let s=arguments.length>3&&void 0!==arguments[3]?arguments[3]:Hf.DISCONNECTED;this.session.save({connection_status:s,disconnection_actor:n,disconnection_message:e,disconnection_reason:t})},onNicknameClash(e){const t=Zl.__;if(wd.settings.get("muc_nickname_from_jid")){const t=e.getAttribute("from").split("/")[1];if(t===Zl.getDefaultMUCNickname())this.join(t+"-2");else{const e=t.lastIndexOf("-"),n=t.substring(e+1,t.length);this.join(t.substring(0,e+1)+String(Number(n)+1))}}else this.save({nickname_validation_message:t("The nickname you chose is reserved or currently in use, please choose a different one.")}),this.session.save({connection_status:Hf.NICKNAME_REQUIRED})},onErrorPresence(e){const t=Zl.__,n=e.querySelector("error"),s=n.getAttribute("type"),i=Yo()(`text[xmlns="${Oo.NS.STANZAS}"]`,n).pop()?.textContent;if("modify"===s)this.handleModifyError(e);else if("auth"===s)if(Yo()(`not-authorized[xmlns="${Oo.NS.STANZAS}"]`,n).length&&(this.save({password_validation_message:i||t("Password incorrect")}),this.session.save({connection_status:Hf.PASSWORD_REQUIRED})),n.querySelector("registration-required")){const e=t("You are not on the member list of this groupchat.");this.setDisconnectionState(e,i)}else n.querySelector("forbidden")&&this.setDisconnectionState(Zl.muc.disconnect_messages[301],i,null,Hf.BANNED);else if("cancel"===s)if(n.querySelector("not-allowed")){const e=t("You are not allowed to create new groupchats.");this.setDisconnectionState(e,i)}else if(n.querySelector("not-acceptable")){const e=t("Your nickname doesn't conform to this groupchat's policies.");this.setDisconnectionState(e,i)}else if(Yo()(`gone[xmlns="${Oo.NS.STANZAS}"]`,n).length){const e=Yo()(`gone[xmlns="${Oo.NS.STANZAS}"]`,n).pop()?.textContent.replace(/^xmpp:/,"").replace(/\?join$/,"");this.save({moved_jid:e,destroyed_reason:i}),this.session.save({connection_status:Hf.DESTROYED})}else if(n.querySelector("conflict"))this.onNicknameClash(e);else if(n.querySelector("item-not-found")){const e=t("This groupchat does not (yet) exist.");this.setDisconnectionState(e,i)}else if(n.querySelector("service-unavailable")){const e=t("This groupchat has reached its maximum number of participants.");this.setDisconnectionState(e,i)}else if(n.querySelector("remote-server-not-found")){const e=t("Remote server not found");this.setDisconnectionState(e,i)}else if(n.querySelector("forbidden")){const e=t("You're not allowed to enter this groupchat");this.setDisconnectionState(e,i)}else{const e=t("An error happened while trying to enter this groupchat");this.setDisconnectionState(e,i)}},onPresenceFromMUCHost(e){if("error"===e.getAttribute("type")){const t=e.querySelector("error");"wait"===t?.getAttribute("type")&&t?.querySelector("resource-constraint")&&this.session.get("connection_status")===Hf.DISCONNECTED&&this.rejoin()}},onPresence(e){if("error"===e.getAttribute("type"))return this.onErrorPresence(e);this.createInfoMessages(e),e.querySelector("status[code='110']")?(this.onOwnPresence(e),"none"!==this.getOwnRole()&&this.session.get("connection_status")===Hf.CONNECTING&&this.session.save("connection_status",Hf.CONNECTED)):this.updateOccupantsOnPresence(e)},async onOwnPresence(e){if(await this.occupants.fetched,"unavailable"===e.getAttribute("type"))return void this.handleDisconnection(e);const t=this.session.get("connection_status");t!==Hf.ENTERED&&t!==Hf.CLOSING?(this.session.save("connection_status",Hf.ENTERED,{silent:!0}),this.updateOccupantsOnPresence(e),this.session.trigger("change:connection_status",this.session,t)):this.updateOccupantsOnPresence(e);e.querySelector("status[code='201']")&&(this.get("auto_configure")?await this.autoConfigureChatRoom().then((()=>this.refreshDiscoInfo())):wd.settings.get("muc_instant_rooms")?await this.sendConfiguration().then((()=>this.refreshDiscoInfo())):this.session.save({view:Fm.MUC.VIEWS.CONFIG}))},isUserMentioned(e){const t=this.get("nick");if(e.get("references").length){return e.get("references").filter((e=>"mention"===e.type)).map((e=>e.value)).includes(t)}return new RegExp(`\\b${t}\\b`).test(e.get("body"))},incrementUnreadMsgsCounter(e){const t={num_unread_general:this.get("num_unread_general")+1};0===this.get("num_unread_general")&&(t.first_unread_id=e.get("id")),this.isUserMentioned(e)&&(t.num_unread=this.get("num_unread")+1),this.save(t)},clearUnreadMsgCounter(){(this.get("num_unread_general")>0||this.get("num_unread")>0||this.get("has_activity"))&&this.sendMarkerForMessage(this.messages.last()),gl(this,{has_activity:!1,num_unread:0,num_unread_general:0})}},pp=fp;const vp=class extends dr{defaults(){return{hats:[],show:"offline",states:[]}}save(e,t,n){let s;return null==e?super.save(e,t,n):("object"==typeof e?(s=e,n=t):(s={})[e]=t,s.occupant_id&&(s.id=s.occupant_id),super.save(s,n))}getDisplayName(){return this.get("nick")||this.get("jid")}isMember(){return["admin","owner","member"].includes(this.get("affiliation"))}isModerator(){return["admin","owner"].includes(this.get("affiliation"))||"moderator"===this.get("role")}isSelf(){return this.get("states").includes("110")}},{Strophe:yp,sizzle:_p,u:bp}=Fm.env;function wp(){const e=wd.settings.get("muc_fetch_members");return Array.isArray(e)?e:e?["member","admin","owner"]:[]}function Sp(e){let t=wd.settings.get("modtools_disable_assign");return Array.isArray(t)||(t=t?Of:[]),"moderator"===e.get("role")?Of.filter((e=>!t.includes(e))):[]}function xp(){Zl.connection.addHandler((e=>(Zl.onDirectMUCInvitation(e),!0)),"jabber:x:conference","message")}function Ap(){return Zl.chatboxes.filter((e=>e.get("type")===Zl.CHATROOMS_TYPE)).forEach((e=>e.session.save({connection_status:Fm.ROOMSTATUS.DISCONNECTED})))}async function Ep(e){if("visible"===e.state&&wd.connection.connected()){(await wd.rooms.get()).forEach((e=>e.rejoinIfNecessary()))}}async function $p(e){if(!bp.isValidMUCJID(e))return $l.warn(`invalid jid "${e}" provided in url fragment`);await wd.waitUntil("roomsAutoJoined"),wd.settings.get("allow_bookmarks")&&await wd.waitUntil("bookmarksInitialized"),wd.rooms.open(e)}async function Cp(e){const t=_p('x[xmlns="jabber:x:conference"]',e).pop(),n=yp.getBareJidFromJid(e.getAttribute("from")),s=t.getAttribute("jid"),i=t.getAttribute("reason");let r;if(wd.settings.get("auto_join_on_invite"))r=!0;else{const e=Zl.roster.get(n)?.getDisplayName()??n;r=await wd.hook("confirmDirectMUCInvitation",{contact:e,reason:i,jid:s},!1)}if(r){(await async function(e,t){t.type=Zl.CHATROOMS_TYPE,t.id=e;const n=await wd.rooms.get(e,t,!0);return n.maybeShow(!0),n}(s,{password:t.getAttribute("password")})).session.get("connection_status")===Fm.ROOMSTATUS.DISCONNECTED&&Zl.chatboxes.get(s).rejoin()}}function kp(){if(!Zl.xmppstatus)throw new Error("Can't call _converse.getDefaultMUCNickname before the statusInitialized has been fired.");const e=Zl.xmppstatus.getNickname();return e||(wd.settings.get("muc_nickname_from_jid")?yp.unescapeNode(yp.getNodeFromJid(Zl.bare_jid)):void 0)}function jp(e){return!!wd.settings.get("muc_show_info_messages").includes(e)}async function Tp(){await Promise.all(wd.settings.get("auto_join_rooms").map((e=>"string"==typeof e?Zl.chatboxes.where({jid:e}).length?Promise.resolve():wd.rooms.open(e):y(e)?wd.rooms.open(e.jid,{...e}):($l.error('Invalid muc criteria specified for "auto_join_rooms"'),Promise.resolve())))),wd.trigger("roomsAutoJoined")}function Ip(){wd.disco.own.features.add(yp.NS.MUC),wd.settings.get("allow_muc_invitations")&&wd.disco.own.features.add("jabber:x:conference")}function Np(){Zl.chatboxes.where({type:Zl.CHATROOMS_TYPE}).forEach((e=>gl(e.session,{connection_status:Fm.ROOMSTATUS.DISCONNECTED})))}function Mp(){window.addEventListener(Zl.unloadevent,(()=>{!wd.connection.isType("websocket")||wd.settings.get("enable_smacks")&&Zl.session.get("smacks_stream_id")||Ap()}))}function Op(){Zl.connection.addHandler((e=>{const t=yp.getBareJidFromJid(e.getAttribute("from"));return Zl.chatboxes.get(t)||wd.waitUntil("chatBoxesFetched").then((async()=>{const n=Zl.chatboxes.get(t);n&&(await n.initialized,n.message_handler.run(e))})),!0}),null,"message","groupchat")}Object.assign(Zl,{getAssignableRoles:Sp});const{u:Rp}=Fm.env;const Dp=class extends gu{model=vp;comparator(e,t){const n=e.get("role")||"none",s=t.get("role")||"none";if(Df[n]===Df[s]){const n=e.getDisplayName().toLowerCase(),s=t.getDisplayName().toLowerCase();return ns?1:0}return Df[n]np(e,t)))),s=n.reduce(((e,t)=>Rp.isErrorObject(t)?e:[...t,...e]),[]),i=e.filter((t=>!Rp.isErrorObject(n[e.indexOf(t)]))),r=s.map((e=>e.jid)).filter((e=>void 0!==e)),o=s.map((e=>!e.jid&&e.nick||void 0)).filter((e=>void 0!==e)),a=this.filter((e=>i.includes(e.get("affiliation"))&&!o.includes(e.get("nick"))&&!r.includes(e.get("jid"))));a.forEach((e=>{e.get("jid")!==Zl.bare_jid&&("offline"===e.get("show")?e.destroy():e.save("affiliation",null))})),s.forEach((e=>{const t=this.findOccupant(e);t?t.save(e):this.create(e)})),wd.trigger("membersFetched")}findOccupant(e){if(e.occupant_id)return this.get(e.occupant_id);const t=e.jid&&Oo.getBareJidFromJid(e.jid);return t&&this.findWhere({jid:t})||e.nick&&this.findWhere({nick:e.nick})}getOwnOccupant(){return this.findOccupant({jid:Zl.bare_jid,occupant_id:this.chatroom.get("occupant_id")})}},zp={affiliations:{set:(e,t)=>(t=Array.isArray(t)?t:[t],ip(e=Array.isArray(e)?e:[e],t))}},{u:Pp}=Fm.env,Lp={rooms:{create(e){let t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};if(t="string"==typeof t?{nick:t}:t||{},!t.nick&&wd.settings.get("muc_nickname_from_jid")&&(t.nick=Oo.getNodeFromJid(Zl.bare_jid)),void 0===e)throw new TypeError("rooms.create: You need to provide at least one JID");return"string"==typeof e?wd.rooms.get(Pp.getJIDFromURI(e),t,!0):e.map((e=>wd.rooms.get(Pp.getJIDFromURI(e),t,!0)))},async open(e){let t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},n=arguments.length>2&&void 0!==arguments[2]&&arguments[2];if(await wd.waitUntil("chatBoxesFetched"),void 0===e){const e="rooms.open: You need to provide at least one JID";throw $l.error(e),new TypeError(e)}if("string"==typeof e){const s=await wd.rooms.get(e,t,!0);return!t.hidden&&s?.maybeShow(n),s}{const s=await Promise.all(e.map((e=>wd.rooms.get(e,t,!0))));return s.forEach((e=>!t.hidden&&e.maybeShow(n))),s}},async get(e){let t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},n=arguments.length>2&&void 0!==arguments[2]&&arguments[2];async function s(e){e=Pp.getJIDFromURI(e);let s=await wd.chatboxes.get(e);return!s&&n?s=await wd.chatboxes.create(e,t,Zl.ChatRoom):(s=s&&s.get("type")===Zl.CHATROOMS_TYPE?s:null,s&&Object.keys(t).length&&s.save(t)),s}if(await wd.waitUntil("chatBoxesFetched"),void 0===e){return(await wd.chatboxes.get()).filter((e=>e.get("type")===Zl.CHATROOMS_TYPE))}return"string"==typeof e?s(e):Promise.all(e.map((e=>s(e))))}}},Fp=["owner","admin","member","outcast","none"];Fm.AFFILIATION_CHANGES=zf,Fm.AFFILIATION_CHANGES_LIST=Pf,Fm.MUC_TRAFFIC_STATES=Lf,Fm.MUC_TRAFFIC_STATES_LIST=Ff,Fm.MUC_ROLE_CHANGES=Uf,Fm.MUC_ROLE_CHANGES_LIST=Bf,Fm.MUC={INFO_CODES:qf},Fm.MUC_NICK_CHANGED_CODE="303",Fm.ROOM_FEATURES=["passwordprotected","unsecured","hidden","publicroom","membersonly","open","persistent","temporary","nonanonymous","semianonymous","moderated","unmoderated","mam_enabled"],Fm.ROOMSTATUS=Hf;const{Strophe:Up}=Fm.env;Up.addNamespace("MUC_ADMIN",Up.NS.MUC+"#admin"),Up.addNamespace("MUC_OWNER",Up.NS.MUC+"#owner"),Up.addNamespace("MUC_REGISTER","jabber:iq:register"),Up.addNamespace("MUC_ROOMCONF",Up.NS.MUC+"#roomconfig"),Up.addNamespace("MUC_USER",Up.NS.MUC+"#user"),Up.addNamespace("MUC_HATS","xmpp:prosody.im/protocol/hats:1"),Up.addNamespace("CONFINFO","urn:ietf:params:xml:ns:conference-info"),Fm.plugins.add("converse-muc",{dependencies:["converse-chatboxes","converse-chat","converse-disco"],overrides:{ChatBoxes:{model(e,t){const{_converse:n}=this.__super__;return e&&e.type==n.CHATROOMS_TYPE?new n.ChatRoom(e,t):this.__super__.model.apply(this,arguments)}}},initialize(){const{__:e,___:t}=Zl;if(wd.settings.extend({allow_muc_invitations:!0,auto_join_on_invite:!1,auto_join_rooms:[],auto_register_muc_nickname:!1,hide_muc_participants:!1,locked_muc_domain:!1,modtools_disable_assign:!1,muc_clear_messages_on_leave:!0,muc_domain:void 0,muc_fetch_members:!0,muc_history_max_stanzas:void 0,muc_instant_rooms:!0,muc_nickname_from_jid:!1,muc_send_probes:!1,muc_show_info_messages:[...Fm.MUC.INFO_CODES.visibility_changes,...Fm.MUC.INFO_CODES.self,...Fm.MUC.INFO_CODES.non_privacy_changes,...Fm.MUC.INFO_CODES.muc_logging_changes,...Fm.MUC.INFO_CODES.nickname_changes,...Fm.MUC.INFO_CODES.disconnected,...Fm.MUC.INFO_CODES.affiliation_changes,...Fm.MUC.INFO_CODES.join_leave_events,...Fm.MUC.INFO_CODES.role_changes],muc_show_logs_before_join:!1,muc_subscribe_to_rai:!1}),wd.promises.add(["roomsAutoJoined"]),wd.settings.get("locked_muc_domain")&&"string"!=typeof wd.settings.get("muc_domain"))throw new Error("Config Error: it makes no sense to set locked_muc_domain to true when muc_domain is not set");Fm.env.muc_utils={computeAffiliationsDelta:op},Object.assign(wd,Lp),Object.assign(wd.rooms,zp),Zl.muc={info_messages:{100:e("This groupchat is not anonymous"),102:e("This groupchat now shows unavailable members"),103:e("This groupchat does not show unavailable members"),104:e("The groupchat configuration has changed"),170:e("Groupchat logging is now enabled"),171:e("Groupchat logging is now disabled"),172:e("This groupchat is now no longer anonymous"),173:e("This groupchat is now semi-anonymous"),174:e("This groupchat is now fully-anonymous"),201:e("A new groupchat has been created")},new_nickname_messages:{210:t("Your nickname has been automatically set to %1$s"),303:t("Your nickname has been changed to %1$s")},disconnect_messages:{301:e("You have been banned from this groupchat"),333:e("You have exited this groupchat due to a technical problem"),307:e("You have been kicked from this groupchat"),321:e("You have been removed from this groupchat because of an affiliation change"),322:e("You have been removed from this groupchat because the groupchat has changed to members-only and you're not a member"),332:e("You have been removed from this groupchat because the service hosting it is being shut down")}},Zl.router.route("converse/room?jid=:jid",$p),Zl.ChatRoom=Zl.ChatBox.extend(pp),Zl.ChatRoomMessage=Zl.Message.extend(kf),Zl.ChatRoomOccupants=Dp,Zl.ChatRoomOccupant=vp,Zl.ChatRoomMessages=gu.extend({model:Zl.ChatRoomMessage,comparator:"time"}),Object.assign(Zl,{getDefaultMUCNickname:kp,isInfoVisible:jp,onDirectMUCInvitation:Cp}),wd.settings.get("allow_muc_invitations")&&(wd.listen.on("connected",xp),wd.listen.on("reconnected",xp)),wd.listen.on("addClientFeatures",(()=>wd.disco.own.features.add(`${Up.NS.CONFINFO}+notify`))),wd.listen.on("addClientFeatures",Ip),wd.listen.on("beforeResourceBinding",Op),wd.listen.on("beforeTearDown",Np),wd.listen.on("chatBoxesFetched",Tp),wd.listen.on("disconnected",Ap),wd.listen.on("statusInitialized",Mp),wd.listen.on("windowStateChanged",Ep)}});const{Strophe:Bp}=Fm.env,qp=dr.extend({idAttribute:"jid",getDisplayName(){return Bp.xmlunescape(this.get("name"))}}),{Strophe:Hp,$iq:Gp,sizzle:Wp}=Fm.env,Vp={model:qp,comparator:e=>e.get("name").toLowerCase(),async initialize(){this.on("add",(e=>this.openBookmarkedRoom(e).then((e=>this.markRoomAsBookmarked(e))).catch((e=>$l.fatal(e))))),this.on("remove",this.markRoomAsUnbookmarked,this),this.on("remove",this.sendBookmarkStanza,this);const e=`converse.room-bookmarks${Zl.bare_jid}`;this.fetched_flag=e+"fetched",Gc(this,e),await this.fetchBookmarks(),wd.trigger("bookmarksInitialized",this)},async openBookmarkedRoom(e){if(wd.settings.get("muc_respect_autojoin")&&e.get("autojoin")){(await wd.rooms.create(e.get("jid"),{nick:e.get("nick")})).maybeShow()}return e},fetchBookmarks(){const e=Xo();return window.sessionStorage.getItem(this.fetched_flag)?this.fetch({success:()=>e.resolve(),error:()=>e.resolve()}):this.fetchBookmarksFromServer(e),e},createBookmark(e){this.create(e),this.sendBookmarkStanza().catch((t=>this.onBookmarkError(t,e)))},sendBookmarkStanza(){const e=Gp({type:"set",from:Zl.connection.jid}).c("pubsub",{xmlns:Hp.NS.PUBSUB}).c("publish",{node:Hp.NS.BOOKMARKS}).c("item",{id:"current"}).c("storage",{xmlns:Hp.NS.BOOKMARKS});return this.forEach((t=>{e.c("conference",{name:t.get("name"),autojoin:t.get("autojoin"),jid:t.get("jid")}).c("nick").t(t.get("nick")).up().up()})),e.up().up().up(),e.c("publish-options").c("x",{xmlns:Hp.NS.XFORM,type:"submit"}).c("field",{var:"FORM_TYPE",type:"hidden"}).c("value").t("http://jabber.org/protocol/pubsub#publish-options").up().up().c("field",{var:"pubsub#persist_items"}).c("value").t("true").up().up().c("field",{var:"pubsub#access_model"}).c("value").t("whitelist"),wd.sendIQ(e)},onBookmarkError(e,t){const{__:n}=Zl;$l.error("Error while trying to add bookmark"),$l.error(e),wd.alert("error",n("Error"),[n("Sorry, something went wrong while trying to save your bookmark.")]),this.get(t.jid)?.destroy()},fetchBookmarksFromServer(e){const t=Gp({from:Zl.connection.jid,type:"get"}).c("pubsub",{xmlns:Hp.NS.PUBSUB}).c("items",{node:Hp.NS.BOOKMARKS});wd.sendIQ(t).then((t=>this.onBookmarksReceived(e,t))).catch((t=>this.onBookmarksReceivedError(e,t)))},markRoomAsBookmarked(e){const t=Zl.chatboxes.get(e.get("jid"));t?.save("bookmarked",!0)},markRoomAsUnbookmarked(e){const t=Zl.chatboxes.get(e.get("jid"));t?.save("bookmarked",!1)},createBookmarksFromStanza(e){const t=Hp.NS.BOOKMARKS;Wp(`items[node="${t}"] item storage[xmlns="${t}"] conference`,e).forEach((e=>{const t=e.getAttribute("jid"),n=this.get(t),s={jid:t,name:e.getAttribute("name")||t,autojoin:"true"===e.getAttribute("autojoin"),nick:e.querySelector("nick")?.textContent||""};n?n.save(s):this.create(s)}))},onBookmarksReceived(e,t){if(this.createBookmarksFromStanza(t),window.sessionStorage.setItem(this.fetched_flag,!0),void 0!==e)return e.resolve()},onBookmarksReceivedError(e,t){const{__:n}=Zl;if(null===t)$l.error("Error: timeout while fetching bookmarks"),wd.alert("error",n("Timeout Error"),[n("The server did not return your bookmarks within the allowed time. You can reload the page to request them again.")]);else{if(e)return t.querySelector('error[type="cancel"] item-not-found')?(window.sessionStorage.setItem(this.fetched_flag,!0),e.resolve()):($l.error("Error while fetching bookmarks"),$l.error(t),e.reject(new Error("Could not fetch bookmarks")));$l.error("Error while fetching bookmarks"),$l.error(t)}},async getUnopenedBookmarks(){return await wd.waitUntil("bookmarksInitialized"),await wd.waitUntil("chatBoxesFetched"),this.filter((e=>!Zl.chatboxes.get(e.get("jid"))))}},Zp=Vp,{Strophe:Qp,sizzle:Jp}=Fm.env;async function Kp(){const e=await wd.disco.getIdentity("pubsub","pep",Zl.bare_jid);return wd.settings.get("allow_public_bookmarks")?!!e:wd.disco.supports(Qp.NS.PUBSUB+"#publish-options",Zl.bare_jid)}function Yp(e){return Jp(`event[xmlns="${Qp.NS.PUBSUB}#event"] items[node="${Qp.NS.BOOKMARKS}"]`,e).length&&wd.waitUntil("bookmarksInitialized").then((()=>Zl.bookmarks.createBookmarksFromStanza(e))).catch((e=>$l.fatal(e))),!0}const{Strophe:Xp}=Fm.env;Xp.addNamespace("BOOKMARKS","storage:bookmarks"),Fm.plugins.add("converse-bookmarks",{dependencies:["converse-chatboxes","converse-muc"],overrides:{ChatRoom:{getDisplayName(){const{_converse:e,getDisplayName:t}=this.__super__,n=this.get("bookmarked")?e.bookmarks?.get(this.get("jid")):null;return n?.get("name")||t.apply(this,arguments)},getAndPersistNickname(e){var t;return e=e||(t=this.get("jid"),wd.settings.get("allow_bookmarks")?Zl.bookmarks?.get(t)?.get("nick"):null),this.__super__.getAndPersistNickname.call(this,e)}}},initialize(){wd.settings.extend({allow_bookmarks:!0,allow_public_bookmarks:!1,muc_respect_autojoin:!0}),wd.promises.add("bookmarksInitialized"),Zl.Bookmark=qp,Zl.Bookmarks=gu.extend(Zp),wd.listen.on("addClientFeatures",(()=>{wd.settings.get("allow_bookmarks")&&wd.disco.own.features.add(Xp.NS.BOOKMARKS+"+notify")})),wd.listen.on("clearSession",(()=>{Zl.bookmarks&&(Zl.bookmarks.clearStore({silent:!0}),window.sessionStorage.removeItem(Zl.bookmarks.fetched_flag),delete Zl.bookmarks)})),wd.listen.on("connected",(async()=>{const{connection:e}=Zl;e.addHandler(Yp,null,"message","headline",null,Zl.bare_jid),await Promise.all([wd.waitUntil("chatBoxesFetched")]),async function(){wd.settings.get("allow_bookmarks")&&await Kp()&&(Zl.bookmarks=new Zl.Bookmarks)}()}))}});const{Strophe:ev}=Fm.env,tv="converse.bosh-session";Fm.plugins.add("converse-bosh",{enabled:()=>!Zl.api.settings.get("blacklisted_plugins").includes("converse-bosh"),initialize(){wd.settings.extend({bosh_service_url:void 0,prebind_url:null}),Zl.startNewPreboundBOSHSession=function(){if(!wd.settings.get("prebind_url"))throw new Error("startNewPreboundBOSHSession: If you use prebind then you MUST supply a prebind_url");const e=new XMLHttpRequest;e.open("GET",wd.settings.get("prebind_url"),!0),e.setRequestHeader("Accept","application/json, text/javascript"),e.onload=async function(){if(e.status>=200&&e.status<400){const t=JSON.parse(e.responseText),n=await gd(t.jid);Zl.connection.attach(n,t.sid,t.rid,Zl.connection.onConnectStatusChanged,59)}else e.onerror()},e.onerror=function(){delete Zl.connection,wd.trigger("noResumeableBOSHSession",Zl)},e.send()},Zl.restoreBOSHSession=async function(){const e=(await async function(){const e=tv;if(Zl.bosh_session||(Zl.bosh_session=new dr({id:e}),Zl.bosh_session.browserStorage=Zl.createStore(e,"session"),await new Promise((e=>Zl.bosh_session.fetch({success:e,error:e})))),Zl.jid){if(Zl.bosh_session.get("jid")!==Zl.jid){const e=await gd(Zl.jid);Zl.bosh_session.clear({silent:!0}),Zl.bosh_session.save({jid:e})}}else{const e=Zl.bosh_session.get("jid");e&&await gd(e)}return Zl.bosh_session}()).get("jid");if(e&&Zl.connection._proto instanceof ev.Bosh)try{return Zl.connection.restore(e,Zl.connection.onConnectStatusChanged),!0}catch(t){return!Zl.isTestEnv()&&$l.warn("Could not restore session for jid: "+e+" Error message: "+t.message),!1}return!1},wd.listen.on("clearSession",(()=>{if(void 0===Zl.bosh_session){const e=tv;sessionStorage.removeItem(e),sessionStorage.removeItem(`${e}-${e}`)}else Zl.bosh_session.destroy(),delete Zl.bosh_session})),wd.listen.on("setUserJID",(()=>{void 0!==Zl.bosh_session&&Zl.bosh_session.save({jid:Zl.jid})})),wd.listen.on("addClientFeatures",(()=>wd.disco.own.features.add(ev.NS.BOSH))),Object.assign(wd,{tokens:{get:e=>void 0===Zl.connection?null:"rid"===e.toLowerCase()?Zl.connection.rid||Zl.connection._proto.rid:"sid"===e.toLowerCase()?Zl.connection.sid||Zl.connection._proto.sid:void 0}})}});const{u:nv}=Fm.env;function sv(e,t){const n=new Uint8Array(e.byteLength+t.byteLength);return n.set(new Uint8Array(e),0),n.set(new Uint8Array(t),e.byteLength),n.buffer}function iv(e){return Array.prototype.map.call(new Uint8Array(e),(e=>("00"+e.toString(16)).slice(-2))).join("")}function rv(e){return new TextDecoder("utf-8").decode(e)}function ov(e){return new TextEncoder("utf-8").encode(e).buffer}function av(e){return btoa(new Uint8Array(e).reduce(((e,t)=>e+String.fromCharCode(t)),""))}function cv(e){const t=window.atob(e),n=t.length,s=new Uint8Array(n);for(let e=0;eparseInt(e,16))));return t.buffer}Object.assign(nv,{arrayBufferToHex:iv,arrayBufferToString:rv,stringToArrayBuffer:ov,arrayBufferToBase64:av,base64ToArrayBuffer:cv});const{Strophe:dv,$build:uv}=Fm.env;function hv(e,t){return e.sort(((e,n)=>e[t]>n[t]?-1:1))}async function mv(){const e=Zl.api.disco.own.identities.get(),t=Zl.api.disco.own.features.get();e.length>1&&(hv(e,"category"),hv(e,"type"),hv(e,"lang"));let n=e.reduce(((e,t)=>`${e}${t.category}/${t.type}/${t?.lang??""}/${t.name}<`),"");t.sort(),n=t.reduce(((e,t)=>`${e}${t}<`),n);return av(await crypto.subtle.digest("SHA-1",ov(n)))}async function gv(e){const t=await async function(){return uv("c",{xmlns:dv.NS.CAPS,hash:"sha-1",node:"https://conversejs.org",ver:await mv()}).tree()}();return e.root().cnode(t).up(),e}const{Strophe:fv}=Fm.env;fv.addNamespace("CAPS","http://jabber.org/protocol/caps"),Fm.plugins.add("converse-caps",{dependencies:["converse-status"],initialize(){wd.listen.on("constructedPresence",((e,t)=>gv(t))),wd.listen.on("constructedMUCPresence",((e,t)=>gv(t)))}});const pv=gu.extend({comparator:"time_opened",model:(e,t)=>new Zl.ChatBox(e,t),onChatBoxesFetched(e){e.filter((e=>!e.isValid())).forEach((e=>e.destroy())),wd.trigger("chatBoxesFetched")},onConnected(e){e||(Gc(this,`converse.chatboxes-${Zl.bare_jid}`),this.fetch({add:!0,success:e=>this.onChatBoxesFetched(e)}))}}),vv=pv,{Strophe:yv}=Fm.env;async function _v(e,t,n){let s;e=yv.getBareJidFromJid(e.toLowerCase()),Object.assign(t,{jid:e,id:e});try{s=new n(t,{collection:Zl.chatboxes})}catch(e){return $l.error(e),null}return await s.initialized,s.isValid()?(Zl.chatboxes.add(s),s):(s.destroy(),null)}const bv={async create(){let e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:[],t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},n=arguments.length>2?arguments[2]:void 0;return await wd.waitUntil("chatBoxesFetched"),"string"==typeof e?_v(e,t,n):Promise.all(e.map((e=>_v(e,t,n))))},get:async e=>(await wd.waitUntil("chatBoxesFetched"),void 0===e?Zl.chatboxes.models:"string"==typeof e?Zl.chatboxes.get(e.toLowerCase()):(e=e.map((e=>e.toLowerCase())),Zl.chatboxes.models.filter((t=>e.includes(t.get("jid"))))))},{Strophe:wv}=Fm.env;Fm.plugins.add("converse-chatboxes",{dependencies:["converse-emoji","converse-roster","converse-vcard"],initialize(){wd.promises.add(["chatBoxesFetched","chatBoxesInitialized","privateChatsAutoJoined"]),Object.assign(wd,{chatboxes:bv}),Zl.ChatBoxes=vv,wd.listen.on("addClientFeatures",(()=>{wd.disco.own.features.add(wv.NS.MESSAGE_CORRECT),wd.disco.own.features.add(wv.NS.HTTPUPLOAD),wd.disco.own.features.add(wv.NS.OUTOFBAND)})),wd.listen.on("pluginsInitialized",(()=>{Zl.chatboxes=new Zl.ChatBoxes,wd.trigger("chatBoxesInitialized")})),wd.listen.on("presencesInitialized",(e=>Zl.chatboxes.onConnected(e))),wd.listen.on("reconnected",(()=>Zl.chatboxes.forEach((e=>e.onReconnection()))))}});const{Strophe:Sv,u:xv}=Fm.env;function Av(e,t){const n=Yo()(`command[xmlns="${Sv.NS.ADHOC}"]`,e).pop(),s={sessionid:n.getAttribute("sessionid"),instructions:Yo()('x[type="form"][xmlns="jabber:x:data"] instructions',n).pop()?.textContent,fields:Yo()('x[type="form"][xmlns="jabber:x:data"] field',n).map((e=>xv.xForm2TemplateResult(e,n,{domain:t}))),actions:Array.from(n.querySelector("actions")?.children).map((e=>e.nodeName.toLowerCase()))??[]};return s}const{Strophe:Ev,$iq:$v,u:Cv,stx:kv}=Fm.env,jv={adhoc:{async getCommands(e){try{return t=await wd.disco.items(e,Ev.NS.ADHOC),Yo()(`query[xmlns="${Sv.NS.DISCO_ITEMS}"][node="${Sv.NS.ADHOC}"] item`,t).map(Ig)}catch(t){return null===t?$l.error(`Error: timeout while fetching ad-hoc commands for ${e}`):($l.error(`Error while fetching ad-hoc commands for ${e}`),$l.error(t)),[]}var t},async fetchCommandForm(e){const t=e.node,n=e.jid,s=$v({type:"set",to:n}).c("command",{xmlns:Ev.NS.ADHOC,node:t,action:"execute"});try{return Av(await wd.sendIQ(s),n)}catch(e){null===e?$l.error(`Error: timeout while trying to execute command for ${n}`):($l.error(`Error while trying to execute command for ${n}`),$l.error(e));const{__:t}=Zl;return{instructions:t("An error occurred while trying to fetch the command form"),fields:[]}}},async runCommand(e,t,n,s,i){const r=kv` + + ${["cancel","prev"].includes(s)?"":kv` + + ${i.reduce(((e,t)=>{let{name:n,value:s}=t;return e+`${s}`}),"")} + `} + + `,o=await wd.sendIQ(r,null,!1);if(null===o){$l.warn("A timeout occurred while trying to run an ad-hoc command");const{__:e}=Zl;return{status:"error",note:e("A timeout occurred")}}Cv.isErrorStanza(o)&&($l.error("Error while trying to execute an ad-hoc command"),$l.error(o));const a=o.querySelector("command"),c=a?.getAttribute("status");return{status:c,..."executing"===c?Av(o):{},note:o.querySelector("note")?.textContent}}}},{Strophe:Tv}=Fm.env;Tv.addNamespace("ADHOC","http://jabber.org/protocol/commands"),Fm.plugins.add("converse-adhoc",{dependencies:["converse-disco"],initialize(){Object.assign(this._converse.api,jv)}});class Iv extends Lg{defaults(){return{bookmarked:!1,hidden:["mobile","fullscreen"].includes(wd.settings.get("view_mode")),message_type:"headline",num_unread:0,time_opened:this.get("time_opened")||(new Date).getTime(),type:Zl.HEADLINES_TYPE}}async initialize(){this.set({box_id:`box-${this.get("jid")}`}),this.initUI(),this.initMessages(),await this.fetchMessages(),wd.trigger("headlinesFeedInitialized",this)}}const Nv={headlines:{async get(e){let t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},n=arguments.length>2&&void 0!==arguments[2]&&arguments[2];async function s(e){let s=await wd.chatboxes.get(e);return!s&&n?s=await wd.chatboxes.create(e,t,Zl.HeadlinesFeed):(s=s&&s.get("type")===Zl.HEADLINES_TYPE?s:null,s&&Object.keys(t).length&&s.save(t)),s}if(void 0===e){return(await wd.chatboxes.get()).filter((e=>e.get("type")===Zl.HEADLINES_TYPE))}return"string"==typeof e?s(e):Promise.all(e.map((e=>s(e))))}}};Fm.plugins.add("converse-headlines",{dependencies:["converse-chat"],overrides:{ChatBoxes:{model(e,t){const{_converse:n}=this.__super__;return e.type==n.HEADLINES_TYPE?new n.HeadlinesFeed(e,t):this.__super__.model.apply(this,arguments)}}},initialize(){function e(){Zl.connection.addHandler((e=>async function(e){if(kg(e)||jg(e)){const t=e.getAttribute("from");if(await wd.waitUntil("rosterInitialized"),t.includes("@")&&!Zl.roster.get(t)&&!wd.settings.get("allow_non_roster_messaging"))return;if(null===e.querySelector("body"))return;const n=Zl.chatboxes.create({id:t,jid:t,type:Zl.HEADLINES_TYPE,from:t}),s=await Og(e);await n.createMessage(s),wd.trigger("message",{chatbox:n,stanza:e,attrs:s})}}(e)||!0),null,"message")}Zl.HeadlinesFeed=Iv,wd.listen.on("connected",e),wd.listen.on("reconnected",e),Object.assign(wd,Nv)}});const Mv=Fm.env.utils;class Ov extends dr{defaults(){return{msgid:Mv.getUniqueId(),is_ephemeral:!1}}}const{Strophe:Rv,$build:Dv}=Fm.env;Rv.addNamespace("RSM","http://jabber.org/protocol/rsm");const zv=["after","before","index","max"],Pv=e=>Number(e),Lv=e=>e.toString(),Fv={after:Lv,before:Lv,count:Pv,first:Lv,index:Pv,last:Lv,max:Pv},Uv=e=>void 0===e,Bv=Object.keys(Fv);class qv{static getQueryParameters(){return lr(arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},zv)}static parseXMLResult(e){const t={};for(var n=0;n0&&void 0!==arguments[0]?arguments[0]:{};this.query=qv.getQueryParameters(e),this.result=e.xml?qv.parseXMLResult(e.xml):{}}toXML(){const e=Dv("set",{xmlns:Rv.NS.RSM});return zv.reduce(((e,t)=>Uv(this.query[t])?e:e.c(t).t((this.query[t]||"").toString()).up()),e).tree()}next(e,t){const n=Object.assign({},this.query,{after:this.result.last,before:t,max:e});return new qv(n)}previous(e,t){const n=Object.assign({},this.query,{after:t,before:this.result.first,max:e});return new qv(n)}}Zl.RSM_ATTRIBUTES=Bv,Zl.RSM=qv;const{Strophe:Hv,$iq:Gv,dayjs:Wv}=Fm.env,{NS:Vv}=Hv,Zv=Fm.env.utils,Qv={archive:{async query(e){if(!wd.connection.connected())throw new Error("Can't call `api.archive.query` before having established an XMPP session");const t={type:"set"};if(e&&e.groupchat){if(!e.with)throw new Error('You need to specify a "with" value containing the chat room JID, when querying groupchat messages.');t.to=e.with}const n=t.to||Zl.bare_jid;if(!await wd.disco.supports(Vv.MAM,n))return $l.warn(`Did not fetch MAM archive for ${n} because it doesn't support ${Vv.MAM}`),{messages:[]};const s=Zv.getUniqueId(),i=Gv(t).c("query",{xmlns:Vv.MAM,queryid:s});if(e){i.c("x",{xmlns:Vv.XFORM,type:"submit"}).c("field",{var:"FORM_TYPE",type:"hidden"}).c("value").t(Vv.MAM).up().up(),e.with&&!e.groupchat&&i.c("field",{var:"with"}).c("value").t(e.with).up().up(),["start","end"].forEach((t=>{if(e[t]){const n=Wv(e[t]);if(!n.isValid())throw new TypeError(`archive.query: invalid date provided for: ${t}`);i.c("field",{var:t}).c("value").t(n.toISOString()).up().up()}})),i.up();const t=new qv(e);Object.keys(t.query).length&&i.cnode(t.toXML())}const r=[],o=Zl.connection.addHandler((t=>{const n=Yo()(`message > result[xmlns="${Vv.MAM}"]`,t).pop();if(void 0===n||n.getAttribute("queryid")!==s)return!0;const i=t.getAttribute("from")||Zl.bare_jid;if(e.groupchat){if(i!==e.with)return $l.warn(`Ignoring alleged groupchat MAM message from ${t.getAttribute("from")}`),!0}else if(i!==Zl.bare_jid)return $l.warn(`Ignoring alleged MAM message from ${t.getAttribute("from")}`),!0;return r.push(t),!0}),Vv.MAM);let a;const c=wd.settings.get("message_archiving_timeout"),l=await wd.sendIQ(i,c,!1);if(null===l){const{__:e}=Zl,t=e("Timeout while trying to fetch archived messages.");return $l.error(t),a=new ed(t),{messages:r,error:a}}if(Zv.isErrorStanza(l)){const{__:e}=Zl,t=e("An error occurred while querying for archived messages.");return $l.error(t),$l.error(l),a=new Error(t),{messages:r,error:a}}let d;Zl.connection.deleteHandler(o);const u=l&&Yo()(`fin[xmlns="${Vv.MAM}"]`,l).pop(),h="true"===u?.getAttribute("complete"),m=Yo()(`set[xmlns="${Vv.RSM}"]`,u).pop();return m&&(d=new qv({...e,xml:m})),{messages:r,rsm:d,complete:h}}}},{Strophe:Jv,$iq:Kv}=Fm.env,{NS:Yv}=Jv,Xv=Fm.env.utils;function ey(e){e?.querySelectorAll("feature-not-implemented").length?$l.warn(`Message Archive Management (XEP-0313) not supported by ${e.getAttribute("from")}`):($l.error(`Error while trying to set archiving preferences for ${e.getAttribute("from")}.`),$l.error(e))}function ty(e,t){const n=Yo()(`prefs[xmlns="${Yv.MAM}"]`,e).pop();if(n.getAttribute("default")!==wd.settings.get("message_archiving")){const e=Kv({type:"set"}).c("prefs",{xmlns:Yv.MAM,default:wd.settings.get("message_archiving")});Array.from(n.children).forEach((t=>e.cnode(t).up())),wd.sendIQ(e).then((()=>t.save({preferences:{default:wd.settings.get("message_archiving")}}))).catch(Zl.onMAMError)}else t.save({preferences:{default:wd.settings.get("message_archiving")}})}function ny(e){const t=e.get("preferences")||{};e.get("var")===Yv.MAM&&void 0!==wd.settings.get("message_archiving")&&t.default!==wd.settings.get("message_archiving")&&wd.sendIQ(Kv({type:"get"}).c("prefs",{xmlns:Yv.MAM})).then((t=>Zl.onMAMPreferences(t,e))).catch(Zl.onMAMError)}function sy(e){wd.settings.get("muc_show_logs_before_join")&&e.features.get("mam_enabled")&&!e.get("prejoin_mam_fetched")&&(oy(e),e.save({prejoin_mam_fetched:!0}))}async function iy(e,t,n,s,i){await wd.emojis.initialize();const r=e.get("type")===Zl.CHATROOMS_TYPE,o=await Promise.all(t.messages.map((t=>r?Yf(t,e):Og(t))));t.messages=o;const a={query:n,chatbox:e,messages:o};if(await wd.trigger("MAMResult",a,{synchronous:!0}),o.forEach((t=>e.queueMessage(t))),t.error){const n=t.error.retry_event_id=Xv.getUniqueId();wd.listen.once(n,(()=>ry(e,s,i))),e.createMessageFromError(t.error)}}async function ry(e){let t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:null;if(e.disable_mam)return;const s=e.get("type")===Zl.CHATROOMS_TYPE,i=s?e.get("jid"):Zl.bare_jid;if(!await wd.disco.supports(Yv.MAM,i))return;const r=wd.settings.get("archived_messages_page_size"),o=Object.assign({groupchat:s,max:r,with:e.get("jid")},t),a=await wd.archive.query(o);if(await iy(e,a,o,t,n),a.rsm&&!a.complete){if(n)return"forwards"===n?t=a.rsm.next(r,t.before).query:"backwards"===n&&(t=a.rsm.previous(r,t.after).query),ry(e,t,n);!async function(e,t,n){if(""==t.before&&(0===e.messages.length||!t.start))return;if(t.before&&!t.start)return;if(null==t.before)return;const s=await Promise.all(n.messages),{rsm:i}=n,r=`stanza_id ${e.get("jid")}`,o=s.find((e=>e[r]===i.result.first)),a={template_hook:"getMessageTemplate",time:new Date(new Date(o.time)-1).toISOString(),before:i.result.first,start:t.start};e.messages.add(new Ov(a))}(e,t,a)}}function oy(e){if(e.disable_mam)return;const t=e.getMostRecentMessage();if(t&&!wd.settings.get("clear_messages_on_reconnection")){if(wd.settings.get("mam_request_all_pages")){const n=t.get(`stanza_id ${e.get("jid")}`);ry(e,n?{after:n}:{start:t.get("time")},"forwards")}else ry(e,{before:"",start:t.get("time")})}else ry(e,{before:""})}const{Strophe:ay}=Fm.env,{NS:cy}=ay;Fm.plugins.add("converse-mam",{dependencies:["converse-disco","converse-muc"],initialize(){wd.settings.extend({archived_messages_page_size:"50",mam_request_all_pages:!0,message_archiving:void 0,message_archiving_timeout:2e4}),Object.assign(wd,Qv),Object.assign(Zl,{onMAMError:ey,onMAMPreferences:ty,handleMAMResult:iy,MAMPlaceholderMessage:Ov}),wd.listen.on("addClientFeatures",(()=>wd.disco.own.features.add(cy.MAM))),wd.listen.on("serviceDiscovered",ny),wd.listen.on("chatRoomViewInitialized",(e=>{wd.settings.get("muc_show_logs_before_join")&&(sy(e.model),e.model.features.on("change:mam_enabled",(()=>sy(e.model))))})),wd.listen.on("enteredNewRoom",(e=>e.features.get("mam_enabled")&&oy(e))),wd.listen.on("chatReconnected",(e=>{e.get("type")===Zl.PRIVATE_CHAT_TYPE&&oy(e)})),wd.listen.on("afterMessagesFetched",(e=>{e.get("type")===Zl.PRIVATE_CHAT_TYPE&&oy(e)}))}});const{Strophe:ly,$iq:dy}=Fm.env;let uy,hy;function my(e){"visible"===e.state&&wd.ping(null,5e3)}function gy(e){uy=new Date;const t=e.getAttribute("from"),n=e.getAttribute("id"),s=dy({type:"result",to:t,id:n});return Zl.connection.sendIQ(s),!0}function fy(){!function(){const{connection:e}=Zl;e.disco&&wd.disco.own.features.add(ly.NS.PING),e.addHandler(gy,ly.NS.PING,"iq","get")}(),Zl.connection.addHandler((()=>{if(wd.settings.get("ping_interval")>0)return uy=new Date,!0})),clearInterval(hy),hy=setInterval(vy,1e3)}function py(){clearInterval(hy)}function vy(){if(Zl.isTestEnv()||!wd.connection.authenticated())return;const e=wd.settings.get("ping_interval");if(e>0){const t=new Date;uy=uy??t,(t-uy)/1e3>e&&wd.ping()}}const{Strophe:yy,$iq:_y,u:by}=Fm.env,wy={async ping(e,t){if(!wd.connection.authenticated())return $l.warn("Not pinging when we know we're not authenticated"),null;var n;n=new Date,uy=n,e=e||yy.getDomainFromJid(Zl.bare_jid);const s=_y({type:"get",to:e,id:by.getUniqueId("ping")}).c("ping",{xmlns:yy.NS.PING}),i=await wd.sendIQ(s,t||1e4,!1);return null===i?($l.warn(`Timeout while pinging ${e}`),e===yy.getDomainFromJid(Zl.bare_jid)&&wd.connection.reconnect(),!1):!by.isErrorStanza(i)||($l.error(`Error while pinging ${e}`),$l.error(i),!1)}},{Strophe:Sy}=Fm.env;Sy.addNamespace("PING","urn:xmpp:ping"),Fm.plugins.add("converse-ping",{initialize(){wd.settings.extend({ping_interval:60}),Object.assign(wd,wy),wd.listen.on("connected",fy),wd.listen.on("reconnected",fy),wd.listen.on("disconnected",py),wd.listen.on("windowStateChanged",my)}});const{Strophe:xy,$iq:Ay}=Fm.env;xy.addNamespace("PUBSUB_ERROR",xy.NS.PUBSUB+"#errors"),Fm.plugins.add("converse-pubsub",{dependencies:["converse-disco"],initialize(){Object.assign(Zl.api,{pubsub:{async publish(e,t,n,s){let i=!(arguments.length>4&&void 0!==arguments[4])||arguments[4];const r=Ay({from:Zl.bare_jid,type:"set",to:e}).c("pubsub",{xmlns:xy.NS.PUBSUB}).c("publish",{node:t}).cnode(n.tree()).up().up();s&&(e=e||Zl.bare_jid,await wd.disco.supports(xy.NS.PUBSUB+"#publish-options",e)?(r.c("publish-options").c("x",{xmlns:xy.NS.XFORM,type:"submit"}).c("field",{var:"FORM_TYPE",type:"hidden"}).c("value").t(`${xy.NS.PUBSUB}#publish-options`).up().up(),Object.keys(s).forEach((e=>r.c("field",{var:e}).c("value").t(s[e]).up().up()))):$l.warn(`_converse.api.publish: ${e} does not support #publish-options, so we didn't set them even though they were provided.`));try{await wd.sendIQ(r)}catch(e){if(!(e instanceof Element&&i&&e.querySelector(`precondition-not-met[xmlns="${xy.NS.PUBSUB_ERROR}"]`)))throw e;{const e=r.tree();e.querySelector("publish-options").outerHTML="",$l.warn(`PubSub: Republishing without publish options. ${e.outerHTML}`),await wd.sendIQ(e)}}}}})}});const Ey=function(e){return"number"==typeof e||B(e)&&"[object Number]"==v(e)};const $y=function(e){return Ey(e)&&e!=+e},{Strophe:Cy,$pres:ky}=Fm.env;class jy extends dr{defaults(){return{status:wd.settings.get("default_state")}}initialize(){this.on("change",(e=>{y(e.changed)&&("status"in e.changed||"status_message"in e.changed)&&wd.user.presence.send(this.get("status"),null,this.get("status_message"))}))}getDisplayName(){return this.getFullname()||this.getNickname()||Zl.bare_jid}getNickname(){return wd.settings.get("nickname")}getFullname(){return""}async constructPresence(e){let t,n=arguments.length>1&&void 0!==arguments[1]?arguments[1]:null,s=arguments.length>2?arguments[2]:void 0;if(e="string"==typeof e?e:this.get("status")||wd.settings.get("default_state"),s="string"==typeof s?s:this.get("status_message"),"subscribe"===e){t=ky({to:n,type:e});const{xmppstatus:s}=Zl,i=s.getNickname();i&&t.c("nick",{xmlns:Cy.NS.NICK}).t(i).up()}else t="unavailable"===e||"probe"===e||"error"===e||"unsubscribe"===e||"unsubscribed"===e||"subscribed"===e?ky({to:n,type:e}):"offline"===e?ky({to:n,type:"unavailable"}):"online"===e?ky({to:n}):ky({to:n}).c("show").t(e).up();s&&t.c("status").t(s).up();const i=wd.settings.get("priority");t.c("priority").t($y(Number(i))?0:i).up();const{idle:r,idle_seconds:o}=Zl;if(r){const e=new Date;e.setSeconds(e.getSeconds()-o),t.c("idle",{xmlns:Cy.NS.IDLE,since:e.toISOString()})}return t=await wd.hook("constructedPresence",null,t),t}}const Ty={status:{get:async()=>(await wd.waitUntil("statusInitialized"),Zl.xmppstatus.get("status")),async set(e,t){const n={status:e};if(!Object.keys(Do).includes(e))throw new Error("Invalid availability value. See https://xmpp.org/rfcs/rfc3921.html#rfc.section.2.2.2.1");"string"==typeof t&&(n.status_message=t),await wd.waitUntil("statusInitialized"),Zl.xmppstatus.save(n)},message:{get:async()=>(await wd.waitUntil("statusInitialized"),Zl.xmppstatus.get("status_message")),async set(e){await wd.waitUntil("statusInitialized"),Zl.xmppstatus.save({status_message:e})}}}},{Strophe:Iy,$build:Ny}=Fm.env;function My(e){wd.trigger("statusInitialized",e)}function Oy(e){if(e=void 0!==Zl.xmppstatus&&e)My(e);else{const t=`converse.xmppstatus-${Zl.bare_jid}`;Zl.xmppstatus=new Zl.XMPPStatus({id:t}),Gc(Zl.xmppstatus,t,"session"),Zl.xmppstatus.fetch({success:()=>My(e),error:()=>My(e),silent:!0})}}function Ry(){Zl.idle_seconds>0&&(Zl.idle_seconds=0),Zl.connection?.authenticated&&(Zl.inactive&&Zl.sendCSI(Zl.ACTIVE),Zl.idle&&(Zl.idle=!1,wd.user.presence.send()),!0===Zl.auto_changed_status&&(Zl.auto_changed_status=!1,Zl.xmppstatus.set("status",wd.settings.get("default_state"))))}function Dy(){if(!Zl.connection?.authenticated)return;const e=Zl.xmppstatus.get("status");Zl.idle_seconds++,wd.settings.get("csi_waiting_time")>0&&Zl.idle_seconds>wd.settings.get("csi_waiting_time")&&!Zl.inactive&&Zl.sendCSI(Zl.INACTIVE),wd.settings.get("idle_presence_timeout")>0&&Zl.idle_seconds>wd.settings.get("idle_presence_timeout")&&!Zl.idle&&(Zl.idle=!0,wd.user.presence.send()),wd.settings.get("auto_away")>0&&Zl.idle_seconds>wd.settings.get("auto_away")&&"away"!==e&&"xa"!==e&&"dnd"!==e?(Zl.auto_changed_status=!0,Zl.xmppstatus.set("status","away")):wd.settings.get("auto_xa")>0&&Zl.idle_seconds>wd.settings.get("auto_xa")&&"xa"!==e&&"dnd"!==e&&(Zl.auto_changed_status=!0,Zl.xmppstatus.set("status","xa"))}function zy(e){wd.send(Ny(e,{xmlns:Iy.NS.CSI})),Zl.inactive=e===Zl.INACTIVE}function Py(){if(wd.settings.get("auto_away")<1&&wd.settings.get("auto_xa")<1&&wd.settings.get("csi_waiting_time")<1&&wd.settings.get("idle_presence_timeout")<1)return;Zl.idle_seconds=0,Zl.auto_changed_status=!1;const{unloadevent:e}=Zl;window.addEventListener("click",Zl.onUserActivity),window.addEventListener("focus",Zl.onUserActivity),window.addEventListener("keypress",Zl.onUserActivity),window.addEventListener("mousemove",Zl.onUserActivity),window.addEventListener(e,Zl.onUserActivity,{once:!0,passive:!0}),Zl.everySecondTrigger=window.setInterval(Zl.onEverySecond,1e3)}function Ly(e,t){const{xmppstatus:n}=Zl,s=n.get("status");["away","chat","dnd","xa"].includes(s)&&t.c("show").t(s).up();const i=n.get("status_message");return i&&t.c("status").t(i).up(),t}const{Strophe:Fy}=Fm.env;Fy.addNamespace("IDLE","urn:xmpp:idle:1"),Fm.plugins.add("converse-status",{initialize(){wd.settings.extend({auto_away:0,auto_xa:0,csi_waiting_time:0,default_state:"online",idle_presence_timeout:300,priority:0}),wd.promises.add(["statusInitialized"]),Zl.XMPPStatus=jy,Zl.onUserActivity=Ry,Zl.onEverySecond=Dy,Zl.sendCSI=zy,Zl.registerIntervalHandler=Py,Object.assign(Zl.api.user,Ty),wd.settings.get("idle_presence_timeout")>0&&wd.listen.on("addClientFeatures",(()=>wd.disco.own.features.add(Fy.NS.IDLE))),wd.listen.on("presencesInitialized",(e=>{e||Zl.registerIntervalHandler()})),wd.listen.on("clearSession",(()=>{cl()&&Zl.xmppstatus&&(Zl.xmppstatus.destroy(),delete Zl.xmppstatus,wd.promises.add(["statusInitialized"]))})),wd.listen.on("connected",(()=>Oy(!1))),wd.listen.on("reconnected",(()=>Oy(!0))),wd.listen.on("constructedMUCPresence",Ly)}});const Uy=dr.extend({initialize(){this.set({filter_text:"",filter_type:"contacts",chat_state:"online"})}}),{$pres:By}=Fm.env;function qy(e){const t=Zl.roster?.get(e.get("jid"));t?.save({num_unread:e.get("num_unread")})}function Hy(){void 0!==Zl.presence_ref&&(Zl.connection.deleteHandler(Zl.presence_ref),delete Zl.presence_ref)}async function Gy(){await(Zl.presences?.clearStore())}async function Wy(){await Gy(),cl()&&(Zl.rostergroups&&(await Zl.rostergroups.clearStore(),delete Zl.rostergroups),Zl.roster&&(Zl.roster.data?.destroy(),await Zl.roster.clearStore(),delete Zl.roster))}function Vy(e){e?wd.trigger("rosterReadyAfterReconnection"):function(){const e=Zl.roster=new Zl.RosterContacts;let t=`converse.contacts-${Zl.bare_jid}`;Gc(e,t);const n=Zl.roster_filter=new Uy;n.id=`_converse.rosterfilter-${Zl.bare_jid}`,Gc(n,n.id),n.fetch(),t=`converse-roster-model-${Zl.bare_jid}`,e.data=new dr,e.data.id=t,Gc(e.data,t),e.data.fetch(),wd.trigger("rosterInitialized")}(),Zl.roster.onConnected(),Hy(),Zl.presence_ref=Zl.connection.addHandler((e=>(Zl.roster.presenceHandler(e),!0)),null,"presence",null),async function(){arguments.length>0&&void 0!==arguments[0]&&arguments[0]&&(Zl.send_initial_presence=!0);try{await Zl.roster.fetchRosterContacts(),wd.trigger("rosterContactsFetched")}catch(e){$l.error(e)}finally{Zl.send_initial_presence&&wd.user.presence.send()}}(!Zl.connection.restored)}async function Zy(e){if(e)!Zl.connection.hasResumed()&&await Gy();else{Zl.presences=new Zl.Presences;const e=`converse.presences-${Zl.bare_jid}`;Gc(Zl.presences,e,"session"),Zl.presences.fetch()}wd.trigger("presencesInitialized",e)}function Qy(){Zl.chatboxes.on("change:num_unread",qy),Zl.chatboxes.on("add",(e=>{e.get("type")===Zl.PRIVATE_CHAT_TYPE&&e.setRosterContact(e.get("jid"))}))}function Jy(){Zl.roster.on("add",(e=>{const t=Zl.chatboxes.findWhere({jid:e.get("jid")});t?.setRosterContact(e.get("jid"))}))}function Ky(e,t){const n=By({to:e,type:"unsubscribed"});t&&""!==t&&n.c("status").t(t),wd.send(n)}function Yy(e,t){const n=e.presence.get("show")||"offline",s=t.presence.get("show")||"offline";if(Do[n]===Do[s]){const n=e.getDisplayName().toLowerCase(),s=t.getDisplayName().toLowerCase();return ns?1:0}return Do[n]t.toLowerCase()?1:0;if(r&&o)return s[e]s[t]?1:0;if(!r&&o){const e=Zl.HEADER_CURRENT_CONTACTS;return s[e]s[t]?1:0}if(r&&!o){const t=Zl.HEADER_CURRENT_CONTACTS;return s[e]s[t]?1:0}}const{Strophe:e_,$iq:t_,$pres:n_}=Fm.env,s_=dr.extend({idAttribute:"jid",defaults:{chat_state:void 0,groups:[],image:Zl.DEFAULT_IMAGE,image_type:Zl.DEFAULT_IMAGE_TYPE,num_unread:0,status:void 0},async initialize(e){this.initialized=Xo(),this.setPresence();const{jid:t}=e;this.set({...e,jid:e_.getBareJidFromJid(t).toLowerCase(),user_id:e_.getNodeFromJid(t)}),this.listenTo(this.presence,"change:show",(()=>wd.trigger("contactPresenceChanged",this))),this.listenTo(this.presence,"change:show",(()=>this.trigger("presenceChanged"))),await wd.trigger("rosterContactInitialized",this,{Synchronous:!0}),this.initialized.resolve()},setPresence(){const e=this.get("jid");this.presence=Zl.presences.findWhere(e)||Zl.presences.create({jid:e})},openChat(){const e=this.attributes;wd.chats.open(e.jid,e,!0)},getFilterCriteria(){const e=this.get("nickname"),t=this.get("jid");let n=this.getDisplayName();return n=n.includes(t)?n:n.concat(` ${t}`),n=n.includes(e)?n:n.concat(` ${e}`),n.toLowerCase()},getDisplayName(){return this.get("nickname")?this.get("nickname"):this.get("jid")},getFullname(){return this.get("jid")},subscribe(e){return wd.user.presence.send("subscribe",this.get("jid"),e),this.save("ask","subscribe"),this},ackSubscribe(){wd.send(n_({type:"subscribe",to:this.get("jid")}))},ackUnsubscribe(){wd.send(n_({type:"unsubscribe",to:this.get("jid")})),this.removeFromRoster(),this.destroy()},unauthorize(e){return Ky(this.get("jid"),e),this},authorize(e){const t=n_({to:this.get("jid"),type:"subscribed"});return e&&""!==e&&t.c("status").t(e),wd.send(t),this},removeFromRoster(){const e=t_({type:"set"}).c("query",{xmlns:e_.NS.ROSTER}).c("item",{jid:this.get("jid"),subscription:"remove"});return wd.sendIQ(e)}}),i_=s_,{Strophe:r_,$iq:o_,sizzle:a_,u:c_}=Fm.env,l_=gu.extend({model:i_,initialize(){const e=`roster.state-${Zl.bare_jid}-${this.get("jid")}`;this.state=new dr({id:e,collapsed_groups:[]}),Gc(this.state,e),this.state.fetch()},onConnected(){this.registerRosterHandler(),this.registerRosterXHandler()},registerRosterHandler(){Zl.connection.addHandler((e=>(Zl.roster.onRosterPush(e),!0)),r_.NS.ROSTER,"iq","set")},registerRosterXHandler(){let e=0;Zl.connection.addHandler((function(t){return window.setTimeout((function(){Zl.connection.flush(),Zl.roster.subscribeToSuggestedItems.bind(Zl.roster)(t)}),e),e+=250*t.querySelectorAll("item").length,!0}),r_.NS.ROSTERX,"message",null)},async fetchRosterContacts(){const e=await new Promise(((e,t)=>{this.fetch({add:!0,silent:!0,success:e,error:(e,n)=>t(n)})}));if(c_.isErrorObject(e)&&($l.error(e),Zl.session.save("roster_cached",!1),this.data.save("version",void 0)),!Zl.session.get("roster_cached"))return Zl.send_initial_presence=!0,Zl.roster.fetchFromServer();wd.trigger("cachedRoster",e)},subscribeToSuggestedItems:e=>(Array.from(e.querySelectorAll("item")).forEach((e=>{"add"===e.getAttribute("action")&&Zl.roster.addAndSubscribe(e.getAttribute("jid"),Zl.xmppstatus.getNickname()||Zl.xmppstatus.getFullname())})),!0),isSelf:e=>c_.isSameBareJID(e,Zl.connection.jid),async addAndSubscribe(e,t,n,s,i){const r=await this.addContactToRoster(e,t,n,i);r instanceof Zl.RosterContact&&r.subscribe(s)},sendContactAddIQ(e,t,n){t=t||null;const s=o_({type:"set"}).c("query",{xmlns:r_.NS.ROSTER}).c("item",{jid:e,name:t});return n.forEach((e=>s.c("group").t(e).up())),wd.sendIQ(s)},async addContactToRoster(e,t,n,s){await wd.waitUntil("rosterContactsFetched"),n=n||[];try{await this.sendContactAddIQ(e,t,n)}catch(n){const{__:s}=Zl;return $l.error(n),alert(s("Sorry, there was an error while trying to add %1$s as a contact.",t||e)),n}return this.create(Object.assign({ask:void 0,nickname:t,groups:n,jid:e,requesting:!1,subscription:"none"},s),{sort:!1})},async subscribeBack(e,t){const n=this.get(e);if(n instanceof Zl.RosterContact)n.authorize().subscribe();else{const n=a_(`nick[xmlns="${r_.NS.NICK}"]`,t).pop()?.textContent||null,s=await this.addContactToRoster(e,n,[],{subscription:"from"});s instanceof Zl.RosterContact&&s.authorize().subscribe()}},onRosterPush(e){const t=e.getAttribute("id"),n=e.getAttribute("from");if(n&&n!==Zl.bare_jid)return void $l.warn(`Ignoring roster illegitimate roster push message from ${e.getAttribute("from")}`);wd.send(o_({type:"result",id:t,from:Zl.connection.jid}));const s=a_(`query[xmlns="${r_.NS.ROSTER}"]`,e).pop();this.data.save("version",s.getAttribute("ver"));const i=a_("item",s);if(i.length>1)throw $l.error(e),new Error('Roster push query may not contain more than one "item" element.');if(0===i.length)return $l.warn(e),void $l.warn('Received a roster push stanza without an "item" element.');this.updateContact(i.pop()),wd.trigger("rosterPush",e)},rosterVersioningSupported(){return wd.disco.stream.getFeature("ver","urn:xmpp:features:rosterver")&&this.data.get("version")},async fetchFromServer(){const e=o_({type:"get",id:c_.getUniqueId("roster")}).c("query",{xmlns:r_.NS.ROSTER});this.rosterVersioningSupported()&&e.attrs({ver:this.data.get("version")});const t=await wd.sendIQ(e,null,!1);if("result"===t.getAttribute("type")){const e=a_(`query[xmlns="${r_.NS.ROSTER}"]`,t).pop();if(e){const t=a_("item",e);if(!this.data.get("version")&&this.models.length){const e=t.map((e=>e.getAttribute("jid")));this.forEach((t=>!t.get("requesting")&&!e.includes(t.get("jid"))&&t.destroy()))}t.forEach((e=>this.updateContact(e))),this.data.save("version",e.getAttribute("ver"))}}else if(!c_.isServiceUnavailableError(t))return $l.error(t),void $l.error("Error while trying to fetch roster from the server");Zl.session.save("roster_cached",!0),wd.trigger("roster",t)},updateContact(e){const t=e.getAttribute("jid"),n=this.get(t),s=e.getAttribute("subscription");if("remove"===s)return n?.destroy();const i=e.getAttribute("ask"),r=e.getAttribute("name"),o=[...new Set(a_("group",e).map((e=>e.textContent)))];n?n.save({subscription:s,ask:i,nickname:r,groups:o,requesting:null}):this.create({nickname:r,ask:i,groups:o,jid:t,subscription:s},{sort:!1})},createRequestingContact(e){const t={jid:r_.getBareJidFromJid(e.getAttribute("from")),subscription:"none",ask:null,requesting:!0,nickname:a_(`nick[xmlns="${r_.NS.NICK}"]`,e).pop()?.textContent||null};wd.trigger("contactRequest",this.create(t))},handleIncomingSubscription(e){const t=e.getAttribute("from"),n=r_.getBareJidFromJid(t),s=this.get(n);if(!wd.settings.get("allow_contact_requests")){const{__:e}=Zl;Ky(t,e("This client does not allow presence subscriptions"))}wd.settings.get("auto_subscribe")?s&&"to"===s.get("subscription")?s.authorize():this.subscribeBack(n,e):s?("none"!==s.get("subscription")||"subscribe"===s.get("ask"))&&s.authorize():this.createRequestingContact(e)},handleOwnPresence(e){const t=e.getAttribute("from"),n=r_.getResourceFromJid(t),s=e.getAttribute("type");if(Zl.connection.jid!==t&&"unavailable"!==s&&(!0===wd.settings.get("synchronize_availability")||wd.settings.get("synchronize_availability")===n)){const t=e.querySelector("show")?.textContent||"online";Zl.xmppstatus.save({status:t},{silent:!0});const n=e.querySelector("status")?.textContent;n&&Zl.xmppstatus.save({status_message:n})}Zl.jid===t&&"unavailable"===s&&wd.user.presence.send()},presenceHandler(e){const t=e.getAttribute("type");if("error"===t)return!0;const n=e.getAttribute("from"),s=r_.getBareJidFromJid(n);if(this.isSelf(s))return this.handleOwnPresence(e);if(a_(`query[xmlns="${r_.NS.MUC}"]`,e).length)return;const i=this.get(s);if(i){const t=e.querySelector("status")?.textContent;i.get("status")!==t&&i.save({status:t})}if("subscribed"===t&&i)i.ackSubscribe();else if("unsubscribed"===t&&i)i.ackUnsubscribe();else{if("unsubscribe"===t)return;if("subscribe"===t)this.handleIncomingSubscription(e);else if("unavailable"===t&&i){const e=r_.getResourceFromJid(n);i.presence.removeResource(e)}else i&&i.presence.addResource(e)}}}),d_=l_,{Strophe:u_}=Fm.env,h_={contacts:{async get(e){await wd.waitUntil("rosterContactsFetched");const t=e=>Zl.roster.get(u_.getBareJidFromJid(e));if(void 0===e)e=Zl.roster.pluck("jid");else if("string"==typeof e)return t(e);return e.map(t)},async add(e,t){if(await wd.waitUntil("rosterContactsFetched"),"string"!=typeof e||!e.includes("@"))throw new TypeError("contacts.add: invalid jid");return Zl.roster.addAndSubscribe(e,t)}}},{Strophe:m_,dayjs:g_,sizzle:f_}=Fm.env,p_=dr.extend({idAttribute:"name"}),v_=gu.extend({model:p_}),y_=dr.extend({idAttribute:"jid",defaults:{show:"offline"},initialize(){this.resources=new v_;const e=`converse.identities-${this.get("jid")}`;Gc(this.resources,e,"session"),this.listenTo(this.resources,"update",this.onResourcesChanged),this.listenTo(this.resources,"change",this.onResourcesChanged)},onResourcesChanged(){const e=this.getHighestPriorityResource(),t=e?.attributes?.show||"offline";this.get("show")!==t&&this.save({show:t})},getHighestPriorityResource(){return this.resources.sortBy((e=>`${e.get("priority")}-${e.get("timestamp")}`)).reverse()[0]},addResource(e){const t=e.getAttribute("from"),n=m_.getResourceFromJid(t),s=f_(`delay[xmlns="${m_.NS.DELAY}"]`,e).pop(),i=e.querySelector("priority")?.textContent,r=this.resources.get(n),o={name:n,priority:$y(parseInt(i,10))?0:parseInt(i,10),show:e.querySelector("show")?.textContent??"online",timestamp:s?g_(s.getAttribute("stamp")).toISOString():(new Date).toISOString()};r?r.save(o):this.resources.create(o)},removeResource(e){const t=this.resources.get(e);t?.destroy()}}),__=gu.extend({model:y_});Fm.plugins.add("converse-roster",{dependencies:["converse-status"],initialize(){wd.settings.extend({allow_contact_requests:!0,auto_subscribe:!1,synchronize_availability:!0}),wd.promises.add(["cachedRoster","roster","rosterContactsFetched","rosterInitialized"]),Object.assign(Zl.api,h_);const{__:e}=Zl;Zl.HEADER_CURRENT_CONTACTS=e("My contacts"),Zl.HEADER_PENDING_CONTACTS=e("Pending contacts"),Zl.HEADER_REQUESTING_CONTACTS=e("Contact requests"),Zl.HEADER_UNGROUPED=e("Ungrouped"),Zl.HEADER_UNREAD=e("New messages"),Zl.Presence=y_,Zl.Presences=__,Zl.RosterContact=i_,Zl.RosterContacts=d_,wd.listen.on("beforeTearDown",(()=>Hy())),wd.listen.on("chatBoxesInitialized",Qy),wd.listen.on("clearSession",Wy),wd.listen.on("presencesInitialized",Vy),wd.listen.on("statusInitialized",Zy),wd.listen.on("streamResumptionFailed",(()=>Zl.session.set("roster_cached",!1))),wd.waitUntil("rosterContactsFetched").then(Jy)}});const{Strophe:b_}=Fm.env,w_=Fm.env.utils;function S_(){return!(wd.connection.isType("bosh")&&!Zl.isTestEnv())&&wd.disco.stream.getFeature("sm",b_.NS.SM)}function x_(e){if(!Zl.session.get("smacks_enabled"))return!0;const t=parseInt(e.getAttribute("h"),10),n=Zl.session.get("num_stanzas_handled_by_server"),s=t-n;if(s<0){const e=`New reported stanza count lower than previous. New: ${t} - Previous: ${n}`;$l.error(e)}const i=Zl.session.get("unacked_stanzas");if(s>i.length){const e=`Higher reported acknowledge count than unacknowledged stanzas. Reported Acknowledged Count: ${s} -Unacknowledged Stanza Count: ${i.length} -New: ${t} - Previous: ${n}`;$l.error(e)}return Zl.session.save({num_stanzas_handled_by_server:t,num_stanzas_since_last_ack:0,unacked_stanzas:i.slice(s)}),!0}function A_(){if(Zl.session.get("smacks_enabled")){const e=Zl.session.get("num_stanzas_handled"),t=w_.toStanza(``);wd.send(t)}return!0}function E_(e){if(Zl.session.get("smacks_enabled")&&(w_.isTagEqual(e,"iq")||w_.isTagEqual(e,"presence")||w_.isTagEqual(e,"message"))){const e=Zl.session.get("num_stanzas_handled");Zl.session.save("num_stanzas_handled",e+1)}return!0}function $_(){Zl.session.save({smacks_enabled:Zl.session.get("smacks_enabled")||!1,num_stanzas_handled:Zl.session.get("num_stanzas_handled")||0,num_stanzas_handled_by_server:Zl.session.get("num_stanzas_handled_by_server")||0,num_stanzas_since_last_ack:Zl.session.get("num_stanzas_since_last_ack")||0,unacked_stanzas:Zl.session.get("unacked_stanzas")||[]})}function C_(){Zl.session?.save({smacks_enabled:!1,num_stanzas_handled:0,num_stanzas_handled_by_server:0,num_stanzas_since_last_ack:0,unacked_stanzas:[]})}function k_(e){const t={smacks_enabled:!0};return["1","true"].includes(e.getAttribute("resume"))&&(t.smacks_stream_id=e.getAttribute("id")),Zl.session.save(t),!0}function j_(e){return e.querySelector("item-not-found")?$l.warn("Could not resume previous SMACKS session, session id not found. A new session will be established."):($l.error("Failed to enable stream management"),$l.error(e.outerHTML)),C_(),wd.trigger("streamResumptionFailed"),!0}function T_(e){k_(e),x_(e),function(){const e=Zl.session.get("unacked_stanzas");Zl.session.save("unacked_stanzas",[]),e.forEach((e=>wd.send(e)))}(),Zl.connection.do_bind=!1,Zl.connection.authenticated=!0,Zl.connection.restored=!0,Zl.connection._changeConnectStatus(b_.Status.CONNECTED,null)}async function I_(){if(wd.settings.get("enable_smacks")&&!Zl.session.get("smacks_enabled")&&await S_()){const e=Xo();Zl.connection._addSysHandler((t=>e.resolve(k_(t))),b_.NS.SM,"enabled"),Zl.connection._addSysHandler((t=>e.resolve(j_(t))),b_.NS.SM,"failed");const t=wd.connection.isType("websocket")||Zl.isTestEnv(),n=w_.toStanza(``);wd.send(n),Zl.connection.flush(),await e}}const N_=[];async function M_(){if(!wd.settings.get("enable_smacks"))return;if(!await S_())return;const e=Zl.connection;for(;N_.length;)e.deleteHandler(N_.pop());N_.push(e.addHandler(E_)),N_.push(e.addHandler(A_,b_.NS.SM,"r")),N_.push(e.addHandler(x_,b_.NS.SM,"a")),Zl.session?.get("smacks_stream_id")?await async function(){const e=Xo();Zl.connection._addSysHandler((t=>e.resolve(T_(t))),b_.NS.SM,"resumed"),Zl.connection._addSysHandler((t=>e.resolve(j_(t))),b_.NS.SM,"failed");const t=Zl.session.get("smacks_stream_id"),n=Zl.session.get("num_stanzas_handled"),s=w_.toStanza(``);wd.send(s),Zl.connection.flush(),await e}():C_()}function O_(e){if(Zl.session){if(Zl.session.get("smacks_enabled")&&(w_.isTagEqual(e,"iq")||w_.isTagEqual(e,"presence")||w_.isTagEqual(e,"message"))){const t=b_.serialize(e);Zl.session.save("unacked_stanzas",(Zl.session.get("unacked_stanzas")||[]).concat([t]));const n=wd.settings.get("smacks_max_unacked_stanzas");if(n>0){const e=Zl.session.get("num_stanzas_since_last_ack")+1;e%n==0&&wd.send(w_.toStanza(``)),Zl.session.save({num_stanzas_since_last_ack:e})}}}else $l.warn("No _converse.session!")}const{Strophe:R_}=Fm.env;R_.addNamespace("SM","urn:xmpp:sm:3"),Fm.plugins.add("converse-smacks",{initialize(){wd.settings.extend({enable_smacks:!0,smacks_max_unacked_stanzas:5}),wd.listen.on("afterResourceBinding",I_),wd.listen.on("beforeResourceBinding",M_),wd.listen.on("send",O_),wd.listen.on("userSessionInitialized",$_)}});const D_=dr.extend({idAttribute:"jid",defaults:{image:Zl.DEFAULT_IMAGE,image_type:Zl.DEFAULT_IMAGE_TYPE},set(e,t,n){let s;return"object"==typeof e?(s=e,n=t):(s={})[e]=t,"image"in s&&!s.image?(s.image=Zl.DEFAULT_IMAGE,s.image_type=Zl.DEFAULT_IMAGE_TYPE,dr.prototype.set.call(this,s,n)):dr.prototype.set.apply(this,arguments)},getDisplayName(){return this.get("nickname")||this.get("fullname")||this.get("jid")}}),z_=D_,{Strophe:P_,$iq:L_,u:F_}=Fm.env;function U_(e,t,n){const s=L_(t?{type:e,to:t}:{type:e});return n?s.cnode(n):s.c("vCard",{xmlns:P_.NS.VCARD}),s}async function B_(e){let t;if(e instanceof Zl.Message){if(["error","info"].includes(e.get("type")))return;t=e.get("from")}else t=e.get("jid");t?(await wd.waitUntil("VCardsInitialized"),e.vcard=Zl.vcards.get(t)||Zl.vcards.create({jid:t}),e.vcard.on("change",(()=>e.trigger("vcard:change"))),e.trigger("vcard:add")):$l.warn("Could not set VCard on model because no JID found!")}async function q_(e){await wd.waitUntil("VCardsInitialized"),e.vcard=function(e){const t=e?.collection?.chatroom,n=e.get("nick");if(n&&t?.get("nick")===n)return Zl.xmppstatus.vcard;{const t=e.get("jid")||e.get("from");return t?Zl.vcards.get(t)||Zl.vcards.create({jid:t}):void $l.warn("Could not get VCard for occupant because no JID found!")}}(e),e.vcard&&(e.vcard.on("change",(()=>e.trigger("vcard:change"))),e.trigger("vcard:add"))}async function H_(e){["error","info"].includes(e.get("type"))||(await wd.waitUntil("VCardsInitialized"),e.vcard=function(e){const t=e?.collection?.chatbox,n=P_.getResourceFromJid(e.get("from"));if(n&&t?.get("nick")===n)return Zl.xmppstatus.vcard;{const t=e.occupant?.get("jid")||e.get("from");return t?Zl.vcards.get(t)||Zl.vcards.create({jid:t}):void $l.warn(`Could not get VCard for message because no JID found! msgid: ${e.get("msgid")}`)}}(e),e.vcard&&(e.vcard.on("change",(()=>e.trigger("vcard:change"))),e.trigger("vcard:add")))}async function G_(){Zl.vcards=new Zl.VCards;const e=`${Zl.bare_jid}-converse.vcards`;Gc(Zl.vcards,e),await new Promise((e=>{Zl.vcards.fetch({success:e,error:e},{silent:!0})}));const t=Zl.vcards;if(Zl.session){const e=Zl.session.get("bare_jid"),n=Zl.xmppstatus;n.vcard=t.get(e)||t.create({jid:e}),n.vcard&&(n.vcard.on("change",(()=>n.trigger("vcard:change"))),n.trigger("vcard:add"))}wd.trigger("VCardsInitialized")}async function W_(e){const t=P_.getBareJidFromJid(e)===Zl.bare_jid?null:e;let n;try{n=await wd.sendIQ(U_("get",t))}catch(n){return{jid:e,stanza:n,vcard_error:(new Date).toISOString()}}return async function(e,t){const n=t.querySelector("vCard");let s={};if(null!==n&&(s={stanza:t,fullname:n.querySelector("FN")?.textContent,nickname:n.querySelector("NICKNAME")?.textContent,image:n.querySelector("PHOTO BINVAL")?.textContent,image_type:n.querySelector("PHOTO TYPE")?.textContent,url:n.querySelector("URL")?.textContent,role:n.querySelector("ROLE")?.textContent,email:n.querySelector("EMAIL USERID")?.textContent,vcard_updated:(new Date).toISOString(),vcard_error:void 0}),s.image){const e=F_.base64ToArrayBuffer(s.image),t=await crypto.subtle.digest("SHA-1",e);s.image_hash=F_.arrayBufferToHex(t)}return s}(0,n)}const{dayjs:V_,u:Z_}=Fm.env,Q_={vcard:{async set(e,t){if(!e)throw Error("No jid provided for the VCard data");const n=document.createElement("div"),s=Z_.toStanza(`\n \n ${t.fn}\n ${t.nickname}\n ${t.url}\n ${t.role}\n ${t.email}\n \n ${t.image_type}\n ${t.image}\n \n `,n);let i;try{i=await wd.sendIQ(U_("set",e,s))}catch(e){throw e}return await wd.vcard.update(e,!0),i},get(e,t){if("string"==typeof e)return W_(e);const n=e.get("vcard_error"),s=n&&V_(n).isSame(new Date,"day");if(t||!e.get("vcard_updated")&&!s){const t=e.get("jid");return t||$l.error("No JID to get vcard for"),W_(t)}return Promise.resolve({})},async update(e,t){const n=await this.get(e,t);(e="string"==typeof e?Zl.vcards.get(e):e)?Object.keys(n).length&&(delete n.stanza,e.save(n)):$l.error(`Could not find a VCard model for ${e}`)}}},{Strophe:J_}=Fm.env;Fm.plugins.add("converse-vcard",{dependencies:["converse-status","converse-roster"],overrides:{XMPPStatus:{getNickname(){const{_converse:e}=this.__super__,t=this.__super__.getNickname.apply(this);return!t&&e.xmppstatus.vcard?e.xmppstatus.vcard.get("nickname"):t},getFullname(){const{_converse:e}=this.__super__,t=this.__super__.getFullname.apply(this);return!t&&e.xmppstatus.vcard?e.xmppstatus.vcard.get("fullname"):t}},RosterContact:{getDisplayName(){return!this.get("nickname")&&this.vcard?this.vcard.getDisplayName():this.__super__.getDisplayName.apply(this)},getFullname(){return this.vcard?this.vcard.get("fullname"):this.__super__.getFullname.apply(this)}}},initialize(){wd.promises.add("VCardsInitialized"),Zl.VCard=z_,Zl.VCards=gu.extend({model:Zl.VCard,initialize(){this.on("add",(e=>e.get("jid")&&wd.vcard.update(e)))}}),wd.listen.on("chatRoomInitialized",(e=>{B_(e),e.occupants.forEach(q_),e.listenTo(e.occupants,"add",q_),e.listenTo(e.occupants,"change:image_hash",(e=>function(e){const t=e.get("image_hash"),n=[];e.get("jid")&&n.push(Zl.vcards.get(e.get("jid"))),n.push(Zl.vcards.get(e.get("from"))),n.forEach((e=>t&&e?.get("image_hash")!==t&&wd.vcard.update(e,!0)))}(e)))})),wd.listen.on("chatBoxInitialized",(e=>B_(e))),wd.listen.on("chatRoomMessageInitialized",(e=>H_(e))),wd.listen.on("addClientFeatures",(()=>wd.disco.own.features.add(J_.NS.VCARD))),wd.listen.on("clearSession",(()=>{cl()&&(wd.promises.add("VCardsInitialized"),Zl.vcards&&(Zl.vcards.clearStore(),delete Zl.vcards))})),wd.listen.on("messageInitialized",(e=>B_(e))),wd.listen.on("rosterContactInitialized",(e=>B_(e))),wd.listen.on("statusInitialized",G_),Object.assign(Zl.api,Q_)}});var K_=n(8216),Y_=n.n(K_);const{dayjs:X_}=Fm.env;let eb;function tb(e,t){return"string"==typeof e&&t.includes(e)}function nb(e,t){if("en"===e||t(e))return e;const{languages:n}=window.navigator;let s;for(let e=0;enb(e,(e=>tb(e,t))),translate(e){if(!eb)return Y_().sprintf.apply(Y_(),arguments);const t=eb.translate(e);return arguments.length>1?t.fetch.apply(t,[].slice.call(arguments,1)):t.fetch()},async initialize(){if(Zl.isTestEnv())Zl.locale="en";else try{const e=wd.settings.get("i18n");Zl.locale=Vo.getLocale(e,wd.settings.get("locales")),eb=await async function(){const{api:e,locale:t}=Zl,s=function(e){const t=e.toLowerCase().replace("_","-");return"ug"===t?"ug-cn":t}(t);if(!tb(t,e.settings.get("locales"))||"en"===t)return;const{default:i}=await n(6404)(`./${t}/LC_MESSAGES/converse.po`);return await n(9434)(`./${s}.js`),X_.locale(nb(s,(e=>X_.locale(e)))),new(Y_())(i)}()}catch(e){$l.fatal(e.message),Zl.locale="en"}},__(){return Vo.translate(...arguments)}});const ib=Vo.__,rb={};wd.elements={registry:rb,define(e,t){this.registry[e]=t},register(){Object.keys(rb).forEach((e=>{customElements.get(e)||customElements.define(e,rb[e])}))}};class ob extends Pm{createRenderRoot(){return this}connectedCallback(){super.connectedCallback(),this.initialize?.()}disconnectedCallback(){super.disconnectedCallback(),this.stopListening()}}Object.assign(ob.prototype,Tn);const ab=["converse-adhoc-views","converse-bookmark-views","converse-chatboxviews","converse-chatview","converse-controlbox","converse-dragresize","converse-fullscreen","converse-headlines-view","converse-mam-views","converse-minimize","converse-modal","converse-muc-views","converse-notification","converse-omemo","converse-profile","converse-push","converse-register","converse-roomslist","converse-rootview","converse-rosterview","converse-singleton"];var cb=n(3379),lb=n.n(cb),db=n(7795),ub=n.n(db),hb=n(569),mb=n.n(hb),gb=n(3565),fb=n.n(gb),pb=n(9216),vb=n.n(pb),yb=n(4589),_b=n.n(yb),bb=n(6407),wb={};wb.styleTagTransform=_b(),wb.setAttributes=fb(),wb.insert=mb().bind(null,"head"),wb.domAPI=ub(),wb.insertStyleElement=vb();lb()(bb.Z,wb);bb.Z&&bb.Z.locals&&bb.Z.locals;var Sb=n(8959),xb=n.n(Sb);const Ab=e=>bm``;var Eb;const $b=window,Cb=$b.trustedTypes,kb=Cb?Cb.createPolicy("lit-html",{createHTML:e=>e}):void 0,jb="$lit$",Tb=`lit$${(Math.random()+"").slice(9)}$`,Ib="?"+Tb,Nb=`<${Ib}>`,Mb=document,Ob=()=>Mb.createComment(""),Rb=e=>null===e||"object"!=typeof e&&"function"!=typeof e,Db=Array.isArray,zb=e=>Db(e)||"function"==typeof(null==e?void 0:e[Symbol.iterator]),Pb="[ \t\n\f\r]",Lb=/<(?:(!--|\/[^a-zA-Z])|(\/?[a-zA-Z][^>\s]*)|(\/?$))/g,Fb=/-->/g,Ub=/>/g,Bb=RegExp(`>|${Pb}(?:([^\\s"'>=/]+)(${Pb}*=${Pb}*(?:[^ \t\n\f\r"'\`<>=]|("|')|))|$)`,"g"),qb=/'/g,Hb=/"/g,Gb=/^(?:script|style|textarea|title)$/i,Wb=e=>function(t){for(var n=arguments.length,s=new Array(n>1?n-1:0),i=1;i{const n=e.length-1,s=[];let i,r=2===t?"":"",o=Lb;for(let t=0;t"===c[0]?(o=null!=i?i:Lb,l=-1):void 0===c[1]?l=-2:(l=o.lastIndex-c[2].length,a=c[1],o=void 0===c[3]?Bb:'"'===c[3]?Hb:qb):o===Hb||o===qb?o=Bb:o===Fb||o===Ub?o=Lb:(o=Bb,i=void 0);const u=o===Bb&&e[t+1].startsWith("/>")?" ":"";r+=o===Lb?n+Nb:l>=0?(s.push(a),n.slice(0,l)+jb+n.slice(l)+Tb+u):n+Tb+(-2===l?(s.push(void 0),t):u)}const a=r+(e[n]||"")+(2===t?"":"");if(!Array.isArray(e)||!e.hasOwnProperty("raw"))throw Error("invalid template strings array");return[void 0!==kb?kb.createHTML(a):a,s]};class Yb{constructor(e,t){let n,{strings:s,_$litType$:i}=e;this.parts=[];let r=0,o=0;const a=s.length-1,c=this.parts,[l,d]=Kb(s,i);if(this.el=Yb.createElement(l,t),Jb.currentNode=this.el.content,2===i){const e=this.el.content,t=e.firstChild;t.remove(),e.append(...t.childNodes)}for(;null!==(n=Jb.nextNode())&&c.length0){n.textContent=Cb?Cb.emptyScript:"";for(let s=0;s2&&void 0!==arguments[2]?arguments[2]:e,s=arguments.length>3?arguments[3]:void 0;var i,r,o,a;if(t===Vb)return t;let c=void 0!==s?null===(i=n._$Co)||void 0===i?void 0:i[s]:n._$Cl;const l=Rb(t)?void 0:t._$litDirective$;return(null==c?void 0:c.constructor)!==l&&(null===(r=null==c?void 0:c._$AO)||void 0===r||r.call(c,!1),void 0===l?c=void 0:(c=new l(e),c._$AT(e,n,s)),void 0!==s?(null!==(o=(a=n)._$Co)&&void 0!==o?o:a._$Co=[])[s]=c:n._$Cl=c),void 0!==c&&(t=Xb(e,c._$AS(e,t.values),c,s)),t}class ew{constructor(e,t){this._$AV=[],this._$AN=void 0,this._$AD=e,this._$AM=t}get parentNode(){return this._$AM.parentNode}get _$AU(){return this._$AM._$AU}u(e){var t;const{el:{content:n},parts:s}=this._$AD,i=(null!==(t=null==e?void 0:e.creationScope)&&void 0!==t?t:Mb).importNode(n,!0);Jb.currentNode=i;let r=Jb.nextNode(),o=0,a=0,c=s[0];for(;void 0!==c;){if(o===c.index){let t;2===c.type?t=new tw(r,r.nextSibling,this,e):1===c.type?t=new c.ctor(r,c.name,c.strings,this,e):6===c.type&&(t=new aw(r,this,e)),this._$AV.push(t),c=s[++a]}o!==(null==c?void 0:c.index)&&(r=Jb.nextNode(),o++)}return Jb.currentNode=Mb,i}v(e){let t=0;for(const n of this._$AV)void 0!==n&&(void 0!==n.strings?(n._$AI(e,n,t),t+=n.strings.length-2):n._$AI(e[t])),t++}}class tw{constructor(e,t,n,s){var i;this.type=2,this._$AH=Zb,this._$AN=void 0,this._$AA=e,this._$AB=t,this._$AM=n,this.options=s,this._$Cp=null===(i=null==s?void 0:s.isConnected)||void 0===i||i}get _$AU(){var e,t;return null!==(t=null===(e=this._$AM)||void 0===e?void 0:e._$AU)&&void 0!==t?t:this._$Cp}get parentNode(){let e=this._$AA.parentNode;const t=this._$AM;return void 0!==t&&11===(null==e?void 0:e.nodeType)&&(e=t.parentNode),e}get startNode(){return this._$AA}get endNode(){return this._$AB}_$AI(e){e=Xb(this,e,arguments.length>1&&void 0!==arguments[1]?arguments[1]:this),Rb(e)?e===Zb||null==e||""===e?(this._$AH!==Zb&&this._$AR(),this._$AH=Zb):e!==this._$AH&&e!==Vb&&this._(e):void 0!==e._$litType$?this.g(e):void 0!==e.nodeType?this.$(e):zb(e)?this.T(e):this._(e)}k(e){return this._$AA.parentNode.insertBefore(e,this._$AB)}$(e){this._$AH!==e&&(this._$AR(),this._$AH=this.k(e))}_(e){this._$AH!==Zb&&Rb(this._$AH)?this._$AA.nextSibling.data=e:this.$(Mb.createTextNode(e)),this._$AH=e}g(e){var t;const{values:n,_$litType$:s}=e,i="number"==typeof s?this._$AC(e):(void 0===s.el&&(s.el=Yb.createElement(s.h,this.options)),s);if((null===(t=this._$AH)||void 0===t?void 0:t._$AD)===i)this._$AH.v(n);else{const e=new ew(i,this),t=e.u(this.options);e.v(n),this.$(t),this._$AH=e}}_$AC(e){let t=Qb.get(e.strings);return void 0===t&&Qb.set(e.strings,t=new Yb(e)),t}T(e){Db(this._$AH)||(this._$AH=[],this._$AR());const t=this._$AH;let n,s=0;for(const i of e)s===t.length?t.push(n=new tw(this.k(Ob()),this.k(Ob()),this,this.options)):n=t[s],n._$AI(i),s++;s0&&void 0!==arguments[0]?arguments[0]:this._$AA.nextSibling,t=arguments.length>1?arguments[1]:void 0;var n;for(null===(n=this._$AP)||void 0===n||n.call(this,!1,!0,t);e&&e!==this._$AB;){const t=e.nextSibling;e.remove(),e=t}}setConnected(e){var t;void 0===this._$AM&&(this._$Cp=e,null===(t=this._$AP)||void 0===t||t.call(this,e))}}class nw{constructor(e,t,n,s,i){this.type=1,this._$AH=Zb,this._$AN=void 0,this.element=e,this.name=t,this._$AM=s,this.options=i,n.length>2||""!==n[0]||""!==n[1]?(this._$AH=Array(n.length-1).fill(new String),this.strings=n):this._$AH=Zb}get tagName(){return this.element.tagName}get _$AU(){return this._$AM._$AU}_$AI(e){let t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:this,n=arguments.length>2?arguments[2]:void 0,s=arguments.length>3?arguments[3]:void 0;const i=this.strings;let r=!1;if(void 0===i)e=Xb(this,e,t,0),r=!Rb(e)||e!==this._$AH&&e!==Vb,r&&(this._$AH=e);else{const s=e;let o,a;for(e=i[0],o=0;o1&&void 0!==arguments[1]?arguments[1]:this,0))&&void 0!==t?t:Zb)===Vb)return;const n=this._$AH,s=e===Zb&&n!==Zb||e.capture!==n.capture||e.once!==n.once||e.passive!==n.passive,i=e!==Zb&&(n===Zb||s);s&&this.element.removeEventListener(this.name,this,n),i&&this.element.addEventListener(this.name,this,e),this._$AH=e}handleEvent(e){var t,n;"function"==typeof this._$AH?this._$AH.call(null!==(n=null===(t=this.options)||void 0===t?void 0:t.host)&&void 0!==n?n:this.element,e):this._$AH.handleEvent(e)}}class aw{constructor(e,t,n){this.element=e,this.type=6,this._$AN=void 0,this._$AM=t,this.options=n}get _$AU(){return this._$AM._$AU}_$AI(e){Xb(this,e)}}const cw=$b.litHtmlPolyfillSupport;null==cw||cw(Yb,tw),(null!==(Eb=$b.litHtmlVersions)&&void 0!==Eb?Eb:$b.litHtmlVersions=[]).push("2.7.4");const lw=(e,t,n)=>{var s,i;const r=null!==(s=null==n?void 0:n.renderBefore)&&void 0!==s?s:t;let o=r._$litPart$;if(void 0===o){const e=null!==(i=null==n?void 0:n.renderBefore)&&void 0!==i?i:null;r._$litPart$=o=new tw(t.insertBefore(Ob(),e),e,void 0,null!=n?n:{})}return o._$AI(e),o},dw=/^\s*bm`${t?"":bm`${e}`}`,fw=(e,t)=>{const n=ib('Download file "%1$s"',t);return bm`${n}`},pw=e=>bm`
${"hidden"!==e.type?bm``:""} ${"password"===e.type&&e.fixed_username?bm``:""}
`,vw=e=>bm`
`,yw=e=>bm``,_w=e=>bm`
${e.label?bm``:""}
${e.domain}
`;function bw(e){e.preventDefault(),wd.rooms.open(e.target.href)}const ww=(e,t)=>{let n=e.normalizePath().toString();return e._parts.protocol||t.startsWith("http://")||t.startsWith("https://")||(n="http://"+n),"xmpp"===e._parts.protocol&&"join"===e._parts.query?bm`${t}`:bm`${t}`},Sw=(e,t)=>bm`${t?"":bm`${e}`}`,{sizzle:xw,Strophe:Aw}=Fm.env,Ew=["http","https","xmpp","mailto"];function $w(e,t){return{"muc#roomconfig_lang":"language","muc#roomconfig_roomsecret":t?.new_password?"new-password":"current-password"}[e]}const Cw={"text-private":"password","text-single":"text",fixed:"label",boolean:"checkbox",hidden:"hidden","jid-multi":"textarea","list-single":"dropdown","list-multi":"dropdown"},kw={"xs:anyURI":"url","xs:byte":"number","xs:date":"date","xs:dateTime":"datetime","xs:int":"number","xs:integer":"number","xs:time":"time"},jw=/\s*\n\s*/;function Tw(e){let t;e=e.tree?.()??e;const n=[],s=document.createTreeWalker(e,NodeFilter.SHOW_TEXT,(e=>"body"===e.parentElement.nodeName.toLowerCase()?NodeFilter.FILTER_REJECT:NodeFilter.FILTER_ACCEPT));for(;t=s.nextNode();)n.push(t);return n.forEach((e=>jw.test(e.data)&&e.parentElement.removeChild(e))),e}const Iw=new XMLSerializer;function Nw(e){const t=e.getAttribute("name");if(!t)return null;let n;return n="checkbox"===e.getAttribute("type")?e.checked?1:0:"TEXTAREA"==e.tagName?e.value.split("\n").filter((e=>e.trim())):"SELECT"==e.tagName?xl.getSelectValues(e):e.value,{name:t,value:n}}function Mw(e){const t=Cw[e.getAttribute("type")];if("text"==t){const n=e.getElementsByTagNameNS("http://jabber.org/protocol/xdata-validate","validate");if(1===n.length){const e=n[0].getAttribute("datatype");return kw[e]||t}}return t}function Ow(e){const t=Xm(e);try{return decodeURI(t.filename())}catch(e){return $l.debug(e),t.filename()}}function Rw(e){const t=Xm(e);return null===t?e:lg(t)?Sw(e):cg(t)?gw(e):(dg(t),fw(t.toString(),Ow(t)))}function Dw(e,t){return t instanceof Element&&t.classList.contains(e)}function zw(e,t){return t instanceof Element&&t.classList.add(e),t}function Pw(e,t){return t instanceof Element&&t.classList.remove(e),t}function Lw(e){return e instanceof Element&&e.parentNode&&e.parentNode.removeChild(e),e}function Fw(e,t){let n=e;for(;null!==n&&!xw.matchesSelector(n,t);)n=n.parentElement;return n}function Uw(e){const t=RegExp("^w{3}.","ig").test(e)?`http://${e}`:e,n=Xm(e);return null===n||!function(e){try{return!!new URL(e)}catch(e){return!1}}(t)||!function(e){return!!(arguments.length>1&&void 0!==arguments[1]?arguments[1]:Ew).includes(e)}(n._parts.protocol)&&n._parts.protocol?e:ww(n,e)}function Bw(e){let t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:200;return new Promise(((n,s)=>{if(!e){const e="An element needs to be passed in to slideOut";return $l.warn(e),void s(new Error(e))}const i=e.getAttribute("data-slider-marker");i&&(e.removeAttribute("data-slider-marker"),cancelAnimationFrame(i));const r=xl.calculateElementHeight(e);if(window.converse_disable_effects)return e.style.height=r+"px",function(e){e.removeAttribute("data-slider-marker"),e.classList.remove("collapsed"),e.style.overflow="",e.style.height=""}(e),void n();if(!xl.hasClass("collapsed",e)&&!xl.hasClass("hidden",e))return void n();const o=t/17;let a=0;e.style.height="0",e.style.overflow="hidden",e.classList.remove("hidden"),e.classList.remove("collapsed"),e.setAttribute("data-slider-marker",requestAnimationFrame((function t(){a+=r/o,a1&&void 0!==arguments[1]?arguments[1]:200;return new Promise(((n,s)=>{if(!e){const e="An element needs to be passed in to slideIn";return $l.warn(e),s(new Error(e))}if(xl.hasClass("collapsed",e))return n(e);if(window.converse_disable_effects)return e.classList.add("collapsed"),e.style.height="",n(e);const i=e.getAttribute("data-slider-marker");i&&(e.removeAttribute("data-slider-marker"),cancelAnimationFrame(i));const r=e.offsetHeight,o=t/17;let a=r;e.style.overflow="hidden",e.setAttribute("data-slider-marker",requestAnimationFrame((function t(){a-=r/o,a>0?(e.style.height=a+"px",e.setAttribute("data-slider-marker",requestAnimationFrame(t).toString())):(e.removeAttribute("data-slider-marker"),e.classList.add("collapsed"),e.style.height="",n(e))})).toString())}))}function Hw(e,t){e.classList.remove("visible"),t?.()}xl.calculateElementHeight=function(e){return Array.from(e.children).reduce(((e,t)=>e+t.offsetHeight),0)},xl.getNextElement=function(e){let t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:"*",n=e.nextElementSibling;for(;null!==n&&!xw.matchesSelector(n,t);)n=n.nextElementSibling;return n},xl.getPreviousElement=function(e){let t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:"*",n=e.previousElementSibling;for(;null!==n&&!xw.matchesSelector(n,t);)n=n.previousElementSibling;return n},xl.getFirstChildElement=function(e){let t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:"*",n=e.firstElementChild;for(;null!==n&&!xw.matchesSelector(n,t);)n=n.nextElementSibling;return n},xl.getLastChildElement=function(e){let t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:"*",n=e.lastElementChild;for(;null!==n&&!xw.matchesSelector(n,t);)n=n.previousElementSibling;return n},xl.toggleClass=function(e,t){xl.hasClass(e,t)?Pw(e,t):zw(e,t)},xl.getElementFromTemplateResult=function(e){const t=document.createElement("div");return zm(e,t),t.firstElementChild},xl.showElement=e=>{Pw("collapsed",e),Pw("hidden",e)},xl.hideElement=function(e){return e instanceof Element&&e.classList.add("hidden"),e},xl.nextUntil=function(e,t){const n=[];let s=e.nextElementSibling;for(;null!==s&&!s.matches(t);)n.push(s),s=s.nextElementSibling;return n},xl.unescapeHTML=function(e){var t=document.createElement("div");return t.innerHTML=e,t.innerText},xl.escapeHTML=function(e){return e.replace(/&/g,"&").replace(//g,">").replace(/"/g,""")},xl.slideInAllElements=function(e){let t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:300;return Promise.all(Array.from(e).map((e=>xl.slideIn(e,t))))},xl.slideToggleElement=function(e,t){return xl.hasClass("collapsed",e)||xl.hasClass("hidden",e)?xl.slideOut(e,t):xl.slideIn(e,t)},xl.isInDOM=function(e){return document.querySelector("body").contains(e)},xl.isVisible=function(e){return null!==e&&(!xl.hasClass("hidden",e)&&(e.offsetWidth>0||e.offsetHeight>0||e.getClientRects().length>0))},xl.fadeIn=function(e,t){if(e||$l.warn("An element needs to be passed in to fadeIn"),window.converse_disable_effects)return e.classList.remove("hidden"),Hw(e,t);xl.hasClass("hidden",e)?(e.classList.add("visible"),e.classList.remove("hidden"),e.addEventListener("webkitAnimationEnd",(()=>Hw(e,t))),e.addEventListener("animationend",(()=>Hw(e,t))),e.addEventListener("oanimationend",(()=>Hw(e,t)))):Hw(e,t)},xl.xForm2TemplateResult=function(e,t){let n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{};if("list-single"===e.getAttribute("type")||"list-multi"===e.getAttribute("type")){const t=xl.queryChildren(e,"value").map((e=>e?.textContent)),n=xl.queryChildren(e,"option").map((n=>{const s=n.querySelector("value")?.textContent;return{value:s,label:n.getAttribute("label"),selected:t.includes(s),required:!!e.querySelector("required")}}));return vw({options:n,id:xl.getUniqueId(),label:e.getAttribute("label"),multiple:"list-multi"===e.getAttribute("type"),name:e.getAttribute("var"),required:!!e.querySelector("required")})}if("fixed"===e.getAttribute("type")){const t=e.querySelector("value")?.textContent;return(e=>bm`

${e.text}

`)({text:t})}if("jid-multi"===e.getAttribute("type"))return(e=>{const t=xl.getUniqueId();return bm`
`})({name:e.getAttribute("var"),label:e.getAttribute("label")||"",value:e.querySelector("value")?.textContent,required:!!e.querySelector("required")});if("boolean"===e.getAttribute("type")){const t=e.querySelector("value")?.textContent;return(e=>bm`
`)({id:xl.getUniqueId(),name:e.getAttribute("var"),label:e.getAttribute("label")||"",checked:"1"===t||"true"===t?'checked="1"':""})}if("url"===e.getAttribute("var"))return yw({label:e.getAttribute("label")||"",value:e.querySelector("value")?.textContent});if("username"===e.getAttribute("var"))return _w({domain:" @"+n.domain,name:e.getAttribute("var"),type:Mw(e),label:e.getAttribute("label")||"",value:e.querySelector("value")?.textContent,required:!!e.querySelector("required")});if("password"===e.getAttribute("var"))return pw({name:e.getAttribute("var"),type:"password",label:e.getAttribute("label")||"",value:e.querySelector("value")?.textContent,required:!!e.querySelector("required")});if("ocr"===e.getAttribute("var")){const n=e.querySelector("uri"),s=xw('data[cid="'+n.textContent.replace(/^cid:/,"")+'"]',t)[0];return(e=>bm`
${e.label?bm``:""}
`)({label:e.getAttribute("label"),name:e.getAttribute("var"),data:s?.textContent,type:n.getAttribute("type"),required:!!e.querySelector("required")})}{const t=e.getAttribute("var");return pw({id:xl.getUniqueId(),label:e.getAttribute("label")||"",name:t,fixed_username:n?.fixed_username,autocomplete:$w(t,n),placeholder:null,required:!!e.querySelector("required"),type:Mw(e),value:e.querySelector("value")?.textContent})}},Object.assign(xl,{hasClass:Dw,addClass:zw,ancestor:Fw,getOOBURLMarkup:Rw,isEqualNode:function(e,t){if(!xl.isElement(e))throw new Error("Element being compared must be an Element!");e=Tw(e),t=Tw(t);let n=e.isEqualNode(t);if(!n){const{xmlHtmlNode:s}=Aw,i=Iw.serializeToString(e),r=Iw.serializeToString(t);n=i===r||s(i).isEqualNode(s(r))}return n},removeClass:Pw,removeElement:Lw,slideIn:qw,slideOut:Bw});const Gw=xl;var Ww=n(1064),Vw={};Vw.styleTagTransform=_b(),Vw.setAttributes=fb(),Vw.insert=mb().bind(null,"head"),Vw.domAPI=ub(),Vw.insertStyleElement=vb();lb()(Ww.Z,Vw);Ww.Z&&Ww.Z.locals&&Ww.Z.locals;const Zw=uw.extend({className:"modal",persistent:!1,events:{"click .nav-item .nav-link":"switchTab"},initialize(e){if(!this.id)throw new Error("Each modal class must have a unique id attribute");Object.assign(this,e),this.render(),this.el.setAttribute("tabindex","-1"),this.el.setAttribute("role","dialog"),this.el.setAttribute("aria-hidden","true");const t=this.el.querySelector(".modal-title").getAttribute("id");t&&this.el.setAttribute("aria-labelledby",t),this.insertIntoDOM();const n=xb().Modal;this.modal=new n(this.el,{backdrop:!0,keyboard:!0}),this.el.addEventListener("hide.bs.modal",(()=>this.onHide()),!1)},onHide(){Pw("selected",this.trigger_el),!this.persistent&&wd.modal.remove(this)},insertIntoDOM(){document.querySelector("#converse-modals").insertAdjacentElement("beforeEnd",this.el)},switchTab(e){e.stopPropagation(),e.preventDefault(),Yo()(".nav-link.active",this.el).forEach((e=>{Pw("active",this.el.querySelector(e.getAttribute("href"))),Pw("active",e)})),zw("active",e.target),zw("active",this.el.querySelector(e.target.getAttribute("href")))},alert(e){let t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:"primary";const n=this.el.querySelector(".modal-alert");if(null===n)return void $l.error("Could not find a .modal-alert element in the modal to show an alert message in!");zm(Ab({type:`alert-${t}`,message:e}),n);const s=n.firstElementChild;setTimeout((()=>{zw("fade-out",s),setTimeout((()=>Lw(s)),600)}),5e3)},show(e){e&&(e.preventDefault(),this.trigger_el=e.target,!Dw("chat-image",this.trigger_el)&&zw("selected",this.trigger_el)),this.modal.show()}}),Qw=Zw,Jw=bm``,Kw=bm``,Yw=("undefined"!=typeof Element&&Element.prototype,/^(\S+)\s*(.*)$/),Xw=["model","collection","events"];class eS extends HTMLElement{events={};constructor(e){super(),this.cid=jn("view"),this._domEvents=[],Be(this,lr(e,Xw))}createRenderRoot(){return this}connectedCallback(){this._initialized||(this.preinitialize.apply(this,arguments),this.initialize.apply(this,arguments),this._initialized=!0),this.delegateEvents()}disconnectedCallback(){this.undelegateEvents(),this.stopListening()}preinitialize(){}initialize(){}render(){return _(this.beforeRender)&&this.beforeRender(),_(this.toHTML)&&lw(this.toHTML(),this),_(this.afterRender)&&this.afterRender(),this}delegateEvents(){if(!this.events)return this;this.undelegateEvents();for(const e in this.events){let t=this.events[e];if(_(t)||(t=this[t]),!t)continue;const n=e.match(Yw);this.delegate(n[1],n[2],t.bind(this))}return this}delegate(e,t,n){const s=this;if(!s)return this;if("function"==typeof t&&(n=t,t=null),-1!==["focus","blur"].indexOf(e)){const s=this.querySelectorAll(t);for(let t=0,i=s.length;tthis.insertIntoDOM())),this.addEventListener("hide.bs.modal",(()=>this.onHide()),!1)}initialize(){this.modal=new(xb().Modal)(this,{backdrop:!0,keyboard:!0}),this.initialized.resolve(),this.render()}toHTML(){return(e=>{const t=e.model?.get("alert"),n=e.model?.get("level")??"";return bm``})(this)}getModalTitle(){return""}switchTab(e){e?.stopPropagation(),e?.preventDefault(),this.tab=e.target.getAttribute("data-name"),this.render()}onHide(){this.modal.hide()}insertIntoDOM(){document.querySelector("#converse-modals").insertAdjacentElement("beforeEnd",this)}alert(e){let t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:"primary";this.model.set("alert",{message:e,type:t}),setTimeout((()=>{this.model.set("alert",void 0)}),5e3)}async show(){await this.initialized,this.modal.show(),this.render()}};wd.elements.define("converse-alert-modal",class extends tS{initialize(){super.initialize(),this.listenTo(this.model,"change",(()=>this.render())),this.addEventListener("hide.bs.modal",(()=>this.remove()),!1)}renderModal(){return(e=>bm``)(this.model.toJSON())}getModalTitle(){return this.model.get("title")}});const nS=e=>bm`
${e.model.get("messages")?.map((e=>bm`

${e}

`))}
${e.model.get("fields")?.map((e=>(e=>bm`
`)(e)))}
`;class sS extends tS{constructor(e){super(e),this.confirmation=Xo()}initialize(){super.initialize(),this.listenTo(this.model,"change",(()=>this.render())),this.addEventListener("hide.bs.modal",(()=>{this.confirmation.isResolved||this.confirmation.reject()}),!1)}renderModal(){return nS(this)}getModalTitle(){return this.model.get("title")}onConfimation(e){e.preventDefault();const t=new FormData(e.target),n=(this.model.get("fields")||[]).map((e=>{const n=t.get(e.name).trim();return e.value=n,e.challenge&&(e.challenge_failed=n!==e.challenge),e}));if(n.filter((e=>e.challenge_failed)).length)return this.model.set("fields",n),void this.model.trigger("change");this.confirmation.resolve(n),this.modal.hide()}renderModalFooter(){return""}}wd.elements.define("converse-confirm-modal",sS);let iS=[],rS={};const oS={modal:{show(e,t,n){let s;if("string"==typeof e)s=this.get(e)??this.create(e,t),Object.assign(s,t);else{const n=e,i=n.id??t.id;s=this.get(i)??this.create(n,t)}return s.show(n),s},get:e=>rS[e]??iS.filter((t=>t.id==e)).pop(),create(e,t){let n;if("string"==typeof e){const s=customElements.get(e);n=rS[e]=new s(t)}else{n=new e(t),iS.push(n)}return n},remove(e){let t;"string"==typeof e?(t=rS[e],delete rS[e]):(t=e,iS=iS.filter((e=>e!==t))),t?.remove()},removeAll(){iS.forEach((e=>e.remove())),iS=[],rS={}}},async confirm(e){let t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:[];"string"==typeof t&&(t=[t]);const n=new dr({title:e,messages:t,fields:arguments.length>2&&void 0!==arguments[2]?arguments[2]:[],type:"confirm"}),s=new sS({model:n});let i;s.show();try{i=await s.confirmation}catch(e){i=!1}return s.remove(),i},async prompt(e){let t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:[];"string"==typeof t&&(t=[t]);const n=new dr({title:e,messages:t,fields:[{name:"reason",placeholder:arguments.length>2&&void 0!==arguments[2]?arguments[2]:""}],type:"prompt"}),s=new sS({model:n});let i;s.show();try{i=(await s.confirmation).pop()?.value}catch(e){i=!1}return s.remove(),i},alert(e,t,n){let s;"string"==typeof n&&(n=[n]),"error"===e?s="alert-danger":"info"===e?s="alert-info":"warn"===e&&(s="alert-warning");const i=new dr({title:t,messages:n,level:s,type:"alert"});oS.modal.show("converse-alert-modal",{model:i})}},aS=oS;Fm.env.BootstrapModal=Qw,Fm.plugins.add("converse-modal",{initialize(){wd.listen.on("disconnect",(()=>{const e=document.querySelector("#converse-modals");e&&(e.innerHTML="")})),wd.listen.on("clearSession",(()=>wd.modal.removeAll())),Object.assign(Zl.api,aS)}});const cS=Fm.env.utils,lS={getElement:(e,t)=>"string"==typeof e?(t||document).querySelector(e):e||null,bind(e,t){if(e)for(var n in t){if(!Object.prototype.hasOwnProperty.call(t,n))continue;const s=t[n];n.split(/\s+/).forEach((t=>e.addEventListener(t,s)))}},unbind(e,t){if(e)for(var n in t){if(!Object.prototype.hasOwnProperty.call(t,n))continue;const s=t[n];n.split(/\s+/).forEach((t=>e.removeEventListener(t,s)))}},regExpEscape:e=>e.replace(/[-\\^$*+?.()|[\]{}]/g,"\\$&"),isMention:(e,t)=>t.includes(e[0])||cS.isMentionBoundary(e[0])&&t.includes(e[1])},dS=function(e,t){return RegExp(lS.regExpEscape(t.trim()),"i").test(e)},uS=function(e,t){return RegExp("^"+lS.regExpEscape(t.trim()),"i").test(e)},hS=function(e,t){const n=e.query.toLowerCase(),s=e.label.toLowerCase().indexOf(n),i=t.label.toLowerCase().indexOf(n);return s===i?function(e,t){return e.length!==t.length?e.length-t.length:e{t=t.trim();const n=document.createElement("li");n.setAttribute("aria-selected","false");const s=new RegExp("("+t+")","ig");return(t?e.split(s):[e]).forEach((e=>{if(t&&e.match(s)){const t=document.createElement("mark");t.textContent=e,n.appendChild(t)}else n.appendChild(document.createTextNode(e))})),n};const gS=class extends String{constructor(e,t){super();const n=Array.isArray(e)?{label:e[0],value:e[1]}:"object"==typeof e&&"label"in e&&"value"in e?e:{label:e,value:e};this.label=n.label||n.value,this.value=n.value,this.query=t}get lenth(){return this.label.length}toString(){return""+this.label}valueOf(){return this.toString()}},fS=Fm.env.utils;class pS{constructor(e){let t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};this.suggestions=[],this.is_opened=!1,fS.hasClass("suggestion-box",e)?this.container=e:this.container=e.querySelector(".suggestion-box"),this.input=this.container.querySelector(".suggestion-box__input"),this.input.setAttribute("aria-autocomplete","list"),this.ul=this.container.querySelector(".suggestion-box__results"),this.status=this.container.querySelector(".suggestion-box__additions"),Object.assign(this,{match_current_word:!1,ac_triggers:[],include_triggers:[],min_chars:2,max_items:10,auto_evaluate:!0,auto_first:!1,data:e=>e,filter:dS,sort:!1!==t.sort&&hS,item:mS},t),this.index=-1,this.bindEvents(),this.input.hasAttribute("list")?(this.list="#"+this.input.getAttribute("list"),this.input.removeAttribute("list")):this.list=this.input.getAttribute("data-list")||t.list||[]}bindEvents(){const e={blur:()=>this.close({reason:"blur"})};this.auto_evaluate&&(e.input=e=>this.evaluate(e)),this._events={input:e,form:{submit:()=>this.close({reason:"submit"})},ul:{mousedown:e=>this.onMouseDown(e),mouseover:e=>this.onMouseOver(e)}},lS.bind(this.input,this._events.input),lS.bind(this.input.form,this._events.form),lS.bind(this.ul,this._events.ul)}set list(e){if(Array.isArray(e)||"function"==typeof e)this._list=e;else if("string"==typeof e&&e.includes(","))this._list=e.split(/\s*,\s*/);else{const t=lS.getElement(e)?.children||[];this._list=Array.from(t).filter((e=>!e.disabled)).map((e=>{const t=e.textContent.trim(),n=e.value||t,s=e.label||t;return""!==n?{label:s,value:n}:null})).filter((e=>e))}document.activeElement===this.input&&this.evaluate()}get list(){return this._list}get selected(){return this.index>-1}get opened(){return this.is_opened}close(e){this.opened&&(this.ul.setAttribute("hidden",""),this.is_opened=!1,this.index=-1,this.trigger("suggestion-box-close",e||{}))}insertValue(e){this.match_current_word?fS.replaceCurrentWord(this.input,e.value):this.input.value=e.value}open(){this.ul.removeAttribute("hidden"),this.is_opened=!0,this.auto_first&&-1===this.index&&this.goto(0),this.trigger("suggestion-box-open")}destroy(){lS.unbind(this.input,this._events.input),lS.unbind(this.input.form,this._events.form),this.input.removeAttribute("aria-autocomplete")}next(){const e=this.ul.children.length;this.goto(this.index1&&void 0!==arguments[1])||arguments[1];const n=this.ul.children;this.selected&&n[this.index].setAttribute("aria-selected","false"),this.index=e,e>-1&&n.length>0&&(n[e].setAttribute("aria-selected","true"),n[e].focus(),this.status.textContent=n[e].textContent,t&&(this.ul.scrollTop=n[e].offsetTop-this.ul.clientHeight+n[e].clientHeight),this.trigger("suggestion-box-highlight",{text:this.suggestions[this.index]}))}select(e){if(e?this.index=fS.siblingIndex(e):e=this.ul.children[this.index],e){const e=this.suggestions[this.index];this.insertValue(e),this.close({reason:"select"}),this.auto_completing=!1,this.trigger("suggestion-box-selectcomplete",{text:e})}}onMouseOver(e){const t=fS.ancestor(e.target,"li");if(t){const e=Array.prototype.slice.call(this.ul.children).indexOf(t);this.goto(e,!1)}}onMouseDown(e){if(0!==e.button)return;const t=fS.ancestor(e.target,"li");t&&(e.preventDefault(),this.select(t,e.target))}onKeyDown(e){if(this.opened){if([Fm.keycodes.ENTER,Fm.keycodes.TAB].includes(e.keyCode)&&this.selected)return e.preventDefault(),e.stopPropagation(),this.select(),!0;if(e.keyCode===Fm.keycodes.ESCAPE)return this.close({reason:"esc"}),!0;if([Fm.keycodes.UP_ARROW,Fm.keycodes.DOWN_ARROW].includes(e.keyCode))return e.preventDefault(),e.stopPropagation(),this[e.keyCode===Fm.keycodes.UP_ARROW?"previous":"next"](),!0}if(![Fm.keycodes.SHIFT,Fm.keycodes.META,Fm.keycodes.META_RIGHT,Fm.keycodes.ESCAPE,Fm.keycodes.ALT].includes(e.keyCode))if(this.ac_triggers.includes(e.key))"Tab"===e.key&&e.preventDefault(),this.auto_completing=!0;else if("Backspace"===e.key){const t=fS.getCurrentWord(e.target,e.target.selectionEnd-1);lS.isMention(t,this.ac_triggers)&&(this.auto_completing=!0)}}async evaluate(e){const t=this.selected&&e&&(e.keyCode===Fm.keycodes.UP_ARROW||e.keyCode===Fm.keycodes.DOWN_ARROW);if(!this.auto_evaluate&&!this.auto_completing||t)return;let n=this.match_current_word?fS.getCurrentWord(this.input):this.input.value;const s=lS.isMention(n,this.ac_triggers);s&&!this.include_triggers.includes(e.key)&&(n=fS.isMentionBoundary(n[0])?n.slice("2"):n.slice("1"));const i=n.length&&n.length>=this.min_chars;if(s||i){this.auto_completing=!0;const e="function"==typeof this._list?await this._list(n):this._list;if(0===e.length||!this.auto_completing)return void this.close({reason:"nomatches"});this.index=-1,this.ul.innerHTML="",this.suggestions=e.map((e=>new gS(this.data(e,n),n))).filter((e=>this.filter(e,n))),!1!==this.sort&&(this.suggestions=this.suggestions.sort(this.sort)),this.suggestions=this.suggestions.slice(0,this.max_items),this.suggestions.forEach((e=>this.ul.appendChild(this.item(e,n)))),0===this.ul.children.length?this.close({reason:"nomatches"}):this.open()}else this.close({reason:"nomatches"}),s||(this.auto_completing=!1)}}Object.assign(pS.prototype,Tn);const vS=pS;wd.elements.define("converse-autocomplete",class extends ob{static get properties(){return{position:{type:String},autofocus:{type:Boolean},getAutoCompleteList:{type:Function},list:{type:Array},auto_evaluate:{type:Boolean},auto_first:{type:Boolean},filter:{type:String},include_triggers:{type:String},min_chars:{type:Number},name:{type:String},placeholder:{type:String},triggers:{type:String},required:{type:Boolean}}}constructor(){super(),this.position="above",this.auto_evaluate=!0,this.auto_first=!1,this.filter="contains",this.include_triggers="",this.match_current_word=!1,this.max_items=10,this.min_chars=1,this.triggers=""}render(){const e=`suggestion-box__results--${this.position}`;return bm`
`}firstUpdated(){this.auto_complete=new vS(this.firstElementChild,{ac_triggers:this.triggers.split(" "),auto_evaluate:this.auto_evaluate,auto_first:this.auto_first,filter:"contains"==this.filter?dS:uS,include_triggers:[],list:this.list??(e=>this.getAutoCompleteList(e)),match_current_word:!0,max_items:this.max_items,min_chars:this.min_chars}),this.auto_complete.on("suggestion-box-selectcomplete",(()=>this.auto_completing=!1))}onKeyDown(e){this.auto_complete.onKeyDown(e)}onKeyUp(e){this.auto_complete.evaluate(e)}});var yS=n(2642),_S={};_S.styleTagTransform=_b(),_S.setAttributes=fb(),_S.insert=mb().bind(null,"head"),_S.domAPI=ub(),_S.insertStyleElement=vb();lb()(yS.Z,_S);yS.Z&&yS.Z.locals&&yS.Z.locals;Zl.FILTER_CONTAINS=dS,Zl.FILTER_STARTSWITH=uS,Zl.AutoComplete=vS;const bS={execute:ib("Execute"),prev:ib("Previous"),next:ib("Next"),complete:ib("Complete")},wS=(e,t)=>bm`
  • ${t.node===e.showform?((e,t)=>{const n=ib("Cancel");return bm`
    ${t.alert?bm``:""}

    ${t.instructions}

    ${t.fields}
    ${t.actions.map((t=>bm``))}
    `})(e,t):""}
  • `,SS=function(){let e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};return e.classes?.includes("hor_centered")?bm`
    `:bm``},xS=e=>{return e.image?bm``:"";var t,n};var AS=n(7233),ES={};ES.styleTagTransform=_b(),ES.setAttributes=fb(),ES.insert=mb().bind(null,"head"),ES.domAPI=ub(),ES.insertStyleElement=vb();lb()(AS.Z,ES);AS.Z&&AS.Z.locals&&AS.Z.locals;wd.elements.define("converse-avatar",class extends ob{static get properties(){return{data:{type:Object},width:{type:String},height:{type:String},nonce:{type:String}}}constructor(){super(),this.width=36,this.height=36}render(){const e=this.data?.image_type||Zl.DEFAULT_IMAGE_TYPE;let t;if(this.data?.data_uri)t=this.data?.data_uri;else{t="data:"+e+";base64,"+(this.data?.image||Zl.DEFAULT_IMAGE)}return xS({classes:this.getAttribute("class"),height:this.height,width:this.width,image:t,image_type:e})}});const{I:$S}=Kh,CS=()=>document.createComment(""),kS=(e,t,n)=>{const s=e._$AA.parentNode,i=void 0===t?e._$AB:t._$AA;if(void 0===n){const t=s.insertBefore(CS(),i),r=s.insertBefore(CS(),i);n=new $S(t,r,e,e.options)}else{const t=n._$AB.nextSibling,r=n._$AM,o=r!==e;if(o){let t;n._$AQ?.(e),n._$AM=e,void 0!==n._$AP&&(t=e._$AU)!==r._$AU&&n._$AP(t)}if(t!==i||o){let e=n._$AA;for(;e!==t;){const t=e.nextSibling;s.insertBefore(e,i),e=t}}}return n},jS=function(e,t){let n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:e;return e._$AI(t,n),e},TS={},IS=e=>{e._$AP?.(!1,!0);let t=e._$AA;const n=e._$AB.nextSibling;for(;t!==n;){const e=t.nextSibling;t.remove(),t=e}},NS=2,MS=e=>function(){for(var t=arguments.length,n=new Array(t),s=0;s{const n=e._$AN;if(void 0===n)return!1;for(const e of n)e._$AO?.(t,!1),RS(e,t);return!0},DS=e=>{let t,n;do{if(void 0===(t=e._$AM))break;n=t._$AN,n.delete(e),e=t}while(0===n?.size)},zS=e=>{for(let t;t=e._$AM;e=t){let n=t._$AN;if(void 0===n)t._$AN=n=new Set;else if(n.has(e))break;n.add(e),FS(t)}};function PS(e){void 0!==this._$AN?(DS(this),this._$AM=e,zS(this)):this._$AM=e}function LS(e){let t=arguments.length>1&&void 0!==arguments[1]&&arguments[1],n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:0;const s=this._$AH,i=this._$AN;if(void 0!==i&&0!==i.size)if(t)if(Array.isArray(s))for(let e=n;e{e.type==NS&&(e._$AP??=LS,e._$AQ??=PS)};class US extends OS{constructor(){super(...arguments),this._$AN=void 0}_$AT(e,t,n){super._$AT(e,t,n),zS(this),this.isConnected=e._$AU}_$AO(e){let t=!(arguments.length>1&&void 0!==arguments[1])||arguments[1];e!==this.isConnected&&(this.isConnected=e,e?this.reconnected?.():this.disconnected?.()),t&&(RS(this,e),DS(this))}setValue(e){if((e=>void 0===e.strings)(this._$Ct))this._$Ct._$AI(e,this);else{const t=[...this._$Ct._$AH];t[this._$Ci]=e,this._$Ct._$AI(t,this,0)}}disconnected(){}reconnected(){}}class BS{constructor(e){this.Y=e}disconnect(){this.Y=void 0}reconnect(e){this.Y=e}deref(){return this.Y}}class qS{constructor(){this.Z=void 0,this.q=void 0}get(){return this.Z}pause(){this.Z??=new Promise((e=>this.q=e))}resume(){this.q?.(),this.Z=this.q=void 0}}const HS=e=>!(e=>null===e||"object"!=typeof e&&"function"!=typeof e)(e)&&"function"==typeof e.then,GS=1073741823;const WS=MS(class extends US{constructor(){super(...arguments),this._$Cwt=GS,this._$Cbt=[],this._$CK=new BS(this),this._$CX=new qS}render(){for(var e=arguments.length,t=new Array(e),n=0;n!HS(e)))??Dh}update(e,t){const n=this._$Cbt;let s=n.length;this._$Cbt=t;const i=this._$CK,r=this._$CX;this.isConnected||this.disconnected();for(let e=0;ethis._$Cwt);e++){const o=t[e];if(!HS(o))return this._$Cwt=e,o;e{for(;r.get();)await r.get();const t=i.deref();if(void 0!==t){const n=t._$Cbt.indexOf(o);n>-1&&nthis.alert(ib("Affiliation changed")))),this.addEventListener("roleChanged",(()=>this.alert(ib("role changed"))))}initialize(){super.initialize();const e=this.model??this.message;this.listenTo(e,"change",(()=>this.render())),wd.trigger("occupantModalInitialized",{model:this.model,message:this.message})}getVcard(){const e=this.model??this.message;if(e.vcard)return e.vcard;const t=e?.get("jid")||e?.get("from");return t?Zl.vcards.get(t):null}renderModal(){return(e=>{const t=e.model??e.message,n=t?.get("jid"),s=e.getVcard(),i=t.get("nick"),r=t.get("occupant_id"),o=e.model?.get("role"),a=e.model?.get("affiliation"),c=e.model?.get("hats")?.length?e.model.get("hats"):null,l=e.model.collection.chatroom,d=l.getAllowedCommands().includes("modtools"),u=ib("Add to Contacts"),h=l.features.get("nonanonymous")||"moderator"===l.getOwnRole(),m=n!=Zl.bare_jid,g=wd.contacts.get(n).then((e=>!e&&m&&h)).then((t=>t?bm`
  • `:""));return bm`
    • ${i?bm`
      ${ib("Nickname")}:
      ${i}
      `:""}
    • ${n?bm`
      ${ib("XMPP Address")}:
      ${n}
      `:""}
    • ${ib("Affiliation")}:
      ${a}  ${d?bm`${e.show_affiliation_form?bm``:""}`:""}
    • ${ib("Role")}:
      ${o}  ${d&&o?bm`${e.show_role_form?bm``:""}`:""}
    • ${c?bm`
      ${ib("Hats")}:
      ${c}
      `:""}
    • ${r?bm`
      ${ib("Occupant Id")}:
      ${r}
      `:""}
    • ${WS(g,"")}
    `})(this)}getModalTitle(){const e=this.model??this.message;return e?.getDisplayName()}addToContacts(){const e=(this.model??this.message).get("jid");e&&wd.modal.show("converse-add-contact-modal",{model:new dr({jid:e})})}toggleForm(e){"row-form"===VS.ancestor(e.target,".toggle-form").getAttribute("data-form")?this.show_role_form=!this.show_role_form:this.show_affiliation_form=!this.show_affiliation_form,this.render()}});const JS=(e,t)=>bm`
    • JID: ${t.item.jid}
    • Nickname: ${t.item.nick}
    • Role: ${t.item.role} ${t.assignable_roles.length?(e=>bm``)(t):""}
      ${t.assignable_roles.length?bm``:""}
  • `,KS=(e,t)=>bm`
    • JID: ${t.item.jid}
    • Nickname: ${t.item.nick}
    • Affiliation: ${t.item.affiliation} ${t.assignable_affiliations.length?(e=>bm``)(t):""}
      ${t.assignable_affiliations.length?bm``:""}
  • `,YS=(e,t)=>{const n=ib("Affiliation"),s=ib("No users with that affiliation found."),i=ib("No users with that role found."),r=ib("Type here to filter the search results"),o=ib("Role"),a=ib("Show users"),c=ib("Roles are assigned to users to grant or deny them certain abilities in a multi-user chat. They're assigned either explicitly or implicitly as part of an affiliation. A role that's not due to an affiliation, is only valid for the duration of the user's session."),l=ib("An affiliation is a long-lived entitlement which typically implies a certain role and which grants privileges and responsibilities. For example admins and owners automatically have the moderator role."),d=t.queryable_roles.length&&t.queryable_affiliations.length;return bm`${t.alert_message?bm``:""} ${d?(e=>bm``)(t):""}
    ${t.queryable_affiliations.length?bm`

    ${l}

    ${Array.isArray(t.users_with_affiliation)&&t.users_with_affiliation.length>5?bm``:""}
    ${QS(t.affiliation)?bm`

    ${QS(t.affiliation)}

    `:""}
      ${t.loading_users_with_affiliation?bm`
    • ${SS()}
    • `:""} ${Array.isArray(t.users_with_affiliation)&&0===t.users_with_affiliation.length?bm`
    • ${s}
    • `:""} ${t.users_with_affiliation instanceof Error?bm`
    • ${t.users_with_affiliation.message}
    • `:(t.users_with_affiliation||[]).map((n=>(n.nick||n.jid).match(new RegExp(t.affiliations_filter,"i"))?KS(e,Object.assign({item:n},t)):""))}
    `:""} ${t.queryable_roles.length?bm`

    ${c}

    ${Array.isArray(t.users_with_role)&&t.users_with_role.length>5?bm``:""}
    ${ZS(t.role)?bm`

    ${ZS(t.role)}

    `:""}
      ${t.loading_users_with_role?bm`
    • ${SS()}
    • `:""} ${t.users_with_role&&0===t.users_with_role.length?bm`
    • ${i}
    • `:""} ${(t.users_with_role||[]).map((n=>n.nick.match(t.roles_filter)?JS(e,Object.assign({item:n},t)):""))}
    `:""}
    `};var XS=n(4891),ex={};ex.styleTagTransform=_b(),ex.setAttributes=fb(),ex.insert=mb().bind(null,"head"),ex.domAPI=ub(),ex.insertStyleElement=vb();lb()(XS.Z,ex);XS.Z&&XS.Z.locals&&XS.Z.locals;const{u:tx}=Fm.env;wd.elements.define("converse-modtools",class extends ob{static get properties(){return{affiliation:{type:String},affiliations_filter:{type:String,attribute:!1},alert_message:{type:String,attribute:!1},alert_type:{type:String,attribute:!1},jid:{type:String},muc:{type:Object,attribute:!1},role:{type:String},roles_filter:{type:String,attribute:!1},tab:{type:String},users_with_affiliation:{type:Array,attribute:!1},users_with_role:{type:Array,attribute:!1}}}constructor(){super(),this.tab="affiliations",this.affiliation="",this.affiliations_filter="",this.role="",this.roles_filter="",this.addEventListener("affiliationChanged",(()=>{this.alert(ib("Affiliation changed"),"primary"),this.onSearchAffiliationChange(),this.requestUpdate()})),this.addEventListener("roleChanged",(()=>{this.alert(ib("Role changed"),"primary"),this.requestUpdate()}))}updated(e){e.has("role")&&this.onSearchRoleChange(),e.has("affiliation")&&this.onSearchAffiliationChange(),e.has("jid")&&e.get("jid")&&this.initialize()}async initialize(){this.initialized=Xo();const e=await wd.rooms.get(this.jid);await e.initialized,this.muc=e,this.initialized.resolve()}render(){if(this.muc?.occupants){const e=this.muc.occupants.getOwnOccupant();return YS(this,{affiliations_filter:this.affiliations_filter,alert_message:this.alert_message,alert_type:this.alert_type,assignRole:e=>this.assignRole(e),assignable_affiliations:sp(e),assignable_roles:Sp(e),filterAffiliationResults:e=>this.filterAffiliationResults(e),filterRoleResults:e=>this.filterRoleResults(e),loading_users_with_affiliation:this.loading_users_with_affiliation,queryAffiliation:e=>this.queryAffiliation(e),queryRole:e=>this.queryRole(e),queryable_affiliations:Rf.filter((e=>!wd.settings.get("modtools_disable_query").includes(e))),queryable_roles:Of.filter((e=>!wd.settings.get("modtools_disable_query").includes(e))),roles_filter:this.roles_filter,switchTab:e=>this.switchTab(e),tab:this.tab,toggleForm:e=>this.toggleForm(e),users_with_affiliation:this.users_with_affiliation,users_with_role:this.users_with_role})}return""}switchTab(e){e.stopPropagation(),e.preventDefault(),this.tab=e.target.getAttribute("data-name"),this.requestUpdate()}async onSearchAffiliationChange(){if(this.affiliation){if(await this.initialized,this.clearAlert(),this.loading_users_with_affiliation=!0,this.users_with_affiliation=null,this.shouldFetchAffiliationsList()){const e=await np(this.affiliation,this.jid);e instanceof Error?(this.alert(e.message,"danger"),this.users_with_affiliation=[]):this.users_with_affiliation=e}else this.users_with_affiliation=this.muc.getOccupantsWithAffiliation(this.affiliation);this.loading_users_with_affiliation=!1}}async onSearchRoleChange(){this.role&&(await this.initialized,this.clearAlert(),this.users_with_role=this.muc.getOccupantsWithRole(this.role))}shouldFetchAffiliationsList(){const e=this.affiliation;if("none"===e)return!1;return!wp().includes(e)}toggleForm(e){e.stopPropagation(),e.preventDefault();const t=tx.ancestor(e.target,".toggle-form"),n=t.getAttribute("data-form"),s=tx.ancestor(t,".list-group-item").querySelector(n);tx.hasClass("hidden",s)?tx.removeClass("hidden",s):tx.addClass("hidden",s)}filterRoleResults(e){this.roles_filter=e.target.value,this.render()}filterAffiliationResults(e){this.affiliations_filter=e.target.value}queryRole(e){e.stopPropagation(),e.preventDefault();const t=new FormData(e.target).get("role");this.role=null,this.role=t}queryAffiliation(e){e.stopPropagation(),e.preventDefault();const t=new FormData(e.target).get("affiliation");this.affiliation=null,this.affiliation=t}alert(e,t){this.alert_message=e,this.alert_type=t}clearAlert(){this.alert_message=void 0,this.alert_type=void 0}});wd.elements.define("converse-modtools-modal",class extends tS{constructor(e){super(e),this.id="converse-modtools-modal"}renderModal(){return bm``}getModalTitle(){return ib("Moderator Tools")}});const{Strophe:nx,u:sx}=Fm.env,ix={admin:"admin",ban:"outcast",member:"member",owner:"owner",revoke:"none"},rx={deop:"participant",kick:"none",mute:"visitor",op:"moderator",voice:"participant"};function ox(e){let{contact:t,jid:n,reason:s}=e;return s?wd.confirm(ib('%1$s has invited you to join a groupchat: %2$s, and left the following reason: "%3$s"',t,n,s)):wd.confirm(ib("%1$s has invited you to join a groupchat: %2$s",t,n))}async function ax(e){const t=[ib("Are you sure you want to destroy this groupchat?")];let n=[{name:"challenge",label:ib("Please enter the XMPP address of this groupchat to confirm"),challenge:e.get("jid"),placeholder:ib("name@example.org"),required:!0},{name:"reason",label:ib("Optional reason for destroying this groupchat"),placeholder:ib("Reason")},{name:"newjid",label:ib("Optional XMPP address for a new groupchat that replaces this one"),placeholder:ib("replacement@example.org")}];try{n=await wd.confirm(ib("Confirm"),t,n);const s=n.filter((e=>"reason"===e.name)).pop()?.value,i=n.filter((e=>"newjid"===e.name)).pop()?.value;return e.sendDestroyIQ(s,i).then((()=>e.close()))}catch(e){$l.error(e)}}function cx(e){const t=e.model.session.get("view"),n=e.model.get("jid"),s=Fm.ROOMSTATUS,i=e.model.session.get("connection_status");return t===Fm.MUC.VIEWS.CONFIG?bm``:bm`${i==s.PASSWORD_REQUIRED?bm``:""} ${i==s.ENTERED?bm``:""} ${i==s.CONNECTING?SS():""} ${i==s.NICKNAME_REQUIRED?function(e){const t=e.get("jid");return wd.settings.get("muc_show_logs_before_join")?bm``:bm``}(e.model):""} ${i==s.DISCONNECTED?bm``:""} ${i==s.BANNED?bm``:""} ${i==s.DESTROYED?bm``:""}`}function lx(e,t){t=t.trim();const n=document.createElement("li");if(n.setAttribute("aria-selected","false"),wd.settings.get("muc_mention_autocomplete_show_avatar")){const t=document.createElement("img");let s="data:"+Zl.DEFAULT_IMAGE_TYPE+";base64,"+Zl.DEFAULT_IMAGE;if(Zl.vcards){const t=Zl.vcards.findWhere({nickname:e});t&&(s="data:"+t.get("image_type")+";base64,"+t.get("image"))}t.setAttribute("src",s),t.setAttribute("width","22"),t.setAttribute("class","avatar avatar-autocomplete"),n.appendChild(t)}const s=new RegExp("("+t+")","ig");return(t?e.split(s):[e]).forEach((e=>{if(t&&e.match(s)){const t=document.createElement("mark");t.textContent=e,n.appendChild(t)}else n.appendChild(document.createTextNode(e))})),n}async function dx(){const e=[...await wd.rooms.get(),...await wd.contacts.get()],t=[...new Set(e.map((e=>nx.getDomainFromJid(e.get("jid")))))];return t}function ux(e,t,n){let s=arguments.length>3&&void 0!==arguments[3]?arguments[3]:[],i=arguments.length>4&&void 0!==arguments[4]?arguments[4]:[];const r=rx[t];if(!r)throw Error(`ChatRoomView#setRole called with invalid command: ${t}`);if(!e.verifyAffiliations(s)||!e.verifyRoles(i))return!1;if(!e.validateRoleOrAffiliationChangeArgs(t,n))return!1;const o=e.getNickOrJIDFromCommandArgs(n);if(!o)return!1;const a=n.split(o,2)[1].trim(),c=e.getOccupant(o);return e.setRole(c,r,a,void 0,(t=>e.onCommandError(t))),!0}function hx(e,t,n,s){const i=ix[t];if(!i)throw Error(`verifyAffiliations called with invalid command: ${t}`);if(!e.verifyAffiliations(s))return!1;if(!e.validateRoleOrAffiliationChangeArgs(t,n))return!1;const r=e.getNickOrJIDFromCommandArgs(n);if(!r)return!1;let o;const a=n.split(r,2)[1].trim(),c=e.getOccupant(r);if(c)o=c.get("jid");else{if(!sx.isValidJID(r)){const t=ib("Couldn't find a participant with that nickname. They might have left the groupchat.");return void e.createMessage({message:t,type:"error"})}o=r}const l={jid:o,reason:a};c&&wd.settings.get("auto_register_muc_nickname")&&(l.nick=c.get("nick")),rp(i,e.get("jid"),[l]).then((()=>e.occupants.fetchMembers())).catch((t=>e.onCommandError(t)))}function mx(e,t){if(!e.verifyRoles(["moderator"]))return;let n=wd.modal.get("converse-modtools-modal");n?(n.affiliation=t,n.render()):n=wd.modal.create("converse-modtools-modal",{affiliation:t,jid:e.get("jid")}),n.show()}function gx(e,t){const n=e.model;if(t||n.get("type")!==Zl.CHATROOMS_TYPE||wd.settings.get("muc_disable_slash_commands")&&!Array.isArray(wd.settings.get("muc_disable_slash_commands")))return t;let s=e.text;s=s.replace(/^\s*/,"");const i=(s.match(/^\/([a-zA-Z]*) ?/)||[""]).pop().toLowerCase();if(!i)return!1;const r=s.slice(("/"+i).length+1).trim(),o=n.getAllowedCommands()??[];if("admin"===i&&o.includes(i))return hx(n,i,r,["owner"]),!0;if("ban"===i&&o.includes(i))return hx(n,i,r,["admin","owner"]),!0;if("modtools"===i&&o.includes(i))return mx(n,r),!0;if("deop"===i&&o.includes(i))return ux(n,i,r,["admin","owner"]),!0;if("destroy"===i&&o.includes(i))return!n.verifyAffiliations(["owner"])||(ax(n).catch((e=>n.onCommandError(e))),!0);if("help"===i&&o.includes(i))return n.set({show_help_messages:!1},{silent:!0}),n.set({show_help_messages:!0}),!0;if("kick"===i&&o.includes(i))return ux(n,i,r,[],["moderator"]),!0;if("mute"===i&&o.includes(i))return ux(n,i,r,[],["moderator"]),!0;if("member"===i&&o.includes(i))return hx(n,i,r,["admin","owner"]),!0;if("nick"===i&&o.includes(i)){if(!n.verifyRoles(["visitor","participant","moderator"]))return!0;if(0===r.length){const e=ib('Your nickname is "%1$s"',n.get("nick"));n.createMessage({message:e,type:"error"})}else n.setNickname(r);return!0}return"owner"===i&&o.includes(i)?(hx(n,i,r,["owner"]),!0):"op"===i&&o.includes(i)?(ux(n,i,r,["admin","owner"]),!0):"register"===i&&o.includes(i)?(r.length>1?n.createMessage({message:ib("Error: invalid number of arguments"),type:"error"}):n.registerNickname().then((e=>{e&&n.createMessage({message:e,type:"error"})})),!0):"revoke"===i&&o.includes(i)?(hx(n,i,r,["admin","owner"]),!0):"topic"===i&&o.includes(i)||"subject"===i&&o.includes(i)?(n.setSubject(r),!0):!("voice"!==i||!o.includes(i))&&(ux(n,i,r,[],["moderator"]),!0)}const fx=e=>{const t=ib("On which entity do you want to run commands?"),n=ib("Certain XMPP services and entities allow privileged users to execute ad-hoc commands on them."),s=ib("Commands found"),i=ib("List available commands"),r=ib("XMPP Address"),o=ib("No commands found");return bm`${e.alert?bm``:""} ${e.note?bm`

    ${e.note}

    `:""}
    ${e.fetching?SS():bm``}
    ${"list-commands"===e.view?bm`
    • ${e.commands.length?s:o}:
    • ${e.commands.map((t=>wS(e,t)))}
    `:""}
    `},{Strophe:px,sizzle:vx}=Fm.env;wd.elements.define("converse-adhoc-commands",class extends ob{static get properties(){return{alert:{type:String},alert_type:{type:String},commands:{type:Array},fetching:{type:Boolean},showform:{type:String},view:{type:String}}}constructor(){super(),this.view="choose-service",this.fetching=!1,this.showform="",this.commands=[]}render(){return fx(this)}async fetchCommands(e){e.preventDefault(),delete this.alert_type,delete this.alert,this.fetching=!0;const t=new FormData(e.target).get("jid").trim();let n;try{n=await wd.disco.supports(px.NS.ADHOC,t)}catch(e){$l.error(e)}finally{this.fetching=!1}if(n)try{this.commands=await wd.adhoc.getCommands(t),this.view="list-commands"}catch(e){return $l.error(e),this.alert_type="danger",this.alert=ib("Sorry, an error occurred while looking for commands on that entity."),this.commands=[],void $l.error(e)}else this.alert_type="danger",this.alert=ib("The specified entity doesn't support ad-hoc commands")}async toggleCommandForm(e){e.preventDefault();const t=e.target.getAttribute("data-command-node"),n=this.commands.filter((e=>e.node===t))[0];if(this.showform===t)this.showform="",this.requestUpdate();else{const e=await wd.adhoc.fetchCommandForm(n);n.sessionid=e.sessionid,n.instructions=e.instructions,n.fields=e.fields,n.actions=e.actions,this.showform=t}}executeAction(e){e.preventDefault();const t=e.target.getAttribute("data-action");["execute","next","prev","complete"].includes(t)?this.runCommand(e.target.form,t):$l.error(`Unknown action: ${t}`)}clearCommand(e){delete e.alert,delete e.instructions,delete e.sessionid,delete e.alert_type,e.fields=[],e.acions=[],this.showform=""}async runCommand(e,t){const n=new FormData(e),s=n.get("command_jid").trim(),i=n.get("command_node").trim(),r=this.commands.filter((e=>e.node===i))[0];delete r.alert,this.requestUpdate();const o="prev"===t?[]:vx(":input:not([type=button]):not([type=submit])",e).filter((e=>!["command_jid","command_node"].includes(e.getAttribute("name")))).map(Nw).filter((e=>e)),a=await wd.adhoc.runCommand(s,r.sessionid,r.node,t,o),{fields:c,status:l,note:d,instructions:u,actions:h}=a;if("error"===l)return r.alert_type="danger",r.alert=ib("Sorry, an error occurred while trying to execute the command. See the developer console for details"),this.requestUpdate();"executing"===l?(r.alert=ib("Executing"),r.fields=c,r.instructions=u,r.alert_type="primary",r.actions=h):"completed"===l?(this.alert_type="primary",this.alert=ib("Completed"),this.note=d,this.clearCommand(r)):($l.error(`Unexpected status for ad-hoc command: ${l}`),r.alert=ib("Completed"),r.alert_type="primary"),this.requestUpdate()}async cancel(e){e.preventDefault(),this.showform="",this.requestUpdate();const t=new FormData(e.target.form),n=t.get("command_jid").trim(),s=t.get("command_node").trim(),i=this.commands.filter((e=>e.node===s))[0];delete i.alert,this.requestUpdate();const{status:r}=await wd.adhoc.runCommand(n,i.sessionid,i.node,"cancel",[]);"error"===r?(i.alert_type="danger",i.alert=ib("An error occurred while trying to cancel the command. See the developer console for details")):"canceled"===r?(this.alert_type="",this.alert="",this.clearCommand(i)):($l.error(`Unexpected status for ad-hoc command: ${r}`),i.alert=ib("Error: unexpected result"),i.alert_type="danger"),this.requestUpdate()}}),Fm.plugins.add("converse-adhoc-views",{dependencies:["converse-controlbox","converse-muc"],initialize(){wd.settings.extend({allow_adhoc_commands:!0})}});const yx=function(e,t,n){t=Dt(t,e);var s=null==(e=Hi(e,t))?e:e[zt(Bi(t))];return null==s?void 0:ke(s,e,n)};var _x=Re((function(e,t,n){var s=-1,i="function"==typeof t,r=be(e)?Array(e.length):[];return Il(e,(function(e){r[++s]=i?ke(t,e,n):yx(e,t,n)})),r}));const bx=_x;function wx(e,t){if(wd.settings.get("allow_bookmarks")&&e.model.get("type")===Zl.CHATROOMS_TYPE){const n={i18n_title:ib("Bookmark this groupchat"),i18n_text:ib("Bookmark"),handler:t=>e.showBookmarkModal(t),a_class:"toggle-bookmark",icon_class:"fa-bookmark",name:"bookmark"},s=t.map((e=>e.name)),i=s.indexOf("details"),r=Kp().then((e=>e?n:null));return i>-1?[...t.slice(0,i),r,...t.slice(i)]:[r,...t]}return t}async function Sx(e){e.preventDefault();const t=e.currentTarget.getAttribute("data-bookmark-name"),n=e.currentTarget.getAttribute("data-room-jid");await wd.confirm(ib('Are you sure you want to remove the bookmark "%1$s"?',t))&&bx(Zl.bookmarks.where({jid:n}),dr.prototype.destroy)}function xx(e){e.preventDefault();const t=e.currentTarget.getAttribute("data-room-jid");wd.modal.show("converse-bookmark-form-modal",{jid:t},e)}function Ax(e){e.preventDefault();const{Strophe:t}=Fm.env,n=e.target.textContent,s=e.target.getAttribute("data-room-jid"),i={name:n||t.unescapeNode(t.getNodeFromJid(s))||s};wd.rooms.open(s,i,!0)}const Ex=e=>{const t=e.get("jid"),n=ib("Unbookmark this groupchat"),s=ib("Click to open this groupchat");return bm``};var $x=n(7690),Cx={};Cx.styleTagTransform=_b(),Cx.setAttributes=fb(),Cx.insert=mb().bind(null,"head"),Cx.domAPI=ub(),Cx.insertStyleElement=vb();lb()($x.Z,Cx);$x.Z&&$x.Z.locals&&$x.Z.locals;class kx extends ob{async initialize(){await wd.waitUntil("bookmarksInitialized");const{bookmarks:e,chatboxes:t}=Zl;this.liveFilter=rd((e=>this.model.set({filter_text:e.target.value})),100),this.listenTo(e,"add",(()=>this.requestUpdate())),this.listenTo(e,"remove",(()=>this.requestUpdate())),this.listenTo(t,"add",(()=>this.requestUpdate())),this.listenTo(t,"remove",(()=>this.requestUpdate()));const n=`converse.bookmarks-list-model-${Zl.bare_jid}`;this.model=new dr({id:n}),Gc(this.model,n),this.listenTo(this.model,"change",(()=>this.requestUpdate())),this.model.fetch({success:()=>this.requestUpdate(),error:()=>this.requestUpdate()})}render(){return Zl.bookmarks&&this.model?(e=>{const t=ib("Filter"),n=e.model.get("filter_text"),{bookmarks:s}=Zl,i=n?s.filter((e=>((e,t)=>e.get("name")?.includes(t)||e.get("jid")?.includes(t))(e,n))):s;return bm`
    ${i.map((e=>Ex(e)))}
    `})(this):SS()}clearFilter(e){e?.stopPropagation?.(),this.model.set("filter_text","")}}wd.elements.define("converse-bookmarks",kx);wd.elements.define("converse-bookmark-list-modal",class extends tS{renderModal(){return bm``}getModalTitle(){return ib("Bookmarks")}});class jx extends ob{static get properties(){return{jid:{type:String}}}willUpdate(e){e.has("jid")&&(this.model=Zl.chatboxes.get(this.jid),this.bookmark=Zl.bookmarks.get(this.jid))}render(){return(e=>{const t=e.model.getDisplayName(),n=e.bookmark?.get("nick")??e.model.get("nick"),s=ib('Bookmark for "%1$s"',t),i=ib("Would you like this groupchat to be automatically joined upon startup?"),r=ib("Remove"),o=ib("The name for this bookmark:"),a=ib("What should your nickname for this groupchat be?"),c=e.bookmark?ib("Update"):ib("Save");return bm`
    ${s}
    ${e.bookmark?bm``:""}
    `})(this)}onBookmarkFormSubmitted(e){e.preventDefault(),Zl.bookmarks.createBookmark({jid:this.jid,autojoin:e.target.querySelector('input[name="autojoin"]')?.checked||!1,name:e.target.querySelector("input[name=name]")?.value,nick:e.target.querySelector("input[name=nick]")?.value}),this.closeBookmarkForm(e)}removeBookmark(e){this.bookmark?.destroy(),this.closeBookmarkForm(e)}closeBookmarkForm(e){e.preventDefault();const t=document.createEvent("Event");t.initEvent("hide.bs.modal",!0,!0),this.dispatchEvent(t)}}wd.elements.define("converse-muc-bookmark-form",jx);const Tx=jx;wd.elements.define("converse-bookmark-form-modal",class extends tS{renderModal(){return bm``}getModalTitle(){return ib("Bookmark")}});const{u:Ix}=Fm.env,Nx={setBookmarkState(){if(void 0!==Zl.bookmarks){Zl.bookmarks.where({jid:this.model.get("jid")}).length?this.model.save("bookmarked",!0):this.model.save("bookmarked",!1)}},renderBookmarkForm(){if(!this.bookmark_form){this.bookmark_form=new Zl.MUCBookmarkForm({model:this.model,chatroomview:this});this.querySelector(".chatroom-body").insertAdjacentElement("beforeend",this.bookmark_form.el)}Ix.showElement(this.bookmark_form.el)},showBookmarkModal(e){e?.preventDefault();const t=this.model.get("jid");wd.modal.show("converse-bookmark-form-modal",{jid:t},e)}};Fm.plugins.add("converse-bookmark-views",{dependencies:["converse-chatboxes","converse-muc","converse-muc-views"],initialize(){wd.settings.extend({hide_open_bookmarks:!0}),Zl.removeBookmarkViaEvent=Sx,Zl.addBookmarkViaEvent=xx,Object.assign(Zl.ChatRoomView.prototype,Nx),Zl.MUCBookmarkForm=Tx,Zl.BookmarksView=kx,wd.listen.on("getHeadingButtons",wx),wd.listen.on("chatRoomViewInitialized",(e=>e.setBookmarkState()))}});const Mx=(e,t,n)=>{const s=new Map;for(let i=t;i<=n;i++)s.set(e[i],i);return s},Ox=MS(class extends OS{constructor(e){if(super(e),e.type!==NS)throw Error("repeat() can only be used in text expressions")}dt(e,t,n){let s;void 0===n?n=t:void 0!==t&&(s=t);const i=[],r=[];let o=0;for(const t of e)i[o]=s?s(t,o):o,r[o]=n(t,o),o++;return{values:r,keys:i}}render(e,t,n){return this.dt(e,t,n).values}update(e,t){let[n,s,i]=t;const r=(e=>e._$AH)(e),{values:o,keys:a}=this.dt(n,s,i);if(!Array.isArray(r))return this.ut=a,o;const c=this.ut??=[],l=[];let d,u,h=0,m=r.length-1,g=0,f=o.length-1;for(;h<=m&&g<=f;)if(null===r[h])h++;else if(null===r[m])m--;else if(c[h]===a[g])l[g]=jS(r[h],o[g]),h++,g++;else if(c[m]===a[f])l[f]=jS(r[m],o[f]),m--,f--;else if(c[h]===a[f])l[f]=jS(r[h],o[f]),kS(e,l[f+1],r[h]),h++,f--;else if(c[m]===a[g])l[g]=jS(r[m],o[g]),kS(e,r[h],r[m]),m--,g++;else if(void 0===d&&(d=Mx(a,g,f),u=Mx(c,h,m)),d.has(c[h]))if(d.has(c[m])){const t=u.get(a[g]),n=void 0!==t?r[t]:null;if(null===n){const t=kS(e,r[h]);jS(t,o[g]),l[g]=t}else l[g]=jS(n,o[g]),kS(e,r[h],n),r[t]=null;g++}else IS(r[m]),m--;else IS(r[h]),h++;for(;g<=f;){const t=kS(e,l[f+1]);jS(t,o[g]),l[g++]=t}for(;h<=m;){const e=r[h++];null!==e&&IS(e)}return this.ut=a,function(e){let t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:TS;e._$AH=t}(e,l),Dh}});function Rx(e){const{CONTROLBOX_TYPE:t}=Zl,n="overlayed"===wd.settings.get("view_mode")&&e.get("minimized");return e.get("type")===t||!(e.get("hidden")||n)}wd.elements.define("converse-chats",class extends ob{initialize(){this.model=Zl.chatboxes,this.listenTo(this.model,"add",(()=>this.requestUpdate())),this.listenTo(this.model,"change:closed",(()=>this.requestUpdate())),this.listenTo(this.model,"change:hidden",(()=>this.requestUpdate())),this.listenTo(this.model,"change:jid",(()=>this.requestUpdate())),this.listenTo(this.model,"change:minimized",(()=>this.requestUpdate())),this.listenTo(this.model,"destroy",(()=>this.requestUpdate())),this.listenTo(Zl,"connected",(()=>this.requestUpdate())),this.listenTo(Zl,"reconnected",(()=>this.requestUpdate())),this.listenTo(Zl,"disconnected",(()=>this.requestUpdate()));const e=Qc();this.listenTo(e,"change:view_mode",(()=>this.requestUpdate())),this.listenTo(e,"change:singleton",(()=>this.requestUpdate()));const t=document.getElementById("conversejs-bg");t&&!t.innerHTML.trim()&&zm(bm`
    Logo Converse converse.js
    ${"overlayed"===wd.settings.get("view_mode")?bm`
    `:""}
    `,t);document.querySelector("body").classList.add(`converse-${wd.settings.get("view_mode")}`),wd.trigger("chatBoxViewsInitialized")}render(){return(()=>{const{chatboxes:e,CONTROLBOX_TYPE:t,CHATROOMS_TYPE:n,HEADLINES_TYPE:s}=Zl,i=wd.settings.get("view_mode"),r=Zl?.connection,o=!r?.connected||!r?.authenticated||r?.disconnecting;return bm`${o||"overlayed"!==i?"":bm``} ${Ox(e.filter(Rx),(e=>e.get("jid")),(e=>e.get("type")===t?bm`${"overlayed"===i?bm``:""}`:e.get("type")===n?bm``:e.get("type")===s?bm``:bm``))}`})()}});const Dx=class{constructor(){this.views={}}add(e,t){this.views[e]=t}get(e){return this.views[e]}xget(e){return this.keys().filter((t=>t!==e)).reduce(((e,t)=>(e[t]=this.views[t],e)),{})}getAll(){return Object.values(this.views)}keys(){return Object.keys(this.views)}remove(e){delete this.views[e]}map(e){return Object.values(this.views).map(e)}forEach(e){return Object.values(this.views).forEach(e)}filter(e){return Object.values(this.views).filter(e)}closeAllChatBoxes(){return Promise.all(Object.values(this.views).map((e=>e.close({name:"closeAllChatBoxes"}))))}};function zx(){const e=.01*window.innerHeight;document.documentElement.style.setProperty("--vh",`${e}px`)}var Px=n(148),Lx={};Lx.styleTagTransform=_b(),Lx.setAttributes=fb(),Lx.insert=mb().bind(null,"head"),Lx.domAPI=ub(),Lx.insertStyleElement=vb();lb()(Px.Z,Lx);Px.Z&&Px.Z.locals&&Px.Z.locals;Fm.plugins.add("converse-chatboxviews",{dependencies:["converse-chatboxes","converse-vcard"],initialize(){wd.promises.add(["chatBoxViewsInitialized"]),wd.settings.extend({animate:!0}),Zl.chatboxviews=new Dx,wd.listen.on("chatBoxesInitialized",(()=>{Zl.chatboxes.on("destroy",(e=>Zl.chatboxviews.remove(e.get("jid"))))})),wd.listen.on("cleanup",(()=>delete Zl.chatboxviews)),wd.listen.on("clearSession",(()=>Zl.chatboxviews.closeAllChatBoxes())),wd.listen.on("chatBoxViewsInitialized",zx),window.addEventListener("resize",zx),Object.assign(Fm,{insertInto(e){const t=Zl.chatboxviews?.el;if(t&&!e.contains(t))e.insertAdjacentElement("afterBegin",t);else if(!t)throw new Error("Cannot insert non-existing #conversejs element into the DOM")}})}});var Fx=n(1540),Ux={};Ux.styleTagTransform=_b(),Ux.setAttributes=fb(),Ux.insert=mb().bind(null,"head"),Ux.domAPI=ub(),Ux.insertStyleElement=vb();lb()(Fx.Z,Ux);Fx.Z&&Fx.Z.locals&&Fx.Z.locals;const{Strophe:Bx,u:qx}=Fm.env;class Hx extends ob{static get properties(){return{is_retracted:{type:Boolean},model:{type:Object}}}initialize(){const e=Qc();this.listenTo(e,"change:allowed_audio_domains",(()=>this.requestUpdate())),this.listenTo(e,"change:allowed_image_domains",(()=>this.requestUpdate())),this.listenTo(e,"change:allowed_video_domains",(()=>this.requestUpdate())),this.listenTo(e,"change:render_media",(()=>this.requestUpdate())),this.listenTo(this.model,"change",(()=>this.requestUpdate()))}render(){return bm`${WS(this.renderActions(),"")}`}async renderActions(){const e=this.model.collection.length>2&&this.model===this.model.collection.last(),t=(await this.getActionButtons()).map((e=>Hx.getActionsDropdownItem(e)));return t.length?bm``:""}static getActionsDropdownItem(e){return bm``}async onMessageEditButtonClicked(e){e.preventDefault();const t=this.model.collection.findWhere("correcting"),n=qx.ancestor(this,".chatbox")?.querySelector(".chat-textarea")?.value;if(n&&(!t||t.getMessageText()!==n)){if(!await wd.confirm(ib("You have an unsent message which will be lost if you continue. Are you sure?")))return}t!==this.model?(t?.save("correcting",!1),this.model.save("correcting",!0)):this.model.save("correcting",!1)}async onDirectMessageRetractButtonClicked(){if("me"!==this.model.get("sender"))return $l.error("onMessageRetractButtonClicked called for someone else's message!");const e=ib("Be aware that other XMPP/Jabber clients (and servers) may not yet support retractions and that this message may not be removed everywhere."),t=[ib("Are you sure you want to retract this message?")];wd.settings.get("show_retraction_warning")&&(t[1]=e);if(await wd.confirm(ib("Confirm"),t)){this.model.collection.chatbox.retractOwnMessage(this.model)}}async retractOtherMessage(e){const t=this.model.collection.chatbox,n=await t.retractOtherMessage(this.model,e);if(null===n){const e=ib("A timeout occurred while trying to retract the message");wd.alert("error",ib("Error"),e),$l(e,Bx.LogLevel.WARN)}else if(qx.isErrorStanza(n)){const e=ib("Sorry, you're not allowed to retract this message.");wd.alert("error",ib("Error"),e),$l(e,Bx.LogLevel.WARN),$l(n,Bx.LogLevel.WARN)}}async onMUCMessageRetractButtonClicked(){const e=ib("Be aware that other XMPP/Jabber clients (and servers) may not yet support retractions and that this message may not be removed everywhere.");if(this.model.mayBeRetracted()){const t=[ib("Are you sure you want to retract this message?")];if(wd.settings.get("show_retraction_warning")&&(t[1]=e),await wd.confirm(ib("Confirm"),t)){this.model.collection.chatbox.retractOwnMessage(this.model)}}else if(await this.model.mayBeModerated())if("me"===this.model.get("sender")){let t=[ib("Are you sure you want to retract this message?")];wd.settings.get("show_retraction_warning")&&(t=[t[0],e,t[1]]),await wd.confirm(ib("Confirm"),t)&&this.retractOtherMessage()}else{let t=[ib("You are about to retract this message."),ib("You may optionally include a message, explaining the reason for the retraction.")];wd.settings.get("show_retraction_warning")&&(t=[t[0],e,t[1]]);const n=await wd.prompt(ib("Message Retraction"),t,ib("Optional reason"));!1!==n&&this.retractOtherMessage(n)}else{const e=ib("Sorry, you're not allowed to retract this message");wd.alert("error",ib("Error"),e)}}onMessageRetractButtonClicked(e){e?.preventDefault?.();this.model.collection.chatbox.get("type")===Zl.CHATROOMS_TYPE?this.onMUCMessageRetractButtonClicked():this.onDirectMessageRetractButtonClicked()}onMediaToggleClicked(e){if(e?.preventDefault?.(),this.hasHiddenMedia(this.getMediaURLs()))this.model.save({hide_url_previews:!1,url_preview_transition:"fade-in"});else{(this.model.get("ogp_metadata")||[]).length?this.model.set("url_preview_transition","fade-out"):this.model.save({hide_url_previews:!0,url_preview_transition:"fade-in"})}}hasHiddenMedia(e){if("boolean"==typeof this.model.get("hide_url_previews"))return this.model.get("hide_url_previews");const t=wd.settings.get("render_media");return Array.isArray(t)?e.reduce(((e,n)=>e||!tg(t,n)),!1):!t}getMediaURLs(){const e=(this.model.get("ogp_metadata")||[]).map((e=>({url:e["og:image"],is_image:!0}))).filter((e=>rg(e))),t=Gm(this.model.get("media_urls")||[],this.model.get("body")).filter((e=>rg(e)));return[...new Set([...t.map((e=>e.url)),...e.map((e=>e.url))])]}addMediaRenderingToggle(e){const t=this.getMediaURLs();if(t.length){const n=this.hasHiddenMedia(t);e.push({i18n_text:ib(n?"Show media":"Hide media"),handler:e=>this.onMediaToggleClicked(e),button_class:"chat-msg__action-hide-previews",icon_class:n?"fas fa-eye":"fas fa-eye-slash",name:"hide"})}}async getActionButtons(){const e=[];this.model.get("editable")&&e.push({i18n_text:this.model.get("correcting")?ib("Cancel Editing"):ib("Edit"),handler:e=>this.onMessageEditButtonClicked(e),button_class:"chat-msg__action-edit",icon_class:"fa fa-pencil-alt",name:"edit"});const t=["groupchat","mep"].includes(this.model.get("type"))&&await this.model.mayBeModerated();return!this.is_retracted&&(this.model.mayBeRetracted()||t)&&e.push({i18n_text:ib("Retract"),handler:e=>this.onMessageRetractButtonClicked(e),button_class:"chat-msg__action-retract",icon_class:"fas fa-trash-alt",name:"retract"}),this.model.collection?(this.addMediaRenderingToggle(e),wd.hook("getMessageActionButtons",this,e)):[]}}wd.elements.define("converse-message-actions",Hx);var Gx=n(17),Wx={};Wx.styleTagTransform=_b(),Wx.setAttributes=fb(),Wx.insert=mb().bind(null,"head"),Wx.domAPI=ub(),Wx.insertStyleElement=vb();lb()(Gx.Z,Wx);Gx.Z&&Gx.Z.locals&&Gx.Z.locals;wd.elements.define("converse-image-modal",class extends tS{renderModal(){return(e=>bm``)({src:this.src})}getModalTitle(){return bm`${ib("Image: ")}${Ow(this.src)}`}});var Vx=n(5077);class Zx{constructor(e,t){this.options=Object.assign({width:null,height:null,autoplay:!0,loop:!0,show_progress_bar:!0,progress_bg_color:"rgba(0,0,0,0.4)",progress_color:"rgba(255,0,22,.8)",progress_bar_height:5},t),this.el=e,this.gif_el=e.querySelector("img"),this.canvas=e.querySelector("canvas"),this.ctx=this.canvas.getContext("2d"),this.offscreenCanvas=document.createElement("canvas"),this.patchCanvas=document.createElement("canvas"),this.ctx_scaled=!1,this.frames=[],this.load_error=null,this.playing=this.options.autoplay,this.frame_idx=0,this.iteration_count=0,this.start=null,this.hovering=null,this.frameImageData=null,this.disposal_restore_from_idx=null,this.initialize()}async initialize(){this.options.width&&this.options.height&&this.setSizes(this.options.width,this.options.height);const e=await this.fetchGIF(this.gif_el.src);requestAnimationFrame((()=>this.handleGIFResponse(e)))}initPlayer(){if(!this.load_error&&(this.options.width&&this.options.height||this.ctx.scale(this.getCanvasScale(),this.getCanvasScale()),this.frame_idx=0,this.renderImage(),this.options.autoplay)){const e=this.frames[this.frame_idx]?.delay??0;setTimeout((()=>this.play()),e)}}getNextFrameNo(){return 0===this.frames.length?0:(this.frame_idx+1+this.frames.length)%this.frames.length}onIterationEnd(){return this.iteration_count++,this.options.onIterationEnd?.(this),!this.options.loop&&(this.pause(),!0)}onAnimationFrame(e,t,n){if(!this.playing)return;if(e-tthis.onAnimationFrame(e,t,n)));const s=this.getNextFrameNo();if(0===s&&this.onIterationEnd())return;this.frame_idx=s,this.renderImage();const i=this.frames[this.frame_idx]?.delay||8;requestAnimationFrame((t=>this.onAnimationFrame(t,e,i)))}setSizes(e,t){this.canvas.width=e*this.getCanvasScale(),this.canvas.height=t*this.getCanvasScale(),this.offscreenCanvas.width=e,this.offscreenCanvas.height=t,this.offscreenCanvas.style.width=e+"px",this.offscreenCanvas.style.height=t+"px",this.offscreenCanvas.getContext("2d").setTransform(1,0,0,1,0,0)}doShowProgress(e,t,n){if(n&&this.options.show_progress_bar){let n=this.options.progress_bar_height;const s=(this.canvas.height-n)/(this.ctx_scaled?this.getCanvasScale():1),i=e/t*this.canvas.width/(this.ctx_scaled?this.getCanvasScale():1),r=this.canvas.width/(this.ctx_scaled?this.getCanvasScale():1);n/=this.ctx_scaled?this.getCanvasScale():1,this.ctx.fillStyle=this.options.progress_bg_color,this.ctx.fillRect(i,s,r-i,n),this.ctx.fillStyle=this.options.progress_color,this.ctx.fillRect(0,s,i,n)}}handleGIFResponse(e){try{const t=(0,Vx.vq)(e);this.hdr=t.header,this.lsd=t.lsd,this.setSizes(this.options.width??this.lsd.width,this.options.height??this.lsd.height),this.frames=(0,Vx.zw)(t,!0)}catch(e){this.showError()}this.initPlayer(),!this.options.autoplay&&this.drawPlayIcon()}drawError(){this.ctx.fillStyle="black",this.ctx.fillRect(0,0,this.options.width,this.options.height),this.ctx.strokeStyle="red",this.ctx.lineWidth=3,this.ctx.moveTo(0,0),this.ctx.lineTo(this.options.width,this.options.height),this.ctx.moveTo(0,this.options.height),this.ctx.lineTo(this.options.width,0),this.ctx.stroke()}showError(){this.load_error=!0,this.hdr={width:this.gif_el.width,height:this.gif_el.height},this.frames=[],this.drawError(),this.el.requestUpdate()}manageDisposal(e){if(e<=0)return;const t=this.offscreenCanvas.getContext("2d"),n=this.frames[e-1].disposalType;e>1&&(3===n?null!=this.disposal_restore_from_idx&&t.putImageData(this.frames[this.disposal_restore_from_idx].data,0,0):this.disposal_restore_from_idx=e-1),2===n&&t.clearRect(this.last_frame.dims.left,this.last_frame.dims.top,this.last_frame.dims.width,this.last_frame.dims.height)}renderImage(){let e=!(arguments.length>0&&void 0!==arguments[0])||arguments[0];if(!this.frames.length)return;let t=this.frame_idx;t=parseInt(t.toString(),10),(t>this.frames.length-1||t<0)&&(t=0),this.manageDisposal(t);const n=this.frames[t],s=this.patchCanvas.getContext("2d"),i=this.offscreenCanvas.getContext("2d"),r=n.dims;this.frameImageData&&r.width==this.frameImageData.width&&r.height==this.frameImageData.height||(this.patchCanvas.width=r.width,this.patchCanvas.height=r.height,this.frameImageData=s.createImageData(r.width,r.height)),this.frameImageData.data.set(n.patch),s.putImageData(this.frameImageData,0,0),i.drawImage(this.patchCanvas,r.left,r.top);const o=i.getImageData(0,0,this.offscreenCanvas.width,this.offscreenCanvas.height);this.ctx.putImageData(o,0,0),this.ctx.drawImage(this.canvas,0,0,this.canvas.width,this.canvas.height),e&&this.hovering&&this.drawPauseIcon(),this.last_frame=n}play(){this.playing=!0,requestAnimationFrame((e=>this.onAnimationFrame(e,0,0)))}pause(){this.playing=!1,requestAnimationFrame((()=>this.drawPlayIcon()))}drawPauseIcon(){if(!this.playing)return;this.renderImage(!1),this.ctx.fillStyle="rgb(0, 0, 0, 0.25)",this.ctx.fillRect(0,0,this.canvas.width,this.canvas.height);const e=.1*this.canvas.height;this.ctx.lineWidth=.04*this.canvas.height,this.ctx.beginPath(),this.ctx.moveTo(this.canvas.width/2-e/2,this.canvas.height/2-e),this.ctx.lineTo(this.canvas.width/2-e/2,this.canvas.height/2+e),this.ctx.fillStyle="rgb(200, 200, 200, 0.75)",this.ctx.stroke(),this.ctx.beginPath(),this.ctx.moveTo(this.canvas.width/2+e/2,this.canvas.height/2-e),this.ctx.lineTo(this.canvas.width/2+e/2,this.canvas.height/2+e),this.ctx.fillStyle="rgb(200, 200, 200, 0.75)",this.ctx.stroke(),this.ctx.lineWidth=.02*this.canvas.height,this.ctx.strokeStyle="rgb(200, 200, 200, 0.75)",this.ctx.beginPath(),this.ctx.arc(this.canvas.width/2,this.canvas.height/2,1.5*e,0,2*Math.PI),this.ctx.stroke()}drawPlayIcon(){if(this.playing)return;this.renderImage(!1),this.ctx.fillStyle="rgb(0, 0, 0, 0.25)",this.ctx.fillRect(0,0,this.canvas.width,this.canvas.height);const e=.1*this.canvas.height,t=new Path2D;t.moveTo(this.canvas.width/2+e,this.canvas.height/2),t.lineTo(this.canvas.width/2-e/2,this.canvas.height/2+e),t.lineTo(this.canvas.width/2-e/2,this.canvas.height/2-e),t.closePath(),this.ctx.fillStyle="rgb(200, 200, 200, 0.75)",this.ctx.fill(t);const n=1.5*e;this.ctx.lineWidth=.02*this.canvas.height,this.ctx.strokeStyle="rgb(200, 200, 200, 0.75)",this.ctx.beginPath(),this.ctx.arc(this.canvas.width/2,this.canvas.height/2,n,0,2*Math.PI),this.ctx.stroke()}getCanvasScale(){let e;return e=this.options.max_width&&this.hdr&&this.lsd.width>this.options.max_width?this.options.max_width/this.lsd.width:1,e}fetchGIF(e){const t=Xo(),n=new XMLHttpRequest;return n.open("GET",e,!0),n.responseType="arraybuffer",n?.overrideMimeType("text/plain; charset=x-user-defined"),n.onload=()=>{if(200!=n.status)return this.showError(),t.reject();t.resolve(n.response)},n.onprogress=e=>e.lengthComputable&&this.doShowProgress(e.loaded,e.total,!0),n.onerror=e=>{$l.error(e),this.showError()},n.send(),t}}var Qx=n(9478),Jx={};Jx.styleTagTransform=_b(),Jx.setAttributes=fb(),Jx.insert=mb().bind(null,"head"),Jx.domAPI=ub(),Jx.insertStyleElement=vb();lb()(Qx.Z,Jx);Qx.Z&&Qx.Z.locals&&Qx.Z.locals;wd.elements.define("converse-gif",class extends ob{static get properties(){return{autoplay:{type:Boolean},noloop:{type:Boolean},progress_color:{type:String},fallback:{type:String},src:{type:String}}}constructor(){super(),this.src=null,this.autoplay=!1,this.noloop=!1,this.fallback="url"}initGIF(){const e={autoplay:this.autoplay,loop:!this.noloop};this.progress_color&&(e.progress_color=this.progress_color),this.supergif=new Zx(this,e)}updated(e){this.supergif&&!e.has("src")?(e.has("autoplay")&&(this.supergif.options.autoplay=this.autoplay),e.has("noloop")&&(this.supergif.options.loop=!this.noloop),e.has("progress_color")&&(this.supergif.options.progress_color=this.progress_color)):this.initGIF()}render(){return this.supergif?.load_error&&["url","empty"].includes(this.fallback)?this.renderErrorFallback():bm``}renderErrorFallback(){return"url"===this.fallback?Uw(this.src):"empty"===this.fallback?"":void 0}setHover(){this.supergif&&(this.supergif.hovering=!0,this.hover_timeout&&clearTimeout(this.hover_timeout),this.hover_timeout=setTimeout((()=>this.unsetHover()),2e3))}unsetHover(){this.supergif&&(this.supergif.hovering=!1)}onControlsClicked(e){e.preventDefault(),this.supergif.playing?this.supergif.pause():this.supergif.frames.length>0&&(this.supergif.options.loop=!0,this.supergif.play())}});const Kx=(e,t)=>bm`${t?"":bm`${e}`}`,{URI:Yx}=Fm.env;const Xx=MS(class extends US{render(e,t,n,s){return t?bm`${this.renderImage(e,t,n,s)}`:this.renderImage(e,t,n,s)}renderImage(e,t,n,s){return bm``}onError(e,t,n,s){if(og(e))t&&this.setValue(Uw(t));else{const i=new Yx(e),r=i.filename();i.filename(`${r}.png`),this.setValue(Xx(i.toString(),t,n,s))}}}),eA=e=>bm`${Xx(e.src||e.url,e.href,e.onLoad,e.onClick)}`;const tA=MS(class extends OS{render(e,t,n){const s=new SA(e,t,Object.assign(n,{show_images:!1,embed_videos:!1,embed_audio:!1}));return bm`${WS(async function(e){try{await e.addTemplates()}catch(e){$l.error(e)}return e.payload}(s),bm`${s}`)}`}}),nA=["*","_","~","`"],sA=[...nA,"```",">"],iA={"*":{name:"strong",type:"span"},_:{name:"emphasis",type:"span"},"~":{name:"strike",type:"span"},"`":{name:"preformatted",type:"span"},"```":{name:"preformatted_block",type:"block"},">":{name:"quote",type:"block"}},rA=["_",">","`","~"],oA={emphasis:(e,t,n)=>bm`_${tA(e,t,n)}_`,preformatted:e=>bm`\`${e}\``,preformatted_block:e=>bm`
    \`\`\`
    ${e}
    \`\`\`
    `,quote:(e,t,n)=>bm`
    ${tA(e,t,n)}
    `,strike:(e,t,n)=>bm`~${tA(e,t,n)}~`,strong:(e,t,n)=>bm`*${tA(e,t,n)}*`};function aA(e,t){let n,s=!(arguments.length>2&&void 0!==arguments[2])||arguments[2];if(/(^```[\s,\u200B]*\n)|(^```[\s,\u200B]*$)/.test(e.slice(t))&&(0===t||">"===e[t-1]||/\n\u200B{0,2}$/.test(e.slice(0,t))))n=e.slice(t,t+3);else{if(!sA.includes(e.slice(t,t+1)))return null;if(n=e.slice(t,t+1),!function(e,t,n,s){if(s){const s=RegExp(rA.includes(e)?`^(\\p{L}|\\p{N})${e}`:`^(\\p{L}|\\p{N})\\${e}`,"u");if(n>1&&s.test(t.slice(n-1)))return!1;if(lA(e)&&n>0&&"\n"!==t[n-1])return!1;if(nA.includes(e)&&t[n+1]===e)return!1}else{const s=RegExp(rA.includes(e)?`^${e}(\\p{L}|\\p{N})`:`^\\${e}(\\p{L}|\\p{N})`,"u");if(n]/).shift().length)-s;if("span"===iA[e].type){const s=t.slice(n).split("\n").shift();let i=0,r=s.indexOf(e);for(;-1!==r;){if(aA(t,n+r,!1)===e)return r+2*e.length;r=s.indexOf(e,i++)}return 0}{const s=t.slice(n+1);let i=0,r=s.indexOf(e);for(;-1!==r;){if(aA(t,n+1+r,!1)===e)return r+1+2*e.length;r=s.indexOf(e,i++)}return 0}}(n,e,t):0;return s>0?{d:n,length:s}:{}}const lA=e=>[">",">"].includes(e);function dA(e,t,n,s){const i=oA[iA[e].name];if(lA(e)){return i(t.replace(/\n>\s/g,"\n​​").replace(/\n>/g,"\n​").replace(/\n$/,""),n,s)}return i(t,n,s)}const{dayjs:uA,u:hA}=Fm.env;function mA(e){return e.then((e=>e.filter((e=>e.standalone)).map((e=>async function(e){const t=await e;return bm``}(e))).reverse().map((e=>WS(e,"")))))}function gA(e){return e.then((e=>{const t=e.filter((e=>!e.standalone)).map((e=>async function(e){const t=await e;return t?bm`${t.i18n_text}`:""}(e)));return t.length?bm``:""}))}function fA(e){if(!e.isHidden()&&wd.settings.get("allow_url_history_change")){const t=window.location.hash;t&&e.messages.get(t.slice(1))&&Zl.router.history.navigate()}}const pA=rd((e=>function(e){const t=e.target;if("converse-chat-content"!==t.nodeName.toLowerCase())return;let n=!0;const s=0===Math.floor(t.scrollTop),i=Math.ceil(t.clientHeight-t.scrollTop)>=t.scrollHeight-Math.ceil(t.scrollHeight/20);s?(n=!1,fA(t.model)):i&&wd.trigger("chatBoxScrolledUp",t),t.model.get("scolled")!==n&&t.model.ui.set({scrolled:n})}(e)),50);function vA(e){const t=e.collection?.models;if(!t)return;const n=t.indexOf(e),s=t[n-1];if(!s||uA(e.get("time")).isAfter(uA(s.get("time")),"day")){const t=uA(e.get("time")).startOf("day");return(e=>bm`

    `)({type:"date",time:t.toISOString(),datestring:t.format("dddd MMM Do YYYY")})}}function yA(e){if("groupchat"===e.get("type")){const t=wd.settings.get("muc_hats").filter((e=>e)).map((e=>e.toLowerCase()));let n=[];t.includes("vcard_roles")&&(n=e.vcard?e.vcard.get("role"):null,n=n?n.split(",").filter((e=>e)).map((e=>({title:e}))):[]);const s=[...e.occupant?[e.occupant.get("role")]:[],...e.occupant?[e.occupant.get("affiliation")]:[]].filter((e=>e)).filter((e=>t.includes(e.toLowerCase()))).map((e=>({title:e})));return[...t.includes("xep317")&&e.occupant?.get("hats")||[],...n,...s]}return[]}function _A(){var e;return Fm.emojis.toned||(Fm.emojis.toned=(e=Object.values(Fm.emojis.json.people).filter((e=>e.sn.includes("_tone"))).map((e=>e.sn.replace(/_tone[1-5]/,""))),[...new Set(e)])),Fm.emojis.toned}function bA(e){let t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{unicode_only:!1,add_title_wrapper:!1};const n=e.emoji,s=e.shortname;if(n){if(t.unicode_only)return n;if(wd.settings.get("use_system_emojis"))return t.add_title_wrapper&&s?bm`${n}`:n;{const t=wd.settings.get("emoji_image_path");return bm`${n}`}}return t.unicode_only?s:bm`${s}`}Object.assign(hA,{shortnamesToEmojis:function(e){let t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{unicode_only:!1,add_title_wrapper:!1};return function(e,t){let n=[e];return[...Af(e),...Ef(e)].sort(((e,t)=>t.begin-e.begin)).forEach((e=>{const s=n.shift(),i=bA(e,t);n="string"==typeof i?[s.slice(0,e.begin)+i+s.slice(e.end),...n]:[s.slice(0,e.begin),i,s.slice(e.end),...n]})),n}(e=xf(e),t)}});const wA=e=>"string"==typeof e;class SA extends String{constructor(e){let t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:0,n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{};super(e),this.embed_audio=n?.embed_audio,this.embed_videos=n?.embed_videos,this.mentions=n?.mentions||[],this.media_urls=n?.media_urls,this.nick=n?.nick,this.offset=t,this.onImgClick=n?.onImgClick,this.onImgLoad=n?.onImgLoad,this.options=n,this.payload=[],this.references=[],this.render_styling=n?.render_styling,this.show_images=n?.show_images,this.hide_media_urls=n?.hide_media_urls}shouldRenderMedia(e,t){let n;return"image"===t?n=this.show_images:"audio"===t?n=this.embed_audio:"video"===t&&(n=this.embed_videos),"boolean"==typeof n?n:ng(e,t)}addHyperlinks(e,t){const n=t+this.offset;Gm(this.media_urls||vg(e,t).media_urls||[],e,n).filter((e=>!e.is_encrypted)).forEach((e=>{const n=e.url,s=sg(n);let i;i=ag(n)&&this.shouldRenderMedia(n,"image")?Kx(s,this.hide_media_urls):dg(n)&&this.shouldRenderMedia(n,"image")?eA({src:s,href:this.hide_media_urls?null:s,onClick:this.onImgClick,onLoad:this.onImgLoad}):lg(n)&&this.shouldRenderMedia(n,"video")?Sw(s,this.hide_media_urls):cg(n)&&this.shouldRenderMedia(n,"audio")?gw(s,this.hide_media_urls):Uw(s),this.addTemplateResult(e.start+t,e.end+t,i)}))}addMapURLs(e,t){const n=/geo:([\-0-9.]+),([\-0-9.]+)(?:,([\-0-9.]+))?(?:\?(.*))?/g,s=e.matchAll(n);for(const e of s)this.addTemplateResult(e.index+t,e.index+e[0].length+t,Uw(e[0].replace(n,wd.settings.get("geouri_replacement"))))}addEmojis(e,t){[...Af(e.toString()),...Ef(e.toString())].forEach((e=>{this.addTemplateResult(e.begin+t,e.end+t,bA(e,{add_title_wrapper:!0}))}))}addMentions(e,t){const n=t+this.offset;this.mentions?.forEach((s=>{const i=Number(s.begin)-n;if(i<0||i>=n+e.length)return;const r=Number(s.end)-n,o=e.slice(i,r);o===this.nick?this.addTemplateResult(i+t,r+t,(e=>bm`${e.mention}`)({...s,mention:o})):this.addTemplateResult(i+t,r+t,(e=>bm`${e.mention}`)({...s,mention:o}))}))}addStyling(){if(!function(e){for(let t=0;tArray.from({length:Number(e.end)},((t,n)=>Number(e.begin)+n))));let n=0;for(;ne.includes(n))).length){n++;continue}const{d:s,length:i}=cA(this,n);if(s&&i){const t=lA(s),r=n+i,o=t?r:r-s.length;let a="```"===s?n+s.length+1:n+s.length;t&&" "===this[a]&&(a+=1);const c=a,l=this.slice(a,o);e.push({begin:n,template:dA(s,l,c,this.options),end:r}),n=r}n++}e.forEach((e=>this.addTemplateResult(e.begin,e.end,e.template)))}trimMeMessage(){0===this.offset&&this.isMeCommand()&&(this.payload[0]=this.payload[0].substring(4))}addAnnotations(e){const t=this.marshall();let n=0;for(const s of t)s&&(wA(s)?(e.call(this,s,n),n+=s.length):n=s.end)}async addTemplates(){await wd.trigger("beforeMessageBodyTransformed",this,{Synchronous:!0}),this.render_styling&&this.addStyling(),this.addAnnotations(this.addMentions),this.addAnnotations(this.addHyperlinks),this.addAnnotations(this.addMapURLs),await wd.emojis.initialize(),this.addAnnotations(this.addEmojis),await wd.trigger("afterMessageBodyTransformed",this,{Synchronous:!0}),this.payload=this.marshall(),this.options.show_me_message&&this.trimMeMessage(),this.payload=this.payload.map((e=>wA(e)?e:e.template))}addTemplateResult(e,t,n){this.references.push({begin:e,end:t,template:n})}isMeCommand(){const e=this.toString();return!!e&&e.startsWith("/me ")}marshall(){let e=[this.toString()];return this.references.sort(((e,t)=>t.begin-e.begin)).forEach((t=>{const n=e.shift();e=[n.slice(0,t.begin),t,n.slice(t.end),...e]})),e.reduce(((e,t)=>{return wA(t)?[...e,xf((n=t,n.replace(/\n\n+/g,(e=>`\n${"​".repeat(e.length-2)}\n`))))]:[...e,t];var n}),[])}}class xA{constructor(e,t){let n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{};this.offset=t,this.options=n,this.text=e}async transform(){const e=new SA(this.text,this.offset,this.options);try{await e.addTemplates()}catch(e){$l.error(e)}return e.payload}render(){return bm`${WS(this.transform(),bm`${this.text}`)}`}}const AA=MS(class extends OS{render(e,t,n,s){const i=new xA(e,t,n).render();return s?.(),i}}),EA=AA;var $A=n(6933),CA={};CA.styleTagTransform=_b(),CA.setAttributes=fb(),CA.insert=mb().bind(null,"head"),CA.domAPI=ub(),CA.insertStyleElement=vb();lb()($A.Z,CA);$A.Z&&$A.Z.locals&&$A.Z.locals;wd.elements.define("converse-chat-message-body",class extends ob{static get properties(){return{hide_url_previews:{type:String},is_me_message:{type:Boolean},model:{type:Object},text:{type:String}}}initialize(){const e=Qc();this.listenTo(e,"change:allowed_audio_domains",(()=>this.requestUpdate())),this.listenTo(e,"change:allowed_image_domains",(()=>this.requestUpdate())),this.listenTo(e,"change:allowed_video_domains",(()=>this.requestUpdate())),this.listenTo(e,"change:render_media",(()=>this.requestUpdate()))}onImgClick(e){e.preventDefault(),wd.modal.show("converse-image-modal",{src:e.target.src},e)}onImgLoad(){this.dispatchEvent(new CustomEvent("imageLoaded",{detail:this,bubbles:!0}))}render(){const e={media_urls:this.model.get("media_urls"),mentions:this.model.get("references"),nick:this.model.collection.chatbox.get("nick"),onImgClick:e=>this.onImgClick(e),onImgLoad:()=>this.onImgLoad(),render_styling:!this.model.get("is_unstyled")&&wd.settings.get("allow_message_styling"),show_me_message:!0};return"false"===this.hide_url_previews?(e.embed_audio=!0,e.embed_videos=!0,e.show_images=!0):"true"===this.hide_url_previews&&(e.embed_audio=!1,e.embed_videos=!1,e.show_images=!1),EA(this.text,0,e,(()=>this.model.collection?.trigger("rendered",this.model)))}});var kA=n(8916),jA={};jA.styleTagTransform=_b(),jA.setAttributes=fb(),jA.insert=mb().bind(null,"head"),jA.domAPI=ub(),jA.insertStyleElement=vb();lb()(kA.Z,jA);kA.Z&&kA.Z.locals&&kA.Z.locals;wd.elements.define("converse-icon",class extends ob{static get properties(){return{color:String,class_name:{attribute:"class"},style:String,size:String}}constructor(){super(),this.class_name="",this.style="",this.size="",this.color=""}getSource(){return`#icon-${this.class_name.trim().split(" ")[1].replace("fa-","")}`}getStyles(){const e=this.color.match(/var\((--.*)\)/)?.[1],t=e?getComputedStyle(this).getPropertyValue(e):this.color;return`\n ${this.size?`width: ${this.size};`:""}\n ${this.size?`height: ${this.size};`:""}\n ${t?`fill: ${t};`:""}\n ${this.style}\n `}render(){return bm``}});const{keycodes:TA}=Fm;function IA(e){let t=0;do{isNaN(e.offsetTop)||(t+=e.offsetTop)}while(e=e.offsetParent);return t}function NA(e){let t=0;do{isNaN(e.offsetLeft)||(t+=e.offsetLeft)}while(e=e.offsetParent);return t}class MA{static get DIRECTION(){return{down:"down",end:"end",home:"home",left:"left",right:"right",up:"up"}}static get DEFAULTS(){return{home:[`${TA.SHIFT}+${TA.UP_ARROW}`],end:[`${TA.SHIFT}+${TA.DOWN_ARROW}`],up:[TA.UP_ARROW],down:[TA.DOWN_ARROW],left:[TA.LEFT_ARROW,`${TA.SHIFT}+${TA.TAB}`],right:[TA.RIGHT_ARROW,TA.TAB],getSelector:null,jump_to_picked:null,jump_to_picked_direction:null,jump_to_picked_selector:"picked",onSelected:null,selected:"selected",selector:"li"}}static getClosestElement(e,t){return e.reduce(((e,n)=>{const s=t(n);return sthis.keys[e]=MA.DIRECTION.down)),this.options.end.forEach((e=>this.keys[e]=MA.DIRECTION.end)),this.options.home.forEach((e=>this.keys[e]=MA.DIRECTION.home)),this.options.left.forEach((e=>this.keys[e]=MA.DIRECTION.left)),this.options.right.forEach((e=>this.keys[e]=MA.DIRECTION.right)),this.options.up.forEach((e=>this.keys[e]=MA.DIRECTION.up))}enable(){this.getElements(),this.keydownHandler=e=>this.handleKeydown(e),this.doc.addEventListener("keydown",this.keydownHandler),this.enabled=!0}disable(){this.keydownHandler&&this.doc.removeEventListener("keydown",this.keydownHandler),this.unselect(),this.elements={},this.enabled=!1}destroy(){this.disable(),this.container.domNavigator&&delete this.container.domNavigator}getNextElement(e){let t;if(e===MA.DIRECTION.home)t=this.getElements(e)[0];else if(e===MA.DIRECTION.end)t=Array.from(this.getElements(e)).pop();else if(this.selected)if(e===MA.DIRECTION.right){const n=this.getElements(e);t=n.slice(n.indexOf(this.selected))[1]}else if(e==MA.DIRECTION.left){const n=this.getElements(e);t=n.slice(0,n.indexOf(this.selected)).pop()||this.selected}else if(e==MA.DIRECTION.down){const e=this.selected.offsetLeft,n=this.selected.offsetTop+this.selected.offsetHeight,s=this.elementsAfter(0,n),i=t=>Math.abs(t.offsetLeft-e)+Math.abs(t.offsetTop-n);t=MA.getClosestElement(s,i)}else{if(e!=MA.DIRECTION.up)throw new Error("getNextElement: invalid direction value");{const e=this.selected.offsetLeft,n=this.selected.offsetTop-1,s=this.elementsBefore(1/0,n),i=t=>Math.abs(e-t.offsetLeft)+Math.abs(n-t.offsetTop);t=MA.getClosestElement(s,i)}}else t=e===MA.DIRECTION.right||e===MA.DIRECTION.down?this.getElements(e)[1]:this.getElements(e)[0];return this.options.jump_to_picked&&t&&t.matches(this.options.jump_to_picked)&&e===this.options.jump_to_picked_direction&&(t=this.container.querySelector(this.options.jump_to_picked_selector)||t),t}select(e,t){e&&e!==this.selected&&(this.unselect(),t&&this.scrollTo(e,t),e.matches("input")?e.focus():Gw.addClass(this.options.selected,e),this.selected=e,this.options.onSelected&&this.options.onSelected(e))}unselect(){this.selected&&(Gw.removeClass(this.options.selected,this.selected),delete this.selected)}scrollTo(e,t){if(this.inScrollContainerViewport(e)){if(!function(e){const t=e.getBoundingClientRect();return t.top>=0&&t.left>=0&&t.bottom<=window.innerHeight&&t.right<=window.innerWidth}(e))switch(t){case MA.DIRECTION.left:document.body.scrollLeft=NA(e)-document.body.offsetLeft;break;case MA.DIRECTION.up:document.body.scrollTop=IA(e)-document.body.offsetTop;break;case MA.DIRECTION.right:document.body.scrollLeft=NA(e)-document.body.offsetLeft-(document.documentElement.clientWidth-e.offsetWidth);break;case MA.DIRECTION.down:document.body.scrollTop=IA(e)-document.body.offsetTop-(document.documentElement.clientHeight-e.offsetHeight)}}else{const n=this.scroll_container;if(!n.contains(e))return;switch(t){case MA.DIRECTION.left:n.scrollLeft=e.offsetLeft-n.offsetLeft,n.scrollTop=e.offsetTop-n.offsetTop;break;case MA.DIRECTION.up:n.scrollTop=e.offsetTop-n.offsetTop;break;case MA.DIRECTION.right:n.scrollLeft=e.offsetLeft-n.offsetLeft-(n.offsetWidth-e.offsetWidth),n.scrollTop=e.offsetTop-n.offsetTop-(n.offsetHeight-e.offsetHeight);break;case MA.DIRECTION.down:n.scrollTop=e.offsetTop-n.offsetTop-(n.offsetHeight-e.offsetHeight)}}}inScrollContainerViewport(e){const t=this.scroll_container;return!(e.offsetLeft-t.scrollLeftt.offsetLeft+t.offsetWidth)&&!(e.offsetTop+e.offsetHeight-t.scrollTop>t.offsetTop+t.offsetHeight)))}getElements(e){const t=this.options.getSelector?this.options.getSelector(e):this.options.selector;return this.elements[t]||(this.elements[t]=Array.from(this.container.querySelectorAll(t))),this.elements[t]}elementsAfter(e,t){return this.getElements(MA.DIRECTION.down).filter((n=>n.offsetLeft>=e&&n.offsetTop>=t))}elementsBefore(e,t){return this.getElements(MA.DIRECTION.up).filter((n=>n.offsetLeft<=e&&n.offsetTop<=t))}handleKeydown(e){const t=TA,n=e.shiftKey?this.keys[`${t.SHIFT}+${e.which}`]:this.keys[e.which];if(n){e.preventDefault(),e.stopPropagation();const t=this.getNextElement(n,e);this.select(t,n)}}}const OA=MA,RA=Fm.env.utils;class DA extends ob{connectedCallback(){super.connectedCallback(),this.registerEvents()}registerEvents(){this.clickOutside=e=>this._clickOutside(e),document.addEventListener("click",this.clickOutside)}firstUpdated(){super.firstUpdated(),this.menu=this.querySelector(".dropdown-menu"),this.button=this.querySelector("button"),this.addEventListener("click",(e=>this.toggleMenu(e))),this.addEventListener("keyup",(e=>this.handleKeyUp(e)))}_clickOutside(e){this.contains(e.composedPath()[0])||this.hideMenu(e)}hideMenu(){RA.removeClass("show",this.menu),this.button?.setAttribute("aria-expanded",!1),this.button?.blur()}showMenu(){RA.addClass("show",this.menu),this.button.setAttribute("aria-expanded",!0)}toggleMenu(e){e.preventDefault(),RA.hasClass("show",this.menu)?this.hideMenu():this.showMenu()}handleKeyUp(e){e.keyCode===Fm.keycodes.ESCAPE&&this.hideMenu()}disconnectedCallback(){document.removeEventListener("click",this.clickOutside),super.disconnectedCallback()}}var zA=n(9211),PA={};PA.styleTagTransform=_b(),PA.setAttributes=fb(),PA.insert=mb().bind(null,"head"),PA.domAPI=ub(),PA.insertStyleElement=vb();lb()(zA.Z,PA);zA.Z&&zA.Z.locals&&zA.Z.locals;class LA extends DA{static get properties(){return{icon_classes:{type:String},items:{type:Array}}}constructor(){super(),this.icon_classes="fa fa-bars"}render(){return bm``}firstUpdated(){super.firstUpdated(),this.initArrowNavigation()}connectedCallback(){super.connectedCallback(),this.hideOnEscape=e=>e.keyCode===Go.ESCAPE&&this.hideMenu(),document.addEventListener("keydown",this.hideOnEscape)}disconnectedCallback(){document.removeEventListener("keydown",this.hideOnEscape),super.disconnectedCallback()}hideMenu(){super.hideMenu(),this.navigator?.disable()}initArrowNavigation(){if(!this.navigator){const e={selector:".dropdown-item",onSelected:e=>e.focus()};this.navigator=new OA(this.menu,e)}}enableArrowNavigation(e){e&&(e.preventDefault(),e.stopPropagation()),this.navigator.enable(),this.navigator.select(this.menu.firstElementChild)}handleKeyUp(e){super.handleKeyUp(e),e.keyCode!==Go.DOWN_ARROW||this.navigator.enabled||this.enableArrowNavigation(e)}}wd.elements.define("converse-dropdown",LA);var FA=n(2533),UA={};UA.styleTagTransform=_b(),UA.setAttributes=fb(),UA.insert=mb().bind(null,"head"),UA.domAPI=ub(),UA.insertStyleElement=vb();lb()(FA.Z,UA);FA.Z&&FA.Z.locals&&FA.Z.locals;const{dayjs:BA}=Fm.env;wd.elements.define("converse-message-versions",class extends ob{static get properties(){return{model:{type:Object}}}constructor(){super(),this.model=null}render(){const e=this.model.get("older_versions"),t=Object.keys(e);return bm`${t.length?bm`

    ${ib("Older versions")}

    ${t.map((t=>((e,t)=>bm`

    : ${t[e]}

    `)(t,e)))}`:bm`

    ${ib("No older versions found")}

    `}

    ${ib("Current version")}

    : ${this.model.getMessageText()}

    `}});wd.elements.define("converse-message-versions-modal",class extends tS{renderModal(){return bm``}getModalTitle(){return ib("Message versions")}});const qA=e=>{const t=void 0!==e.model.contact,n=ib("Refresh"),s=wd.settings.get("allow_contact_removal");return bm``};function HA(e){Zl.roster?.get(e.get("jid"))?.trigger("highlight")}function GA(e,t){const n=Zl.roster_filter,s=n.get("filter_type"),i="state"===s?n.get("chat_state").toLowerCase():n.get("filter_text").toLowerCase();if(!i)return!1;if("state"===s){return![Zl.HEADER_REQUESTING_CONTACTS,Zl.HEADER_UNREAD].includes(t)&&("unread_messages"===i?0===e.get("num_unread"):"online"===i?["offline","unavailable"].includes(e.presence.get("show")):!e.presence.get("show").includes(i))}return"contacts"===s?!e.getFilterCriteria().includes(i):void 0}function WA(e){const t=Zl.roster_filter;if("groups"===t.get("filter_type")){const n=t.get("filter_text")?.toLowerCase();if(!n)return!0;if(!e.toLowerCase().includes(n))return!1}return!0}const VA=Fm.env.utils;wd.elements.define("converse-user-details-modal",class extends tS{initialize(){super.initialize(),this.model.rosterContactAdded.then((()=>this.registerContactEventHandlers())),this.listenTo(this.model,"change",this.render),this.registerContactEventHandlers(),wd.trigger("userDetailsModalInitialized",this.model)}renderModal(){return(e=>{const t=e.model?.vcard,n=t?t.toJSON():{},s={...e.model.toJSON(),...n},i=ib("XMPP Address"),r=ib("Email"),o=ib("Full Name"),a=ib("Nickname"),c=ib("The User's Profile Image"),l=ib("Role"),d=ib("URL"),u={alt_text:c,extra_classes:"mb-3",height:"120",width:"120"};return bm``})(this)}renderModalFooter(){return qA(this)}getModalTitle(){return this.model.getDisplayName()}registerContactEventHandlers(){void 0!==this.model.contact&&(this.listenTo(this.model.contact,"change",this.render),this.listenTo(this.model.contact.vcard,"change",this.render),this.model.contact.on("destroy",(()=>{delete this.model.contact,this.render()})))}async refreshContact(e){e&&e.preventDefault&&e.preventDefault();const t=this.el.querySelector(".fa-refresh");VA.addClass("fa-spin",t);try{await wd.vcard.update(this.model.contact.vcard,!0)}catch(e){$l.fatal(e),this.alert(ib("Sorry, something went wrong while trying to refresh"),"danger")}VA.removeClass("fa-spin",t)}async removeContact(e){if(e?.preventDefault?.(),!wd.settings.get("allow_contact_removal"))return;await wd.confirm(ib("Are you sure you want to remove this contact?"))&&(setTimeout((()=>function(e){e.removeFromRoster((()=>e.destroy()),(t=>{t&&$l.error(t),wd.alert("error",ib("Error"),[ib("Sorry, there was an error while trying to remove %1$s as a contact.",e.getDisplayName())])}))}(this.model.contact)),1),this.modal.hide())}});const{filesize:ZA}=Fm.env,{dayjs:QA}=Fm.env,{dayjs:JA}=Fm.env;function KA(e){return!!Xm(e).host()}wd.elements.define("converse-image",class extends ob{static get properties(){return{src:{type:String},onImgLoad:{type:Function},href:{type:String}}}constructor(){super(),this.src=null,this.href=null,this.onImgClick=null,this.onImgLoad=null}render(){return ag(this.src)&&ng(this.src,"image")?Kx(sg(this.src),!0):eA({src:sg(this.src),href:this.href,onClick:this.onImgClick,onLoad:this.onImgLoad})}});const YA=e=>{const t=(n=e.image)&&ig(n,"allowed_image_domains")&&KA(n);var n;const s=e.title||e.description||e.url;return t||s?bm`
    ${t?(e=>bm``)(e):""} ${s?bm`
    ${e.title?((e,t)=>e.url&&KA(e.url)&&!ag(e.image)?bm`${t(e)}`:t(e))(e,(e=>bm`
    ${e.title}
    `)):""} ${e.description?bm`

    `:""} ${e.url?bm`

    ${Xm(e.url).domain()}

    `:""}
    `:""}
    `:""};var XA=n(8906),eE={};eE.styleTagTransform=_b(),eE.setAttributes=fb(),eE.insert=mb().bind(null,"head"),eE.domAPI=ub(),eE.insertStyleElement=vb();lb()(XA.Z,eE);XA.Z&&XA.Z.locals&&XA.Z.locals;wd.elements.define("converse-message-unfurl",class extends ob{static get properties(){return{description:{type:String},image:{type:String},jid:{type:String},title:{type:String},url:{type:String}}}initialize(){const e=Qc();this.listenTo(e,"change:allowed_image_domains",(()=>this.requestUpdate())),this.listenTo(e,"change:render_media",(()=>this.requestUpdate()))}render(){return YA(Object.assign({onload:()=>this.onImageLoad()},{description:this.description||"",image:this.image||"",title:this.title||"",url:this.url||""}))}onImageLoad(){this.dispatchEvent(new CustomEvent("imageLoaded",{detail:this,bubbles:!0}))}});const tE=e=>{const t=ib("Show more"),n="groupchat"===e.model.get("type"),s=ib("Show less"),i=bm`
    ${e.model.get("spoiler_hint")} ${e.model.get("is_spoiler_visible")?s:t}
    `,r=e.model.get("is_spoiler")?"spoiler "+(e.model.get("is_spoiler_visible")?"":"hidden"):"",o=e.model.getMessageText(),a=e.model.get("oob_url")&&o!==e.model.get("oob_url");return bm`${e.model.get("is_spoiler")?i:""} ${e.model.get("subject")?bm`
    ${e.model.get("subject")}
    `:""} ${!e.model.get("received")||e.model.isMeCommand()||n?"":bm``} ${e.model.get("edited")?(e=>{const t=ib("This message has been edited");return bm``})(e):""} ${a?bm`
    ${Rw(e.model.get("oob_url"))}
    `:""}
    ${e.model.get("error_text")||e.model.get("error")}
    `};var nE=n(7643),sE={};sE.styleTagTransform=_b(),sE.setAttributes=fb(),sE.insert=mb().bind(null,"head"),sE.domAPI=ub(),sE.insertStyleElement=vb();lb()(nE.Z,sE);nE.Z&&nE.Z.locals&&nE.Z.locals;const{Strophe:iE,dayjs:rE}=Fm.env;wd.elements.define("converse-chat-message",class extends ob{static get properties(){return{jid:{type:String},mid:{type:String}}}async initialize(){if(await this.setModels(),!this.model)return void $l.error("Could not find module for converse-chat-message");const e=Qc();this.listenTo(e,"change:render_media",(()=>{this.model.save("hide_url_previews",void 0),this.requestUpdate()})),this.listenTo(this.chatbox,"change:first_unread_id",(()=>this.requestUpdate())),this.listenTo(this.model,"change",(()=>this.requestUpdate())),this.model.vcard&&this.listenTo(this.model.vcard,"change",(()=>this.requestUpdate())),"groupchat"===this.model.get("type")&&(this.model.occupant?this.listenTo(this.model.occupant,"change",(()=>this.requestUpdate())):this.listenTo(this.model,"occupantAdded",(()=>{this.requestUpdate(),this.listenTo(this.model.occupant,"change",(()=>this.requestUpdate()))})))}async setModels(){this.chatbox=await wd.chatboxes.get(this.jid),await this.chatbox.initialized,await this.chatbox.messages.fetched,this.model=this.chatbox.messages.get(this.mid),this.model&&this.requestUpdate()}render(){return this.model?this.show_spinner?SS():this.model.get("file")&&this.model.get("upload")!==Zl.SUCCESS?this.renderFileProgress():["mep"].includes(this.model.get("type"))?this.renderMEPMessage():["error","info"].includes(this.model.get("type"))?this.renderInfoMessage():this.renderChatMessage():""}getProps(){return Object.assign(this.model.toJSON(),this.getDerivedMessageProps())}renderRetraction(){return(e=>{const t=e.isRetracted()?e.getRetractionText():null;return bm`
    ${t}
    ${e.model.get("moderation_reason")?bm`${e.model.get("moderation_reason")}`:""}`})(this)}renderMessageText(){return tE(this)}renderMEPMessage(){return(e=>{const t=JA(e.model.get("time")).toISOString();return bm`
    ${e.isRetracted()?e.renderRetraction():bm`${e.model.get("reason")?bm``:""}`}
    `})(this)}renderInfoMessage(){return(e=>{const t=QA(e.model.get("time")).toISOString(),n=ib("Retry");return bm`
    ${e.model.get("reason")?bm`${e.model.get("reason")}`:""} ${e.model.get("error_text")?bm`${e.model.get("error_text")}`:""} ${e.model.get("retry_event_id")?bm`${n}`:""}
    `})(this)}renderFileProgress(){return this.model.file?(e=>{const t=ib("Uploading file:"),n=e.model.file.name,s=ZA(e.model.file.size);return bm`
    ${e.shouldShowAvatar()?bm``:""}
    ${t} ${n}, ${s}
    `})(this):""}renderChatMessage(){return((e,t)=>{const n=ib("New messages"),s=e.model.isFollowup();return bm`${t.is_first_unread?bm`

    ${n}
    `:""}
    ${t.should_show_avatar&&!s?bm``:""}
    ${t.is_me_message||s?"":bm`${t.username} ${t.hats.map((e=>bm`${e.title}`))} ${t.is_encrypted?bm``:""}`}
    ${t.is_me_message?bm`  ${t.is_me_message?"**":""}${t.username} `:""} ${t.is_retracted?e.renderRetraction():e.renderMessageText()}
    ${e.model.get("ogp_metadata")?.map((t=>!0===e.model.get("hide_url_previews")?"":ng(t["og:image"],"image")?bm``:""))}
    `})(this,this.getProps())}shouldShowAvatar(){return wd.settings.get("show_message_avatar")&&!this.model.isMeCommand()&&["chat","groupchat","normal"].includes(this.model.get("type"))}onUnfurlAnimationEnd(){"fade-out"===this.model.get("url_preview_transition")&&this.model.save({hide_url_previews:!0,url_preview_transition:"fade-in"})}async onRetryClicked(){this.show_spinner=!0,this.requestUpdate(),await wd.trigger(this.model.get("retry_event_id"),{synchronous:!0}),this.model.destroy(),this.parentElement.removeChild(this)}isRetracted(){return this.model.get("retracted")||"retracted"===this.model.get("moderated")}hasMentions(){return"groupchat"===this.model.get("type")&&"them"===this.model.get("sender")&&this.chatbox.isUserMentioned(this.model)}getOccupantAffiliation(){return this.model.occupant?.get("affiliation")}getOccupantRole(){return this.model.occupant?.get("role")}getExtraMessageClasses(){const e=[this.model.isFollowup()?"chat-msg--followup":null,this.model.get("is_delayed")?"delayed":null,this.model.isMeCommand()?"chat-msg--action":null,this.isRetracted()?"chat-msg--retracted":null,this.model.get("type"),this.shouldShowAvatar()?"chat-msg--with-avatar":null].map((e=>e));return"groupchat"===this.model.get("type")&&(e.push(this.getOccupantRole()??""),e.push(this.getOccupantAffiliation()??""),"them"===this.model.get("sender")&&this.hasMentions()&&e.push("mentioned")),this.model.get("correcting")&&e.push("correcting"),e.filter((e=>e)).join(" ")}getDerivedMessageProps(){const e=wd.settings.get("time_format");return{pretty_time:rE(this.model.get("edited")||this.model.get("time")).format(e),has_mentions:this.hasMentions(),hats:yA(this.model),is_first_unread:this.chatbox.get("first_unread_id")===this.model.get("id"),is_me_message:this.model.isMeCommand(),is_retracted:this.isRetracted(),username:this.model.getDisplayName(),should_show_avatar:this.shouldShowAvatar()}}getRetractionText(){if(["groupchat","mep"].includes(this.model.get("type"))&&this.model.get("moderated_by")){const e=this.model.get("moderated_by"),t=this.model.collection.chatbox;this.model.mod||(this.model.mod=t.occupants.findOccupant({jid:e})||t.occupants.findOccupant({nick:iE.getResourceFromJid(e)}));const n=this.model.mod?this.model.mod.getDisplayName():"A moderator";return ib("%1$s has removed this message",n)}return ib("%1$s has removed this message",this.model.getDisplayName())}showUserModal(e){if("me"===this.model.get("sender"))wd.modal.show("converse-profile-modal",{model:this.model},e);else if("groupchat"===this.model.get("type"))e.preventDefault(),wd.modal.show("converse-muc-occupant-modal",{model:this.model.getOccupant(),message:this.model},e);else{e.preventDefault();const t=this.model.collection.chatbox;wd.modal.show("converse-user-details-modal",{model:t},e)}}showMessageVersionsModal(e){e.preventDefault(),wd.modal.show("converse-message-versions-modal",{model:this.model},e)}toggleSpoilerMessage(e){e?.preventDefault(),this.model.save({is_spoiler_visible:!this.model.get("is_spoiler_visible")})}});wd.elements.define("converse-message-history",class extends ob{static get properties(){return{model:{type:Object},messages:{type:Array}}}render(){const e=this.messages;return e.length?Ox(e,(e=>e.get("id")),(e=>bm`${this.renderMessage(e)}`)):""}renderMessage(e){if(e.get("dangling_retraction")||e.get("is_only_key"))return"";const t=e.get("template_hook");if("string"==typeof t){const n=wd.hook(t,e,"");return WS(n,"")}{const t=bm``,n=vA(e);return n?[n,t]:t}}});var oE=n(8765),aE={};aE.styleTagTransform=_b(),aE.setAttributes=fb(),aE.insert=mb().bind(null,"head"),aE.domAPI=ub(),aE.insertStyleElement=vb();lb()(oE.Z,aE);oE.Z&&oE.Z.locals&&oE.Z.locals;wd.elements.define("converse-chat-content",class extends ob{static get properties(){return{jid:{type:String}}}disconnectedCallback(){super.disconnectedCallback(),this.removeEventListener("scroll",pA)}async initialize(){await this.setModels(),this.listenTo(this.model,"change:hidden_occupants",(()=>this.requestUpdate())),this.listenTo(this.model.messages,"add",(()=>this.requestUpdate())),this.listenTo(this.model.messages,"change",(()=>this.requestUpdate())),this.listenTo(this.model.messages,"remove",(()=>this.requestUpdate())),this.listenTo(this.model.messages,"rendered",(()=>this.requestUpdate())),this.listenTo(this.model.messages,"reset",(()=>this.requestUpdate())),this.listenTo(this.model.notifications,"change",(()=>this.requestUpdate())),this.listenTo(this.model.ui,"change",(()=>this.requestUpdate())),this.listenTo(this.model.ui,"change:scrolled",this.scrollDown),this.model.occupants&&this.listenTo(this.model.occupants,"change",(()=>this.requestUpdate())),this.addEventListener("scroll",pA)}async setModels(){this.model=await wd.chatboxes.get(this.jid),await this.model.initialized,this.requestUpdate()}render(){return this.model?bm`
    ${this.model.getNotificationsText()}
    ${this.model.ui?.get("chat-content-spinner-top")?SS():""}`:""}scrollDown(){if(!this.model.ui.get("scrolled")){if(this.scrollTo){const e=this.scrollTop?"smooth":"auto";this.scrollTo({top:0,behavior:e})}else this.scrollTop=0;wd.trigger("chatBoxScrolledDown",{chatbox:this.model})}}});class cE extends OS{constructor(e){if(super(e),this.it=zh,e.type!==NS)throw Error(this.constructor.directiveName+"() can only be used in child bindings")}render(e){if(e===zh||null==e)return this._t=void 0,this.it=e;if(e===Dh)return e;if("string"!=typeof e)throw Error(this.constructor.directiveName+"() called with a non-string value");if(e===this.it)return this._t;this.it=e;const t=[e];return t.raw=t,this._t={_$litType$:this.constructor.resultType,strings:t,values:[]}}}cE.directiveName="unsafeHTML",cE.resultType=1;const lE=MS(cE);wd.elements.define("converse-chat-help",class extends ob{static get properties(){return{chat_type:{type:String},messages:{type:Array},model:{type:Object},type:{type:String}}}render(){const e=(new Date).toISOString();return[bm``,...this.messages.map((t=>this.renderHelpMessage({isodate:e,markup:Qo().sanitize(t,{ALLOWED_TAGS:["strong"]})})))]}close(){this.model.set({show_help_messages:!1})}renderHelpMessage(e){return bm`
    ${lE(e.markup)}
    `}});const dE=Fm.env.utils,uE=e=>{const t=wd.settings.get("emoji_categories");return bm`
      ${Object.keys(t).map((n=>t[n]?(e=>bm`
    • ${e.emoji}
    • `)(Object.assign({category:n,emoji:e.sn2Emoji(t[n])},e)):""))}
    `},hE=e=>bm`
  • ${dE.shortnamesToEmojis(e.emoji.sn)}
  • `,mE=e=>{const t=wd.settings.get("emoji_categories");return bm`${Object.keys(t).map((n=>t[n]?(e=>bm`${ib(wd.settings.get("emoji_category_labels")[e.category])}
      ${Object.values(Fm.emojis.json[e.category]).map((t=>hE(Object.assign({emoji:t},e))))}
    `)(Object.assign({category:n},e)):""))}
    `},gE=e=>{const t=ib("Search");return bm`
    ${e.query?"":uE(e)}
    ${e.render_emojis?bm``:""}
    `},{sizzle:fE}=Fm.env;wd.elements.define("converse-emoji-picker-content",class extends ob{static get properties(){return{chatview:{type:Object},search_results:{type:Array},current_skintone:{type:String},model:{type:Object},query:{type:String}}}render(){const e={current_skintone:this.current_skintone,insertEmoji:e=>this.insertEmoji(e),query:this.query,search_results:this.search_results,shouldBeHidden:e=>this.shouldBeHidden(e)};return bm`
    ${(e=>{const t=ib("Search results");return bm`${t}
      ${e.search_results.map((t=>hE(Object.assign({emoji:t},e))))}
    `})(e)} ${mE(e)}
    `}firstUpdated(){this.initIntersectionObserver()}initIntersectionObserver(){if(window.IntersectionObserver){if(this.observer)this.observer.disconnect();else{const e={root:this.querySelector(".emoji-picker__lists"),threshold:[.1]},t=e=>this.setCategoryOnVisibilityChange(e);this.observer=new IntersectionObserver(t,e)}fE(".emoji-picker",this).forEach((e=>this.observer.observe(e)))}}setCategoryOnVisibilityChange(e){const t=this.parentElement.navigator.selected,n=e.filter((e=>e.target.contains(t))).pop();let s;if(s=n||e.reduce(((e,t)=>t.intersectionRatio>=(e?.intersectionRatio||0)?t:e),null),s&&s.isIntersecting){const e=s.target.getAttribute("data-category");e!==this.model.get("current_category")&&(this.parentElement.preserve_scroll=!0,this.model.save({current_category:e}))}}insertEmoji(e){e.preventDefault(),e.stopPropagation();const t="IMG"===e.target.nodeName?e.target.parentElement:e.target;this.parentElement.insertIntoTextArea(t.getAttribute("data-emoji"))}shouldBeHidden(e){if(e.includes("_tone")){if(!this.current_skintone||!e.includes(this.current_skintone))return!0}else if(this.current_skintone&&_A().includes(e))return!0;return!(!this.query||Zl.FILTER_CONTAINS(e,this.query))}});const pE=Fm.env.utils;wd.elements.define("converse-emoji-dropdown",class extends LA{static get properties(){return{chatview:{type:Object}}}constructor(){super(),this.render_emojis=!1}initModel(){return this.init_promise||(this.init_promise=(async()=>{await wd.emojis.initialize();const e=`converse.emoji-${Zl.bare_jid}-${this.chatview.model.get("jid")}`;this.model=new Zl.EmojiPicker({id:e}),Gc(this.model,e),await new Promise((e=>this.model.fetch({success:e,error:e}))),this.model.set({autocompleting:null,ac_position:null})})()),this.init_promise}render(){const e=this.chatview.model.get("type")===Zl.CHATROOMS_TYPE?"--muc-toolbar-btn-color":"--chat-toolbar-btn-color";return bm`
    `}connectedCallback(){super.connectedCallback(),this.render_emojis=!1}toggleMenu(e){e.stopPropagation(),e.preventDefault(),pE.hasClass("show",this.menu)?pE.ancestor(e.target,".toggle-emojis")&&this.hideMenu():this.showMenu()}async showMenu(){await this.initModel(),this.render_emojis||(this.render_emojis=!0,this.requestUpdate(),await this.updateComplete),super.showMenu(),setTimeout((()=>this.querySelector(".emoji-search")?.focus()))}});var vE=n(2432),yE={};yE.styleTagTransform=_b(),yE.setAttributes=fb(),yE.insert=mb().bind(null,"head"),yE.domAPI=ub(),yE.insertStyleElement=vb();lb()(vE.Z,yE);vE.Z&&vE.Z.locals&&vE.Z.locals;const _E=Fm.env.utils;wd.elements.define("converse-emoji-picker",class extends ob{static get properties(){return{chatview:{type:Object},current_category:{type:String,reflect:!0},current_skintone:{type:String,reflect:!0},model:{type:Object},query:{type:String,reflect:!0},render_emojis:{type:Boolean}}}firstUpdated(){super.firstUpdated(),this.listenTo(this.model,"change",(e=>this.onModelChanged(e.changed))),this.initArrowNavigation()}constructor(){super(),this.query="",this._search_results=[],this.debouncedFilter=rd((e=>this.model.set({query:e.value})),250)}get search_results(){return this._search_results}set search_results(e){this._search_results=e,this.requestUpdate()}render(){return gE({chatview:this.chatview,current_category:this.current_category,current_skintone:this.current_skintone,model:this.model,onCategoryPicked:e=>this.chooseCategory(e),onSearchInputBlurred:e=>this.chatview.emitFocused(e),onSearchInputFocus:e=>this.onSearchInputFocus(e),onSearchInputKeyDown:e=>this.onSearchInputKeyDown(e),onSkintonePicked:e=>this.chooseSkinTone(e),query:this.query,search_results:this.search_results,render_emojis:this.render_emojis,sn2Emoji:e=>_E.shortnamesToEmojis(this.getTonedShortname(e))})}updated(e){e.has("query")&&this.updateSearchResults(e),e.has("current_category")&&this.setScrollPosition()}onModelChanged(e){"current_category"in e&&(this.current_category=e.current_category),"current_skintone"in e&&(this.current_skintone=e.current_skintone),"query"in e&&(this.query=e.query)}setScrollPosition(){if(this.preserve_scroll)return void(this.preserve_scroll=!1);const e=this.querySelector(".emoji-lists__container--browse"),t=this.querySelector(`#emoji-picker-${this.current_category}`);t&&(e.scrollTop=t.offsetTop-3*t.offsetHeight+4)}updateSearchResults(e){const t=e.get("query"),n=Zl.FILTER_CONTAINS;if(this.query){if(this.query===t)return this.search_results;t&&this.query.includes(t)?this.search_results=this.search_results.filter((e=>n(e.sn,this.query))):this.search_results=Fm.emojis.list.filter((e=>n(e.sn,this.query)))}else this.search_results.length&&(this.search_results=[])}registerEvents(){this.onGlobalKeyDown=e=>this._onGlobalKeyDown(e);document.querySelector("body").addEventListener("keydown",this.onGlobalKeyDown)}connectedCallback(){super.connectedCallback(),this.registerEvents()}disconnectedCallback(){document.querySelector("body").removeEventListener("keydown",this.onGlobalKeyDown),this.disableArrowNavigation(),super.disconnectedCallback()}_onGlobalKeyDown(e){this.navigator&&(e.keyCode===Go.ENTER&&_E.isVisible(this)?this.onEnterPressed(e):e.keyCode===Go.DOWN_ARROW&&!this.navigator.enabled&&_E.isVisible(this)?this.enableArrowNavigation(e):e.keyCode===Go.ESCAPE&&(this.disableArrowNavigation(),setTimeout((()=>this.chatview.querySelector(".chat-textarea").focus()),50)))}setCategoryForElement(e){const t=this.current_category,n=e?.getAttribute("data-category")||t;t!==n&&this.model.save({current_category:n})}insertIntoTextArea(e){const t=this.model.get("autocompleting"),n=this.model.get("ac_position");this.model.set({autocompleting:null,query:"",ac_position:null}),this.disableArrowNavigation();const s={bubbles:!0,detail:{value:e,autocompleting:t,ac_position:n,jid:this.chatview.model.get("jid")}};this.dispatchEvent(new CustomEvent("emojiSelected",s))}chooseSkinTone(e){e.preventDefault(),e.stopPropagation();const t=("IMG"===e.target.nodeName?e.target.parentElement:e.target).getAttribute("data-skintone").trim();this.current_skintone===t?this.model.save({current_skintone:""}):this.model.save({current_skintone:t})}chooseCategory(e){e.preventDefault&&e.preventDefault(),e.stopPropagation&&e.stopPropagation();const t=e.target.matches("li")?e.target:_E.ancestor(e.target,"li");this.setCategoryForElement(t),this.navigator.select(t),!this.navigator.enabled&&this.navigator.enable()}onSearchInputKeyDown(e){if(e.keyCode===Go.TAB)if(e.target.value){e.preventDefault();const t=Fm.emojis.shortnames.find((t=>Zl.FILTER_CONTAINS(t,e.target.value)));t&&this.model.set({query:t})}else this.navigator.enabled||this.enableArrowNavigation(e);else e.keyCode!==Go.DOWN_ARROW||this.navigator.enabled?e.keyCode!==Go.ENTER&&e.keyCode!==Go.DOWN_ARROW&&this.debouncedFilter(e.target):this.enableArrowNavigation(e)}onEnterPressed(e){e.preventDefault(),e.stopPropagation(),Fm.emojis.shortnames.includes(e.target.value)?this.insertIntoTextArea(e.target.value):1===this.search_results.length?this.insertIntoTextArea(this.search_results[0].sn):this.navigator.selected&&this.navigator.selected.matches(".insert-emoji")?this.insertIntoTextArea(this.navigator.selected.getAttribute("data-emoji")):this.navigator.selected&&this.navigator.selected.matches(".emoji-category")&&this.chooseCategory({target:this.navigator.selected})}onSearchInputFocus(e){this.chatview.emitBlurred(e),this.disableArrowNavigation()}getTonedShortname(e){return _A().includes(e)&&this.current_skintone?`${e.slice(0,e.length-1)}_${this.current_skintone}:`:e}initArrowNavigation(){if(!this.navigator){const e="li:not(.hidden):not(.emoji-skintone), .emoji-search",t={jump_to_picked:".emoji-category",jump_to_picked_selector:".emoji-category.picked",jump_to_picked_direction:OA.DIRECTION.down,picked_selector:".picked",scroll_container:this.querySelector(".emoji-picker__lists"),getSelector:t=>{if(t===OA.DIRECTION.down){const t=this.navigator.selected&&this.navigator.selected.getAttribute("data-category");return t?`ul[data-category="${t}"] li:not(.hidden):not(.emoji-skintone), .emoji-search`:e}return e},onSelected:e=>{e.matches(".insert-emoji")&&this.setCategoryForElement(e.parentElement),e.matches(".insert-emoji, .emoji-category")&&e.firstElementChild.focus(),e.matches(".emoji-search")&&e.focus()}};this.navigator=new OA(this,t)}}disableArrowNavigation(){this.navigator?.disable()}enableArrowNavigation(e){e?.preventDefault?.(),e?.stopPropagation?.(),this.disableArrowNavigation(),this.navigator.enable(),this.navigator.handleKeydown(e)}});wd.elements.define("converse-message-limit-indicator",class extends ob{static get properties(){return{model:{type:Object}}}connectedCallback(){super.connectedCallback(),this.listenTo(this.model,"change:draft",(()=>this.requestUpdate()))}render(){const e=wd.settings.get("message_limit");if(!e)return"";return(e=>{const t=ib("Message characters remaining");return bm`${e}`})(e-(this.model.get("draft")||"").length)}});const bE=e=>bm`${WS(e.getButtons(),"")} ${e.show_send_button?function(){const e=ib("Send the message");return bm``}():""}`;var wE=n(9833),SE={};SE.styleTagTransform=_b(),SE.setAttributes=fb(),SE.insert=mb().bind(null,"head"),SE.domAPI=ub(),SE.insertStyleElement=vb();lb()(wE.Z,SE);wE.Z&&wE.Z.locals&&wE.Z.locals;const xE=Fm.env.Strophe;wd.elements.define("converse-chat-toolbar",class extends ob{static get properties(){return{hidden_occupants:{type:Boolean},is_groupchat:{type:Boolean},message_limit:{type:Number},model:{type:Object},show_call_button:{type:Boolean},show_emoji_button:{type:Boolean},show_send_button:{type:Boolean},show_spoiler_button:{type:Boolean}}}connectedCallback(){super.connectedCallback(),this.listenTo(this.model,"change:composing_spoiler",(()=>this.requestUpdate()))}render(){return bE(this)}firstUpdated(){wd.trigger("renderToolbar",this)}getButtons(){const e=[];if(this.show_emoji_button){const t=Zl.chatboxviews.get(this.model.get("jid"));e.push(bm``)}if(this.show_call_button){const t=this.is_groupchat?"--muc-toolbar-btn-color":"--chat-toolbar-btn-color",n=ib("Start a call");e.push(bm``)}wd.settings.get("message_limit")&&e.push(bm``),this.show_spoiler_button&&e.push(this.getSpoilerButton());const t=wd.disco.supports(xE.NS.HTTPUPLOAD,Zl.domain);if(e.push(bm`${WS(t.then((e=>this.getHTTPUploadButton(e))),"")}`),this.is_groupchat&&wd.settings.get("visible_toolbar_buttons")?.toggle_occupants){const t=ib("Hide participants"),n=ib("Show participants");e.push(bm``)}return Zl.api.hook("getToolbarButtons",this,e)}getHTTPUploadButton(e){if(e){const e=ib("Choose a file to send"),t=this.is_groupchat?"--muc-toolbar-btn-color":"--chat-toolbar-btn-color";return bm` `}return""}getSpoilerButton(){const e=this.model;if(!this.is_groupchat&&!e.presence?.resources.length)return;let t;t=e.get("composing_spoiler")?ib("Click to write as a normal (non-spoiler) message"):ib("Click to write your message as a spoiler");const n=this.is_groupchat?"--muc-toolbar-btn-color":"--chat-toolbar-btn-color",s=bm``;if(this.is_groupchat)return s;{const t=e.get("jid"),n=Promise.all(e.presence.resources.map((e=>wd.disco.supports(xE.NS.SPOILER,`${t}/${e.get("name")}`)))).then((e=>e.reduce(((e,t)=>e&&t),!0)));return bm`${WS(n.then((()=>s)),"")}`}}toggleFileUpload(e){e?.preventDefault?.(),e?.stopPropagation?.(),this.querySelector(".fileupload").click()}onFileSelection(e){this.model.sendFiles(e.target.files)}toggleComposeSpoilerMessage(e){e?.preventDefault?.(),e?.stopPropagation?.(),this.model.set("composing_spoiler",!this.model.get("composing_spoiler"))}toggleOccupants(e){e?.preventDefault?.(),e?.stopPropagation?.(),this.model.save({hidden_occupants:!this.model.get("hidden_occupants")})}toggleCall(e){e?.preventDefault?.(),e?.stopPropagation?.(),wd.trigger("callButtonClicked",{connection:Zl.connection,model:this.model})}});var AE=n(263),EE={};EE.styleTagTransform=_b(),EE.setAttributes=fb(),EE.insert=mb().bind(null,"head"),EE.domAPI=ub(),EE.insertStyleElement=vb();lb()(AE.Z,EE);AE.Z&&AE.Z.locals&&AE.Z.locals;async function $E(e){await wd.confirm(ib("Are you sure you want to clear the messages from this conversation?"))&&await e.clearMessages()}function CE(e){if(e.target.value){const t=e.target.scrollHeight+"px";e.target.style.height!=t&&(e.target.style.height="auto",e.target.style.height=t)}else e.target.style=""}wd.elements.define("converse-chat-heading",class extends ob{static get properties(){return{jid:{type:String}}}initialize(){this.model=Zl.chatboxes.get(this.jid),this.listenTo(this.model,"change:status",(()=>this.requestUpdate())),this.listenTo(this.model,"vcard:add",(()=>this.requestUpdate())),this.listenTo(this.model,"vcard:change",(()=>this.requestUpdate())),this.model.contact&&this.listenTo(this.model.contact,"destroy",(()=>this.requestUpdate())),this.model.rosterContactAdded?.then((()=>{this.listenTo(this.model.contact,"change:nickname",(()=>this.requestUpdate())),this.requestUpdate()}))}render(){return(e=>{const t=ib("The User's Profile Image"),n=bm``,s=e.model.getDisplayName();return bm`
    ${Zl.api.settings.get("singleton")?"":bm``} ${e.type!==Zl.HEADLINES_TYPE?bm`${n}`:""}
    ${e.type!==Zl.HEADLINES_TYPE?bm`${s}`:s}
    ${WS(gA(e.heading_buttons_promise),"")} ${WS(mA(e.heading_buttons_promise),"")}
    ${e.status?bm`

    ${e.status}

    `:""}`})(Object.assign(this.model.toJSON(),{heading_buttons_promise:this.getHeadingButtons(),model:this.model,showUserDetailsModal:e=>this.showUserDetailsModal(e)}))}showUserDetailsModal(e){e.preventDefault(),wd.modal.show("converse-user-details-modal",{model:this.model},e)}close(e){e.preventDefault(),this.model.close()}getHeadingButtons(){const e=[{a_class:"show-user-details-modal",handler:e=>this.showUserDetailsModal(e),i18n_text:ib("Details"),i18n_title:ib("See more information about this person"),icon_class:"fa-id-card",name:"details",standalone:"overlayed"===wd.settings.get("view_mode")}];wd.settings.get("singleton")||e.push({a_class:"close-chatbox-button",handler:e=>this.close(e),i18n_text:ib("Close"),i18n_title:ib("Close and end this conversation"),icon_class:"fa-times",name:"close",standalone:"overlayed"===wd.settings.get("view_mode")});const t=Zl.chatboxviews.get(this.getAttribute("jid"));return t?Zl.api.hook("getHeadingButtons",t,e):e}});const{u:kE}=Fm.env;class jE extends eS{async connectedCallback(){super.connectedCallback(),this.model=Zl.chatboxes.get(this.getAttribute("jid")),await this.model.initialized,this.listenTo(this.model.messages,"change:correcting",this.onMessageCorrecting),this.listenTo(this.model,"change:composing_spoiler",(()=>this.render())),this.handleEmojiSelection=e=>{let{detail:t}=e;this.model.get("jid")===t.jid&&this.insertIntoTextArea(t.value,t.autocompleting,!1,t.ac_position)},document.addEventListener("emojiSelected",this.handleEmojiSelection),this.render()}disconnectedCallback(){super.disconnectedCallback(),document.removeEventListener("emojiSelected",this.handleEmojiSelection)}toHTML(){return(e=>{const t=e.composing_spoiler?ib("Hidden message"):ib("Message"),n=ib("Optional hint"),s=wd.settings.get("show_send_button");return bm`
    `})(Object.assign(this.model.toJSON(),{onDrop:e=>this.onDrop(e),hint_value:this.querySelector(".spoiler-hint")?.value,message_value:this.querySelector(".chat-textarea")?.value,onChange:e=>this.model.set({draft:e.target.value}),onKeyDown:e=>this.onKeyDown(e),onKeyUp:e=>this.onKeyUp(e),onPaste:e=>this.onPaste(e),viewUnreadMessages:e=>this.viewUnreadMessages(e)}))}insertIntoTextArea(e){let t=arguments.length>1&&void 0!==arguments[1]&&arguments[1],n=arguments.length>2&&void 0!==arguments[2]&&arguments[2],s=arguments.length>3?arguments[3]:void 0;const i=this.querySelector(".chat-textarea");if(n?kE.addClass("correcting",i):kE.removeClass("correcting",i),t)i.value=s&&"string"==typeof t?i.value.replace(new RegExp(t,"g"),((n,i)=>i==s-t.length?e+" ":n)):e;else{let t=i.value;t&&" "!==t[t.length-1]&&(t+=" "),i.value=t+e+" "}const r=document.createEvent("HTMLEvents");r.initEvent("change",!1,!0),i.dispatchEvent(r),kE.placeCaretAtEnd(i)}onMessageCorrecting(e){if(e.get("correcting"))this.insertIntoTextArea(ul(e),!0,!0);else{const t=this.model.messages.findWhere("correcting");t&&t!==e?this.insertIntoTextArea(ul(e),!0,!0):this.insertIntoTextArea("",!0,!1)}}onEscapePressed(e){const t=this.model.messages.findLastIndex("correcting"),n=t>=0?this.model.messages.at(t):null;n&&(e.preventDefault(),n.save("correcting",!1),this.insertIntoTextArea("",!0,!1))}onPaste(e){if(e.stopPropagation(),0!==e.clipboardData.files.length)return e.preventDefault(),void this.model.sendFiles(Array.from(e.clipboardData.files));this.model.set({draft:e.clipboardData.getData("text/plain")})}onKeyUp(e){this.model.set({draft:e.target.value})}onKeyDown(e){if(!e.ctrlKey){if(!e.shiftKey&&!e.altKey&&!e.metaKey)if(e.keyCode===Fm.keycodes.TAB){const t=kE.getCurrentWord(e.target,null,/(:.*?:)/g);t.startsWith(":")&&(e.preventDefault(),e.stopPropagation(),this.model.trigger("emoji-picker-autocomplete",e.target,t))}else{if(e.keyCode===Fm.keycodes.FORWARD_SLASH)return;if(e.keyCode===Fm.keycodes.ESCAPE)return this.onEscapePressed(e,this);if(e.keyCode===Fm.keycodes.ENTER)return this.onFormSubmitted(e);if(e.keyCode!==Fm.keycodes.UP_ARROW||e.target.selectionEnd){if(e.keyCode===Fm.keycodes.DOWN_ARROW&&e.target.selectionEnd===e.target.value.length&&kE.hasClass("correcting",this.querySelector(".chat-textarea")))return this.model.editLaterMessage()}else{const e=this.querySelector(".chat-textarea");if(!e.value||kE.hasClass("correcting",e))return this.model.editEarlierMessage()}}[Fm.keycodes.SHIFT,Fm.keycodes.META,Fm.keycodes.META_RIGHT,Fm.keycodes.ESCAPE,Fm.keycodes.ALT].includes(e.keyCode)||this.model.get("chat_state")!==Zl.COMPOSING&&this.model.setChatState(Zl.COMPOSING)}}async onFormSubmitted(e){e?.preventDefault?.();const t=this.querySelector(".chat-textarea"),n=t.value.trim();if(wd.settings.get("message_limit")&&n.length>wd.settings.get("message_limit")||!n.replace(/\s/g,"").length)return;if(!Zl.connection.authenticated){const e=ib("Sorry, the connection has been lost, and your message could not be sent");return wd.alert("error",ib("Error"),e),void wd.connection.reconnect()}let s,i={};this.model.get("composing_spoiler")&&(i=this.querySelector("form.sendXMPPMessage input.spoiler-hint"),s=i.value),kE.addClass("disabled",t),t.setAttribute("disabled","disabled"),this.querySelector("converse-emoji-dropdown")?.hideMenu();const r=await async function(e,t){const n=t.replace(/^\s*/,"").match(/^\/(.*)\s*$/);if(n){let s=!1;if(s=await wd.hook("parseMessageForCommands",{model:e,text:t},s),s)return!0;if("clear"===n[1])return $E(e),!0;if("close"===n[1])return Zl.chatboxviews.get(e.get("jid"))?.close(),!0;if("help"===n[1])return e.set({show_help_messages:!1},{silent:!0}),e.set({show_help_messages:!0}),!0}return!1}(this.model,n),o=r?null:await this.model.sendMessage({body:n,spoiler_hint:s});if((r||o)&&(i.value="",t.value="",kE.removeClass("correcting",t),t.style.height="auto",this.model.set({draft:""})),"overlayed"===wd.settings.get("view_mode")){Zl.chatboxviews.get(this.getAttribute("jid")).querySelector(".chat-content__messages").parentElement.style.display="none"}if(t.removeAttribute("disabled"),kE.removeClass("disabled",t),"overlayed"===wd.settings.get("view_mode")){Zl.chatboxviews.get(this.getAttribute("jid")).querySelector(".chat-content__messages").parentElement.style.display=""}this.model.setChatState(Zl.ACTIVE,{silent:!0}),t.focus()}}wd.elements.define("converse-message-form",jE);var TE=n(298),IE={};IE.styleTagTransform=_b(),IE.setAttributes=fb(),IE.insert=mb().bind(null,"head"),IE.domAPI=ub(),IE.insertStyleElement=vb();lb()(TE.Z,IE);TE.Z&&TE.Z.locals&&TE.Z.locals;class NE extends eS{events={"click .send-button":"sendButtonClicked","click .toggle-clear":"clearMessages"};constructor(){super(),this.debouncedRender=rd(this.render,100)}async connectedCallback(){super.connectedCallback(),await this.initialize(),this.render()}async initialize(){this.model=await wd.chatboxes.get(this.getAttribute("jid")),await this.model.initialized,this.listenTo(this.model,"change:num_unread",this.debouncedRender),this.listenTo(this.model,"emoji-picker-autocomplete",this.autocompleteInPicker),this.addEventListener("focusin",(e=>this.emitFocused(e))),this.addEventListener("focusout",(e=>this.emitBlurred(e)))}render(){zm((e=>{const t=ib("You have unread messages"),n=wd.settings.get("message_limit"),s=wd.settings.get("visible_toolbar_buttons").call,i=wd.settings.get("visible_toolbar_buttons").emoji,r=wd.settings.get("show_send_button"),o=wd.settings.get("visible_toolbar_buttons").spoiler,a=wd.settings.get("show_toolbar");return bm`${e.model.ui.get("scrolled")&&e.model.get("num_unread")?bm`
    ▼ ${t} ▼
    `:""} ${wd.settings.get("show_toolbar")?bm``:""}`})({model:this.model,viewUnreadMessages:e=>this.viewUnreadMessages(e)}),this)}sendButtonClicked(e){this.querySelector("converse-message-form")?.onFormSubmitted(e)}viewUnreadMessages(e){e?.preventDefault?.(),this.model.ui.set({scrolled:!1})}emitFocused(e){Zl.chatboxviews.get(this.getAttribute("jid"))?.emitFocused(e)}emitBlurred(e){Zl.chatboxviews.get(this.getAttribute("jid"))?.emitBlurred(e)}onDrop(e){0!=e.dataTransfer.files.length&&(e.preventDefault(),this.model.sendFiles(e.dataTransfer.files))}onDragOver(e){e.preventDefault()}clearMessages(e){e?.preventDefault?.(),$E(this.model)}async autocompleteInPicker(e,t){await wd.emojis.initialize();const n=this.querySelector("converse-emoji-picker");if(n){n.model.set({ac_position:e.selectionStart,autocompleting:t,query:t});const s=this.querySelector("converse-emoji-dropdown");s?.showMenu()}}}wd.elements.define("converse-chat-bottom-panel",NE);class ME extends ob{static get properties(){return{jid:{type:String}}}disconnectedCallback(){super.disconnectedCallback(),Zl.chatboxviews.remove(this.jid,this)}updated(){this.model&&this.jid!==this.model.get("jid")&&(this.stopListening(),Zl.chatboxviews.remove(this.model.get("jid"),this),delete this.model,this.requestUpdate(),this.initialize())}close(e){return e?.preventDefault?.(),this.model.close(e)}maybeFocus(){wd.settings.get("auto_focus")&&this.focus()}focus(){const e=this.getElementsByClassName("chat-textarea")[0];return e&&document.activeElement!==e&&e.focus(),this}emitBlurred(e){this.contains(document.activeElement)||this.contains(e.relatedTarget)||wd.trigger("chatBoxBlurred",this,e)}emitFocused(e){this.contains(e.relatedTarget)||wd.trigger("chatBoxFocused",this,e)}getBottomPanel(){return this.model.get("type")===Zl.CHATROOMS_TYPE?this.querySelector("converse-muc-bottom-panel"):this.querySelector("converse-chat-bottom-panel")}getMessageForm(){return this.model.get("type")===Zl.CHATROOMS_TYPE?this.querySelector("converse-muc-message-form"):this.querySelector("converse-message-form")}scrollDown(e){e?.preventDefault?.(),e?.stopPropagation?.(),this.model.ui.get("scrolled")&&this.model.ui.set({scrolled:!1}),fA(this.model)}onWindowStateChanged(e){"visible"===e.state?this.model.isHidden()||this.model.clearUnreadMsgCounter():"hidden"===e.state&&(this.model.setChatState(Zl.INACTIVE,{silent:!0}),this.model.sendChatState())}}class OE extends ME{length=200;async initialize(){Zl.chatboxviews.add(this.jid,this),this.model=Zl.chatboxes.get(this.jid),this.listenTo(Zl,"windowStateChanged",this.onWindowStateChanged),this.listenTo(this.model,"change:hidden",(()=>!this.model.get("hidden")&&this.afterShown())),this.listenTo(this.model,"change:show_help_messages",(()=>this.requestUpdate())),await this.model.messages.fetched,!this.model.get("hidden")&&this.afterShown(),wd.trigger("chatBoxViewInitialized",this)}render(){return(e=>bm`
    ${e.model?bm`
    ${e.show_help_messages?bm`
    `:""}
    `:""}
    `)(Object.assign({model:this.model,help_messages:this.getHelpMessages(),show_help_messages:this.model.get("show_help_messages")},this.model.toJSON()))}getHelpMessages(){return[`/clear: ${ib("Remove messages")}`,`/close: ${ib("Close this chat")}`,`/me: ${ib("Write in the third person")}`,`/help: ${ib("Show this menu")}`]}afterShown(){this.model.setChatState(Zl.ACTIVE),this.model.clearUnreadMsgCounter(),this.maybeFocus()}}wd.elements.define("converse-chat",OE);var RE=n(110),DE={};DE.styleTagTransform=_b(),DE.setAttributes=fb(),DE.insert=mb().bind(null,"head"),DE.domAPI=ub(),DE.insertStyleElement=vb();lb()(RE.Z,DE);RE.Z&&RE.Z.locals&&RE.Z.locals;const{Strophe:zE}=Fm.env;Fm.plugins.add("converse-chatview",{dependencies:["converse-chatboxviews","converse-chat","converse-disco","converse-modal"],initialize(){wd.settings.extend({allowed_audio_domains:null,allowed_image_domains:null,allowed_video_domains:null,auto_focus:!0,debounced_content_rendering:!0,filter_url_query_params:null,image_urls_regex:null,message_limit:0,muc_hats:["xep317"],render_media:!0,show_message_avatar:!0,show_retraction_warning:!0,show_send_button:!0,show_toolbar:!0,time_format:"HH:mm",use_system_emojis:!0,visible_toolbar_buttons:{call:!1,clear:!0,emoji:!0,spoiler:!0}}),Zl.ChatBoxView=OE,wd.listen.on("connected",(()=>wd.disco.own.features.add(zE.NS.SPOILER))),wd.listen.on("chatBoxClosed",(e=>{return t=e.get("jid"),void(Zl.router.history.getFragment()===`converse/chat?jid=${t}`&&Zl.router.navigate(""));var t}))}});wd.elements.define("converse-brand-byline",class extends ob{render(){const e="fullscreen"===wd.settings.get("view_mode");return bm`${e?bm`

    ${Zl.VERSION_NAME}

    Open Source XMPP chat client brought to you by Opkode

    Translate it into your own language

    `:""}`}});wd.elements.define("converse-brand-logo",class extends ob{render(){const e="fullscreen"===wd.settings.get("view_mode");return bm` converse.js ${e?bm``:""}`}});wd.elements.define("converse-brand-heading",class extends ob{render(){return Rh``}});const{Strophe:PE}=Fm.env,LE=[PE.Status.ERROR,PE.Status.CONNECTING,PE.Status.CONNFAIL,PE.Status.AUTHENTICATING,PE.Status.AUTHFAIL,PE.Status.DISCONNECTING,PE.Status.RECONNECTING],FE=Object.fromEntries([[PE.Status.ERROR,"Error"],[PE.Status.CONNECTING,"Connecting"],[PE.Status.CONNFAIL,"Connection failure"],[PE.Status.AUTHENTICATING,"Authenticating"],[PE.Status.AUTHFAIL,"Authentication failure"],[PE.Status.CONNECTED,"Connected"],[PE.Status.DISCONNECTED,"Disconnected"],[PE.Status.DISCONNECTING,"Disconnecting"],[PE.Status.ATTACHED,"Attached"],[PE.Status.REDIRECT,"Redirect"],[PE.Status.CONNTIMEOUT,"Connection timeout"],[PE.Status.RECONNECTING,"Reconnecting"]]),UE=Object.fromEntries([[PE.Status.ERROR,"error"],[PE.Status.CONNECTING,"info"],[PE.Status.CONNFAIL,"error"],[PE.Status.AUTHENTICATING,"info"],[PE.Status.AUTHFAIL,"error"],[PE.Status.CONNECTED,"info"],[PE.Status.DISCONNECTED,"error"],[PE.Status.DISCONNECTING,"warn"],[PE.Status.ATTACHED,"info"],[PE.Status.REDIRECT,"info"],[PE.Status.RECONNECTING,"warn"]]),BE=e=>{const t=wd.settings.get("authentication"),n=ib("Log in"),s=ib("XMPP Address"),i=wd.settings.get("locked_domain"),r=wd.settings.get("default_domain"),o=(i||r)&&ib("Username")||ib("user@domain"),a=wd.settings.get("allow_user_trust_override");return bm`
    ${t!==Po?(()=>{const e=ib("Password");return bm`
    `})():""} ${wd.settings.get("show_connection_url_input")?(()=>{const e=ib("Connection URL"),t=ib("HTTP or websocket URL that is used to connect to your XMPP server"),n=ib("e.g. wss://example.org/xmpp-websocket");return bm`

    ${t}

    `})():""} ${a?(e=>{const t=ib("To improve performance, we cache your data in this browser. Uncheck this box if this is a public computer or if you want your data to be deleted when you log out. It's important that you explicitly log out, otherwise not all cached data might be deleted. Please note, when using an untrusted device, OMEMO encryption is NOT available."),n=ib("This is a trusted device");return bm``})("off"!==a):""}
    ${wd.settings.get("allow_registration")&&!wd.settings.get("auto_login")&&Zl.pluggable.plugins["converse-register"].enabled(Zl)?(()=>{const e=ib("Create an account"),t=ib("Don't have a chat account?");return bm`

    ${t}

    `})():""}`},qE=e=>{const t=Zl.connfeedback.get("connection_status");let n,s;LE.includes(t)&&(s=FE[t],n=UE[t]);const i=Zl.connfeedback.get("message");return bm`
    ${"CONNECTING"===Bo[t]?SS({classes:"hor_centered"}):(e=>{const t=wd.settings.get("authentication"),n=ib("Disconnected"),s=ib("Click here to log in anonymously");return bm`${t==Lo||t==Po?BE(e):""} ${t==zo?bm``:""} ${t==Uo?bm`

    ${n}

    `:""}`})(e)}
    `},{Strophe:HE,u:GE}=Fm.env;function WE(){const e=Zl.chatboxes.add(new Zl.ControlBox({id:"controlbox"}));return Zl.chatboxviews.get("controlbox")?.setModel(),e}function VE(e){e?.preventDefault?.();const t=Zl.chatboxes.get("controlbox")||WE();GE.safeSave(t,{closed:!1})}function ZE(){const e=Zl.chatboxviews.get("controlbox");return e.model.set({connected:!1}),e}function QE(){const e=Zl?.chatboxviews,t=e&&e.get("controlbox");t&&(GE.safeSave(t.model,{connected:!1}),t?.controlbox_pane&&(t.controlbox_pane.remove(),delete t.controlbox_pane))}function JE(){(Zl.chatboxes.get("controlbox")||WE()).save({connected:!0})}const{Strophe:KE,u:YE}=Fm.env;wd.elements.define("converse-login-form",class extends ob{initialize(){this.listenTo(Zl.connfeedback,"change",(()=>this.requestUpdate())),this.handler=()=>this.requestUpdate()}connectedCallback(){super.connectedCallback(),wd.settings.listen.on("change",this.handler)}disconnectedCallback(){super.disconnectedCallback(),wd.settings.listen.not("change",this.handler)}render(){return qE(this)}firstUpdated(){this.initPopovers()}async onLoginFormSubmitted(e){if(e?.preventDefault(),wd.settings.get("authentication")===zo)return this.connect(Zl.jid);(function(e){const t=e.querySelector("input[name=jid]");return!t.value||wd.settings.get("locked_domain")||wd.settings.get("default_domain")||GE.isValidJID(t.value)?(t.setCustomValidity(""),!0):(t.setCustomValidity(ib("Please enter a valid XMPP address")),!1)})(e.target)&&(!function(e){let t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};const n=new FormData(e),s=n.get("connection-url");s?.startsWith("ws")?t.websocket_url=s:s?.startsWith("http")&&(t.bosh_service_url=s);let i=n.get("jid");if(wd.settings.get("locked_domain")){const e="@"+wd.settings.get("locked_domain");i.endsWith(e)&&(i=i.substr(0,i.length-e.length)),i=HE.escapeNode(i)+e}else wd.settings.get("default_domain")&&!i.includes("@")&&(i=i+"@"+wd.settings.get("default_domain"));t.jid=i,t.password=n.get("password"),wd.settings.set(t),Zl.config.save({trusted:!!n.get("trusted")})}(e.target),wd.settings.get("bosh_service_url")||wd.settings.get("websocket_url")||await this.discoverConnectionMethods(e),wd.settings.get("bosh_service_url")||wd.settings.get("websocket_url")?this.connect():wd.settings.set("show_connection_url_input",!0))}discoverConnectionMethods(e){if(!wd.settings.get("discover_connection_methods"))return;const t=new FormData(e.target).get("jid"),n=KE.getDomainFromJid(t);return(!Zl.connection?.jid||t&&!YE.isSameDomain(Zl.connection.jid,t))&&hd(),Zl.connection.discoverConnectionMethods(n)}initPopovers(){Array.from(this.querySelectorAll("[data-title]")).forEach((e=>{new(xb().Popover)(e,{trigger:"mobile"===wd.settings.get("view_mode")?"click":"hover",dismissible:"mobile"===wd.settings.get("view_mode"),container:this.parentElement.parentElement.parentElement})}))}connect(e){["converse/login","converse/register"].includes(Zl.router.history.getFragment())&&Zl.router.navigate("",{replace:!0}),Zl.connection?.reset(),wd.user.login(e)}});const XE=e=>bm``;class e$ extends ob{static get properties(){return{jid:{type:String}}}render(){return XE(this.jid)}}wd.elements.define("converse-controlbox-navback",e$);const{dayjs:t$}=Fm.env,n$=dr.extend({defaults:()=>({bookmarked:!1,box_id:"controlbox",chat_state:void 0,closed:!wd.settings.get("show_controlbox_by_default"),num_unread:0,time_opened:t$(0).valueOf(),type:Zl.CONTROLBOX_TYPE,url:""}),validate(e){return e.type===Zl.CONTROLBOX_TYPE?"embedded"===wd.settings.get("view_mode")&&wd.settings.get("singleton")?"Controlbox not relevant in embedded view mode":void 0:Zl.ChatBox.prototype.validate.call(this,e)},maybeShow(e){return e||"controlbox"!==this.get("id")?Zl.ChatBox.prototype.maybeShow.call(this,e):this},onReconnection(){this.save("connected",!0)}});class s$ extends ob{async connectedCallback(){super.connectedCallback(),await wd.waitUntil("initialized"),this.model=Zl.chatboxes.get("controlbox"),this.listenTo(this.model,"change:closed",(()=>this.requestUpdate())),this.requestUpdate()}render(){return(e=>{const t=wd.connection.connected()?ib("Chat Contacts"):ib("Toggle chat");return bm`${t}`})({onClick:VE,hide:!this.model?.get("closed")})}}wd.elements.define("converse-controlbox-toggle",s$);const i$=s$,{Strophe:r$}=Fm.env;const o$=e=>{const t=e.model.toJSON(),n=wd.settings.get("sticky_controlbox");return bm`
    ${n?"":bm``}
    ${t.connected?bm`
    ${wd.settings.get("authentication")===Zl.ANONYMOUS?"":bm`
    `}`:function(e){const t=Zl.connfeedback.get("connection_status");return[r$.Status.RECONNECTING,r$.Status.CONNECTING].includes(t)?SS():"register"===e["active-form"]?bm``:bm``}(t)}
    `},a$=Fm.env.utils;class c$ extends ob{initialize(){this.setModel(),Zl.chatboxviews.add("controlbox",this),this.model.get("connected")&&void 0===this.model.get("closed")&&this.model.set("closed",!wd.settings.get("show_controlbox_by_default")),this.requestUpdate(),wd.trigger("controlBoxInitialized",this)}setModel(){this.model=Zl.chatboxes.get("controlbox"),this.listenTo(Zl.connfeedback,"change:connection_status",(()=>this.requestUpdate())),this.listenTo(this.model,"change:active-form",(()=>this.requestUpdate())),this.listenTo(this.model,"change:connected",(()=>this.requestUpdate())),this.listenTo(this.model,"change:closed",(()=>!this.model.get("closed")&&this.afterShown())),this.requestUpdate()}render(){return this.model?o$(this):""}close(e){if(e?.preventDefault?.(),("closeAllChatBoxes"!==e?.name||Zl.disconnection_cause===Fo&&!wd.settings.get("show_controlbox_by_default"))&&!wd.settings.get("sticky_controlbox"))return a$.safeSave(this.model,{closed:!0}),wd.trigger("controlBoxClosed",this),this}afterShown(){return wd.trigger("controlBoxOpened",this),this}}wd.elements.define("converse-controlbox",c$);const l$=c$,{u:d$}=Fm.env,u$={controlbox:{async open(){await wd.waitUntil("chatBoxesFetched");const e=await wd.chatboxes.get("controlbox")||wd.chatboxes.create("controlbox",{},Zl.Controlbox);return d$.safeSave(e,{closed:!1}),e},get:()=>Zl.chatboxviews.get("controlbox")}};var h$=n(7740),m$={};m$.styleTagTransform=_b(),m$.setAttributes=fb(),m$.insert=mb().bind(null,"head"),m$.domAPI=ub(),m$.insertStyleElement=vb();lb()(h$.Z,m$);h$.Z&&h$.Z.locals&&h$.Z.locals;var g$=n(4706),f$={};f$.styleTagTransform=_b(),f$.setAttributes=fb(),f$.insert=mb().bind(null,"head"),f$.domAPI=ub(),f$.insertStyleElement=vb();lb()(g$.Z,f$);g$.Z&&g$.Z.locals&&g$.Z.locals;Fm.plugins.add("converse-controlbox",{dependencies:["converse-modal","converse-chatboxes","converse-chat","converse-rosterview","converse-chatview"],enabled:e=>!e.api.settings.get("singleton"),overrides:{ChatBoxes:{model(e,t){return e&&"controlbox"==e.id?new n$(e,t):this.__super__.model.apply(this,arguments)}}},initialize(){wd.settings.extend({allow_logout:!0,allow_user_trust_override:!0,default_domain:void 0,locked_domain:void 0,show_connection_url_input:!1,show_controlbox_by_default:!1,sticky_controlbox:!1}),wd.promises.add("controlBoxInitialized",!1),Object.assign(wd,u$),Zl.ControlBoxView=l$,Zl.ControlBox=n$,Zl.ControlBoxToggle=i$,wd.listen.on("chatBoxesFetched",JE),wd.listen.on("clearSession",QE),wd.listen.on("will-reconnect",ZE),wd.waitUntil("chatBoxViewsInitialized").then(WE).catch((e=>$l.fatal(e)))}});wd.elements.define("converse-headlines-heading",class extends ob{static get properties(){return{jid:{type:String}}}async initialize(){this.model=Zl.chatboxes.get(this.jid),await this.model.initialized,this.requestUpdate()}render(){return(e=>bm`
    ${Zl.api.settings.get("singleton")?"":bm``}
    ${e.display_name}
    ${WS(gA(e.heading_buttons_promise),"")} ${WS(mA(e.heading_buttons_promise),"")}
    ${e.status?bm`

    ${e.status}

    `:""}`)({...this.model.toJSON(),display_name:this.model.getDisplayName(),heading_buttons_promise:this.getHeadingButtons()})}getHeadingButtons(){const e=[];return wd.settings.get("singleton")||e.push({a_class:"close-chatbox-button",handler:e=>this.close(e),i18n_text:ib("Close"),i18n_title:ib("Close these announcements"),icon_class:"fa-times",name:"close",standalone:"overlayed"===wd.settings.get("view_mode")}),Zl.api.hook("getHeadingButtons",this,e)}close(e){e.preventDefault(),this.model.close()}});wd.elements.define("converse-headlines",class extends ME{async initialize(){Zl.chatboxviews.add(this.jid,this),this.model=Zl.chatboxes.get(this.jid),this.model.disable_mam=!0,this.listenTo(Zl,"windowStateChanged",this.onWindowStateChanged),this.listenTo(this.model,"change:hidden",(()=>this.afterShown())),this.listenTo(this.model,"destroy",this.remove),this.listenTo(this.model.messages,"add",(()=>this.requestUpdate())),this.listenTo(this.model.messages,"remove",(()=>this.requestUpdate())),this.listenTo(this.model.messages,"reset",(()=>this.requestUpdate())),await this.model.messages.fetched,this.model.maybeShow(),wd.trigger("headlinesBoxViewInitialized",this)}render(){return(e=>bm`
    ${e?bm`
    `:""}
    `)(this.model)}async close(e){return e?.preventDefault?.(),Zl.router.history.getFragment()==="converse/chat?jid="+this.model.get("jid")&&Zl.router.navigate(""),await this.model.close(e),this}getNotifications(){return[]}afterShown(){this.model.clearUnreadMsgCounter()}});const p$=e=>{const t=e.model.filter((e=>e.get("type")===Zl.HEADLINES_TYPE)),n=ib("Announcements");return bm`
    ${n}
    ${t.map((t=>function(e,t){const n=ib("Click to open this server message");return bm``}(e,t)))}
    `};class v$ extends ob{initialize(){this.model=Zl.chatboxes,this.listenTo(this.model,"add",(e=>this.renderIfHeadline(e))),this.listenTo(this.model,"remove",(e=>this.renderIfHeadline(e))),this.listenTo(this.model,"destroy",(e=>this.renderIfHeadline(e))),this.requestUpdate()}render(){return p$(this)}renderIfHeadline(e){return e?.get("type")===Zl.HEADLINES_TYPE&&this.requestUpdate()}async openHeadline(e){e.preventDefault();const t=e.target.getAttribute("data-headline-jid");(await wd.headlines.get(t)).maybeShow(!0)}}wd.elements.define("converse-headlines-feeds-list",v$);var y$=n(8250),_$={};_$.styleTagTransform=_b(),_$.setAttributes=fb(),_$.insert=mb().bind(null,"head"),_$.domAPI=ub(),_$.insertStyleElement=vb();lb()(y$.Z,_$);y$.Z&&y$.Z.locals&&y$.Z.locals;var b$=n(2118),w$={};w$.styleTagTransform=_b(),w$.setAttributes=fb(),w$.insert=mb().bind(null,"head"),w$.domAPI=ub(),w$.insertStyleElement=vb();lb()(b$.Z,w$);b$.Z&&b$.Z.locals&&b$.Z.locals;Fm.plugins.add("converse-headlines-view",{dependencies:["converse-headlines","converse-chatview"],initialize(){Zl.HeadlinesFeedsList=v$,Zl.HeadlinesPanel=v$}});var S$=n(7725),x$={};x$.styleTagTransform=_b(),x$.setAttributes=fb(),x$.insert=mb().bind(null,"head"),x$.domAPI=ub(),x$.insertStyleElement=vb();lb()(S$.Z,x$);S$.Z&&S$.Z.locals&&S$.Z.locals;function A$(e,t){return e instanceof Ov?Rh``:t}async function E$(e){if(!e.model.ui.get("chat-content-spinner-top")&&e.model.messages.length){const t=e.model.get("type")===Zl.CHATROOMS_TYPE,n=e.model.getOldestMessage();if(n){const s=t?e.model.get("jid"):Zl.bare_jid,i=n&&n.get(`stanza_id ${s}`);e.model.ui.set("chat-content-spinner-top",!0);try{i?await ry(e.model,{before:i}):await ry(e.model,{end:n.get("time")})}catch(t){return $l.error(t),void e.model.ui.set("chat-content-spinner-top",!1)}wd.settings.get("allow_url_history_change")&&Zl.router.history.navigate(`#${n.get("msgid")}`),setTimeout((()=>e.model.ui.set("chat-content-spinner-top",!1)),250)}}}wd.elements.define("converse-mam-placeholder",class extends ob{static get properties(){return{model:{type:Object}}}render(){return(e=this).model.get("fetching")?SS({classes:"hor_centered"}):Rh`
    `;var e}async fetchMissingMessages(e){e?.preventDefault?.(),this.model.set("fetching",!0);const t={before:this.model.get("before"),start:this.model.get("start")};await ry(this.model.collection.chatbox,t),this.model.destroy()}}),Fm.plugins.add("converse-mam-views",{dependencies:["converse-mam","converse-chatview","converse-muc-views"],initialize(){wd.listen.on("chatBoxScrolledUp",E$),wd.listen.on("getMessageTemplate",A$)}});const{Strophe:$$,sizzle:C$}=Fm.env;wd.elements.define("converse-muc-affiliation-form",class extends ob{static get properties(){return{muc:{type:Object},jid:{type:String},affiliation:{type:String},alert_message:{type:String,attribute:!1},alert_type:{type:String,attribute:!1}}}render(){return(e=>{const t=ib("Change affiliation"),n=ib("New affiliation"),s=ib("Reason"),i=sp(e.muc.getOwnOccupant());return bm`
    ${e.alert_message?bm``:""}
    `})(this)}alert(e,t){this.alert_message=e,this.alert_type=t}async assignAffiliation(e){e.stopPropagation(),e.preventDefault(),this.alert();const t=new FormData(e.target),n=t.get("affiliation"),s={jid:this.jid,reason:t.get("reason")},i=this.muc.get("jid");try{await rp(n,i,[s])}catch(e){return null===e?this.alert(ib("Timeout error while trying to set the affiliation"),"danger"):C$(`not-allowed[xmlns="${$$.NS.STANZAS}"]`,e).length?this.alert(ib("Sorry, you're not allowed to make that change"),"danger"):this.alert(ib("Sorry, something went wrong while trying to set the affiliation"),"danger"),void $l.error(e)}await this.muc.occupants.fetchMembers();const r=new CustomEvent("affiliationChanged",{bubbles:!0});this.dispatchEvent(r)}});const{Strophe:k$,sizzle:j$}=Fm.env;wd.elements.define("converse-muc-role-form",class extends ob{static get properties(){return{muc:{type:Object},jid:{type:String},role:{type:String},alert_message:{type:String,attribute:!1},alert_type:{type:String,attribute:!1}}}render(){return(e=>{const t=ib("Change role"),n=ib("New Role"),s=ib("Reason"),i=Sp(e.muc.getOwnOccupant());return bm`
    `})(this)}alert(e,t){this.alert_message=e,this.alert_type=t}assignRole(e){e.stopPropagation(),e.preventDefault(),this.alert();const t=new FormData(e.target),n=this.muc.getOccupant(t.get("jid")||t.get("nick")),s=t.get("role"),i=t.get("reason");this.muc.setRole(n,s,i,(()=>{const e=new CustomEvent("roleChanged",{bubbles:!0});this.dispatchEvent(e)}),(e=>{j$(`not-allowed[xmlns="${k$.NS.STANZAS}"]`,e).length?this.alert(ib("You're not allowed to make that change"),"danger"):(this.alert(ib("Sorry, something went wrong while trying to set the role"),"danger"),ml(e)&&$l.error(e))}))}});wd.elements.define("converse-muc-message-form",class extends jE{async connectedCallback(){super.connectedCallback(),await this.model.initialized}toHTML(){return(e=>{const t=e.composing_spoiler?ib("Hidden message"):ib("Message"),n=ib("Optional hint"),s=wd.settings.get("show_send_button");return bm`
    `})(Object.assign(this.model.toJSON(),{hint_value:this.querySelector(".spoiler-hint")?.value,message_value:this.querySelector(".chat-textarea")?.value,onChange:e=>this.model.set({draft:e.target.value}),onDrop:e=>this.onDrop(e),onKeyDown:e=>this.onKeyDown(e),onKeyUp:e=>this.onKeyUp(e),onPaste:e=>this.onPaste(e),scrolled:this.model.ui.get("scrolled"),viewUnreadMessages:e=>this.viewUnreadMessages(e)}))}afterRender(){const e=this.model.session.get("connection_status")===Fm.ROOMSTATUS.ENTERED,t=e&&!(this.model.features.get("moderated")&&"visitor"===this.model.getOwnRole());e&&t&&this.initMentionAutoComplete()}initMentionAutoComplete(){this.mention_auto_complete=new Zl.AutoComplete(this,{auto_first:!0,auto_evaluate:!1,min_chars:wd.settings.get("muc_mention_autocomplete_min_chars"),match_current_word:!0,list:()=>this.getAutoCompleteList(),filter:"contains"==wd.settings.get("muc_mention_autocomplete_filter")?Zl.FILTER_CONTAINS:Zl.FILTER_STARTSWITH,ac_triggers:["Tab","@"],include_triggers:[],item:lx}),this.mention_auto_complete.on("suggestion-box-selectcomplete",(()=>this.auto_completing=!1))}getAutoCompleteList(){return this.model.getAllKnownNicknames().map((e=>({label:e,value:`@${e}`})))}onKeyDown(e){this.mention_auto_complete.onKeyDown(e)||super.onKeyDown(e)}onKeyUp(e){this.mention_auto_complete.evaluate(e),super.onKeyUp(e)}});var T$=n(6714),I$={};I$.styleTagTransform=_b(),I$.setAttributes=fb(),I$.insert=mb().bind(null,"head"),I$.domAPI=ub(),I$.insertStyleElement=vb();lb()(T$.Z,I$);T$.Z&&T$.Z.locals&&T$.Z.locals;class N$ extends ob{static get properties(){return{jid:{type:String}}}connectedCallback(){super.connectedCallback(),this.model=Zl.chatboxes.get(this.jid)}render(){return(e=>{const t=ib("Nickname"),n=e.model?.isEntered()?ib("Change nickname"):ib("Enter groupchat"),s=wd.settings.get("muc_show_logs_before_join")?ib("Choose a nickname to enter"):ib("Please choose your nickname"),i=e.model?.get("nickname_validation_message");return bm`

    ${i}

    `})(this)}submitNickname(e){e.preventDefault();const t=e.target.nick.value.trim();t&&(this.model.isEntered()?(this.model.setNickname(t),this.closeModal()):this.model.join(t))}closeModal(){const e=document.createEvent("Event");e.initEvent("hide.bs.modal",!0,!0),this.dispatchEvent(e)}}wd.elements.define("converse-muc-nickname-form",N$);const M$=e=>{const t=ib("You have unread messages"),n=e.model.session.get("connection_status"),s=ib("You're not allowed to send messages in this room");return n===Fm.ROOMSTATUS.ENTERED?bm`${e.model.ui.get("scrolled")&&e.model.get("num_unread_general")?bm`
    ▼ ${t} ▼
    `:""} ${e.can_edit?(e=>{const t=ib("You have unread messages"),n=wd.settings.get("message_limit"),s=wd.settings.get("visible_toolbar_buttons").call,i=wd.settings.get("visible_toolbar_buttons").emoji,r=wd.settings.get("show_send_button"),o=wd.settings.get("visible_toolbar_buttons").spoiler,a=wd.settings.get("show_toolbar");return bm`${e.model.ui.get("scrolled")&&e.model.get("num_unread")?bm`
    ▼ ${t} ▼
    `:""} ${a?bm``:""}`})(e):bm`${s}`}`:n!=Fm.ROOMSTATUS.NICKNAME_REQUIRED?"":wd.settings.get("muc_show_logs_before_join")?bm``:void 0};var O$=n(5777),R$={};R$.styleTagTransform=_b(),R$.setAttributes=fb(),R$.insert=mb().bind(null,"head"),R$.domAPI=ub(),R$.insertStyleElement=vb();lb()(O$.Z,R$);O$.Z&&O$.Z.locals&&O$.Z.locals;wd.elements.define("converse-muc-bottom-panel",class extends NE{events={"click .hide-occupants":"hideOccupants","click .send-button":"sendButtonClicked"};async initialize(){await super.initialize(),this.listenTo(this.model,"change:hidden_occupants",this.debouncedRender),this.listenTo(this.model,"change:num_unread_general",this.debouncedRender),this.listenTo(this.model.features,"change:moderated",this.debouncedRender),this.listenTo(this.model.occupants,"add",this.renderIfOwnOccupant),this.listenTo(this.model.occupants,"change:role",this.renderIfOwnOccupant),this.listenTo(this.model.session,"change:connection_status",this.debouncedRender)}render(){const e=this.model.session.get("connection_status")===Fm.ROOMSTATUS.ENTERED,t=e&&!(this.model.features.get("moderated")&&"visitor"===this.model.getOwnRole());zm(M$({can_edit:t,entered:e,model:this.model,is_groupchat:!0,viewUnreadMessages:e=>this.viewUnreadMessages(e)}),this)}renderIfOwnOccupant(e){e.get("jid")===Zl.bare_jid&&this.debouncedRender()}sendButtonClicked(e){this.querySelector("converse-muc-message-form")?.onFormSubmitted(e)}hideOccupants(e){e?.preventDefault?.(),e?.stopPropagation?.(),this.model.save({hidden_occupants:!0})}});const D$={offline:"Offline",unavailable:"Unavailable",xa:"Extended Away",away:"Away",dnd:"Do not disturb",chat:"Chattty",online:"Online"},z$=e=>{const t=e.get("role"),n=(e=>ib("Click to mention %1$s in your message.",e.get("nick")))(e),s=ib("This user is a moderator."),i=ib("This user can send messages in this groupchat."),r=ib("This user can NOT send messages in this groupchat."),o=e.get("jid")?`${e.get("jid")} `:"";return"moderator"===t?`${o}${s} ${n}`:"participant"===t?`${o}${i} ${n}`:"visitor"===t?`${o}${r} ${n}`:["visitor","participant","moderator"].includes(t)?void 0:`${o}${n}`},P$=(e,t)=>{const n=e.get("affiliation"),s=D$[e.get("show")],i=ib("Admin"),r=ib("Member"),o=ib("Moderator"),a=ib("Owner"),c=ib("Visitor"),l=e.get("role"),d=e.get("show");let u,h;return[u,h]="online"===d?["fa fa-circle","chat-status-online"]:"dnd"===d?["fa fa-minus-circle","chat-status-busy"]:"away"===d?["fa fa-circle","chat-status-away"]:["fa fa-circle","subdued-color"],bm`
  • ${e.getDisplayName()} ${"owner"===n?bm`${a}`:""} ${"admin"===n?bm`${i}`:""} ${"member"===n?bm`${r}`:""} ${"moderator"===l?bm`${o}`:""} ${"visitor"===l?bm`${c}`:""}
  • `};var L$=n(5152),F$={};F$.styleTagTransform=_b(),F$.setAttributes=fb(),F$.insert=mb().bind(null,"head"),F$.domAPI=ub(),F$.insertStyleElement=vb();lb()(L$.Z,F$);L$.Z&&L$.Z.locals&&L$.Z.locals;var U$=n(7428),B$={};B$.styleTagTransform=_b(),B$.setAttributes=fb(),B$.insert=mb().bind(null,"head"),B$.domAPI=ub(),B$.insertStyleElement=vb();lb()(U$.Z,B$);U$.Z&&U$.Z.locals&&U$.Z.locals;const{u:q$}=Fm.env;wd.elements.define("converse-muc-sidebar",class extends ob{static get properties(){return{jid:{type:String}}}connectedCallback(){super.connectedCallback(),this.model=Zl.chatboxes.get(this.jid),this.listenTo(this.model.occupants,"add",(()=>this.requestUpdate())),this.listenTo(this.model.occupants,"remove",(()=>this.requestUpdate())),this.listenTo(this.model.occupants,"change",(()=>this.requestUpdate())),this.listenTo(this.model.occupants,"vcard:change",(()=>this.requestUpdate())),this.listenTo(this.model.occupants,"vcard:add",(()=>this.requestUpdate())),this.model.initialized.then((()=>this.requestUpdate()))}render(){const e=(e=>{const t=1===e.occupants.length?ib("Participant"):ib("Participants");return bm`
    ${e.occupants.length} ${t}
      ${Ox(e.occupants,(e=>e.get("jid")),(t=>P$(t,e)))}
    `})(Object.assign(this.model.toJSON(),{occupants:[...this.model.occupants.models],closeSidebar:e=>this.closeSidebar(e),onOccupantClicked:e=>this.onOccupantClicked(e)}));return e}closeSidebar(e){e?.preventDefault?.(),e?.stopPropagation?.(),q$.safeSave(this.model,{hidden_occupants:!0})}onOccupantClicked(e){e?.preventDefault?.();const t=Zl.chatboxviews.get(this.getAttribute("jid"));t?.getMessageForm().insertIntoTextArea(`@${e.target.textContent}`)}});const{u:H$}=Fm.env;wd.elements.define("converse-muc-chatarea",class extends ob{static get properties(){return{jid:{type:String},show_help_messages:{type:Boolean},type:{type:String}}}async initialize(){this.model=await wd.rooms.get(this.jid),this.listenTo(this.model,"change:show_help_messages",(()=>this.requestUpdate())),this.listenTo(this.model,"change:hidden_occupants",(()=>this.requestUpdate())),this.listenTo(this.model.session,"change:connection_status",(()=>this.requestUpdate())),this.onMouseMove=this._onMouseMove.bind(this),this.onMouseUp=this._onMouseUp.bind(this),this.requestUpdate()}render(){return(e=>bm`
    ${e.model?.get("show_help_messages")?bm`
    `:""}
    ${e.model?bm``:""}`)({getHelpMessages:()=>this.getHelpMessages(),jid:this.jid,model:this.model,onMousedown:e=>this.onMousedown(e),show_send_button:wd.settings.get("show_send_button"),shouldShowSidebar:()=>this.shouldShowSidebar(),type:this.type})}shouldShowSidebar(){return!this.model.get("hidden_occupants")&&this.model.session.get("connection_status")===Fm.ROOMSTATUS.ENTERED}getHelpMessages(){const e=wd.settings.get("muc_disable_slash_commands"),t=Array.isArray(e)?e:[];return[`/admin: ${ib("Change user's affiliation to admin")}`,`/ban: ${ib("Ban user by changing their affiliation to outcast")}`,`/clear: ${ib("Clear the chat area")}`,`/close: ${ib("Close this groupchat")}`,`/deop: ${ib("Change user role to participant")}`,`/destroy: ${ib("Remove this groupchat")}`,`/help: ${ib("Show this menu")}`,`/kick: ${ib("Kick user from groupchat")}`,`/me: ${ib("Write in 3rd person")}`,`/member: ${ib("Grant membership to a user")}`,`/modtools: ${ib("Opens up the moderator tools GUI")}`,`/mute: ${ib("Remove user's ability to post messages")}`,`/nick: ${ib("Change your nickname")}`,`/op: ${ib("Grant moderator role to user")}`,`/owner: ${ib("Grant ownership of this groupchat")}`,`/register: ${ib("Register your nickname")}`,`/revoke: ${ib("Revoke the user's current affiliation")}`,`/subject: ${ib("Set groupchat subject")}`,`/topic: ${ib("Set groupchat subject (alias for /subject)")}`,`/voice: ${ib("Allow muted user to post messages")}`].filter((e=>t.every((t=>!e.startsWith(t+"<",9))))).filter((e=>this.model.getAllowedCommands().some((t=>e.startsWith(t+"<",9)))))}onMousedown(e){H$.hasClass("dragresize-occupants-left",e.target)&&this.onStartResizeOccupants(e)}onStartResizeOccupants(e){this.resizing=!0,this.addEventListener("mousemove",this.onMouseMove),this.addEventListener("mouseup",this.onMouseUp);const t=this.querySelector("converse-muc-sidebar"),n=window.getComputedStyle(t);this.width=parseInt(n.width.replace(/px$/,""),10),this.prev_pageX=e.pageX}_onMouseMove(e){if(this.resizing){e.preventDefault();const t=this.prev_pageX-e.pageX;this.resizeSidebarView(t,e.pageX),this.prev_pageX=e.pageX}}_onMouseUp(e){if(this.resizing){e.preventDefault(),this.resizing=!1,this.removeEventListener("mousemove",this.onMouseMove),this.removeEventListener("mouseup",this.onMouseUp);const t=this.querySelector("converse-muc-sidebar").getBoundingClientRect(),n=this.calculateSidebarWidth(t,0);H$.safeSave(this.model,{occupants_width:n})}}calculateSidebarWidth(e,t){let n=e.width+t;const s=this.clientWidth;return n<.2*s?(n=.2*s,this.is_minimum=!0):n>.75*s?(n=.75*s,this.is_maximum=!0):s-n<250?(n=s-250,this.is_maximum=!0):(this.is_maximum=!1,this.is_minimum=!1),n}resizeSidebarView(e,t){const n=this.querySelector("converse-muc-sidebar"),s=n.getBoundingClientRect();if(this.is_minimum)this.is_minimum=s.leftt;else{const t=this.calculateSidebarWidth(s,e);n.style.flex="0 0 "+t+"px"}}});const{sizzle:G$}=Fm.env,W$=Fm.env.utils,{sizzle:V$}=Fm.env,Z$=Fm.env.utils;class Q$ extends ob{static get properties(){return{jid:{type:String}}}connectedCallback(){super.connectedCallback(),this.model=Zl.chatboxes.get(this.jid),this.listenTo(this.model.features,"change:passwordprotected",(()=>this.requestUpdate())),this.listenTo(this.model.session,"change:config_stanza",(()=>this.requestUpdate())),this.getConfig()}render(){return(e=>{const t=wd.settings.get("roomconfig_whitelist"),n=e.model.session.get("config_stanza");let s,i=[],r="";if(n){const o=W$.toStanza(n);i=G$("field",o),t.length&&(i=i.filter((e=>t.includes(e.getAttribute("var")))));const a={new_password:!e.model.features.get("passwordprotected"),fixed_username:e.model.get("jid")};i=i.map((e=>W$.xForm2TemplateResult(e,o,a))),r=o.querySelector("instructions")?.textContent,s=o.querySelector("title")?.textContent}else s=ib("Loading configuration form");const o=ib("Save"),a=ib("Cancel");return bm`
    ${s}${s!==r?bm`

    ${r}

    `:""} ${i.length?i:SS({classes:"hor_centered"})}
    ${i.length?bm`
    `:""}
    `})({model:this.model,closeConfigForm:e=>this.closeForm(e),submitConfigForm:e=>this.submitConfigForm(e)})}async getConfig(){const e=await this.model.fetchRoomConfiguration();this.model.session.set("config_stanza",e.outerHTML)}async submitConfigForm(e){e.preventDefault();const t=V$(":input:not([type=button]):not([type=submit])",e.target).map(Z$.webForm2xForm).filter((e=>e));try{await this.model.sendConfiguration(t)}catch(e){$l.error(e);const t=ib("Sorry, an error occurred while trying to submit the config form.")+" "+ib("Check your browser's developer console for details.");wd.alert("error",ib("Error"),t)}await this.model.refreshDiscoInfo(),this.closeForm()}closeForm(e){e?.preventDefault?.(),this.model.session.set("view",null)}}wd.elements.define("converse-muc-config-form",Q$);const J$=e=>{const t=ib("This groupchat no longer exists"),n=ib('The following reason was given: "%1$s"',e.reason||"");return bm`

    ${t}

    ${e.reason?bm`

    ${n}

    `:""} ${e.moved_jid?(e=>{const t=ib("The conversation has moved to a new address. Click the link below to enter.");return bm`

    ${t}

    `})(e):""}`};wd.elements.define("converse-muc-destroyed",class extends ob{static get properties(){return{jid:{type:String}}}connectedCallback(){super.connectedCallback(),this.model=Zl.chatboxes.get(this.jid)}render(){const e=this.model.get("destroyed_reason"),t=this.model.get("moved_jid");return J$({moved_jid:t,reason:e,onSwitch:e=>this.onSwitch(e)})}async onSwitch(e){e.preventDefault();const t=this.model.get("moved_jid");(await wd.rooms.get(t,{},!0)).maybeShow(!0),this.model.destroy()}});wd.elements.define("converse-muc-disconnected",class extends ob{static get properties(){return{jid:{type:String}}}connectedCallback(){super.connectedCallback(),this.model=Zl.chatboxes.get(this.jid)}render(){const e=this.model.session.get("disconnection_message");if(!e)return;const t=[e],n=this.model.session.get("disconnection_actor");n&&t.push(ib("This action was done by %1$s.",n));const s=this.model.session.get("disconnection_reason");return s&&t.push(ib('The reason given is: "%1$s".',s)),(e=>bm`

    ${e[0]}

    ${e.slice(1).map((e=>bm`

    ${e}

    `))}
    `)(t)}});const K$=e=>{const t=e.toJSON(),n=e.config.toJSON(),s=e.features.toJSON(),i=e.occupants.filter((e=>"offline"!==e.get("show"))).length,r=ib("XMPP address"),o=ib("Message archiving"),a=ib("Messages are archived on the server"),c=ib("Description"),l=ib("Features"),d=ib("Hidden"),u=ib("This groupchat is not publicly searchable"),h=ib("This groupchat is restricted to members only"),m=ib("Members only"),g=ib("Moderated"),f=ib("Participants entering this groupchat need to request permission to write"),p=ib("Name"),v=ib("This groupchat does not require a password upon entry"),y=ib("No password required"),_=ib("Not anonymous"),b=ib("All other groupchat participants can see your XMPP address"),w=ib("Not moderated"),S=ib("Participants entering this groupchat can write right away"),x=ib("Online users"),A=ib("Open"),E=ib("Anyone can join this groupchat"),$=ib("This groupchat requires a password before entry"),C=ib("Password protected"),k=ib("Persistent"),j=ib("This groupchat persists even if it's unoccupied"),T=ib("Public"),I=ib("Semi-anonymous"),N=ib("Only moderators can see your XMPP address"),M=ib("Temporary"),O=ib("This groupchat will disappear once the last person leaves");return bm`

    ${p}: ${t.name}

    ${r}:

    ${c}:

    ${t.subject?(e=>{const t=ib("Topic"),n=ib("Topic author");return bm`

    ${t}:

    ${n}: ${e.subject&&e.subject.author}

    `})(t):""}

    ${x}: ${i}

    ${l}:

      ${s.passwordprotected?bm`
    • ${C} - ${$}
    • `:""} ${s.unsecured?bm`
    • ${y} - ${v}
    • `:""} ${s.hidden?bm`
    • ${d} - ${u}
    • `:""} ${s.public_room?bm`
    • ${T} - ${t.__("This groupchat is publicly searchable")}
    • `:""} ${s.membersonly?bm`
    • ${m} - ${h}
    • `:""} ${s.open?bm`
    • ${A} - ${E}
    • `:""} ${s.persistent?bm`
    • ${k} - ${j}
    • `:""} ${s.temporary?bm`
    • ${M} - ${O}
    • `:""} ${s.nonanonymous?bm`
    • ${_} - ${b}
    • `:""} ${s.semianonymous?bm`
    • ${I} - ${N}
    • `:""} ${s.moderated?bm`
    • ${g} - ${f}
    • `:""} ${s.unmoderated?bm`
    • ${w} - ${S}
    • `:""} ${s.mam_enabled?bm`
    • ${o} - ${a}
    • `:""}

    `};var Y$=n(1067),X$={};X$.styleTagTransform=_b(),X$.setAttributes=fb(),X$.insert=mb().bind(null,"head"),X$.domAPI=ub(),X$.insertStyleElement=vb();lb()(Y$.Z,X$);Y$.Z&&Y$.Z.locals&&Y$.Z.locals;wd.elements.define("converse-muc-details-modal",class extends tS{initialize(){super.initialize(),this.listenTo(this.model,"change",(()=>this.render())),this.listenTo(this.model.features,"change",(()=>this.render())),this.listenTo(this.model.occupants,"add",(()=>this.render())),this.listenTo(this.model.occupants,"change",(()=>this.render()))}renderModal(){return K$(this.model)}getModalTitle(){return ib("Groupchat info for %1$s",this.model.getDisplayName())}});const eC=Fm.env.utils;wd.elements.define("converse-muc-invite-modal",class extends tS{initialize(){super.initialize(),this.listenTo(this.model,"change",(()=>this.render()))}renderModal(){return(e=>{const t=ib("Invite"),n=ib("user@example.org"),s=ib("Please enter a valid XMPP address"),i=ib("XMPP Address"),r=ib("Optional reason for the invitation");return bm`
    ${e.model.get("invalid_invite_jid")?bm`
    ${s}
    `:""}
    `})(this)}getModalTitle(){return ib("Invite someone to this groupchat")}getAutoCompleteList(){return Zl.roster.map((e=>({label:e.getDisplayName(),value:e.get("jid")})))}submitInviteForm(e){e.preventDefault();const t=new FormData(e.target),n=t.get("invitee_jids")?.trim(),s=t.get("reason");eC.isValidJID(n)?(this.chatroomview.model.directInvite(n,s),this.modal.hide()):this.model.set({invalid_invite_jid:!0})}});wd.elements.define("converse-muc-nickname-modal",class extends tS{renderModal(){return bm``}getModalTitle(){return ib("Change your nickname")}});var tC=n(2864),nC={};nC.styleTagTransform=_b(),nC.setAttributes=fb(),nC.insert=mb().bind(null,"head"),nC.domAPI=ub(),nC.insertStyleElement=vb();lb()(tC.Z,nC);tC.Z&&tC.Z.locals&&tC.Z.locals;wd.elements.define("converse-rich-text",class extends ob{static get properties(){return{embed_audio:{type:Boolean},embed_videos:{type:Boolean},mentions:{type:Array},nick:{type:String},offset:{type:Number},onImgClick:{type:Function},onImgLoad:{type:Function},render_styling:{type:Boolean},show_images:{type:Boolean},hide_media_urls:{type:Boolean},show_me_message:{type:Boolean},text:{type:String}}}constructor(){super(),this.embed_audio=!1,this.embed_videos=!1,this.hide_media_urls=!1,this.mentions=[],this.offset=0,this.render_styling=!1,this.show_image_urls=!0,this.show_images=!1,this.show_me_message=!1}render(){const e={embed_audio:this.embed_audio,embed_videos:this.embed_videos,hide_media_urls:this.hide_media_urls,mentions:this.mentions,nick:this.nick,onImgClick:this.onImgClick,onImgLoad:this.onImgLoad,render_styling:this.render_styling,show_images:this.show_images,show_me_message:this.show_me_message};return EA(this.text,this.offset,e)}});var sC=n(4083),iC={};iC.styleTagTransform=_b(),iC.setAttributes=fb(),iC.insert=mb().bind(null,"head"),iC.domAPI=ub(),iC.insertStyleElement=vb();lb()(sC.Z,iC);sC.Z&&sC.Z.locals&&sC.Z.locals;wd.elements.define("converse-muc-heading",class extends ob{async initialize(){this.model=Zl.chatboxes.get(this.getAttribute("jid")),this.listenTo(this.model,"change",(()=>this.requestUpdate())),this.listenTo(this.model,"vcard:add",(()=>this.requestUpdate())),this.listenTo(this.model,"vcard:change",(()=>this.requestUpdate())),this.user_settings=await Zl.api.user.settings.getModel(),this.listenTo(this.user_settings,"change:mucs_with_hidden_subject",(()=>this.requestUpdate())),await this.model.initialized,this.listenTo(this.model.features,"change:open",(()=>this.requestUpdate())),this.model.occupants.forEach((e=>this.onOccupantAdded(e))),this.listenTo(this.model.occupants,"add",this.onOccupantAdded),this.listenTo(this.model.occupants,"change:affiliation",this.onOccupantAffiliationChanged),this.requestUpdate()}render(){return this.model&&this.user_settings?(e=>{const t=e.model.toJSON(),n=e.user_settings?.get("mucs_with_hidden_subject",[])?.includes(e.model.get("jid")),s=e.getHeadingButtons(n),i=ib("Hide the groupchat topic"),r=ib("This groupchat is bookmarked"),o=t.subject?t.subject.text:"",a=o&&!n,c=e.model.vcard?.get("image");return bm`
    ${c&&c!==Zl.DEFAULT_IMAGE?bm``:""}
    ${Zl.api.settings.get("singleton")?"":bm``}
    ${e.model.getDisplayName()} ${t.bookmarked?bm``:""}
    ${WS(mA(s),"")} ${WS(gA(s),"")}
    ${a?bm`

    `:""}`})(this):""}onOccupantAdded(e){e.get("jid")===Zl.bare_jid&&this.requestUpdate()}onOccupantAffiliationChanged(e){e.get("jid")===Zl.bare_jid&&this.requestUpdate()}showRoomDetailsModal(e){e.preventDefault(),wd.modal.show("converse-muc-details-modal",{model:this.model},e)}showInviteModal(e){e.preventDefault(),wd.modal.show("converse-muc-invite-modal",{model:new dr,chatroomview:this},e)}toggleTopic(e){e?.preventDefault?.(),this.model.toggleSubjectHiddenState()}getAndRenderConfigurationForm(){this.model.session.set("view",Fm.MUC.VIEWS.CONFIG)}close(e){e.preventDefault(),this.model.close()}destroy(e){e.preventDefault(),ax(this.model)}getHeadingButtons(e){const t=[];t.push({i18n_text:ib("Details"),i18n_title:ib("Show more information about this groupchat"),handler:e=>this.showRoomDetailsModal(e),a_class:"show-muc-details-modal",icon_class:"fa-info-circle",name:"details"}),"owner"===this.model.getOwnAffiliation()&&t.push({i18n_text:ib("Configure"),i18n_title:ib("Configure this groupchat"),handler:()=>this.getAndRenderConfigurationForm(),a_class:"configure-chatroom-button",icon_class:"fa-wrench",name:"configure"}),t.push({i18n_text:ib("Nickname"),i18n_title:ib("Change the nickname you're using in this groupchat"),handler:e=>wd.modal.show("converse-muc-nickname-modal",{model:this.model},e),a_class:"open-nickname-modal",icon_class:"fa-smile",name:"nickname"}),this.model.invitesAllowed()&&t.push({i18n_text:ib("Invite"),i18n_title:ib("Invite someone to join this groupchat"),handler:e=>this.showInviteModal(e),a_class:"open-invite-modal",icon_class:"fa-user-plus",name:"invite"});const n=this.model.get("subject");n&&n.text&&t.push({i18n_text:ib(e?"Show topic":"Hide topic"),i18n_title:ib(e?"Show the topic message in the heading":"Hide the topic in the heading"),handler:e=>this.toggleTopic(e),a_class:"hide-topic",icon_class:"fa-minus-square",name:"toggle-topic"});if(this.model.session.get("connection_status")===Fm.ROOMSTATUS.ENTERED){const e=this.model.getAllowedCommands();e.includes("modtools")&&t.push({i18n_text:ib("Moderate"),i18n_title:ib("Moderate this groupchat"),handler:()=>mx(this.model),a_class:"moderate-chatroom-button",icon_class:"fa-user-cog",name:"moderate"}),e.includes("destroy")&&t.push({i18n_text:ib("Destroy"),i18n_title:ib("Remove this groupchat"),handler:e=>this.destroy(e),a_class:"destroy-chatroom-button",icon_class:"fa-trash",name:"destroy"})}wd.settings.get("singleton")||t.push({i18n_text:ib("Leave"),i18n_title:ib("Leave and close this groupchat"),handler:async e=>{e.stopPropagation();const t=[ib("Are you sure you want to leave this groupchat?")];await wd.confirm(ib("Confirm"),t)&&this.close(e)},a_class:"close-chatbox-button",standalone:"overlayed"===wd.settings.get("view_mode"),icon_class:"fa-sign-out-alt",name:"signout"});const s=Zl.chatboxviews.get(this.getAttribute("jid"));return s?Zl.api.hook("getHeadingButtons",s,t):Promise.resolve(t)}});class rC extends ob{static get properties(){return{jid:{type:String}}}connectedCallback(){super.connectedCallback(),this.model=Zl.chatboxes.get(this.jid),this.listenTo(this.model,"change:password_validation_message",this.render),this.render()}render(){return(e=>{const t=ib("This groupchat requires a password"),n=ib("Password: "),s=ib("Submit");return bm`

    ${e.validation_message}

    `})({jid:this.model.get("jid"),submitPassword:e=>this.submitPassword(e),validation_message:this.model.get("password_validation_message")})}submitPassword(e){e.preventDefault();const t=this.querySelector("input[type=password]").value;this.model.join(this.model.get("nick"),t),this.model.set("password_validation_message",null)}}wd.elements.define("converse-muc-password-form",rC);class oC extends ME{length=300;is_chatroom=!0;async initialize(){this.model=await wd.rooms.get(this.jid),Zl.chatboxviews.add(this.jid,this),this.setAttribute("id",this.model.get("box_id")),this.listenTo(Zl,"windowStateChanged",this.onWindowStateChanged),this.listenTo(this.model,"change:composing_spoiler",this.requestUpdateMessageForm),this.listenTo(this.model.session,"change:connection_status",this.onConnectionStatusChanged),this.listenTo(this.model.session,"change:view",(()=>this.requestUpdate())),this.onConnectionStatusChanged(),this.model.maybeShow(),wd.trigger("chatRoomViewInitialized",this)}render(){return(e=>bm`
    ${e.model?bm`
    ${cx(e)}
    `:""}
    `)({model:this.model})}onConnectionStatusChanged(){this.model.session.get("connection_status")===Fm.ROOMSTATUS.CONNECTING&&(this.model.session.save({disconnection_actor:void 0,disconnection_message:void 0,disconnection_reason:void 0}),this.model.save({moved_jid:void 0,password_validation_message:void 0,reason:void 0})),this.requestUpdate()}}wd.elements.define("converse-muc",oC);var aC=n(2832),cC={};cC.styleTagTransform=_b(),cC.setAttributes=fb(),cC.insert=mb().bind(null,"head"),cC.domAPI=ub(),cC.insertStyleElement=vb();lb()(aC.Z,cC);aC.Z&&aC.Z.locals&&aC.Z.locals;const{Strophe:lC}=Fm.env;Fm.MUC.VIEWS={CONFIG:"config-form"},Fm.plugins.add("converse-muc-views",{dependencies:["converse-modal","converse-controlbox","converse-chatview"],initialize(){const{_converse:e}=this;wd.settings.extend({auto_list_rooms:!1,cache_muc_messages:!0,locked_muc_nickname:!1,modtools_disable_query:[],muc_disable_slash_commands:!1,muc_mention_autocomplete_filter:"contains",muc_mention_autocomplete_min_chars:0,muc_mention_autocomplete_show_avatar:!0,muc_roomid_policy:null,muc_roomid_policy_hint:null,roomconfig_whitelist:[],show_retraction_warning:!0,visible_toolbar_buttons:{toggle_occupants:!0}}),e.ChatRoomView=oC,wd.settings.get("muc_domain")||wd.listen.on("serviceDiscovered",(async e=>{if(e?.get("var")===lC.NS.MUC){if(e.entity.get("jid").includes("@"))return;await e.entity.getIdentity("conference","text")&&wd.settings.set("muc_domain",lC.getDomainFromJid(e.get("from")))}})),wd.listen.on("clearsession",(()=>{const t=e.chatboxviews.get("controlbox");t&&t.roomspanel&&(t.roomspanel.model.destroy(),t.roomspanel.remove(),delete t.roomspanel)})),wd.listen.on("chatBoxClosed",(t=>{var n;t.get("type")===e.CHATROOMS_TYPE&&(n=t.get("jid"),Zl.router.history.getFragment()===`converse/room?jid=${n}`&&Zl.router.navigate(""))})),wd.listen.on("parseMessageForCommands",gx),wd.listen.on("confirmDirectMUCInvitation",ox)}});const dC=dr.extend({defaults:{collapsed:!1}});wd.elements.define("converse-minimized-chats",class extends ob{async initialize(){this.model=Zl.chatboxes,await this.initToggle(),this.listenTo(this.minchats,"change:collapsed",(()=>this.requestUpdate())),this.listenTo(this.model,"add",(()=>this.requestUpdate())),this.listenTo(this.model,"change:fullname",(()=>this.requestUpdate())),this.listenTo(this.model,"change:jid",(()=>this.requestUpdate())),this.listenTo(this.model,"change:minimized",(()=>this.requestUpdate())),this.listenTo(this.model,"change:name",(()=>this.requestUpdate())),this.listenTo(this.model,"change:num_unread",(()=>this.requestUpdate())),this.listenTo(this.model,"remove",(()=>this.requestUpdate())),this.listenTo(Zl,"connected",(()=>this.requestUpdate())),this.listenTo(Zl,"reconnected",(()=>this.requestUpdate())),this.listenTo(Zl,"disconnected",(()=>this.requestUpdate()))}render(){const e=this.model.where({minimized:!0}),t=e.reduce(((e,t)=>e+t.get("num_unread")),0),n=e.reduce(((e,t)=>e+(t.get("minimized")?1:0)),0),s={chats:e,num_unread:t,num_minimized:n,collapsed:this.minchats.get("collapsed")};return s.toggle=e=>this.toggle(e),(e=>bm``)(s)}async initToggle(){const e=`converse.minchatstoggle-${Zl.bare_jid}`;this.minchats=new dC({id:e}),Gc(this.minchats,e,"session"),await new Promise((e=>this.minchats.fetch({success:e,error:e})))}toggle(e){e?.preventDefault(),this.minchats.save({collapsed:!this.minchats.get("collapsed")})}});const{dayjs:uC,u:hC}=Fm.env;function mC(e){if("controlbox"===e.model.get("id")){if(hC.isVisible(e))return hC.getOuterWidth(e,!0);{const e=document.querySelector("converse-controlbox-toggle");return e?hC.getOuterWidth(e,!0):0}}return!e.model.get("minimized")&&hC.isVisible(e)?hC.getOuterWidth(e,!0):0}function gC(){const e=document.querySelector("converse-minimized-chats");return Zl.chatboxes.pluck("minimized").includes(!0)?hC.getOuterWidth(e,!0):0}function fC(e){const t=e?e.model.get("id"):null,n=e?hC.getOuterWidth(e,!0):0;return Object.values(Zl.chatboxviews.xget(t)).reduce(((e,t)=>e+mC(t)),n)}function pC(e){if(Zl.isTestEnv()||wd.settings.get("no_trimming")||"overlayed"!==wd.settings.get("view_mode"))return;const t=Zl.chatboxviews.filter((e=>!e.model.get("minimized")&&!e.model.get("closed")&&hC.isVisible(e)));if(t.length<=1)return;const n=hC.getOuterWidth(document.querySelector("body"),!0);if(mC(t[0])===n)return;if(document.querySelector("converse-minimized-chats"))for(;gC()+fC(e)>n;){const t=vC([e?e.model.get("id"):null]);if(!t)break;{const e=Zl.chatboxes.get(t.get("id"));e?.save("hidden",!0),_C(t)}}}function vC(e){e.push("controlbox");let t=0,n=Zl.chatboxes.sort().at(t);for(;e.includes(n.get("id"))||!0===n.get("minimized");)if(t++,n=Zl.chatboxes.at(t),!n)return null;return n}function yC(e,t){e?.preventDefault?e.preventDefault():t=e,hC.safeSave(t,{hidden:!1,minimized:!1,time_opened:(new Date).getTime()})}function _C(e,t){e?.preventDefault?e.preventDefault():t=e,t.setChatState(Zl.INACTIVE),hC.safeSave(t,{hidden:!0,minimized:!0,time_minimized:(new Date).toISOString()})}function bC(e){e.get("minimized")?function(e){wd.trigger("chatBoxMinimized",e)}(e):function(e){e.isScrolledUp()||e.clearUnreadMsgCounter(),e.setChatState(Zl.ACTIVE),wd.trigger("chatBoxMaximized",e)}(e)}wd.elements.define("converse-minimized-chat",class extends ob{static get properties(){return{model:{type:Object},title:{type:String},type:{type:String},num_unread:{type:Number}}}render(){return(e=>{const t=ib("Click to restore this chat");let n;return n="chatroom"===e.type?"var(--chatroom-head-color)":"headline"===e.type?"var(--headlines-head-text-color)":"var(--chat-head-text-color)",bm``})({close:e=>this.close(e),num_unread:this.num_unread,restore:e=>this.restore(e),title:this.title,type:this.type})}close(e){e?.preventDefault(),this.model.close()}restore(e){e?.preventDefault(),yC(this.model)}});var wC=n(4540),SC={};SC.styleTagTransform=_b(),SC.setAttributes=fb(),SC.insert=mb().bind(null,"head"),SC.domAPI=ub(),SC.insertStyleElement=vb();lb()(wC.Z,SC);wC.Z&&wC.Z.locals&&wC.Z.locals;Fm.plugins.add("converse-minimize",{dependencies:["converse-chatview","converse-controlbox","converse-muc-views","converse-headlines-view","converse-dragresize"],enabled:e=>"overlayed"===e.api.settings.get("view_mode"),overrides:{ChatBox:{maybeShow(e){return!e&&this.get("minimized")?this:this.__super__.maybeShow.apply(this,arguments)},isHidden(){return this.__super__.isHidden.call(this)||this.get("minimized")}},ChatBoxView:{isNewMessageHidden(){return this.model.get("minimized")||this.__super__.isNewMessageHidden.apply(this,arguments)},setChatBoxHeight(e){if(!this.model.get("minimized"))return this.__super__.setChatBoxHeight.call(this,e)},setChatBoxWidth(e){if(!this.model.get("minimized"))return this.__super__.setChatBoxWidth.call(this,e)}}},initialize(){function e(e){!function(e){e.on("change:hidden",(t=>!t.get("hidden")&&yC(e)),e),"controlbox"!==e.get("id")&&e.save({minimized:e.get("minimized")||!1,time_minimized:e.get("time_minimized")||uC()})}(e),e.on("change:minimized",(()=>bC(e)))}wd.settings.extend({no_trimming:!1}),wd.promises.add("minimizedChatsInitialized"),Zl.MinimizedChatsToggle=dC,Zl.minimize={trimChats:pC,minimize:_C,maximize:yC},wd.listen.on("chatBoxViewInitialized",(e=>Zl.minimize.trimChats(e))),wd.listen.on("chatRoomViewInitialized",(e=>Zl.minimize.trimChats(e))),wd.listen.on("controlBoxOpened",(e=>Zl.minimize.trimChats(e))),wd.listen.on("chatBoxInitialized",e),wd.listen.on("chatRoomInitialized",e),wd.listen.on("getHeadingButtons",((e,t)=>e.model.get("type")===Zl.CHATROOMS_TYPE?function(e,t){const n={a_class:"toggle-chatbox-button",handler:t=>_C(t,e.model),i18n_text:ib("Minimize"),i18n_title:ib("Minimize this groupchat"),icon_class:"fa-minus",name:"minimize",standalone:"overlayed"===Zl.api.settings.get("view_mode")},s=t.map((e=>e.name)),i=s.indexOf("signout");return i>-1?[...t.slice(0,i),n,...t.slice(i)]:[n,...t]}(e,t):function(e,t){const n={a_class:"toggle-chatbox-button",handler:t=>_C(t,e.model),i18n_text:ib("Minimize"),i18n_title:ib("Minimize this chat"),icon_class:"fa-minus",name:"minimize",standalone:"overlayed"===Zl.api.settings.get("view_mode")},s=t.map((e=>e.name)),i=s.indexOf("close");return i>-1?[...t.slice(0,i),n,...t.slice(i)]:[n,...t]}(e,t)));const t=rd((()=>Zl.minimize.trimChats()),250);wd.listen.on("registeredGlobalEventHandlers",(()=>window.addEventListener("resize",t))),wd.listen.on("unregisteredGlobalEventHandlers",(()=>window.removeEventListener("resize",t)))}});var xC=n(7090),AC=n.n(xC);const{Strophe:EC}=Fm.env,$C="Notification"in window;let CC;function kC(e){return Zl.isTestEnv()||(Zl.chatboxes.get(e.from)?.isHidden()??!1)}function jC(){return Zl.isTestEnv()||$C&&wd.settings.get("show_desktop_notifications")&&"granted"===Notification.permission}function TC(){CC=null,navigator.clearAppBadge?.().catch((e=>$l.error("Could not clear unread count in app badge "+e)))}function IC(){if(wd.settings.get("show_tab_notifications")){CC=CC??new Fm.env.Favico({type:"circle",animation:"pop"});const e=Zl.chatboxes.models.reduce(((e,t)=>e+(t.get("num_unread")||0)),0);CC.badge(e),navigator.setAppBadge?.(e).catch((e=>$l.error("Could set unread count in app badge - "+e)))}}function NC(e,t,n){return e.reduce(((e,s)=>e||(e=>[Zl.bare_jid,`${t}/${n}`].includes(e.uri.replace(/^xmpp:/,"")))(s)),!1)}function MC(e){const{attrs:t}=e;if(!t||t.is_forwarded)return!1;if("groupchat"===t.type)return async function(e){if(!e?.body&&!e?.message)return!1;const t=e.from,n=e.from_muc,s=wd.settings.get("notify_all_room_messages"),i=Zl.chatboxes.get(n),r=EC.getResourceFromJid(t),o=r&&EC.unescapeNode(r)||"";let a=!1;const c=i.get("nick");wd.settings.get("notify_nicknames_without_references")&&(a=new RegExp(`\\b${c}\\b`).test(e.body));const l=o!==c,d=!0===s||Array.isArray(s)&&s.includes(n)||NC(e.references,n,c)||a;if(l&&d)return await wd.hook("shouldNotifyOfGroupMessage",e,!0);return!1}(t);if("info"===t.type)return async function(e){if(!e.from_muc)return!1;const t=await wd.rooms.get(e.from_muc);if(!t)return!1;const n=t.get("nick"),s=e.from_muc,i=wd.settings.get("notify_all_room_messages");return!0===i||Array.isArray(i)&&i.includes(s)||NC(e.references,s,n)}(t);if(t.is_headline)return kC(t);const n=EC.getBareJidFromJid(t.from)===Zl.bare_jid;return!ol(t)&&!n&&("all"===wd.settings.get("show_desktop_notifications")||kC(t))}async function OC(e){if(!await MC(e))return!1;wd.trigger("messageNotification",e),function(){if(wd.settings.get("play_sounds")&&void 0!==window.Audio){const e=new Audio(wd.settings.get("sounds_path")+"msg_received.ogg"),t=e.canPlayType("audio/ogg");if("probably"===t)return e.play();const n=new Audio(wd.settings.get("sounds_path")+"msg_received.mp3"),s=n.canPlayType("audio/mp3");"probably"===s?n.play():"maybe"===t?e.play():"maybe"===s&&n.play()}}(),function(e){const{attrs:t}=e;if(t.is_error)return;if(!jC())return;let n,s;const i=t.from,r=EC.getBareJidFromJid(i);if("info"==t.type)n=t.message;else if("headline"===t.type){if(r.includes("@")&&!wd.settings.get("allow_non_roster_messaging"))return;n=ib("Notification from %1$s",r)}else if(r.includes("@"))if("groupchat"===t.type)n=ib("%1$s says",EC.getResourceFromJid(i));else{if(void 0===Zl.roster)return void $l.error("Could not send notification, because roster is undefined");if(s=Zl.roster.get(r),void 0!==s)n=ib("%1$s says",s.getDisplayName());else{if(!wd.settings.get("allow_non_roster_messaging"))return;n=ib("%1$s says",r)}}else n=ib("Notification from %1$s",r);let o;if("info"==t.type)o=t.reason;else if(o=t.is_encrypted?t.plaintext:t.body,!o)return;const a=new Notification(n,{body:o,lang:Zl.locale,icon:wd.settings.get("notification_icon"),requireInteraction:!wd.settings.get("notification_delay")});wd.settings.get("notification_delay")&&setTimeout((()=>a.close()),wd.settings.get("notification_delay")),a.onclick=function(e){e.preventDefault(),window.focus(),Zl.chatboxes.get(r).maybeShow(!0)}}(e)}function RC(e){jC()&&function(e){if("error"===e.klass||"warn"===e.klass){const t=new Notification(e.subject,{body:e.message,lang:Zl.locale,icon:wd.settings.get("notification_icon")});setTimeout(t.close.bind(t),5e3)}}(e)}function DC(e){jC()&&wd.settings.get("show_chat_state_notifications")&&function(e){if(wd.settings.get("chatstate_notification_blacklist")?.includes(e.jid))return;const t=e.presence.get("show");let n=null;if("offline"===t?n=ib("has gone offline"):"away"===t?n=ib("has gone away"):"dnd"===t?n=ib("is busy"):"online"===t&&(n=ib("has come online")),null===n)return;const s=new Notification(e.getDisplayName(),{body:n,lang:Zl.locale,icon:wd.settings.get("notification_icon")});setTimeout((()=>s.close()),5e3)}(e)}function zC(e){jC()&&function(e){const t=new Notification(e.getDisplayName(),{body:ib("wants to be your contact"),lang:Zl.locale,icon:wd.settings.get("notification_icon")});setTimeout((()=>t.close()),5e3)}(e)}function PC(){$C&&!["denied","granted"].includes(Notification.permission)&&Notification.requestPermission()}Fm.env.Favico=AC(),Fm.plugins.add("converse-notification",{dependencies:["converse-chatboxes"],initialize(){wd.settings.extend({chatstate_notification_blacklist:[],notification_delay:5e3,notification_icon:"/images/logo/conversejs-filled.svg",notify_all_room_messages:!1,notify_nicknames_without_references:!1,play_sounds:!0,show_chat_state_notifications:!1,show_desktop_notifications:!0,show_tab_notifications:!0,sounds_path:wd.settings.get("assets_path")+"/sounds/"}),wd.listen.on("clearSession",TC),wd.waitUntil("chatBoxesInitialized").then((()=>Zl.chatboxes.on("change:num_unread",IC))),wd.listen.on("pluginsInitialized",(function(){wd.listen.on("contactRequest",zC),wd.listen.on("contactPresenceChanged",DC),wd.listen.on("message",OC),wd.listen.on("feedback",RC),wd.listen.on("connected",PC)}))}});const LC=Fm.env.utils;class FC extends tS{initialize(){super.initialize(),this.render(),this.addEventListener("shown.bs.modal",(()=>{this.querySelector('input[name="status_message"]').focus()}),!1)}renderModal(){return(e=>{const t=ib("Away"),n=ib("Busy"),s=ib("Online"),i=ib("Save"),r=ib("Away for long"),o=ib("Personal status message"),a=e.model.get("status"),c=e.model.get("status_message");return bm`
    `})(this)}getModalTitle(){return ib("Change chat status")}clearStatusMessage(e){e&&e.preventDefault&&(e.preventDefault(),LC.hideElement(this.querySelector(".clear-input")));this.querySelector('input[name="status_message"]').value=""}onFormSubmitted(e){e.preventDefault();const t=new FormData(e.target);this.model.save({status_message:t.get("status_message"),status:t.get("chat_status")}),this.modal.hide()}}Zl.ChatStatusModal=FC,wd.elements.define("converse-chat-status-modal",FC);const UC=ib("Your profile picture");wd.elements.define("converse-image-picker",class extends ob{static get properties(){return{height:{type:Number},data:{type:Object},width:{type:Number}}}render(){return bm``}openFileSelection(e){e.preventDefault(),this.querySelector('input[type="file"]').click()}updateFilePreview(e){const t=e.target.files[0],n=new FileReader;n.onloadend=()=>{this.data={data_uri:n.result,image_type:t.type}},n.readAsDataURL(t)}});const BC=e=>{const t={...e.model.toJSON(),...e.model.vcard.toJSON()},n=ib("Email"),s=ib("Full Name"),i=ib("XMPP Address"),r=ib("Nickname"),o=ib("Role"),a=ib("Save and close"),c=ib("Use commas to separate multiple roles. Your roles are shown next to your name on your chat messages."),l=ib("URL"),d=ib("OMEMO"),u=ib("Profile"),h=ib("Reset Password"),m=[bm``];return m.push(bm``),Zl.pluggable.plugins["converse-omemo"]?.enabled(Zl)&&m.push(bm``),bm`
    ${t.jid}
    ${c}

    ${"passwordreset"===e.tab?bm``:""}
    ${Zl.pluggable.plugins["converse-omemo"]?.enabled(Zl)?(e=>bm`
    ${"omemo"===e.tab?bm``:""}
    `)(e):""}
    `};var qC=n(7340),HC=n.n(qC);const{Strophe:GC,$iq:WC,sizzle:VC,u:ZC}=Fm.env;wd.elements.define("converse-change-password-form",class extends ob{static get properties(){return{passwords_mismatched:{type:Boolean},alert_message:{type:String}}}initialize(){this.passwords_mismatched=!1,this.alert_message=""}render(){return(e=>{const t=ib("Submit"),n=ib("The new passwords must match"),s=ib("New password"),i=ib("Confirm new password");return bm`
    ${e.alert_message?bm``:""}
    ${e.passwords_mismatched?bm`${n}`:""}
    `})(this)}checkPasswordsMatch(e){const t=new FormData(e.target.form??e.target),n=t.get("password"),s=t.get("password_check");return this.passwords_mismatched=n&&n!==s,this.passwords_mismatched}async onSubmit(e){if(e.preventDefault(),this.checkPasswordsMatch(e))return;const t=WC({type:"get",to:Zl.domain}).c("query",{xmlns:GC.NS.REGISTER}),n=await wd.sendIQ(t);if(null===n)return void(this.alert_message=ib("Timeout error"));if(VC(`error service-unavailable[xmlns="${GC.NS.STANZAS}"]`,n).length)return void(this.alert_message=ib("Your server does not support in-band password reset"));if(ZC.isErrorStanza(n))return this.alert_message=ib("Your server responded with an unknown error, check the console for details"),$l.error("Could not set password"),void $l.error(n);const s=n.querySelector("username").textContent,i=new FormData(e.target).get("password"),r=WC({type:"set",to:Zl.domain}).c("query",{xmlns:GC.NS.REGISTER}).c("username",{},s).c("password",{},i),o=await wd.sendIQ(r);null===o?this.alert_message=ib("Timeout error while trying to set your password"):VC(`error not-allowed[xmlns="${GC.NS.STANZAS}"]`,o).length?this.alert_message=ib("Your server does not allow in-band password reset"):VC(`error forbidden[xmlns="${GC.NS.STANZAS}"]`,o).length||ZC.isErrorStanza(o)?this.alert_message=ib("You are not allowed to change your password"):wd.alert("info",ib("Success"),[ib("Your new password has been set")])}});const QC=new(HC())({targetSize:.1,quality:.75,maxWidth:256,maxHeight:256});wd.elements.define("converse-profile-modal",class extends tS{constructor(e){super(e),this.tab="profile"}initialize(){super.initialize(),this.listenTo(this.model,"change",this.render),wd.trigger("profileModalInitialized",this.model)}renderModal(){return BC(this)}getModalTitle(){return ib("Your Profile")}async setVCard(e){try{await wd.vcard.set(Zl.bare_jid,e)}catch(e){return $l.fatal(e),void this.alert([ib("Sorry, an error happened while trying to save your profile data."),ib("You can check your browser's developer console for any error output.")].join(" "))}this.modal.hide()}onFormSubmitted(e){e.preventDefault();const t=new FileReader,n=new FormData(e.target),s=n.get("image"),i={fn:n.get("fn"),nickname:n.get("nickname"),role:n.get("role"),email:n.get("email"),url:n.get("url")};if(s.size){const e=[s];QC.compress(e).then((e=>{const{photo:n}=e[0];t.onloadend=()=>{Object.assign(i,{image:btoa(t.result),image_type:s.type}),this.setVCard(i)},t.readAsBinaryString(n.data)}))}else Object.assign(i,{image:this.model.vcard.get("image"),image_type:this.model.vcard.get("image_type")}),this.setVCard(i)}});const JC=e=>{const t=ib("%1$s Open Source %2$s XMPP chat client brought to you by %3$s Opkode %2$s",'',"",''),n=ib("%1$s Translate %2$s it into your own language",'',""),s=wd.settings.get("show_client_info"),i=wd.settings.get("allow_adhoc_commands");return bm`${s&&i?(e=>{const t=ib("About"),n=ib("Commands");return bm``})(e):""}
    ${s?bm`

    Converse

    ${Zl.VERSION_NAME}

    ${lE(Qo().sanitize(t))}

    ${lE(Qo().sanitize(n))}

    `:""} ${i?bm`
    `:""}
    `};wd.elements.define("converse-user-settings-modal",class extends tS{constructor(e){super(e);const t=wd.settings.get("show_client_info"),n=wd.settings.get("allow_adhoc_commands");t&&n||t?this.tab="about":n&&(this.tab="commands")}renderModal(){return JC(this)}getModalTitle(){return ib("Settings")}});const{Strophe:KC,$iq:YC,sizzle:XC,u:ek}=Fm.env;async function tk(e){e?.preventDefault();await wd.confirm(ib("Are you sure you want to log out?"))&&wd.user.logout()}function nk(){const e=ib("Log out");return bm``}const sk=e=>{const t=e.model.get("status")||"offline",n=e.model.get("status_message")||ib("I am %1$s","chat"===(s=t)?ib("online"):"dnd"===s?ib("busy"):"xa"===s?ib("away for long"):"away"===s?ib("away"):"offline"===s?ib("offline"):ib(s)||ib("online"));var s;const i=ib("Click to change your chat status"),r=wd.settings.get("show_client_info")||wd.settings.get("allow_adhoc_commands");let o,a;return[o,a]="online"===t?["fa fa-circle chat-status","chat-status-online"]:"dnd"===t?["fa fa-minus-circle chat-status","chat-status-busy"]:"away"===t?["fa fa-circle chat-status","chat-status-away"]:["fa fa-circle chat-status","subdued-color"],bm`
    ${e.model.getDisplayName()} ${r?function(e){const t=ib("Show details about this chat client");return bm``}(e):""} ${wd.settings.get("allow_logout")?nk():""}
    `};wd.elements.define("converse-user-profile",class extends ob{initialize(){this.model=Zl.xmppstatus,this.listenTo(this.model,"change",(()=>this.requestUpdate())),this.listenTo(this.model,"vcard:add",(()=>this.requestUpdate())),this.listenTo(this.model,"vcard:change",(()=>this.requestUpdate()))}render(){return sk(this)}showProfileModal(e){e?.preventDefault(),wd.modal.show("converse-profile-modal",{model:this.model},e)}showStatusChangeModal(e){e?.preventDefault(),wd.modal.show("converse-chat-status-modal",{model:this.model},e)}showUserSettingsModal(e){e?.preventDefault(),wd.modal.show("converse-user-settings-modal",{model:this.model,_converse:Zl},e)}}),Fm.plugins.add("converse-profile",{dependencies:["converse-status","converse-modal","converse-vcard","converse-chatboxviews","converse-adhoc-views"],initialize(){wd.settings.extend({show_client_info:!0})}});const ik=function(){var e=arguments.length;if(!e)return[];for(var t=Array(e-1),n=arguments[0],s=e;s--;)t[s-1]=arguments[s];return cs(Z(n)?ts(n):[n],tr(t,1))},rk={name:"AES-GCM",length:128},ok={aac:"audio/aac",abw:"application/x-abiword",arc:"application/x-freearc",avi:"video/x-msvideo",azw:"application/vnd.amazon.ebook",bin:"application/octet-stream",bmp:"image/bmp",bz:"application/x-bzip",bz2:"application/x-bzip2",cda:"application/x-cdf",csh:"application/x-csh",css:"text/css",csv:"text/csv",doc:"application/msword",docx:"application/vnd.openxmlformats-officedocument.wordprocessingml.document",eot:"application/vnd.ms-fontobject",epub:"application/epub+zip",gif:"image/gif",gz:"application/gzip",htm:"text/html",html:"text/html",ico:"image/vnd.microsoft.icon",ics:"text/calendar",jar:"application/java-archive",jpeg:"image/jpeg",jpg:"image/jpeg",js:"text/javascript",json:"application/json",jsonld:"application/ld+json",m4a:"audio/mp4",mid:"audio/midi",midi:"audio/midi",mjs:"text/javascript",mp3:"audio/mpeg",mp4:"video/mp4",mpeg:"video/mpeg",mpkg:"application/vnd.apple.installer+xml",odp:"application/vnd.oasis.opendocument.presentation",ods:"application/vnd.oasis.opendocument.spreadsheet",odt:"application/vnd.oasis.opendocument.text",oga:"audio/ogg",ogv:"video/ogg",ogx:"application/ogg",opus:"audio/opus",otf:"font/otf",png:"image/png",pdf:"application/pdf",php:"application/x-httpd-php",ppt:"application/vnd.ms-powerpoint",pptx:"application/vnd.openxmlformats-officedocument.presentationml.presentation",rar:"application/vnd.rar",rtf:"application/rtf",sh:"application/x-sh",svg:"image/svg+xml",swf:"application/x-shockwave-flash",tar:"application/x-tar",tif:"image/tiff",tiff:"image/tiff",ts:"video/mp2t",ttf:"font/ttf",txt:"text/plain",vsd:"application/vnd.visio",wav:"audio/wav",weba:"audio/webm",webm:"video/webm",webp:"image/webp",woff:"font/woff",woff2:"font/woff2",xhtml:"application/xhtml+xml",xls:"application/vnd.ms-excel",xlsx:"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",xml:"text/xml",xul:"application/vnd.mozilla.xul+xml",zip:"application/zip","3gp":"video/3gpp","3g2":"video/3gpp2","7z":"application/x-7z-compressed"},{Strophe:ak,URI:ck,sizzle:lk,u:dk}=Fm.env;function uk(e){e=e.replace(/^05/,"");for(let t=1;t<8;t++){const n=8*t+t-1;e=e.slice(0,n)+" "+e.slice(n)}return e}function hk(e,t){return e.get("omemo_active")&&t.body&&(t.is_encrypted=!0,t.plaintext=t.body,t.body=ib("This is an OMEMO encrypted message which your client doesn’t seem to support. Find more information on https://conversations.im/omemo")),t}async function mk(e){const t="localhost"===window.location.hostname&&"localhost"===e.domain()?"http":"https",n=e.toString().replace(/^aesgcm/,t),s=await async function(e){let t;try{t=await fetch(e)}catch(t){return $l.error(`${t.name}: Failed to download encrypted media: ${e}`),$l.error(t),null}if(t.status>=200&&t.status<400)return t.arrayBuffer()}(n);if(null===s)return $l.error(`Could not decrypt a received encrypted file ${e.toString()} since it could not be downloaded`),new Error(ib("Error: could not decrypt a received encrypted file, because it could not be downloaded"));const i=e.hash().slice(1),r=i.substring(i.length-64),o=i.replace(r,"");let a;try{a=await async function(e,t,n){const s=await crypto.subtle.importKey("raw",lv(t),"AES-GCM",!1,["decrypt"]),i={name:"AES-GCM",iv:lv(e)};return crypto.subtle.decrypt(i,s,n)}(o,r,s)}catch(t){return $l.error(`Could not decrypt file ${e.toString()}`),$l.error(t),null}const[c,l]=e.filename().split("."),d=ok[l];try{const e=new File([a],c,{type:d});return URL.createObjectURL(e)}catch(t){return $l.error(`Could not decrypt file ${e.toString()}`),$l.error(t),null}}function gk(e,t,n){if(s=t,"[object Error]"===Object.prototype.toString.call(s))return bm`

    ${t.message}

    `;var s;const i=e.toString();return dg(i)?eA({src:t,onClick:n.onImgClick,onLoad:n.onImgLoad}):cg(i)?gw(t):lg(i)?Sw(t):fw(t,e.filename())}function fk(e){Zl.config.get("trusted")&&e.addAnnotations(((t,n)=>function(e,t,n){const s=[];try{const t={start:/\b(aesgcm:\/\/)/gi};ck.withinString(e,((e,t,n)=>(s.push({url:e,start:t,end:n}),e)),t)}catch(e){return void $l.debug(e)}s.forEach((s=>{const i=Xm(e.slice(s.start,s.end)),r=mk(i).then((e=>gk(i,e,n))),o=bm`${WS(r,"")}`;n.addTemplateResult(s.start+t,s.end+t,o)}))}(t,n,e)))}async function pk(e,t){if(wd.settings.get("clear_cache_on_logout")||!t.is_encrypted||t.encryption_namespace!==ak.NS.OMEMO)return t;const n=lk(`encrypted[xmlns="${ak.NS.OMEMO}"]`,e).pop(),s=n.querySelector("header");t.encrypted={device_id:s.getAttribute("sid")};const i=await(wd.omemo?.getDeviceID()),r=i&&lk(`key[rid="${i}"]`,n).pop();return r?(Object.assign(t.encrypted,{iv:s.querySelector("iv").textContent,key:r.textContent,payload:n.querySelector("payload")?.textContent||null,prekey:["true","1"].includes(r.getAttribute("prekey"))}),!0===t.encrypted.prekey?async function(e){const t=bk(e),n=_k(t,parseInt(e.encrypted.device_id,10)),s=cv(e.encrypted.key);let i;try{i=await n.decryptPreKeyWhisperMessage(s,"binary")}catch(t){return $l.error(`${t.name} ${t.message}`),Object.assign(e,Sk(t))}try{const t=await wk(e,i);return await Zl.omemo_store.generateMissingPreKeys(),await Zl.omemo_store.publishBundle(),t?Object.assign(e,{plaintext:t}):Object.assign(e,{is_only_key:!0})}catch(t){return $l.error(`${t.name} ${t.message}`),Object.assign(e,Sk(t))}}(t):async function(e){const t=bk(e),n=_k(t,parseInt(e.encrypted.device_id,10)),s=cv(e.encrypted.key);try{const t=await n.decryptWhisperMessage(s,"binary"),i=await wk(e,t);return Object.assign(e,{plaintext:i})}catch(t){return $l.error(`${t.name} ${t.message}`),Object.assign(e,Sk(t))}}(t)):Object.assign(t,{error_condition:"not-encrypted-for-this-device",error_type:"Decryption",is_ephemeral:!0,is_error:!0,type:"error"})}function vk(){Zl.chatboxes.on("add",(e=>{Tk(e),e.get("type")===Zl.CHATROOMS_TYPE&&(e.occupants.on("add",(t=>async function(e,t){if(t.isSelf()||!e.features.get("nonanonymous")||!e.features.get("membersonly"))return;if(e.get("omemo_active")){await Zl.contactHasOMEMOSupport(t.get("jid"))||(e.createMessage({message:ib("%1$s doesn't appear to have a client that supports OMEMO. Encrypted chat will no longer be possible in this grouchat.",t.get("nick")),type:"error"}),e.save({omemo_active:!1,omemo_supported:!1}))}}(e,t))),e.features.on("change",(()=>Tk(e))))}))}function yk(e){e.listenTo(e.model.messages,"add",(t=>{t.get("is_encrypted")&&!t.get("is_error")&&e.model.save("omemo_supported",!0)})),e.listenTo(e.model,"change:omemo_supported",(()=>{!e.model.get("omemo_supported")&&e.model.get("omemo_active")?e.model.set("omemo_active",!1):e.querySelector("converse-chat-toolbar")?.requestUpdate()})),e.listenTo(e.model,"change:omemo_active",(()=>{e.querySelector("converse-chat-toolbar").requestUpdate()}))}function _k(e,t){const n=new libsignal.SignalProtocolAddress(e,t);return new window.libsignal.SessionCipher(Zl.omemo_store,n)}function bk(e){const t=e.from_muc?e.from_real_jid:e.from;if(!t)throw Object.assign(e,{error_text:ib("Sorry, could not decrypt a received OMEMO message because we don't have the XMPP address for that user."),error_type:"Decryption",is_ephemeral:!0,is_error:!0,type:"error"}),new Error("Could not find JID to decrypt OMEMO message for");return t}async function wk(e,t){const n=bk(e),s=await wd.omemo.devicelists.get(n,!0),i=e.encrypted;let r=s.devices.get(i.device_id);if(r||(r=await s.devices.create({id:i.device_id,jid:n},{promise:!0})),i.payload){const e=t.slice(0,16),n=t.slice(16),s=await Ok.decryptMessage(Object.assign(i,{key:e,tag:n}));return r.save("active",!0),s}}function Sk(e){return{error_text:ib("Sorry, could not decrypt a received OMEMO message due to an error.")+` ${e.name} ${e.message}`,error_condition:e.name,error_message:e.message,error_type:"Decryption",is_ephemeral:!0,is_error:!0,type:"error"}}function xk(e){const t=e.querySelector("signedPreKeyPublic"),n=e.querySelector("signedPreKeySignature"),s=lk("prekeys > preKeyPublic",e).map((e=>({id:parseInt(e.getAttribute("preKeyId"),10),key:e.textContent})));return{identity_key:e.querySelector("identityKey").textContent.trim(),signed_prekey:{id:parseInt(t.getAttribute("signedPreKeyId"),10),public_key:t.textContent,signature:n.textContent},prekeys:s}}async function Ak(e){if(e.get("bundle")?.fingerprint)return;const t=await e.getBundle();t.fingerprint=iv(cv(t.identity_key)),e.save("bundle",t),e.trigger("change:bundle")}async function Ek(e){await wd.waitUntil("OMEMOInitialized");const t=await wd.omemo.devicelists.get(e,!0);return await t.fetchDevices(),t.devices}async function $k(e){if(!e.get("bundle"))return $l.error(`Could not build an OMEMO session for device ${e.get("id")} because we don't have its bundle`),null;const t=new libsignal.SignalProtocolAddress(e.get("jid"),e.get("id")),n=await Zl.omemo_store.loadSession(t.toString());if(n)return n;try{const t=await async function(e){const t=new libsignal.SignalProtocolAddress(e.get("jid"),e.get("id")),n=new libsignal.SessionBuilder(Zl.omemo_store,t),s=e.getRandomPreKey(),i=await e.getBundle();return n.processPreKey({registrationId:parseInt(e.get("id"),10),identityKey:cv(i.identity_key),signedPreKey:{keyId:i.signed_prekey.id,publicKey:cv(i.signed_prekey.public_key),signature:cv(i.signed_prekey.signature)},preKey:{keyId:s.id,publicKey:cv(s.key)}})}(e);return t}catch(t){return $l.error(`Could not build an OMEMO session for device ${e.get("id")}`),$l.error(t),null}}function Ck(){Zl.connection.addHandler((async e=>{try{lk(`event[xmlns="${ak.NS.PUBSUB}#event"]`,e).length&&(await wd.waitUntil("OMEMOInitialized"),await async function(e){const t=lk(`items[node="${ak.NS.OMEMO_DEVICELIST}"]`,e).pop();if(!t)return;const n=`item list[xmlns="${ak.NS.OMEMO}"] device`,s=lk(n,t).map((e=>e.getAttribute("id"))),i=e.getAttribute("from"),r=await wd.omemo.devicelists.get(i,!0),o=r.devices;Fd(o.pluck("id"),s).forEach((e=>{i===Zl.bare_jid&&e===Zl.omemo_store.get("device_id")||o.get(e).save("active",!1)})),s.forEach((e=>{const t=o.get(e);t?t.save("active",!0):o.create({id:e,jid:i})})),dk.isSameBareJID(i,Zl.bare_jid)&&r.publishCurrentDevice(s)}(e),await async function(e){const t=lk("items",e).pop();if(!t||!t.getAttribute("node").startsWith(ak.NS.OMEMO_BUNDLES))return;const n=t.getAttribute("node").split(":")[1],s=e.getAttribute("from"),i=lk("item > bundle",t).pop(),r=await wd.omemo.devicelists.get(s,!0);(r.devices.get(n)||r.devices.create({id:n,jid:s})).save({bundle:xk(i)})}(e))}catch(e){$l.error(e.message)}return!0}),null,"message","headline")}async function kk(){if(void 0===Zl.omemo_store){const e=`converse.omemosession-${Zl.bare_jid}`;Zl.omemo_store=new Zl.OMEMOStore({id:e}),Gc(Zl.omemo_store,e)}await Zl.omemo_store.fetchSession()}async function jk(e){if(!e)if(Zl.config.get("trusted")&&!wd.settings.get("clear_cache_on_logout")){try{await async function(){Zl.devicelists=new Zl.DeviceLists;const e=`converse.devicelists-${Zl.bare_jid}`;Gc(Zl.devicelists,e),await new Promise((e=>{Zl.devicelists.fetch({success:e,error:(t,n)=>{$l.error(n),e()}})})),await wd.omemo.devicelists.get(Zl.bare_jid,!0)}(),await kk(),await Zl.omemo_store.publishBundle()}catch(e){return $l.error("Could not initialize OMEMO support"),void $l.error(e)}wd.trigger("OMEMOInitialized")}else $l.warn("Not initializing OMEMO, since this browser is not trusted or clear_cache_on_logout is set to true")}async function Tk(e){let t;e.get("type")===Zl.CHATROOMS_TYPE?(await wd.waitUntil("OMEMOInitialized"),t=e.features.get("nonanonymous")&&e.features.get("membersonly")):e.get("type")===Zl.PRIVATE_CHAT_TYPE&&(t=await Zl.contactHasOMEMOSupport(e.get("jid"))),e.set("omemo_supported",t),t&&wd.settings.get("omemo_default")&&e.set("omemo_active",!0)}function Ik(e){e.stopPropagation(),e.preventDefault();const t=dk.ancestor(e.target,"converse-chat-toolbar");if(!t.model.get("omemo_supported")){let e;return e=t.model.get("type")===Zl.CHATROOMS_TYPE?[ib("Cannot use end-to-end encryption in this groupchat, either the groupchat has some anonymity or not all participants support OMEMO.")]:[ib("Cannot use end-to-end encryption because %1$s uses a client that doesn't support OMEMO.",t.model.contact.getDisplayName())],wd.alert("error",ib("Error"),e)}t.model.save({omemo_active:!t.model.get("omemo_active")})}function Nk(e,t){const n=e.model,s=n.get("type")===Zl.CHATROOMS_TYPE;let i,r;if(n.get("omemo_supported")){const e=ib("Messages are being sent in plaintext"),t=ib("Messages are sent encrypted");i=n.get("omemo_active")?t:e}else i=ib(s?"This groupchat needs to be members-only and non-anonymous in order to support OMEMO encrypted messages":"OMEMO encryption is not supported");return r=n.get("omemo_supported")?n.get("omemo_active")?s?"var(--muc-color)":"var(--chat-toolbar-btn-color)":"var(--error-color)":"var(--muc-toolbar-btn-disabled-color)",t.push(bm``),t}async function Mk(e,t){let{stanza:n}=t;const{message:s}=t;if(!s.get("is_encrypted"))return t;if(!s.get("body"))throw new Error("No message body to encrypt!");const i=await async function(e){const t=ib("Sorry, no devices found to which we can send an OMEMO encrypted message.");let n;if(e.get("type")===Zl.CHATROOMS_TYPE){const t=await Promise.all(e.occupants.map((e=>Ek(e.get("jid")))));n=t.reduce(((e,t)=>ik(e,t.models)),[])}else if(e.get("type")===Zl.PRIVATE_CHAT_TYPE){const s=await Ek(e.get("jid"));if(0===s.length){const e=new Error(t);throw e.user_facing=!0,e}const i=(await wd.omemo.devicelists.get(Zl.bare_jid)).devices;n=[...i.models,...s.models]}const s=Zl.omemo_store.get("device_id");n=n.filter((e=>e.get("id")!==s)),await Promise.all(n.map((e=>e.getBundle())));const i=n.filter((e=>e)).map((e=>$k(e)));if(await Promise.all(i),i.includes(null)&&(n=n.filter((e=>i[n.indexOf(e)])),0===n.length)){const e=new Error(t);throw e.user_facing=!0,e}return n}(e);n.c("encrypted",{xmlns:ak.NS.OMEMO}).c("header",{sid:Zl.omemo_store.get("device_id")});const{key_and_tag:r,iv:o,payload:a}=await Ok.encryptMessage(s.get("plaintext")),c=await Promise.all(i.filter((e=>-1!=e.get("trusted")&&e.get("active"))).map((e=>function(e,t){return _k(t.get("jid"),t.get("id")).encrypt(e).then((e=>({payload:e,device:t})))}(r,e))));return n=await function(e,t,n){for(const s in t)if(Object.prototype.hasOwnProperty.call(t,s)){const i=t[s].payload,r=t[s].device,o=3==parseInt(i.type,10);e.c("key",{rid:r.get("id")}).t(btoa(i.body)),o&&e.attrs({prekey:o}),e.up(),s==t.length-1&&e.c("iv").t(n).up().up()}return Promise.resolve(e)}(n,c,o),n.c("payload").t(a).up().up(),n.c("store",{xmlns:ak.NS.HINTS}).up(),n.c("encryption",{xmlns:ak.NS.EME,namespace:ak.NS.OMEMO}),{message:s,stanza:n}}const Ok={decryptMessage:async function(e){const t=await crypto.subtle.importKey("raw",e.key,rk,!0,["encrypt","decrypt"]),n=sv(cv(e.payload),e.tag),s={name:"AES-GCM",iv:cv(e.iv),tagLength:128};return rv(await crypto.subtle.decrypt(s,t,n))},encryptMessage:async function(e){const t=crypto.getRandomValues(new window.Uint8Array(12)),n=await crypto.subtle.generateKey(rk,!0,["encrypt","decrypt"]),s={name:"AES-GCM",iv:t,tagLength:128},i=await crypto.subtle.encrypt(s,n,ov(e)),r=i.byteLength-16,o=i.slice(0,r),a=i.slice(r),c=await crypto.subtle.exportKey("raw",n);return{key:c,tag:a,key_and_tag:sv(c,a),payload:av(o),iv:av(t)}},formatFingerprint:uk},Rk=e=>{const t=ib("OMEMO Fingerprints"),n=ib("No OMEMO-enabled devices found"),s=e.devicelist.devices;return bm`
    • ${t}
    • ${s.length?s.map((t=>((e,t)=>{const n=ib("Trusted"),s=ib("Untrusted");return t.get("bundle")&&t.get("bundle").fingerprint?bm`
    • ${uk(t.get("bundle").fingerprint)}
    • `:""})(e,t))):bm`
    • ${n}
    • `}
    `};wd.elements.define("converse-omemo-fingerprints",class extends ob{static get properties(){return{jid:{type:String}}}async initialize(){this.devicelist=await wd.omemo.devicelists.get(this.jid,!0),this.listenTo(this.devicelist.devices,"change:bundle",(()=>this.requestUpdate())),this.listenTo(this.devicelist.devices,"change:trusted",(()=>this.requestUpdate())),this.listenTo(this.devicelist.devices,"remove",(()=>this.requestUpdate())),this.listenTo(this.devicelist.devices,"add",(()=>this.requestUpdate())),this.listenTo(this.devicelist.devices,"reset",(()=>this.requestUpdate())),this.requestUpdate()}render(){return this.devicelist?Rk(this):""}toggleDeviceTrust(e){const t=e.target;this.devicelist.devices.get(t.getAttribute("name")).save("trusted",parseInt(t.value,10))}});const Dk=e=>bm`${e.device.get("bundle")&&e.device.get("bundle").fingerprint?(e=>{const t=ib("Checkbox for selecting the following fingerprint");return bm`
  • `})(e):(e=>{const t=ib("Device without a fingerprint"),n=ib("Checkbox for selecting the following device");return bm`
  • `})(e)}`,zk=e=>{const t=ib("This device's OMEMO fingerprint"),n=ib("Generate new keys and fingerprint");return bm`
    • ${t}
    • ${e.current_device&&e.current_device.get("bundle")&&e.current_device.get("bundle").fingerprint?(e=>bm`${uk(e.current_device.get("bundle").fingerprint)}`)(e):SS()}
    ${e.other_devices?.length?(e=>{const t=ib("Other OMEMO-enabled devices"),n=ib("Checkbox to select fingerprints of all other OMEMO devices"),s=ib("Remove checked devices and close"),i=ib("Select all");return bm`
    • ${e.other_devices?.map((t=>Dk(Object.assign({device:t},e))))}
    `})(e):""}
    `},{Strophe:Pk,sizzle:Lk,u:Fk}=Fm.env;wd.elements.define("converse-omemo-profile",class extends ob{async initialize(){this.devicelist=await wd.omemo.devicelists.get(Zl.bare_jid,!0),await this.setAttributes(),this.listenTo(this.devicelist.devices,"change:bundle",(()=>this.requestUpdate())),this.listenTo(this.devicelist.devices,"reset",(()=>this.requestUpdate())),this.listenTo(this.devicelist.devices,"reset",(()=>this.requestUpdate())),this.listenTo(this.devicelist.devices,"remove",(()=>this.requestUpdate())),this.listenTo(this.devicelist.devices,"add",(()=>this.requestUpdate())),this.requestUpdate()}async setAttributes(){this.device_id=await wd.omemo.getDeviceID(),this.current_device=this.devicelist.devices.get(this.device_id),this.other_devices=this.devicelist.devices.filter((e=>e.get("id")!==this.device_id))}render(){return this.devicelist?zk(this):SS()}selectAll(e){let t=Fk.ancestor(e.target,"li");for(;t;)t.querySelector('input[type="checkbox"]').checked=e.target.checked,t=t.nextElementSibling}async removeSelectedFingerprints(e){e.preventDefault(),e.stopPropagation(),e.target.querySelector(".select-all").checked=!1;const t=Lk('.fingerprint-removal-item input[type="checkbox"]:checked',e.target).map((e=>e.value));try{await this.devicelist.removeOwnDevices(t)}catch(e){$l.error(e),Zl.api.alert(Pk.LogLevel.ERROR,ib("Error"),[ib("Sorry, an error occurred while trying to remove the devices.")])}await this.setAttributes(),this.requestUpdate()}async generateOMEMODeviceBundle(e){e.preventDefault();await wd.confirm(ib("Are you sure you want to generate new OMEMO keys? This will remove your old keys and all previously encrypted messages will no longer be decryptable on this device."))&&(await wd.omemo.bundle.generate(),await this.setAttributes(),this.requestUpdate())}});const Uk={async generateFingerprints(e){const t=await Ek(e);return Promise.all(t.map((e=>Ak(e))))},getDeviceForContact:(e,t)=>Ek(e).then((e=>e.get(t))),contactHasOMEMOSupport:async e=>(await Ek(e)).length>0},Bk=Uk;class qk extends Error{constructor(e,t){super(e,t),this.name="IQError",this.iq=t}}const{Strophe:Hk,sizzle:Gk,$iq:Wk}=Fm.env,Vk=dr.extend({defaults:{trusted:0,active:!0},getRandomPreKey(){const e=this.get("bundle");return e.prekeys[fl(e.prekeys.length)]},async fetchBundleFromServer(){const e=Wk({type:"get",from:Zl.bare_jid,to:this.get("jid")}).c("pubsub",{xmlns:Hk.NS.PUBSUB}).c("items",{node:`${Hk.NS.OMEMO_BUNDLES}:${this.get("id")}`});let t;try{t=await wd.sendIQ(e)}catch(t){return $l.error(`Could not fetch bundle for device ${this.get("id")} from ${this.get("jid")}`),$l.error(t),null}if(t.querySelector("error"))throw new qk("Could not fetch bundle",t);const n=Gk(`items[node="${Hk.NS.OMEMO_BUNDLES}:${this.get("id")}"]`,t).pop(),s=xk(Gk(`bundle[xmlns="${Hk.NS.OMEMO}"]`,n).pop());return this.save("bundle",s),s},getBundle(){return this.get("bundle")?Promise.resolve(this.get("bundle"),this):this.fetchBundleFromServer()}}),{Strophe:Zk,$build:Qk,$iq:Jk,sizzle:Kk}=Fm.env,Yk=dr.extend({idAttribute:"jid",async initialize(){this.initialized=Xo(),await this.initDevices(),this.initialized.resolve()},initDevices(){this.devices=new Zl.Devices;const e=`converse.devicelist-${Zl.bare_jid}-${this.get("jid")}`;return Gc(this.devices,e),this.fetchDevices()},async onDevicesFound(e){if(0===e.length){let e=[];try{e=await this.fetchDevicesFromServer()}catch(e){null===e?$l.error(`Timeout error while fetching devices for ${this.get("jid")}`):($l.error(`Could not fetch devices for ${this.get("jid")}`),$l.error(e)),this.destroy()}this.get("jid")===Zl.bare_jid&&this.publishCurrentDevice(e)}},fetchDevices(){return void 0===this._devices_promise&&(this._devices_promise=new Promise((e=>{this.devices.fetch({success:t=>e(this.onDevicesFound(t)),error:(t,n)=>{$l.error(n),e()}})}))),this._devices_promise},async getOwnDeviceId(){let e=Zl.omemo_store.get("device_id");return this.devices.get(e)||(await Zl.omemo_store.generateBundle(),e=Zl.omemo_store.get("device_id")),e},async publishCurrentDevice(e){if(this.get("jid")===Zl.bare_jid){if(await kk(),Zl.omemo_store)return e.includes(await this.getOwnDeviceId())?void 0:this.publishDevices();$l.warn("publishCurrentDevice: omemo_store is not defined, likely a timing issue")}},async fetchDevicesFromServer(){const e=Jk({type:"get",from:Zl.bare_jid,to:this.get("jid")}).c("pubsub",{xmlns:Zk.NS.PUBSUB}).c("items",{node:Zk.NS.OMEMO_DEVICELIST}),t=await wd.sendIQ(e),n=`list[xmlns="${Zk.NS.OMEMO}"] device`,s=Kk(n,t).map((e=>e.getAttribute("id"))),i=this.get("jid");return Promise.all(s.map((e=>this.devices.create({id:e,jid:i},{promise:!0}))))},publishDevices(){const e=Qk("item",{id:"current"}).c("list",{xmlns:Zk.NS.OMEMO});this.devices.filter((e=>e.get("active"))).forEach((t=>e.c("device",{id:t.get("id")}).up()));return wd.pubsub.publish(null,Zk.NS.OMEMO_DEVICELIST,e,{"pubsub#access_model":"open"},!1)},async removeOwnDevices(e){if(this.get("jid")!==Zl.bare_jid)throw new Error("Cannot remove devices from someone else's device list");return await Promise.all(e.map((e=>this.devices.get(e))).map((e=>new Promise((t=>e.destroy({success:t,error:(e,n)=>{$l.error(n),t()}})))))),this.publishDevices()}}),Xk=Yk,ej=gu.extend({model:Xk}),tj=gu.extend({model:Vk});var nj=Math.ceil,sj=Math.max;const ij=function(e,t,n,s){for(var i=-1,r=sj(nj((t-e)/(n||1)),0),o=Array(r);r--;)o[s?r:++i]=e,e+=n;return o};const rj=function(e){return function(t,n,s){return s&&"number"!=typeof s&&De(t,n,s)&&(n=s=void 0),t=An(t),void 0===n?(n=t,t=0):n=An(n),s=void 0===s?t!!t.startsWith("session"+e)&&t)),n={};return t.forEach((e=>{n[e]=void 0})),this.save(n),Promise.resolve()},publishBundle(){const e=this.get("signed_prekey"),t=`${oj.NS.OMEMO_BUNDLES}:${this.get("device_id")}`,n=aj("item").c("bundle",{xmlns:oj.NS.OMEMO}).c("signedPreKeyPublic",{signedPreKeyId:e.id}).t(e.pubKey).up().c("signedPreKeySignature").t(e.signature).up().c("identityKey").t(this.get("identity_keypair").pubKey).up().c("prekeys");Object.values(this.get("prekeys")).forEach(((e,t)=>n.c("preKeyPublic",{preKeyId:t}).t(e.pubKey).up()));return wd.pubsub.publish(null,t,n,{"pubsub#access_model":"open"},!1)},async generateMissingPreKeys(){const e=Fd(bx(rj(0,Zl.NUM_PREKEYS),Number.prototype.toString),Object.keys(this.getPreKeys()));if(e.length<1)return $l.warn("No missing prekeys to generate for our own device"),Promise.resolve();(await Promise.all(e.map((e=>libsignal.KeyHelper.generatePreKey(parseInt(e,10)))))).forEach((e=>this.storePreKey(e.keyId,e.keyPair)));const t=Object.keys(this.getPreKeys()).map((e=>({id:e.keyId,key:cj.arrayBufferToBase64(e.pubKey)}))),n=(await wd.omemo.devicelists.get(Zl.bare_jid)).devices.get(this.get("device_id")),s=await n.getBundle();n.save("bundle",Object.assign(s,{prekeys:t}))},async generatePreKeys(){const e=Zl.NUM_PREKEYS,{KeyHelper:t}=libsignal,n=await Promise.all(rj(0,e).map((e=>t.generatePreKey(e))));return n.forEach((e=>this.storePreKey(e.keyId,e.keyPair))),n.map((e=>({id:e.keyId,key:cj.arrayBufferToBase64(e.keyPair.pubKey)})))},async generateBundle(){const e=await libsignal.KeyHelper.generateIdentityKeyPair(),t=cj.arrayBufferToBase64(e.pubKey),n=await async function(){const e=(await wd.omemo.devicelists.get(Zl.bare_jid,!0)).devices.pluck("id");let t=libsignal.KeyHelper.generateRegistrationId(),n=0;for(;e.includes(t);)if(t=libsignal.KeyHelper.generateRegistrationId(),n++,10===n)throw new Error("Unable to generate a unique device ID");return t.toString()}();this.save({device_id:n,identity_keypair:{privKey:cj.arrayBufferToBase64(e.privKey),pubKey:t},identity_key:t});const s=await libsignal.KeyHelper.generateSignedPreKey(e,0);this.storeSignedPreKey(s);const i={identity_key:t,device_id:n,prekeys:await this.generatePreKeys()};i.signed_prekey={id:s.keyId,public_key:cj.arrayBufferToBase64(s.keyPair.pubKey),signature:cj.arrayBufferToBase64(s.signature)};const r=await wd.omemo.devicelists.get(Zl.bare_jid);(await r.devices.create({id:i.device_id,jid:Zl.bare_jid},{promise:!0})).save("bundle",i)},fetchSession(){return void 0===this._setup_promise&&(this._setup_promise=new Promise(((e,t)=>{this.fetch({success:()=>{this.get("device_id")?e():this.generateBundle().then(e).catch(t)},error:(n,s)=>{$l.warn("Could not fetch OMEMO session from cache, we'll generate a new one."),$l.warn(s),this.generateBundle().then(e).catch(t)}})}))),this._setup_promise}}),dj=lj,uj={omemo:{getDeviceID:async()=>(await wd.waitUntil("OMEMOInitialized"),Zl.omemo_store.get("device_id")),devicelists:{async get(e){let t=arguments.length>1&&void 0!==arguments[1]&&arguments[1];const n=Zl.devicelists.get(e)||(t?Zl.devicelists.create({jid:e}):null);return await(n?.initialized),n}},bundle:{generate:async()=>{await wd.waitUntil("OMEMOInitialized");const e=await wd.omemo.devicelists.get(Zl.bare_jid),t=Zl.omemo_store.get("device_id");if(t){const n=e.devices.get(t);Zl.omemo_store.unset(t),n&&await new Promise((e=>n.destroy({success:e,error:e}))),e.devices.trigger("remove")}await Zl.omemo_store.generateBundle(),await e.publishDevices();const n=Ak(e.devices.get(Zl.omemo_store.get("device_id")));return await Zl.omemo_store.publishBundle(),n}}}},{Strophe:hj}=Fm.env;Fm.env.omemo=Ok,hj.addNamespace("OMEMO_DEVICELIST",hj.NS.OMEMO+".devicelist"),hj.addNamespace("OMEMO_VERIFICATION",hj.NS.OMEMO+".verification"),hj.addNamespace("OMEMO_WHITELISTED",hj.NS.OMEMO+".whitelisted"),hj.addNamespace("OMEMO_BUNDLES",hj.NS.OMEMO+".bundles"),Fm.plugins.add("converse-omemo",{enabled:e=>window.libsignal&&e.config.get("trusted")&&!wd.settings.get("clear_cache_on_logout")&&!e.api.settings.get("blacklisted_plugins").includes("converse-omemo"),dependencies:["converse-chatview","converse-pubsub","converse-profile"],initialize(){wd.settings.extend({omemo_default:!1}),wd.promises.add(["OMEMOInitialized"]),Zl.NUM_PREKEYS=100,Object.assign(Zl,Bk),Object.assign(Zl.api,uj),Zl.OMEMOStore=dj,Zl.Device=Vk,Zl.Devices=tj,Zl.DeviceList=Xk,Zl.DeviceLists=ej,wd.waitUntil("chatBoxesInitialized").then(vk),wd.listen.on("getOutgoingMessageAttributes",hk),wd.listen.on("createMessageStanza",(async(e,t)=>{try{t=await Mk(e,t)}catch(t){!function(e,t){if("IQError"===e.name){t.save("omemo_supported",!1);const n=[];lk(`presence-subscription-required[xmlns="${ak.NS.PUBSUB_ERROR}"]`,e.iq).length?n.push(ib("Sorry, we're unable to send an encrypted message because %1$s requires you to be subscribed to their presence in order to see their OMEMO information",e.iq.getAttribute("from"))):lk('remote-server-not-found[xmlns="urn:ietf:params:xml:ns:xmpp-stanzas"]',e.iq).length?n.push(ib("Sorry, we're unable to send an encrypted message because the remote server for %1$s could not be found",e.iq.getAttribute("from"))):(n.push(ib("Unable to send an encrypted message due to an unexpected error.")),n.push(e.iq.outerHTML)),wd.alert("error",ib("Error"),n)}else e.user_facing&&wd.alert("error",ib("Error"),[e.message]);throw e}(t,e)}return t})),wd.listen.on("afterFileUploaded",((e,t)=>e.file.xep454_ivkey?function(e,t){const n=t.oob_url.replace(/^https?:/,"aesgcm:")+"#"+e.file.xep454_ivkey;return Object.assign(t,{oob_url:null,message:n,body:n})}(e,t):t)),wd.listen.on("beforeFileUpload",((e,t)=>e.get("omemo_active")?async function(e){const t=crypto.getRandomValues(new Uint8Array(12)),n=await crypto.subtle.generateKey({name:"AES-GCM",length:256},!0,["encrypt","decrypt"]),s=await crypto.subtle.encrypt({name:"AES-GCM",iv:t},n,await e.arrayBuffer()),i=await window.crypto.subtle.exportKey("raw",n),r=new File([s],e.name,{type:e.type,lastModified:e.lastModified});return r.xep454_ivkey=iv(t)+iv(i),r}(t):t)),wd.listen.on("parseMessage",pk),wd.listen.on("parseMUCMessage",pk),wd.listen.on("chatBoxViewInitialized",yk),wd.listen.on("chatRoomViewInitialized",yk),wd.listen.on("connected",Ck),wd.listen.on("getToolbarButtons",Nk),wd.listen.on("statusInitialized",jk),wd.listen.on("addClientFeatures",(()=>wd.disco.own.features.add(`${hj.NS.OMEMO_DEVICELIST}+notify`))),wd.listen.on("afterMessageBodyTransformed",fk),wd.listen.on("userDetailsModalInitialized",(e=>{const t=e.get("jid");Zl.generateFingerprints(t).catch((e=>$l.error(e)))})),wd.listen.on("profileModalInitialized",(()=>{Zl.generateFingerprints(Zl.bare_jid).catch((e=>$l.error(e)))})),wd.listen.on("clearSession",(()=>{delete Zl.omemo_store,cl()&&Zl.devicelists&&(Zl.devicelists.clearStore(),delete Zl.devicelists)}))}});const{Strophe:mj,$iq:gj}=Fm.env;async function fj(e){e=e||Zl.bare_jid;const t=Zl.session.get("push_enabled")||[];if(t.includes(e))return;const n=wd.settings.get("push_app_servers").filter((e=>!e.disable)),s=wd.settings.get("push_app_servers").filter((e=>e.disable)),i=n.map((t=>async function(e,t){if(!t.jid||!t.node)return;if(!await wd.disco.getIdentity("pubsub","push",t.jid))return $l.warn(`Not enabling push the service "${t.jid}", it doesn't have the right disco identtiy.`);const n=await Promise.all([wd.disco.supports(mj.NS.PUSH,t.jid),wd.disco.supports(mj.NS.PUSH,e)]);if(!n[0]&&!n[1])return void $l.warn(`Not enabling push app server "${t.jid}", no disco support from your server.`);const s=gj({type:"set"});return e!==Zl.bare_jid&&s.attrs({to:e}),s.c("enable",{xmlns:mj.NS.PUSH,jid:t.jid,node:t.node}),t.secret&&s.c("x",{xmlns:mj.NS.XFORM,type:"submit"}).c("field",{var:"FORM_TYPE"}).c("value").t(`${mj.NS.PUBSUB}#publish-options`).up().up().c("field",{var:"secret"}).c("value").t(t.secret),wd.sendIQ(s)}(e,t))),r=s.map((t=>async function(e,t){if(!t.jid)return;if(!await wd.disco.supports(mj.NS.PUSH,e||Zl.bare_jid))return void $l.warn(`Not disabling push app server "${t.jid}", no disco support from your server.`);const n=gj({type:"set"});e!==Zl.bare_jid&&n.attrs({to:e}),n.c("disable",{xmlns:mj.NS.PUSH,jid:t.jid}),t.node&&n.attrs({node:t.node}),wd.sendIQ(n).catch((e=>{$l.error(`Could not disable push app server for ${t.jid}`),$l.error(e)}))}(e,t)));try{await Promise.all(i.concat(r))}catch(e){$l.error("Could not enable or disable push App Server"),e&&$l.error(e)}finally{t.push(e)}Zl.session.save("push_enabled",t)}function pj(e){e.get("type")==Zl.CHATROOMS_TYPE&&fj(mj.getDomainFromJid(e.get("jid")))}const{Strophe:vj}=Fm.env;vj.addNamespace("PUSH","urn:xmpp:push:0"),Fm.plugins.add("converse-push",{initialize(){wd.settings.extend({push_app_servers:[],enable_muc_push:!1}),wd.listen.on("statusInitialized",(()=>fj())),wd.settings.get("enable_muc_push")&&wd.listen.on("chatBoxesInitialized",(()=>Zl.chatboxes.on("add",pj)))}});const yj=()=>{const e=ib("Already have a chat account?"),t=ib("Log in here");return bm`

    ${e}

    `},_j=e=>{const t=wd.settings.get("registration_domain"),n=ib("Create your account"),s=ib("Please enter the XMPP provider to register with:"),i=!t&&e.status===bj;return bm`
    ${n}
    ${t||(()=>{const e=wd.settings.get("domain_placeholder"),t=ib("Tip: A list of public XMPP providers is available"),n=ib("here"),s=wd.settings.get("providers_link");return bm`

    ${t} ${n}.

    `})()}
    ${i?(()=>{const e=ib("Fetch registration form"),t=ib("Already have a chat account?"),n=ib("Log in here");return bm`

    ${t}

    `})():""}
    `},bj=0,wj=e=>bm`${e.alert_message?bm``:""} ${e.status===bj?_j(e):""} ${1===e.status?(e=>{const t=wd.settings.get("registration_domain"),n=ib("Cancel");return bm`
    ${SS({classes:"hor_centered"})} ${t?"":bm``}
    `})(e):""} ${2===e.status?(e=>{const t=ib("Choose a different provider"),n=ib("Account Registration:"),s=ib("Register"),i=wd.settings.get("registration_domain");return bm`
    ${n} ${e.domain}

    ${e.title}

    ${e.instructions}

    ${e.form_fields}
    ${e.fields?bm``:""} ${i?"":bm``} ${yj()}
    `})(e):""} ${3===e.status?yj():""}`;async function Sj(e){await wd.waitUntil("controlBoxInitialized");Zl.chatboxes.get("controlbox").set({"active-form":e})}const xj=e=>`${e}`;function Aj(e){const t=e.getAttribute("name");if(!t)return null;let n;return n="checkbox"===e.getAttribute("type")?e.checked?1:0:"TEXTAREA"==e.tagName?e.value.split("\n").filter((e=>e.trim())):"SELECT"==e.tagName?xl.getSelectValues(e):e.value,xl.toStanza(((e,t)=>`${t}`)(t,Array.isArray(n)?n.map(xj):xj(n)))}xl.webForm2xForm=Aj;var Ej=n(3538),$j={};$j.styleTagTransform=_b(),$j.setAttributes=fb(),$j.insert=mb().bind(null,"head"),$j.domAPI=ub(),$j.insertStyleElement=vb();lb()(Ej.Z,$j);Ej.Z&&Ej.Z.locals&&Ej.Z.locals;const{Strophe:Cj,sizzle:kj,$iq:jj}=Fm.env,Tj=Fm.env.utils,Ij=1,Nj=2;wd.elements.define("converse-register-panel",class extends ob{static get properties(){return{status:{type:String},alert_message:{type:String},alert_type:{type:String}}}constructor(){super(),this.alert_type="info",this.setErrorMessage=e=>this.setMessage(e,"danger"),this.setFeedbackMessage=e=>this.setMessage(e,"info")}initialize(){this.reset(),this.listenTo(Zl,"connectionInitialized",(()=>this.registerHooks()));const e=wd.settings.get("registration_domain");e?this.fetchRegistrationForm(e):this.status=0}render(){return wj(this)}setMessage(e,t){this.alert_type=t,this.alert_message=e}registerHooks(){const e=Zl.connection,t=e._connect_cb.bind(e);e._connect_cb=(e,n,s)=>{this._registering?this.getRegistrationFields(e,n)&&(this._registering=!1):t(e,n,s)}}getRegistrationFields(e,t){const n=Zl.connection;n.connected=!0;const s=n._proto._reqToData(e);if(!s)return;if(n._proto._connect_cb(s)===Cj.Status.CONNFAIL)return this.status=0,this.setErrorMessage(ib("Sorry, we're unable to connect to your chosen provider.")),!1;const i=s.getElementsByTagName("register"),r=s.getElementsByTagName("mechanism");if(0===i.length&&0===r.length)return n._proto._no_auth_received(t),!1;if(0===i.length)return n._changeConnectStatus(Cj.Status.REGIFAIL),this.alert_type="danger",this.setErrorMessage(ib("Sorry, the given provider does not support in band account registration. Please try with a different provider.")),!0;n._addSysHandler((e=>this.onRegistrationFields(e)),null,"iq",null,null);const o=jj({type:"get"}).c("query",{xmlns:Cj.NS.REGISTER}).tree();return o.setAttribute("id",n.getUniqueId("sendIQ")),n.send(o),n.connected=!1,!0}onRegistrationFields(e){return"error"===e.getAttribute("type")?(this.reportErrors(e),wd.settings.get("registration_domain")?this.status=3:this.status=0,!1):(this.setFields(e),this.status===Ij&&this.renderRegistrationForm(e),!1)}reset(e){Object.assign(this,{fields:{},urls:[],title:"",instructions:"",registered:!1,_registering:!1,domain:null,form_type:null}),e&&Object.assign(this,e)}onFormSubmission(e){e?.preventDefault?.(),null===e.target.querySelector("input[name=domain]")?this.submitRegistrationForm(e.target):this.onProviderChosen(e.target)}onProviderChosen(e){const t=e.querySelector("input[name=domain]")?.value;t&&this.fetchRegistrationForm(t.trim())}fetchRegistrationForm(e){return this.status=Ij,this.reset({domain:Cj.getDomainFromJid(e),_registering:!0}),hd(this.domain),Zl.connection?.connect(this.domain,"",(e=>this.onConnectStatusChanged(e))),!1}onConnectStatusChanged(e){$l.debug("converse-register: onConnectStatusChanged"),[Cj.Status.DISCONNECTED,Cj.Status.CONNFAIL,Cj.Status.REGIFAIL,Cj.Status.NOTACCEPTABLE,Cj.Status.CONFLICT].includes(e)?($l.error(`Problem during registration: Strophe.Status is ${Bo[e]}`),this.abortRegistration()):e===Cj.Status.REGISTERED&&($l.debug("Registered successfully."),Zl.connection.reset(),["converse/login","converse/register"].includes(Zl.router.history.getFragment())&&Zl.router.navigate("",{replace:!0}),Sj("login"),this.fields.password&&this.fields.username?(Zl.connection.connect(this.fields.username.toLowerCase()+"@"+this.domain.toLowerCase(),this.fields.password,Zl.onConnectStatusChanged),this.setFeedbackMessage(ib("Now logging you in"))):this.setFeedbackMessage(ib("Registered successfully")),this.reset())}getLegacyFormFields(){const e=Object.keys(this.fields).map((e=>"username"===e?_w({domain:` @${this.domain}`,name:e,type:"text",label:e,value:"",required:!0}):pw({label:e,name:e,placeholder:e,required:!0,type:"password"===e||"email"===e?e:"text",value:""}))),t=this.urls.map((e=>yw({label:"",value:e})));return[...e,...t]}getFormFields(e){return"xform"===this.form_type?Array.from(e.querySelectorAll("field")).map((t=>Tj.xForm2TemplateResult(t,e,{domain:this.domain}))):this.getLegacyFormFields()}renderRegistrationForm(e){this.form_fields=this.getFormFields(e),this.status=Nj}reportErrors(e){const t=Array.from(e.querySelectorAll("error"));t.length?this.setErrorMessage(t.reduce(((e,t)=>`${e}\n${t.textContent}`),"")):this.setErrorMessage(ib("The provider rejected your registration attempt. Please check the values you entered for correctness."))}renderProviderChoiceForm(e){e?.preventDefault?.(),Zl.connection._proto._abortAllRequests(),Zl.connection.reset(),this.status=0}abortRegistration(){Zl.connection._proto._abortAllRequests(),Zl.connection.reset(),[Ij,Nj].includes(this.status)?wd.settings.get("registration_domain")&&this.fetchRegistrationForm(wd.settings.get("registration_domain")):this.requestUpdate()}submitRegistrationForm(e){const t=kj(":input:not([type=button]):not([type=submit])",e),n=jj({type:"set",id:Tj.getUniqueId()}).c("query",{xmlns:Cj.NS.REGISTER});if("xform"===this.form_type){n.c("x",{xmlns:Cj.NS.XFORM,type:"submit"});const e=t.map((e=>Aj(e))).filter((e=>e));e.forEach((e=>n.cnode(e).up()))}else t.forEach((e=>n.c(e.getAttribute("name"),{},e.value)));Zl.connection._addSysHandler((e=>this._onRegisterIQ(e)),null,"iq",null,null),Zl.connection.send(n),this.setFields(n.tree())}setFields(e){const t=e.querySelector("query"),n=kj(`x[xmlns="${Cj.NS.XFORM}"]`,t);n.length>0?this._setFieldsFromXForm(n.pop()):this._setFieldsFromLegacy(t)}_setFieldsFromLegacy(e){[].forEach.call(e.children,(e=>{"instructions"!==e.tagName.toLowerCase()?"x"!==e.tagName.toLowerCase()?this.fields[e.tagName.toLowerCase()]=Cj.getText(e):"jabber:x:oob"===e.getAttribute("xmlns")&&this.urls.concat(kj("url",e).map((e=>e.textContent))):this.instructions=Cj.getText(e)})),this.form_type="legacy"}_setFieldsFromXForm(e){this.title=e.querySelector("title")?.textContent??"",this.instructions=e.querySelector("instructions")?.textContent??"",e.querySelectorAll("field").forEach((e=>{const t=e.getAttribute("var");t?this.fields[t.toLowerCase()]=e.querySelector("value")?.textContent??"":$l.warn("Found field we couldn't parse")})),this.form_type="xform"}_onRegisterIQ(e){if("error"===e.getAttribute("type")){$l.error("Registration failed."),this.reportErrors(e);let t=e.getElementsByTagName("error");if(1!==t.length)return Zl.connection._changeConnectStatus(Cj.Status.REGIFAIL,"unknown"),!1;t=t[0].firstElementChild.tagName.toLowerCase(),"conflict"===t?Zl.connection._changeConnectStatus(Cj.Status.CONFLICT,t):"not-acceptable"===t?Zl.connection._changeConnectStatus(Cj.Status.NOTACCEPTABLE,t):Zl.connection._changeConnectStatus(Cj.Status.REGIFAIL,t)}else Zl.connection._changeConnectStatus(Cj.Status.REGISTERED,null);return!1}});const{Strophe:Mj}=Fm.env;Mj.addNamespace("REGISTER","jabber:iq:register");const Oj=Object.keys(Mj.Status).reduce(((e,t)=>Math.max(e,Mj.Status[t])),0);Mj.Status.REGIFAIL=Oj+1,Mj.Status.REGISTERED=Oj+2,Mj.Status.CONFLICT=Oj+3,Mj.Status.NOTACCEPTABLE=Oj+5,Fm.plugins.add("converse-register",{dependencies:["converse-controlbox"],enabled:()=>!0,initialize(){const{router:e}=Zl;Bo[Mj.Status.REGIFAIL]="REGIFAIL",Bo[Mj.Status.REGISTERED]="REGISTERED",Bo[Mj.Status.CONFLICT]="CONFLICT",Bo[Mj.Status.NOTACCEPTABLE]="NOTACCEPTABLE",wd.settings.extend({allow_registration:!0,domain_placeholder:ib(" e.g. conversejs.org"),providers_link:"https://compliance.conversations.im/",registration_domain:""}),e.route("converse/login",(()=>Sj("login"))),e.route("converse/register",(()=>Sj("register")))}});const{Strophe:Rj}=Fm.env,Dj=dr.extend({defaults:function(){return{muc_domain:wd.settings.get("muc_domain"),nick:Zl.getDefaultMUCNickname(),toggle_state:Zl.OPENED}},initialize(){wd.settings.listen.on("change:muc_domain",(e=>this.setDomain(e)))},setDomain(e){wd.settings.get("locked_muc_domain")||this.save("muc_domain",Rj.getDomainFromJid(e))}}),{Strophe:zj,$iq:Pj,sizzle:Lj}=Fm.env;zj.addNamespace("MUCSEARCH","https://xmlns.zombofant.net/muclumbus/search/1.0");const Fj={};function Uj(e){return Fj[e]||(Fj[e]=async function(e){const t=Pj({type:"get",from:Zl.bare_jid,to:"api@search.jabber.network"}).c("search",{xmlns:zj.NS.MUCSEARCH}).c("set",{xmlns:zj.NS.RSM}).c("max").t(10).up().up().c("x",{xmlns:zj.NS.XFORM,type:"submit"}).c("field",{var:"FORM_TYPE",type:"hidden"}).c("value").t("https://xmlns.zombofant.net/muclumbus/search/1.0#params").up().up().c("field",{var:"q",type:"text-single"}).c("value").t(e).up().up().c("field",{var:"sinname",type:"boolean"}).c("value").t("true").up().up().c("field",{var:"sindescription",type:"boolean"}).c("value").t("false").up().up().c("field",{var:"sinaddr",type:"boolean"}).c("value").t("true").up().up().c("field",{var:"min_users",type:"text-single"}).c("value").t("1").up().up().c("field",{var:"key",type:"list-single"}).c("value").t("address").up().c("option").c("value").t("nusers").up().up().c("option").c("value").t("address");let n;try{n=await wd.sendIQ(t)}catch(e){return $l.error(e),[]}const s=`result[xmlns="${zj.NS.MUCSEARCH}"] item`;return Lj(s,n).map((e=>{const t=e.getAttribute("address");return{label:`${e.querySelector("name")?.textContent} (${t})`,value:t}}))}(e)),Fj[e]}const Bj=e=>{const t=ib("Join"),n=e.model.get("muc_domain")||wd.settings.get("muc_domain");let s="";wd.settings.get("locked_muc_domain")||(s=n?`name@${n}`:ib("name@conference.example.org"));const i=ib(n?"Groupchat name":"Groupchat address"),r=e.muc_roomid_policy_error_msg,o=wd.settings.get("muc_roomid_policy_hint");return bm`
    ${r?bm``:""}
    ${o?bm`
    ${lE(Qo().sanitize(o,{ALLOWED_TAGS:["b","br","em"]}))}
    `:""} ${wd.settings.get("locked_muc_nickname")?"":(e=>{const t=ib("Nickname"),n=ib("This field is required");return bm`
    `})(e)}
    `};var qj=n(5902),Hj={};Hj.styleTagTransform=_b(),Hj.setAttributes=fb(),Hj.insert=mb().bind(null,"head"),Hj.domAPI=ub(),Hj.insertStyleElement=vb();lb()(qj.Z,Hj);qj.Z&&qj.Z.locals&&qj.Z.locals;const Gj=Fm.env.utils,{Strophe:Wj}=Fm.env;wd.elements.define("converse-add-muc-modal",class extends tS{initialize(){super.initialize(),this.listenTo(this.model,"change:muc_domain",(()=>this.render())),this.muc_roomid_policy_error_msg=null,this.render(),this.addEventListener("shown.bs.modal",(()=>{this.querySelector('input[name="chatroom"]').focus()}),!1)}renderModal(){return Bj(this)}getModalTitle(){return ib("Enter a new Groupchat")}parseRoomDataFromEvent(e){const t=new FormData(e),n=t.get("chatroom")?.trim();let s;if(wd.settings.get("locked_muc_nickname")){if(s=Zl.getDefaultMUCNickname(),!s)throw new Error("Using locked_muc_nickname but no nickname found!")}else s=t.get("nickname").trim();return{jid:n,nick:s}}openChatRoom(e){if(e.preventDefault(),this.checkRoomidPolicy())return;const t=this.parseRoomDataFromEvent(e.target);let n;""===t.nick&&(t.nick=void 0),wd.settings.get("locked_muc_domain")||wd.settings.get("muc_domain")&&!Gj.isValidJID(t.jid)?n=`${Wj.escapeNode(t.jid)}@${wd.settings.get("muc_domain")}`:(n=t.jid,this.model.setDomain(n)),wd.rooms.open(n,Object.assign(t,{jid:n}),!0),e.target.reset(),this.modal.hide()}checkRoomidPolicy(){if(wd.settings.get("muc_roomid_policy")&&wd.settings.get("muc_domain")){let e=this.querySelector("converse-autocomplete input").value;!wd.settings.get("locked_muc_domain")&&Gj.isValidJID(e)||(e=`${Wj.escapeNode(e)}@${wd.settings.get("muc_domain")}`);const t=Wj.getNodeFromJid(e),n=Wj.getDomainFromJid(e);if(wd.settings.get("muc_domain")===n&&!wd.settings.get("muc_roomid_policy").test(t))return this.muc_roomid_policy_error_msg=ib("Groupchat id is invalid."),!0;this.muc_roomid_policy_error_msg=null,this.render()}}});const Vj=function(e){return e&&e.length?e[0]:void 0},Zj=e=>{const t=ib("Description:"),n=ib("Groupchat XMPP Address:"),s=ib("Participants:"),i=ib("Features:"),r=ib("Requires authentication"),o=ib("Hidden"),a=ib("Requires an invitation"),c=ib("Moderated"),l=ib("Non-anonymous"),d=ib("Open"),u=ib("Permanent"),h=ib("Public"),m=ib("Semi-anonymous"),g=ib("Temporary"),f=ib("Unmoderated");return bm`

    ${n} ${e.jid}

    ${t} ${e.desc}

    ${s} ${e.occ}

    ${i}

      ${e.passwordprotected?bm`
    • ${r}
    • `:""} ${e.hidden?bm`
    • ${o}
    • `:""} ${e.membersonly?bm`
    • ${a}
    • `:""} ${e.moderated?bm`
    • ${c}
    • `:""} ${e.nonanonymous?bm`
    • ${l}
    • `:""} ${e.open?bm`
    • ${d}
    • `:""} ${e.persistent?bm`
    • ${u}
    • `:""} ${e.publicroom?bm`
    • ${h}
    • `:""} ${e.semianonymous?bm`
    • ${m}
    • `:""} ${e.temporary?bm`
    • ${g}
    • `:""} ${e.unmoderated?bm`
    • ${f}
    • `:""}

    `},Qj=e=>bm`${e.show_form?(e=>{const t=ib("Show groupchats"),n=ib("Server address");return bm`
    `})(e):""}
      ${e.loading_items?bm`
    • ${SS()}
    • `:""} ${e.feedback_text?bm`
    • ${e.feedback_text}
    • `:""} ${Ox(e.items,(e=>e.jid),(t=>((e,t)=>{const n=ib("Show more information on this groupchat"),s=ib("Click to open this groupchat");return bm`
    • `})(e,t)))}
    `,{Strophe:Jj,$iq:Kj,sizzle:Yj}=Fm.env,Xj=Fm.env.utils;function eT(e){const t=Xj.ancestor(e.target,".room-item"),n=t.querySelector("div.room-info");n?(Xj.slideIn(n).then(Xj.removeElement),t.querySelector("a.room-info").classList.remove("selected")):(t.insertAdjacentElement("beforeend",Xj.getElementFromTemplateResult(SS())),wd.disco.info(e.target.getAttribute("data-room-jid"),null).then((e=>function(e,t){e.querySelector("span.spinner").remove(),e.querySelector("a.room-info").classList.add("selected"),e.insertAdjacentHTML("beforeEnd",Xj.getElementFromTemplateResult(Zj({jid:t.getAttribute("from"),desc:Vj(Yj('field[var="muc#roominfo_description"] value',t))?.textContent,occ:Vj(Yj('field[var="muc#roominfo_occupants"] value',t))?.textContent,hidden:Yj('feature[var="muc_hidden"]',t).length,membersonly:Yj('feature[var="muc_membersonly"]',t).length,moderated:Yj('feature[var="muc_moderated"]',t).length,nonanonymous:Yj('feature[var="muc_nonanonymous"]',t).length,open:Yj('feature[var="muc_open"]',t).length,passwordprotected:Yj('feature[var="muc_passwordprotected"]',t).length,persistent:Yj('feature[var="muc_persistent"]',t).length,publicroom:Yj('feature[var="muc_publicroom"]',t).length,semianonymous:Yj('feature[var="muc_semianonymous"]',t).length,temporary:Yj('feature[var="muc_temporary"]',t).length,unmoderated:Yj('feature[var="muc_unmoderated"]',t).length})))}(t,e))).catch((e=>$l.error(e))))}function tT(e){return al()&&!e.get("hidden")}wd.elements.define("converse-muc-list-modal",class extends tS{constructor(e){super(e),this.items=[],this.loading_items=!1}initialize(){super.initialize(),this.listenTo(this.model,"change:muc_domain",this.onDomainChange),this.listenTo(this.model,"change:feedback_text",(()=>this.render())),this.addEventListener("shown.bs.modal",(()=>wd.settings.get("locked_muc_domain")&&this.updateRoomsList())),this.model.save("feedback_text","")}renderModal(){return Qj(Object.assign(this.model.toJSON(),{show_form:!wd.settings.get("locked_muc_domain"),server_placeholder:this.model.get("muc_domain")||ib("conference.example.org"),items:this.items,loading_items:this.loading_items,openRoom:e=>this.openRoom(e),setDomainFromEvent:e=>this.setDomainFromEvent(e),submitForm:e=>this.showRooms(e),toggleRoomInfo:e=>this.toggleRoomInfo(e)}))}getModalTitle(){return ib("Query for Groupchats")}openRoom(e){e.preventDefault();const t=e.target.getAttribute("data-room-jid"),n=e.target.getAttribute("data-room-name");this.modal.hide(),wd.rooms.open(t,{name:n},!0)}toggleRoomInfo(e){e.preventDefault(),eT(e)}onDomainChange(){wd.settings.get("auto_list_rooms")&&this.updateRoomsList()}onRoomsFound(e){this.loading_items=!1;const t=e?Yj("query item",e):[];return t.length?(this.model.set({feedback_text:ib("Groupchats found")},{silent:!0}),this.items=t.map(Ig)):(this.items=[],this.model.set({feedback_text:ib("No groupchats found")},{silent:!0})),this.render(),!0}updateRoomsList(){const e=Kj({to:this.model.get("muc_domain"),from:Zl.connection.jid,type:"get"}).c("query",{xmlns:Jj.NS.DISCO_ITEMS});wd.sendIQ(e).then((e=>this.onRoomsFound(e))).catch((()=>this.onRoomsFound()))}showRooms(e){e.preventDefault(),this.loading_items=!0,this.render();const t=new FormData(e.target);this.model.setDomain(t.get("server")),this.updateRoomsList()}setDomainFromEvent(e){this.model.setDomain(e.target.value)}setNick(e){this.model.save({nick:e.target.value})}});function nT(e,t){const n=ib("Leave this groupchat"),s=t.get("num_unread_general")||t.get("has_activity");return bm`
    ${t.get("num_unread")?(e=>bm`${e.get("num_unread")}`)(t):t.get("has_activity")?bm``:""} ${t.getDisplayName()} ${wd.settings.get("allow_bookmarks")?function(e){const t=e.get("bookmarked")??!1,n=ib("Bookmark");return bm``}(t):""}
    `}const{Strophe:sT,u:iT}=Fm.env;wd.elements.define("converse-rooms-list",class extends ob{initialize(){const e=`converse.roomspanel${Zl.bare_jid}`;this.model=new Dj({id:e}),Gc(this.model,e),this.model.fetch(),this.listenTo(Zl.chatboxes,"add",this.renderIfChatRoom),this.listenTo(Zl.chatboxes,"remove",this.renderIfChatRoom),this.listenTo(Zl.chatboxes,"destroy",this.renderIfChatRoom),this.listenTo(Zl.chatboxes,"change",this.renderIfRelevantChange),this.listenTo(this.model,"change",(()=>this.requestUpdate())),this.requestUpdate()}render(){return(e=>{const{chatboxes:t,CHATROOMS_TYPE:n,CLOSED:s}=Zl,i=t.filter((e=>e.get("type")===n));i.sort(((e,t)=>e.getDisplayName().toLowerCase()<=t.getDisplayName().toLowerCase()?-1:1));const r=ib("Click to toggle the list of open groupchats"),o=ib("Groupchats"),a=ib("Query for groupchats"),c=ib("Add a new groupchat"),l=ib("Show bookmarked groupchats"),d=e.model.get("toggle_state")===s;return bm`
    ${i.map((t=>nT(e,t)))}
    `})(this)}renderIfChatRoom(e){iT.isChatRoom(e)&&this.requestUpdate()}renderIfRelevantChange(e){const t=["bookmarked","hidden","name","num_unread","num_unread_general","has_activity"],n=e.changed||{};iT.isChatRoom(e)&&Object.keys(n).filter((e=>t.includes(e))).length&&this.requestUpdate()}showRoomDetailsModal(e){const t=e.currentTarget.getAttribute("data-room-jid"),n=Zl.chatboxes.get(t);e.preventDefault(),wd.modal.show("converse-muc-details-modal",{model:n},e)}async openRoom(e){e.preventDefault();const t=e.target.textContent,n=e.target.getAttribute("data-room-jid"),s={name:t||sT.unescapeNode(sT.getNodeFromJid(n))||n};await wd.rooms.open(n,s,!0)}async closeRoom(e){e.preventDefault();const t=e.currentTarget.getAttribute("data-room-name"),n=e.currentTarget.getAttribute("data-room-jid");if(await wd.confirm(ib("Are you sure you want to leave the groupchat %1$s?",t))){(await wd.rooms.get(n)).close()}}toggleRoomsList(e){e?.preventDefault?.();const t=this.querySelector(".open-rooms-list");this.model.get("toggle_state")===Zl.CLOSED?iT.slideOut(t).then((()=>this.model.save({toggle_state:Zl.OPENED}))):iT.slideIn(t).then((()=>this.model.save({toggle_state:Zl.CLOSED})))}}),Fm.plugins.add("converse-roomslist",{dependencies:["converse-singleton","converse-controlbox","converse-muc","converse-bookmarks"],initialize(){}});wd.elements.define("converse-fontawesome",class extends ob{render(){return bm` `}});function rT(){if(!wd.settings.get("auto_insert"))return;const e=wd.settings.get("root");if(!e.querySelector("converse-root")){const t=document.createElement("converse-root"),n=e.querySelector("body");n?n.appendChild(t):e.appendChild(t)}}var oT=n(7089),aT={};aT.styleTagTransform=_b(),aT.setAttributes=fb(),aT.insert=mb().bind(null,"head"),aT.domAPI=ub(),aT.insertStyleElement=vb();lb()(oT.Z,aT);oT.Z&&oT.Z.locals&&oT.Z.locals;class cT extends ob{render(){return(()=>{const e=wd.settings.get("singleton")?["converse-singleton"]:[];return e.push(`converse-${wd.settings.get("view_mode")}`),bm`
    `})()}initialize(){this.setAttribute("id","conversejs"),this.setClasses();const e=Qc();this.listenTo(e,"change:view_mode",(()=>this.setClasses())),this.listenTo(e,"change:singleton",(()=>this.setClasses())),window.matchMedia("(prefers-color-scheme: dark)").addListener((()=>this.setClasses())),window.matchMedia("(prefers-color-scheme: light)").addListener((()=>this.setClasses()))}setClasses(){this.className="",this.classList.add("conversejs"),this.classList.add(`converse-${wd.settings.get("view_mode")}`),this.classList.add(`theme-${window.matchMedia("(prefers-color-scheme: dark)").matches?wd.settings.get("dark_theme"):wd.settings.get("theme")}`),this.requestUpdate()}}Fm.plugins.add("converse-rootview",{initialize(){wd.settings.extend({auto_insert:!0,theme:"classic",dark_theme:"dracula"}),wd.listen.on("chatBoxesInitialized",rT),wd.elements.define("converse-root",cT)}});const lT=e=>{const t=ib("Add"),n=ib("name@example.org"),s=ib("Please enter a valid XMPP address"),i=ib("Group"),r=ib("Name"),o=ib("XMPP Address");return bm`
    `};wd.elements.define("converse-add-contact-modal",class extends tS{initialize(){super.initialize(),this.listenTo(this.model,"change",(()=>this.render())),this.render(),this.addEventListener("shown.bs.modal",(()=>this.querySelector('input[name="jid"]')?.focus()),!1)}renderModal(){return lT(this)}getModalTitle(){return ib("Add a Contact")}afterRender(){"string"==typeof wd.settings.get("xhr_user_search_url")?this.initXHRAutoComplete():this.initJIDAutoComplete()}initJIDAutoComplete(){if(!wd.settings.get("autocomplete_add_contact"))return;const e=this.querySelector(".suggestion-box__jid").parentElement;this.jid_auto_complete=new Zl.AutoComplete(e,{data:(e,t)=>`${t.slice(0,t.indexOf("@"))}@${e}`,filter:Zl.FILTER_STARTSWITH,list:[...new Set(Zl.roster.map((e=>Oo.getDomainFromJid(e.get("jid")))))]})}initGroupAutoComplete(){if(!wd.settings.get("autocomplete_add_contact"))return;const e=this.querySelector(".suggestion-box__jid").parentElement;this.jid_auto_complete=new Zl.AutoComplete(e,{data:(e,t)=>`${t.slice(0,t.indexOf("@"))}@${e}`,filter:Zl.FILTER_STARTSWITH,list:[...new Set(Zl.roster.map((e=>Oo.getDomainFromJid(e.get("jid")))))]})}initXHRAutoComplete(){if(!wd.settings.get("autocomplete_add_contact"))return this.initXHRFetch();const e=this.querySelector(".suggestion-box__name").parentElement;this.name_auto_complete=new Zl.AutoComplete(e,{auto_evaluate:!1,filter:Zl.FILTER_STARTSWITH,list:[]});const t=new window.XMLHttpRequest;t.onload=()=>{if(t.responseText){const e=t.responseText;this.name_auto_complete.list=JSON.parse(e).map((e=>({label:e.fullname||e.jid,value:e.jid}))),this.name_auto_complete.auto_completing=!0,this.name_auto_complete.evaluate()}};const n=this.querySelector('input[name="name"]');n.addEventListener("input",rd((()=>{t.open("GET",`${wd.settings.get("xhr_user_search_url")}q=${encodeURIComponent(n.value)}`,!0),t.send()}),300)),this.name_auto_complete.on("suggestion-box-selectcomplete",(e=>{this.querySelector('input[name="name"]').value=e.text.label,this.querySelector('input[name="jid"]').value=e.text.value}))}initXHRFetch(){this.xhr=new window.XMLHttpRequest,this.xhr.onload=()=>{if(this.xhr.responseText){const e=this.xhr.responseText,t=JSON.parse(e).map((e=>({label:e.fullname||e.jid,value:e.jid})));if(1!==t.length){const e=this.querySelector(".invalid-feedback");return e.textContent=ib("Sorry, could not find a contact with that name"),void zw("d-block",e)}const n=t[0].value;if(this.validateSubmission(n)){const e=this.querySelector("form"),s=t[0].label;this.afterSubmission(e,n,s)}}}}validateSubmission(e){const t=this.querySelector(".invalid-feedback");return!e||Jo(e.split("@")).length<2?(zw("is-invalid",this.querySelector('input[name="jid"]')),zw("d-block",t),!1):Zl.roster.get(Oo.getBareJidFromJid(e))?(t.textContent=ib("This contact has already been added"),zw("d-block",t),!1):(Pw("d-block",t),!0)}afterSubmission(e,t,n,s){s&&!Array.isArray(s)&&(s=[s]),Zl.roster.addAndSubscribe(t,n,s),this.model.clear(),this.modal.hide()}addContactFromForm(e){e.preventDefault();const t=new FormData(e.target),n=(t.get("jid")||"").trim();if(!n&&"string"==typeof wd.settings.get("xhr_user_search_url")){const e=this.querySelector('input[name="name"]');return this.xhr.open("GET",`${wd.settings.get("xhr_user_search_url")}q=${encodeURIComponent(e.value)}`,!0),void this.xhr.send()}this.validateSubmission(n)&&this.afterSubmission(e.target,n,t.get("name"),t.get("group"))}});const{u:dT}=Fm.env;function uT(e){const t=e.get("jid"),n=[];if(al()){const e=Zl.chatboxes.get(t);e&&!e.get("hidden")&&n.push("open")}const s=e.get("ask"),i=e.get("requesting"),r=e.get("subscription");return"subscribe"===s||"from"===r?n.push("pending-xmpp-contact"):!0===i?n.push("requesting-xmpp-contact"):("both"===r||"to"===r||dT.isSameBareJID(t,Zl.connection.jid))&&(n.push("current-xmpp-contact"),n.push(r),n.push(e.presence.get("show"))),bm`
  • `}const hT=e=>{const t=ib("Click to hide these contacts"),n=Zl.roster.state.get("collapsed_groups");return bm``},mT=e=>{const t=ib("Contacts"),n=ib("Click to toggle contacts"),s=ib("Add a contact"),i=ib("Re-sync your contacts"),r=(Zl.roster||[]).reduce(((e,t)=>function(e,t){if(t.get("requesting")){const n=Zl.HEADER_REQUESTING_CONTACTS;e[n]?e[n].push(t):e[n]=[t]}else{let n;wd.settings.get("roster_groups")?(n=t.get("groups"),n=0===n.length?[Zl.HEADER_UNGROUPED]:n):n="subscribe"===t.get("ask")?[Zl.HEADER_PENDING_CONTACTS]:[Zl.HEADER_CURRENT_CONTACTS];for(const s of n)e[s]?e[s].push(t):e[s]=[t]}if(t.get("num_unread")){const n=Zl.HEADER_UNREAD;e[n]?e[n].push(t):e[n]=[t]}return e}(e,t)),{}),o=Object.keys(r).filter(WA),a=e.model.get("toggle_state")===Zl.CLOSED;return o.sort(Xy),bm`
    ${t} ${wd.settings.get("allow_contact_requests")?bm``:""}
    ${Ox(o,(e=>e),(e=>{const t=r[e].filter((t=>function(e,t){const n=e.presence.get("show");return wd.settings.get("hide_offline_users")&&"offline"===n?("subscribe"===e.get("ask")||"from"===e.get("subscription")||!0===e.get("requesting"))&&!GA(e,t):!GA(e,t)}(t,e)));return t.sort(Yy),t.length?hT({contacts:t,name:e}):""}))}
    `};wd.elements.define("converse-roster",class extends ob{async initialize(){const e=`converse.contacts-panel${Zl.bare_jid}`;this.model=new dr({id:e}),Gc(this.model,e),this.model.fetch(),await wd.waitUntil("rosterInitialized");const{chatboxes:t,presences:n,roster:s}=Zl;this.listenTo(Zl,"rosterContactsFetched",(()=>this.requestUpdate())),this.listenTo(n,"change:show",(()=>this.requestUpdate())),this.listenTo(t,"change:hidden",(()=>this.requestUpdate())),this.listenTo(s,"add",(()=>this.requestUpdate())),this.listenTo(s,"destroy",(()=>this.requestUpdate())),this.listenTo(s,"remove",(()=>this.requestUpdate())),this.listenTo(s,"change",(()=>this.requestUpdate())),this.listenTo(s.state,"change",(()=>this.requestUpdate())),this.listenTo(this.model,"change",(()=>this.requestUpdate())),wd.trigger("rosterViewInitialized")}render(){return mT(this)}showAddContactModal(e){wd.modal.show("converse-add-contact-modal",{model:new dr},e)}async syncContacts(e){e.preventDefault();const{roster:t}=Zl;this.syncing_contacts=!0,this.requestUpdate(),t.data.save("version",null),await t.fetchFromServer(),wd.user.presence.send(),this.syncing_contacts=!1,this.requestUpdate()}toggleRoster(e){e?.preventDefault?.();const t=this.querySelector(".list-container.roster-contacts");this.model.get("toggle_state")===Zl.CLOSED?Bw(t).then((()=>this.model.save({toggle_state:Zl.OPENED}))):qw(t).then((()=>this.model.save({toggle_state:Zl.CLOSED})))}});const gT={dnd:ib("This contact is busy"),online:ib("This contact is online"),offline:ib("This contact is offline"),unavailable:ib("This contact is unavailable"),xa:ib("This contact is away for an extended period"),away:ib("This contact is away")},fT=(e,t)=>{const n=t.presence.get("show")||"offline";let s,i;[s,i]="online"===n?["fa fa-circle","chat-status-online"]:"dnd"===n?["fa fa-minus-circle","chat-status-busy"]:"away"===n?["fa fa-circle","chat-status-away"]:["fa fa-circle","subdued-color"];const r=gT[n],o=t.get("num_unread")||0,a=t.getDisplayName(),c=ib("Click to chat with %1$s (XMPP address: %2$s)",a,e.model.get("jid"));return bm`${o?bm`${o}`:""} ${a} ${wd.settings.get("allow_contact_removal")?((e,t)=>{const n=t.getDisplayName(),s=ib("Click to remove %1$s as a contact",n);return bm``})(e,t):""}`};class pT extends ob{static get properties(){return{model:{type:Object}}}initialize(){this.listenTo(this.model,"change",(()=>this.requestUpdate())),this.listenTo(this.model,"highlight",(()=>this.requestUpdate())),this.listenTo(this.model,"vcard:add",(()=>this.requestUpdate())),this.listenTo(this.model,"vcard:change",(()=>this.requestUpdate())),this.listenTo(this.model,"presenceChanged",(()=>this.requestUpdate()))}render(){if(!0===this.model.get("requesting")){const e=this.model.getDisplayName();return(e=>bm`${e.display_name} `)(Object.assign(this.model.toJSON(),{display_name:e,openChat:e=>this.openChat(e),acceptRequest:e=>this.acceptRequest(e),declineRequest:e=>this.declineRequest(e),desc_accept:ib("Click to accept the contact request from %1$s",e),desc_decline:ib("Click to decline the contact request from %1$s",e)}))}return fT(this,this.model)}openChat(e){e?.preventDefault?.(),this.model.openChat()}async removeContact(e){if(e?.preventDefault?.(),!wd.settings.get("allow_contact_removal"))return;if(await wd.confirm(ib("Are you sure you want to remove this contact?")))try{this.model.removeFromRoster(),this.model.collection&&this.model.destroy()}catch(e){$l.error(e),wd.alert("error",ib("Error"),[ib("Sorry, there was an error while trying to remove %1$s as a contact.",this.model.getDisplayName())])}}async acceptRequest(e){e?.preventDefault?.(),await Zl.roster.sendContactAddIQ(this.model.get("jid"),this.model.getFullname(),[]),this.model.authorize().subscribe()}async declineRequest(e){e&&e.preventDefault&&e.preventDefault();return await wd.confirm(ib("Are you sure you want to decline this contact request?"))&&this.model.unauthorize().destroy(),this}}wd.elements.define("converse-roster-contact",pT);class vT extends ob{async initialize(){await wd.waitUntil("rosterInitialized"),this.model=Zl.roster_filter,this.liveFilter=rd((()=>{this.model.save({filter_text:this.querySelector(".roster-filter").value})}),250),this.listenTo(Zl,"rosterContactsFetched",(()=>this.requestUpdate())),this.listenTo(Zl.presences,"change:show",(()=>this.requestUpdate())),this.listenTo(Zl.roster,"add",(()=>this.requestUpdate())),this.listenTo(Zl.roster,"destroy",(()=>this.requestUpdate())),this.listenTo(Zl.roster,"remove",(()=>this.requestUpdate())),this.listenTo(this.model,"change",this.dispatchUpdateEvent),this.listenTo(this.model,"change",(()=>this.requestUpdate())),this.requestUpdate()}render(){return this.model?(e=>{const t=ib("Filter"),n=ib("Filter by contact name"),s=ib("Filter by group name"),i=ib("Filter by status"),r=ib("Any"),o=ib("Unread"),a=ib("Online"),c=ib("Chatty"),l=ib("Busy"),d=ib("Away"),u=ib("Extended Away"),h=ib("Offline");return bm`
    `})(Object.assign(this.model.toJSON(),{visible:this.shouldBeVisible(),changeChatStateFilter:e=>this.changeChatStateFilter(e),changeTypeFilter:e=>this.changeTypeFilter(e),clearFilter:e=>this.clearFilter(e),liveFilter:e=>this.liveFilter(e),submitFilter:e=>this.submitFilter(e)})):""}dispatchUpdateEvent(){this.dispatchEvent(new CustomEvent("update",{detail:this.model.changed}))}changeChatStateFilter(e){e&&e.preventDefault(),this.model.save({chat_state:this.querySelector(".state-type").value})}changeTypeFilter(e){e&&e.preventDefault();const t=Fw(e.target,"converse-icon")?.dataset.type||"contacts";"state"===t?this.model.save({filter_type:t,chat_state:this.querySelector(".state-type").value}):this.model.save({filter_type:t,filter_text:this.querySelector(".roster-filter").value})}submitFilter(e){e&&e.preventDefault(),this.liveFilter()}isActive(){return"state"===this.model.get("filter_type")||this.model.get("filter_text")}shouldBeVisible(){return Zl.roster?.length>=5||this.isActive()}clearFilter(e){e&&e.preventDefault(),this.model.save({filter_text:""})}}wd.elements.define("converse-roster-filter",vT);var yT=n(3925),_T={};_T.styleTagTransform=_b(),_T.setAttributes=fb(),_T.insert=mb().bind(null,"head"),_T.domAPI=ub(),_T.insertStyleElement=vb();lb()(yT.Z,_T);yT.Z&&yT.Z.locals&&yT.Z.locals;Fm.plugins.add("converse-rosterview",{dependencies:["converse-roster","converse-modal","converse-chatboxviews"],initialize(){wd.settings.extend({autocomplete_add_contact:!0,allow_contact_removal:!0,hide_offline_users:!1,roster_groups:!0,xhr_user_search_url:null}),wd.promises.add("rosterViewInitialized"),Zl.RosterFilter=Uy,Zl.RosterFilterView=vT,Zl.RosterContactView=pT,wd.listen.on("chatBoxesInitialized",(()=>{Zl.chatboxes.on("destroy",(e=>HA(e))),Zl.chatboxes.on("change:hidden",(e=>HA(e)))})),wd.listen.on("afterTearDown",(()=>Zl.rotergroups?.off().reset()))}});var bT=n(705),wT={};wT.styleTagTransform=_b(),wT.setAttributes=fb(),wT.insert=mb().bind(null,"head"),wT.domAPI=ub(),wT.insertStyleElement=vb();lb()(bT.Z,wT);bT.Z&&bT.Z.locals&&bT.Z.locals;Fm.plugins.add("converse-singleton",{enabled:e=>e.api.settings.get("singleton"),initialize(){wd.settings.extend({allow_logout:!1,allow_muc_invitations:!1,hide_muc_server:!0});const e=wd.settings.get("auto_join_rooms"),t=wd.settings.get("auto_join_private_chats");if(!Array.isArray(e)&&!Array.isArray(t))throw new Error("converse-singleton: auto_join_rooms must be an Array");if(0===e.length&&0===t.length)throw new Error("If you set singleton set to true, you need to specify auto_join_rooms or auto_join_private_chats");if(e.length>0&&t.length>0)throw new Error("It doesn't make sense to have singleton set to true and auto_join_rooms or auto_join_private_chats set to more then one, since only one chat room may be open at any time.")}});const{u:ST}=Fm.env;function xT(e){let t=!(arguments.length>1&&void 0!==arguments[1])||arguments[1];if(!wd.settings.get("allow_dragresize"))return!0;e.preventDefault();const n=ST.ancestor(e.target,".box-flyout"),s=window.getComputedStyle(n),i=n.parentElement;i.height=parseInt(s.height.replace(/px$/,""),10),Zl.resizing={chatbox:i,direction:"top"},i.prev_pageY=e.pageY,t&&wd.trigger("startVerticalResize",i)}function AT(e){let t=!(arguments.length>1&&void 0!==arguments[1])||arguments[1];if(!wd.settings.get("allow_dragresize"))return!0;e.preventDefault();const n=ST.ancestor(e.target,".box-flyout"),s=window.getComputedStyle(n),i=n.parentElement;i.width=parseInt(s.width.replace(/px$/,""),10),Zl.resizing={chatbox:i,direction:"left"},i.prev_pageX=e.pageX,t&&wd.trigger("startHorizontalResize",i)}function ET(e){AT(e,!1),xT(e,!1),Zl.resizing.direction="topleft",wd.trigger("startDiagonalResize",this)}function $T(e,t){if(void 0===e)return;if(void 0===t)return e;return e!==t&&Math.abs(e-t)<10?t:e}function CT(e){if(!Zl.resizing||!wd.settings.get("allow_dragresize"))return!0;e.preventDefault(),Zl.resizing.chatbox.resizeChatBox(e)}function kT(e){if(!Zl.resizing||!wd.settings.get("allow_dragresize"))return!0;e.preventDefault();const t=$T(Zl.resizing.chatbox.height,Zl.resizing.chatbox.model.get("default_height")),n=$T(Zl.resizing.chatbox.width,Zl.resizing.chatbox.model.get("default_width"));wd.connection.connected()?(Zl.resizing.chatbox.model.save({height:t}),Zl.resizing.chatbox.model.save({width:n})):(Zl.resizing.chatbox.model.set({height:t}),Zl.resizing.chatbox.model.set({width:n})),Zl.resizing=null}const jT=()=>bm`
    `;wd.elements.define("converse-dragresize",class extends ob{render(){return jT()}});const TT={initDragResize(){const e=this,t=rd((()=>e.setDimensions()));window.addEventListener("resize",e.debouncedSetDimensions),this.listenTo(this.model,"destroy",(()=>window.removeEventListener("resize",t)));const n=this.querySelector(".box-flyout"),s=window.getComputedStyle(n);if(void 0===this.model.get("height")){const e=parseInt(s.height.replace(/px$/,""),10),t=parseInt(s.width.replace(/px$/,""),10);this.model.set("height",e),this.model.set("default_height",e),this.model.set("width",t),this.model.set("default_width",t)}const i=s["min-width"],r=s["min-height"];return this.model.set("min_width",i.endsWith("px")?Number(i.replace(/px$/,"")):0),this.model.set("min_height",r.endsWith("px")?Number(r.replace(/px$/,"")):0),this.prev_pageY=0,this.prev_pageX=0,Zl.connection?.connected&&(this.height=this.model.get("height"),this.width=this.model.get("width")),this},resizeChatBox(e){let t;0===Zl.resizing.direction.indexOf("top")&&(t=e.pageY-this.prev_pageY,t&&(this.height=this.height-t>(this.model.get("min_height")||0)?this.height-t:this.model.get("min_height"),this.prev_pageY=e.pageY,this.setChatBoxHeight(this.height))),Zl.resizing.direction.includes("left")&&(t=this.prev_pageX-e.pageX,t&&(this.width=this.width+t>(this.model.get("min_width")||0)?this.width+t:this.model.get("min_width"),this.prev_pageX=e.pageX,this.setChatBoxWidth(this.width)))},setDimensions(){this.adjustToViewport(),this.setChatBoxHeight(this.model.get("height")),this.setChatBoxWidth(this.model.get("width"))},setChatBoxHeight(e){e=e?$T(e,this.model.get("default_height"))+"px":"";const t=this.querySelector(".box-flyout");null!==t&&(t.style.height=e)},setChatBoxWidth(e){e=e?$T(e,this.model.get("default_width"))+"px":"",this.style.width=e;const t=this.querySelector(".box-flyout");null!==t&&(t.style.width=e)},adjustToViewport(){const e=Math.max(document.documentElement.clientWidth,window.innerWidth||0),t=Math.max(document.documentElement.clientHeight,window.innerHeight||0);e<=480?(this.model.set("height",void 0),this.model.set("width",void 0)):e<=this.model.get("width")?this.model.set("width",void 0):t<=this.model.get("height")&&this.model.set("height",void 0)}};Fm.plugins.add("converse-dragresize",{dependencies:["converse-chatview","converse-headlines-view","converse-muc-views"],enabled:e=>"overlayed"==e.api.settings.get("view_mode"),overrides:{ChatBox:{initialize(){const e=this.__super__.initialize.apply(this,arguments),t=this.get("height"),n=this.get("width"),s="controlbox"===this.get("id")?e=>this.set(e):e=>this.save(e);return s({height:$T(t,this.get("default_height")),width:$T(n,this.get("default_width"))}),e}}},initialize(){function e(e){const t=document.getElementsByTagName("iframe");for(let n of t)e.addEventListener("mousedown",(()=>{n.style.pointerEvents="none"}),{once:!0}),e.addEventListener("mouseup",(()=>{n.style.pointerEvents="initial"}),{once:!0})}wd.settings.extend({allow_dragresize:!0}),Object.assign(Zl.ChatBoxView.prototype,TT),Object.assign(Zl.ChatRoomView.prototype,TT),Zl.ControlBoxView&&Object.assign(Zl.ControlBoxView.prototype,TT),wd.listen.on("registeredGlobalEventHandlers",(function(){document.addEventListener("mousemove",CT),document.addEventListener("mouseup",kT)})),wd.listen.on("unregisteredGlobalEventHandlers",(function(){document.removeEventListener("mousemove",CT),document.removeEventListener("mouseup",kT)})),wd.listen.on("beforeShowingChatView",(e=>e.initDragResize().setDimensions())),wd.listen.on("startDiagonalResize",e),wd.listen.on("startHorizontalResize",e),wd.listen.on("startVerticalResize",e)}});var IT=n(6763),NT={};NT.styleTagTransform=_b(),NT.setAttributes=fb(),NT.insert=mb().bind(null,"head"),NT.domAPI=ub(),NT.insertStyleElement=vb();lb()(IT.Z,NT);IT.Z&&IT.Z.locals&&IT.Z.locals;Fm.plugins.add("converse-fullscreen",{enabled:()=>al(),initialize(){wd.settings.extend({chatview_avatar_height:50,chatview_avatar_width:50,hide_open_bookmarks:!0,show_controlbox_by_default:!0,sticky_controlbox:!0})}}),Zl.CustomElement=ob;const MT=Fm.initialize;Fm.initialize=function(e,t){return Array.isArray(e.whitelisted_plugins)?e.whitelisted_plugins=e.whitelisted_plugins.concat(ab):e.whitelisted_plugins=ab,MT(e,t)};const OT=Fm},8959:function(e,t,n){var s,i,r;i=[],void 0===(r="function"==typeof(s=function(){"use strict";var e=void 0!==n.g?n.g:this||window,t=document,s=t.documentElement,i="body",r=e.BSN={},o=r.supports=[],a="data-toggle",c="data-dismiss",l="Alert",d="Button",u="Collapse",h="Dropdown",m="Modal",g="Popover",f="Tab",p="data-backdrop",v="data-keyboard",y="data-target",_="data-height",b="data-title",w="data-dismissible",S="data-trigger",x="data-animation",A="data-container",E="data-placement",$="data-delay",C="backdrop",k="keyboard",j="delay",T="content",I="target",N="currentTarget",M="animation",O="placement",R="container",D="offsetTop",z="offsetLeft",P="scrollTop",L="scrollLeft",F="clientWidth",U="clientHeight",B="offsetWidth",q="offsetHeight",H="innerWidth",G="scrollHeight",W="height",V="aria-expanded",Z="aria-hidden",Q="aria-selected",J="click",K="focus",Y="hover",X="keydown",ee="keyup",te="resize",ne="onmouseleave"in t?["mouseenter","mouseleave"]:["mouseover","mouseout"],se="show",ie="shown",re="hide",oe="hidden",ae="close",ce="closed",le="change",de="getAttribute",ue="setAttribute",he="hasAttribute",me="createElement",ge="appendChild",fe="innerHTML",pe="getElementsByTagName",ve="preventDefault",ye="getBoundingClientRect",_e="querySelectorAll",be="getElementsByClassName",we="getComputedStyle",Se="indexOf",xe="parentNode",Ae="length",Ee="toLowerCase",$e="Transition",Ce="Duration",ke="Webkit",je="style",Te="push",Ie="tabindex",Ne="contains",Me="active",Oe="show",Re="collapsing",De="left",ze="right",Pe="top",Le="bottom",Fe=/\b(top|bottom|left|right)+/,Ue=0,Be="fixed-top",qe="fixed-bottom",He=ke+$e in s[je]||$e[Ee]()in s[je],Ge=ke+$e in s[je]?ke[Ee]()+$e+"End":$e[Ee]()+"end",We=ke+Ce in s[je]?ke[Ee]()+$e+Ce:$e[Ee]()+Ce,Ve=function(e){e.focus?e.focus():e.setActive()},Ze=function(e,t){e.classList.add(t)},Qe=function(e,t){e.classList.remove(t)},Je=function(e,t){return e.classList[Ne](t)},Ke=function(e,t){return[].slice.call(e[be](t))},Ye=function(e,n){return"object"==typeof e?e:(n||t).querySelector(e)},Xe=function(e,n){var s=n.charAt(0),i=n.substr(1);if("."===s){for(;e&&e!==t;e=e[xe])if(null!==Ye(n,e[xe])&&Je(e,i))return e}else if("#"===s)for(;e&&e!==t;e=e[xe])if(e.id===i)return e;return!1},et=function(e,t,n,s){s=s||!1,e.addEventListener(t,n,s)},tt=function(e,t,n,s){s=s||!1,e.removeEventListener(t,n,s)},nt=function(e,t,n,s){et(e,t,(function i(r){n(r),tt(e,t,i,s)}),s)},st=!!function(){var t=!1;try{var n=Object.defineProperty({},"passive",{get:function(){t=!0}});nt(e,"testPassive",null,n)}catch(e){}return t}()&&{passive:!0},it=function(t){var n=He?e[we](t)[We]:0;return n="number"!=typeof(n=parseFloat(n))||isNaN(n)?0:1e3*n},rt=function(e,t){var n=0;it(e)?nt(e,Ge,(function(e){!n&&t(e),n=1})):setTimeout((function(){!n&&t(),n=1}),17)},ot=function(e,t,n){var s=new CustomEvent(e+".bs."+t);s.relatedTarget=n,this.dispatchEvent(s)},at=function(){return{y:e.pageYOffset||s[P],x:e.pageXOffset||s[L]}},ct=function(e,n,r,o){var a,c,l,d,u,h,m={w:n[B],h:n[q]},g=s[F]||t[i][F],f=s[U]||t[i][U],p=e[ye](),v=o===t[i]?at():{x:o[z]+o[L],y:o[D]+o[P]},y={w:p[ze]-p[De],h:p[Le]-p[Pe]},_=Je(n,"popover"),b=Ye(".arrow",n),w=p[Pe]+y.h/2-m.h/2<0,S=p[De]+y.w/2-m.w/2<0,x=p[De]+m.w/2+y.w/2>=g,A=p[Pe]+m.h/2+y.h/2>=f,E=p[Pe]-m.h<0,$=p[De]-m.w<0,C=p[Pe]+m.h+y.h>=f,k=p[De]+m.w+y.w>=g;r=(r=(r=(r=(r=(r===De||r===ze)&&$&&k?Pe:r)===Pe&&E?Le:r)===Le&&C?Pe:r)===De&&$?ze:r)===ze&&k?De:r,-1===n.className[Se](r)&&(n.className=n.className.replace(Fe,r)),u=b[B],h=b[q],r===De||r===ze?(c=r===De?p[De]+v.x-m.w-(_?u:0):p[De]+v.x+y.w,w?(a=p[Pe]+v.y,l=y.h/2-u):A?(a=p[Pe]+v.y-m.h+y.h,l=m.h-y.h/2-u):(a=p[Pe]+v.y-m.h/2+y.h/2,l=m.h/2-(_?.9*h:h/2))):r!==Pe&&r!==Le||(a=r===Pe?p[Pe]+v.y-m.h-(_?h:0):p[Pe]+v.y+y.h,S?(c=0,d=p[De]+y.w/2-u):x?(c=g-1.01*m.w,d=m.w-(g-p[De])+y.w/2-u/2):(c=p[De]+v.x-m.w/2+y.w/2,d=m.w/2-(_?u:u/2))),n[je][Pe]=a+"px",n[je][De]=c+"px",l&&(b[je][Pe]=l+"px"),d&&(b[je][De]=d+"px")};r.version="2.0.27";var lt=function(e){e=Ye(e);var t=this,n="alert",s=Xe(e,"."+n),i=function(){Je(s,"fade")?rt(s,o):o()},r=function(i){s=Xe(i[I],"."+n),(e=Ye("["+c+'="'+n+'"]',s))&&s&&(e===i[I]||e[Ne](i[I]))&&t.close()},o=function(){ot.call(s,ce,n),tt(e,J,r),s[xe].removeChild(s)};this.close=function(){s&&e&&Je(s,Oe)&&(ot.call(s,ae,n),Qe(s,Oe),s&&i())},l in e||et(e,J,r),e[l]=t};o[Te]([l,lt,"["+c+'="alert"]']);var dt=function(e){e=Ye(e);var n=!1,s="button",i="checked",r="LABEL",o="INPUT",a=function(e){32===(e.which||e.keyCode)&&e[I]===t.activeElement&&l(e)},c=function(e){32===(e.which||e.keyCode)&&e[ve]()},l=function(t){var a=t[I].tagName===r?t[I]:t[I][xe].tagName===r?t[I][xe]:null;if(a){var c=Ke(a[xe],"btn"),l=a[pe](o)[0];if(l){if("checkbox"===l.type&&(l[i]?(Qe(a,Me),l[de](i),l.removeAttribute(i),l[i]=!1):(Ze(a,Me),l[de](i),l[ue](i,i),l[i]=!0),n||(n=!0,ot.call(l,le,s),ot.call(e,le,s))),"radio"===l.type&&!n&&(!l[i]||0===t.screenX&&0==t.screenY)){Ze(a,Me),Ze(a,K),l[ue](i,i),l[i]=!0,ot.call(l,le,s),ot.call(e,le,s),n=!0;for(var d=0,u=c[Ae];d1?o-1:0:40===i&&o×',k=Ye(s[R]),T=Ye(d),N=Xe(n,".modal"),D=Xe(n,"."+Be),z=Xe(n,"."+qe);this[h]=s[h]?s[h]:null,this[m]=s[m]?s[m]:r||Y,this[M]=s[M]&&s[M]!==v?s[M]:o||v,this[O]=s[O]?s[O]:a||Pe,this[j]=parseInt(s[j]||l)||200,this[_]=!(!s[_]&&"true"!==c),this[R]=k||T||D||z||N||t[i];var P=this,L=s.title||n[de](b)||null,F=s.content||n[de](y)||null;if(F||this[h]){var U=null,B=0,q=this[O],H=function(e){null!==U&&e[I]===Ye(".close",U)&&P.hide()},G=function(){P[R].removeChild(U),B=null,U=null},W=function(){L=s.title||n[de](b),F=(F=s.content||n[de](y))?F.trim():null,U=t[me](p);var e=t[me](p);if(e[ue](f,"arrow"),U[ge](e),null!==F&&null===P[h]){if(U[ue]("role","tooltip"),null!==L){var i=t[me]("h3");i[ue](f,u+"-header"),i[fe]=P[_]?L+C:L,U[ge](i)}var r=t[me](p);r[ue](f,u+"-body"),r[fe]=P[_]&&null===L?F+C:F,U[ge](r)}else{var o=t[me](p);P[h]=P[h].trim(),o[fe]=P[h],U[fe]=o.firstChild[fe]}P[R][ge](U),U[je].display="block",U[ue](f,u+" bs-"+u+"-"+q+" "+P[M])},V=function(){!Je(U,Oe)&&Ze(U,Oe)},Z=function(){ct(n,U,q,P[R])},Q=function(s){J!=P[m]&&"focus"!=P[m]||!P[_]&&s(n,"blur",P.hide),P[_]&&s(t,J,H),s(e,te,P.hide,st)},K=function(){Q(et),ot.call(n,ie,u)},X=function(){Q(tt),G(),ot.call(n,oe,u)};this.toggle=function(){null===U?P.show():P.hide()},this.show=function(){clearTimeout(B),B=setTimeout((function(){null===U&&(q=P[O],W(),Z(),V(),ot.call(n,se,u),P[M]?rt(U,K):K())}),20)},this.hide=function(){clearTimeout(B),B=setTimeout((function(){U&&null!==U&&Je(U,Oe)&&(ot.call(n,re,u),Qe(U,Oe),P[M]?rt(U,X):X())}),P[j])},g in n||(P[m]===Y?(et(n,ne[0],P.show),P[_]||et(n,ne[1],P.hide)):J!=P[m]&&"focus"!=P[m]||et(n,P[m],P.toggle)),n[g]=P}};o[Te]([g,gt,"["+a+'="popover"]']);var ft=function(e,t){var n=(e=Ye(e))[de](_),s="tab",i="height",r="float",o="isAnimating";t=t||{},this[i]=!!He&&(t[i]||"true"===n);var a,c,l,d,u,h,m,g=this,p=Xe(e,".nav"),v=!1,y=p&&Ye(".dropdown-toggle",p),b=function(){v[je][i]="",Qe(v,Re),p[o]=!1},w=function(){v?h?b():setTimeout((function(){v[je][i]=m+"px",v[B],rt(v,b)}),50):p[o]=!1,ot.call(a,ie,s,c)},S=function(){v&&(l[je][r]=De,d[je][r]=De,u=l[G]),Ze(d,Me),ot.call(a,se,s,c),Qe(l,Me),ot.call(c,oe,s,a),v&&(m=d[G],h=m===u,Ze(v,Re),v[je][i]=u+"px",v[q],l[je][r]="",d[je][r]=""),Je(d,"fade")?setTimeout((function(){Ze(d,Oe),rt(d,w)}),20):w()};if(p){p[o]=!1;var x=function(){var e,t=Ke(p,Me);return 1!==t[Ae]||Je(t[0][xe],"dropdown")?t[Ae]>1&&(e=t[t[Ae]-1]):e=t[0],e},A=function(){return Ye(x()[de]("href"))},E=function(e){e[ve](),a=e[N],!p[o]&&!Je(a,Me)&&g.show()};this.show=function(){d=Ye((a=a||e)[de]("href")),c=x(),l=A(),p[o]=!0,Qe(c,Me),c[ue](Q,"false"),Ze(a,Me),a[ue](Q,"true"),y&&(Je(e[xe],"dropdown-menu")?Je(y,Me)||Ze(y,Me):Je(y,Me)&&Qe(y,Me)),ot.call(c,re,s,a),Je(l,"fade")?(Qe(l,Oe),rt(l,S)):S()},f in e||et(e,J,E),g[i]&&(v=A()[xe]),e[f]=g}};o[Te]([f,ft,"["+a+'="tab"]']);var pt=function(e,t){for(var n=0,s=t[Ae];n{"use strict";n.d(t,{Z:()=>a});var s=n(9518),i=n.n(s),r=n(1782),o=n.n(r)()(i());o.push([e.id,"","",{version:3,sources:[],names:[],mappings:"",sourceRoot:""}]);const a=o},148:(e,t,n)=>{"use strict";n.d(t,{Z:()=>a});var s=n(9518),i=n.n(s),r=n(1782),o=n.n(r)()(i());o.push([e.id,"","",{version:3,sources:[],names:[],mappings:"",sourceRoot:""}]);const a=o},298:(e,t,n)=>{"use strict";n.d(t,{Z:()=>a});var s=n(9518),i=n.n(s),r=n(1782),o=n.n(r)()(i());o.push([e.id,"","",{version:3,sources:[],names:[],mappings:"",sourceRoot:""}]);const a=o},263:(e,t,n)=>{"use strict";n.d(t,{Z:()=>a});var s=n(9518),i=n.n(s),r=n(1782),o=n.n(r)()(i());o.push([e.id,"","",{version:3,sources:[],names:[],mappings:"",sourceRoot:""}]);const a=o},110:(e,t,n)=>{"use strict";n.d(t,{Z:()=>a});var s=n(9518),i=n.n(s),r=n(1782),o=n.n(r)()(i());o.push([e.id,"","",{version:3,sources:[],names:[],mappings:"",sourceRoot:""}]);const a=o},7740:(e,t,n)=>{"use strict";n.d(t,{Z:()=>a});var s=n(9518),i=n.n(s),r=n(1782),o=n.n(r)()(i());o.push([e.id,"","",{version:3,sources:[],names:[],mappings:"",sourceRoot:""}]);const a=o},4706:(e,t,n)=>{"use strict";n.d(t,{Z:()=>a});var s=n(9518),i=n.n(s),r=n(1782),o=n.n(r)()(i());o.push([e.id,"","",{version:3,sources:[],names:[],mappings:"",sourceRoot:""}]);const a=o},6763:(e,t,n)=>{"use strict";n.d(t,{Z:()=>a});var s=n(9518),i=n.n(s),r=n(1782),o=n.n(r)()(i());o.push([e.id,"","",{version:3,sources:[],names:[],mappings:"",sourceRoot:""}]);const a=o},2118:(e,t,n)=>{"use strict";n.d(t,{Z:()=>a});var s=n(9518),i=n.n(s),r=n(1782),o=n.n(r)()(i());o.push([e.id,"","",{version:3,sources:[],names:[],mappings:"",sourceRoot:""}]);const a=o},8250:(e,t,n)=>{"use strict";n.d(t,{Z:()=>a});var s=n(9518),i=n.n(s),r=n(1782),o=n.n(r)()(i());o.push([e.id,"","",{version:3,sources:[],names:[],mappings:"",sourceRoot:""}]);const a=o},7725:(e,t,n)=>{"use strict";n.d(t,{Z:()=>a});var s=n(9518),i=n.n(s),r=n(1782),o=n.n(r)()(i());o.push([e.id,"","",{version:3,sources:[],names:[],mappings:"",sourceRoot:""}]);const a=o},4540:(e,t,n)=>{"use strict";n.d(t,{Z:()=>a});var s=n(9518),i=n.n(s),r=n(1782),o=n.n(r)()(i());o.push([e.id,"","",{version:3,sources:[],names:[],mappings:"",sourceRoot:""}]);const a=o},1064:(e,t,n)=>{"use strict";n.d(t,{Z:()=>a});var s=n(9518),i=n.n(s),r=n(1782),o=n.n(r)()(i());o.push([e.id,"","",{version:3,sources:[],names:[],mappings:"",sourceRoot:""}]);const a=o},5902:(e,t,n)=>{"use strict";n.d(t,{Z:()=>a});var s=n(9518),i=n.n(s),r=n(1782),o=n.n(r)()(i());o.push([e.id,"","",{version:3,sources:[],names:[],mappings:"",sourceRoot:""}]);const a=o},2832:(e,t,n)=>{"use strict";n.d(t,{Z:()=>a});var s=n(9518),i=n.n(s),r=n(1782),o=n.n(r)()(i());o.push([e.id,"","",{version:3,sources:[],names:[],mappings:"",sourceRoot:""}]);const a=o},4891:(e,t,n)=>{"use strict";n.d(t,{Z:()=>a});var s=n(9518),i=n.n(s),r=n(1782),o=n.n(r)()(i());o.push([e.id,"","",{version:3,sources:[],names:[],mappings:"",sourceRoot:""}]);const a=o},5777:(e,t,n)=>{"use strict";n.d(t,{Z:()=>a});var s=n(9518),i=n.n(s),r=n(1782),o=n.n(r)()(i());o.push([e.id,"","",{version:3,sources:[],names:[],mappings:"",sourceRoot:""}]);const a=o},1067:(e,t,n)=>{"use strict";n.d(t,{Z:()=>a});var s=n(9518),i=n.n(s),r=n(1782),o=n.n(r)()(i());o.push([e.id,"","",{version:3,sources:[],names:[],mappings:"",sourceRoot:""}]);const a=o},4083:(e,t,n)=>{"use strict";n.d(t,{Z:()=>a});var s=n(9518),i=n.n(s),r=n(1782),o=n.n(r)()(i());o.push([e.id,"","",{version:3,sources:[],names:[],mappings:"",sourceRoot:""}]);const a=o},7428:(e,t,n)=>{"use strict";n.d(t,{Z:()=>a});var s=n(9518),i=n.n(s),r=n(1782),o=n.n(r)()(i());o.push([e.id,"","",{version:3,sources:[],names:[],mappings:"",sourceRoot:""}]);const a=o},6714:(e,t,n)=>{"use strict";n.d(t,{Z:()=>a});var s=n(9518),i=n.n(s),r=n(1782),o=n.n(r)()(i());o.push([e.id,"","",{version:3,sources:[],names:[],mappings:"",sourceRoot:""}]);const a=o},3538:(e,t,n)=>{"use strict";n.d(t,{Z:()=>a});var s=n(9518),i=n.n(s),r=n(1782),o=n.n(r)()(i());o.push([e.id,"","",{version:3,sources:[],names:[],mappings:"",sourceRoot:""}]);const a=o},7089:(e,t,n)=>{"use strict";n.d(t,{Z:()=>a});var s=n(9518),i=n.n(s),r=n(1782),o=n.n(r)()(i());o.push([e.id,"","",{version:3,sources:[],names:[],mappings:"",sourceRoot:""}]);const a=o},3925:(e,t,n)=>{"use strict";n.d(t,{Z:()=>a});var s=n(9518),i=n.n(s),r=n(1782),o=n.n(r)()(i());o.push([e.id,"","",{version:3,sources:[],names:[],mappings:"",sourceRoot:""}]);const a=o},705:(e,t,n)=>{"use strict";n.d(t,{Z:()=>a});var s=n(9518),i=n.n(s),r=n(1782),o=n.n(r)()(i());o.push([e.id,"","",{version:3,sources:[],names:[],mappings:"",sourceRoot:""}]);const a=o},2642:(e,t,n)=>{"use strict";n.d(t,{Z:()=>a});var s=n(9518),i=n.n(s),r=n(1782),o=n.n(r)()(i());o.push([e.id,"","",{version:3,sources:[],names:[],mappings:"",sourceRoot:""}]);const a=o},7233:(e,t,n)=>{"use strict";n.d(t,{Z:()=>a});var s=n(9518),i=n.n(s),r=n(1782),o=n.n(r)()(i());o.push([e.id,"","",{version:3,sources:[],names:[],mappings:"",sourceRoot:""}]);const a=o},8765:(e,t,n)=>{"use strict";n.d(t,{Z:()=>a});var s=n(9518),i=n.n(s),r=n(1782),o=n.n(r)()(i());o.push([e.id,"","",{version:3,sources:[],names:[],mappings:"",sourceRoot:""}]);const a=o},2432:(e,t,n)=>{"use strict";n.d(t,{Z:()=>a});var s=n(9518),i=n.n(s),r=n(1782),o=n.n(r)()(i());o.push([e.id,"","",{version:3,sources:[],names:[],mappings:"",sourceRoot:""}]);const a=o},1540:(e,t,n)=>{"use strict";n.d(t,{Z:()=>a});var s=n(9518),i=n.n(s),r=n(1782),o=n.n(r)()(i());o.push([e.id,"","",{version:3,sources:[],names:[],mappings:"",sourceRoot:""}]);const a=o},6933:(e,t,n)=>{"use strict";n.d(t,{Z:()=>a});var s=n(9518),i=n.n(s),r=n(1782),o=n.n(r)()(i());o.push([e.id,"","",{version:3,sources:[],names:[],mappings:"",sourceRoot:""}]);const a=o},7643:(e,t,n)=>{"use strict";n.d(t,{Z:()=>a});var s=n(9518),i=n.n(s),r=n(1782),o=n.n(r)()(i());o.push([e.id,"","",{version:3,sources:[],names:[],mappings:"",sourceRoot:""}]);const a=o},9833:(e,t,n)=>{"use strict";n.d(t,{Z:()=>a});var s=n(9518),i=n.n(s),r=n(1782),o=n.n(r)()(i());o.push([e.id,"","",{version:3,sources:[],names:[],mappings:"",sourceRoot:""}]);const a=o},8906:(e,t,n)=>{"use strict";n.d(t,{Z:()=>a});var s=n(9518),i=n.n(s),r=n(1782),o=n.n(r)()(i());o.push([e.id,"","",{version:3,sources:[],names:[],mappings:"",sourceRoot:""}]);const a=o},9211:(e,t,n)=>{"use strict";n.d(t,{Z:()=>a});var s=n(9518),i=n.n(s),r=n(1782),o=n.n(r)()(i());o.push([e.id,"","",{version:3,sources:[],names:[],mappings:"",sourceRoot:""}]);const a=o},9478:(e,t,n)=>{"use strict";n.d(t,{Z:()=>a});var s=n(9518),i=n.n(s),r=n(1782),o=n.n(r)()(i());o.push([e.id,"","",{version:3,sources:[],names:[],mappings:"",sourceRoot:""}]);const a=o},8916:(e,t,n)=>{"use strict";n.d(t,{Z:()=>a});var s=n(9518),i=n.n(s),r=n(1782),o=n.n(r)()(i());o.push([e.id,"","",{version:3,sources:[],names:[],mappings:"",sourceRoot:""}]);const a=o},2533:(e,t,n)=>{"use strict";n.d(t,{Z:()=>a});var s=n(9518),i=n.n(s),r=n(1782),o=n.n(r)()(i());o.push([e.id,"","",{version:3,sources:[],names:[],mappings:"",sourceRoot:""}]);const a=o},2864:(e,t,n)=>{"use strict";n.d(t,{Z:()=>a});var s=n(9518),i=n.n(s),r=n(1782),o=n.n(r)()(i());o.push([e.id,"","",{version:3,sources:[],names:[],mappings:"",sourceRoot:""}]);const a=o},17:(e,t,n)=>{"use strict";n.d(t,{Z:()=>a});var s=n(9518),i=n.n(s),r=n(1782),o=n.n(r)()(i());o.push([e.id,"","",{version:3,sources:[],names:[],mappings:"",sourceRoot:""}]);const a=o},6407:(e,t,n)=>{"use strict";n.d(t,{Z:()=>a});var s=n(9518),i=n.n(s),r=n(1782),o=n.n(r)()(i());o.push([e.id,"","",{version:3,sources:[],names:[],mappings:"",sourceRoot:""}]);const a=o},5152:(e,t,n)=>{"use strict";n.d(t,{Z:()=>a});var s=n(9518),i=n.n(s),r=n(1782),o=n.n(r)()(i());o.push([e.id,"","",{version:3,sources:[],names:[],mappings:"",sourceRoot:""}]);const a=o},9434:(e,t,n)=>{var s={"./af.js":[5348,9210],"./am.js":[6282,5073],"./ar-dz.js":[1230,9406],"./ar-iq.js":[3790,2990],"./ar-kw.js":[1611,9897],"./ar-ly.js":[7955,3521],"./ar-ma.js":[5501,5313],"./ar-sa.js":[7113,485],"./ar-tn.js":[1878,8040],"./ar.js":[7197,6755],"./az.js":[3848,4963],"./be.js":[3986,9478],"./bg.js":[8210,578],"./bi.js":[8813,2984],"./bm.js":[3757,2263],"./bn-bd.js":[5150,1351],"./bn.js":[2248,280],"./bo.js":[5552,9950],"./br.js":[3746,760],"./bs.js":[9559,9833],"./ca.js":[8728,102],"./cs.js":[652,7400],"./cv.js":[8628,4481],"./cy.js":[5315,6740],"./da.js":[3872,2548],"./de-at.js":[4444,7175],"./de-ch.js":[7650,1679],"./de.js":[7547,52],"./dv.js":[7771,5569],"./el.js":[4610,1606],"./en-au.js":[8514,5485],"./en-ca.js":[1234,4035],"./en-gb.js":[6764,6031],"./en-ie.js":[6557,8129],"./en-il.js":[7474,3463],"./en-in.js":[3716,6898],"./en-nz.js":[375,8547],"./en-sg.js":[1621,1735],"./en-tt.js":[1647,6105],"./en.js":[6487,535],"./eo.js":[633,5121],"./es-do.js":[2803,8758],"./es-mx.js":[1300,7416],"./es-pr.js":[3995,911],"./es-us.js":[138,3208],"./es.js":[336,3411],"./et.js":[9289,4153],"./eu.js":[4772,1396],"./fa.js":[1823,5544],"./fi.js":[3943,2130],"./fo.js":[4335,8745],"./fr-ca.js":[2549,7363],"./fr-ch.js":[1270,7952],"./fr.js":[7704,1910],"./fy.js":[7624,6376],"./ga.js":[8319,688],"./gd.js":[4598,5050],"./gl.js":[8664,5818],"./gom-latn.js":[6281,825],"./gu.js":[8818,3623],"./he.js":[3184,9372],"./hi.js":[8496,8010],"./hr.js":[6800,7419],"./ht.js":[6630,5822],"./hu.js":[327,8214],"./hy-am.js":[4619,5407],"./id.js":[909,9513],"./is.js":[7701,1194],"./it-ch.js":[6906,6010],"./it.js":[4871,1880],"./ja.js":[5142,1107],"./jv.js":[3126,4305],"./ka.js":[5907,5186],"./kk.js":[2554,5206],"./km.js":[7468,2475],"./kn.js":[6880,7523],"./ko.js":[5806,3446],"./ku.js":[6842,7024],"./ky.js":[3826,5055],"./lb.js":[8107,5215],"./lo.js":[4042,1204],"./lt.js":[6511,7899],"./lv.js":[4391,631],"./me.js":[2,145],"./mi.js":[3938,7454],"./mk.js":[8799,4951],"./ml.js":[7919,7679],"./mn.js":[1783,8618],"./mr.js":[5866,5600],"./ms-my.js":[9283,882],"./ms.js":[8437,9095],"./mt.js":[4756,9665],"./my.js":[2641,5166],"./nb.js":[340,646],"./ne.js":[7443,9030],"./nl-be.js":[9935,3155],"./nl.js":[9513,1520],"./nn.js":[6128,7050],"./oc-lnc.js":[9402,7203],"./pa-in.js":[7963,5850],"./pl.js":[29,1211],"./pt-br.js":[9815,5274],"./pt.js":[5525,265],"./rn.js":[388,4678],"./ro.js":[810,8022],"./ru.js":[7775,559],"./rw.js":[5509,3221],"./sd.js":[7067,1298],"./se.js":[8286,1942],"./si.js":[7473,9333],"./sk.js":[4115,6783],"./sl.js":[7849,9625],"./sq.js":[3354,8603],"./sr-cyrl.js":[8404,3435],"./sr.js":[7941,7390],"./ss.js":[1901,9238],"./sv-fi.js":[5759,9997],"./sv.js":[9508,9652],"./sw.js":[1761,9733],"./ta.js":[7809,7645],"./te.js":[9301,7714],"./tet.js":[3850,555],"./tg.js":[7049,2446],"./th.js":[368,1729],"./tk.js":[8454,5256],"./tl-ph.js":[2107,9443],"./tlh.js":[4270,2814],"./tr.js":[9366,8665],"./tzl.js":[1174,2843],"./tzm-latn.js":[4320,3933],"./tzm.js":[9146,4342],"./ug-cn.js":[2880,6890],"./uk.js":[9116,1619],"./ur.js":[5003,9568],"./uz-latn.js":[6090,1110],"./uz.js":[9052,3153],"./vi.js":[5955,8073],"./x-pseudo.js":[1017,4423],"./yo.js":[4048,8692],"./zh-cn.js":[8516,9630],"./zh-hk.js":[8104,3755],"./zh-tw.js":[9761,6776],"./zh.js":[9542,8458]};function i(e){if(!n.o(s,e))return Promise.resolve().then((()=>{var t=new Error("Cannot find module '"+e+"'");throw t.code="MODULE_NOT_FOUND",t}));var t=s[e],i=t[0];return n.e(t[1]).then((()=>n.t(i,23)))}i.keys=()=>Object.keys(s),i.id=9434,e.exports=i},7340:e=>{window,e.exports=function(e){var t={};function n(s){if(t[s])return t[s].exports;var i=t[s]={i:s,l:!1,exports:{}};return e[s].call(i.exports,i,i.exports,n),i.l=!0,i.exports}return n.m=e,n.c=t,n.d=function(e,t,s){n.o(e,t)||Object.defineProperty(e,t,{configurable:!1,enumerable:!0,get:s})},n.r=function(e){Object.defineProperty(e,"__esModule",{value:!0})},n.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(t,"a",t),t},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},n.p="",n(n.s=7)}([function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.loadImageElement=function(e,t){return new Promise((function(n,s){e.addEventListener("load",(function(){n(e)}),!1),e.addEventListener("error",(function(e){s(e)}),!1),e.src=t}))},t.resize=function(e,t,n,s){if(!n&&!s)return{currentWidth:e,currentHeight:t};var i=e/t,r=void 0,o=void 0;return i>n/s?o=(r=Math.min(e,n))/i:r=(o=Math.min(t,s))*i,{width:r,height:o}}},function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.base64ToFile=function(e){for(var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:"image/jpeg",n=window.atob(e),s=[],i=0;i8)return r.drawImage(e,0,0,i.width,i.height),i;switch(s>4&&(i.width=n,i.height=t),s){case 2:r.translate(t,0),r.scale(-1,1);break;case 3:r.translate(t,n),r.rotate(Math.PI);break;case 4:r.translate(0,n),r.scale(1,-1);break;case 5:r.rotate(.5*Math.PI),r.scale(1,-1);break;case 6:r.rotate(.5*Math.PI),r.translate(0,-n);break;case 7:r.rotate(.5*Math.PI),r.translate(t,-n),r.scale(-1,1);break;case 8:r.rotate(-.5*Math.PI),r.translate(-t,0)}return s>4?r.drawImage(e,0,0,i.height,i.width):r.drawImage(e,0,0,i.width,i.height),i},t.canvasToBlob=function(e,t){return new Promise((function(n,s){e.toBlob((function(e){n(e)}),"image/jpeg",t)}))},t.size=function(e){return{kB:.001*e,MB:1e-6*e}},t.blobToBase64=function(e){return new Promise((function(t,n){var s=new window.FileReader;s.addEventListener("load",(function(e){t(e.target.result)}),!1),s.addEventListener("error",(function(e){n(e)}),!1),s.readAsDataURL(e)}))}},function(e,t,n){e.exports=n(6)},function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.extractOrientation=function(e){return new Promise((function(t,n){var s=new window.FileReader;s.onload=function(e){var n=new DataView(e.target.result);65496!==n.getUint16(0,!1)&&t(-2);for(var s=n.byteLength,i=2;i=0;--r){var o=this.tryEntries[r],a=o.completion;if("root"===o.tryLoc)return s("end");if(o.tryLoc<=this.prev){var c=i.call(o,"catchLoc"),l=i.call(o,"finallyLoc");if(c&&l){if(this.prev=0;--n){var s=this.tryEntries[n];if(s.tryLoc<=this.prev&&i.call(s,"finallyLoc")&&this.prev=0;--t){var n=this.tryEntries[t];if(n.finallyLoc===e)return this.complete(n.completion,n.afterLoc),j(n),f}},catch:function(e){for(var t=this.tryEntries.length-1;t>=0;--t){var n=this.tryEntries[t];if(n.tryLoc===e){var s=n.completion;if("throw"===s.type){var i=s.arg;j(n)}return i}}throw new Error("illegal catch attempt")},delegateYield:function(e,t,s){return this.delegate={iterator:I(e),resultName:t,nextLoc:s},"next"===this.method&&(this.arg=n),f}}}function b(e,t,n,s){var i=t&&t.prototype instanceof S?t:S,r=Object.create(i.prototype),o=new T(s||[]);return r._invoke=function(e,t,n){var s=u;return function(i,r){if(s===m)throw new Error("Generator is already running");if(s===g){if("throw"===i)throw r;return N()}for(n.method=i,n.arg=r;;){var o=n.delegate;if(o){var a=C(o,n);if(a){if(a===f)continue;return a}}if("next"===n.method)n.sent=n._sent=n.arg;else if("throw"===n.method){if(s===u)throw s=g,n.arg;n.dispatchException(n.arg)}else"return"===n.method&&n.abrupt("return",n.arg);s=m;var c=w(e,t,n);if("normal"===c.type){if(s=n.done?g:h,c.arg===f)continue;return{value:c.arg,done:n.done}}"throw"===c.type&&(s=g,n.method="throw",n.arg=c.arg)}}}(e,n,o),r}function w(e,t,n){try{return{type:"normal",arg:e.call(t,n)}}catch(e){return{type:"throw",arg:e}}}function S(){}function x(){}function A(){}function E(e){["next","throw","return"].forEach((function(t){e[t]=function(e){return this._invoke(t,e)}}))}function $(e){var t;this._invoke=function(n,s){function r(){return new Promise((function(t,r){!function t(n,s,r,o){var a=w(e[n],e,s);if("throw"!==a.type){var c=a.arg,l=c.value;return l&&"object"==typeof l&&i.call(l,"__await")?Promise.resolve(l.__await).then((function(e){t("next",e,r,o)}),(function(e){t("throw",e,r,o)})):Promise.resolve(l).then((function(e){c.value=e,r(c)}),o)}o(a.arg)}(n,s,t,r)}))}return t=t?t.then(r,r):r()}}function C(e,t){var s=e.iterator[t.method];if(s===n){if(t.delegate=null,"throw"===t.method){if(e.iterator.return&&(t.method="return",t.arg=n,C(e,t),"throw"===t.method))return f;t.method="throw",t.arg=new TypeError("The iterator does not provide a 'throw' method")}return f}var i=w(s,e.iterator,t.arg);if("throw"===i.type)return t.method="throw",t.arg=i.arg,t.delegate=null,f;var r=i.arg;return r?r.done?(t[e.resultName]=r.value,t.next=e.nextLoc,"return"!==t.method&&(t.method="next",t.arg=n),t.delegate=null,f):r:(t.method="throw",t.arg=new TypeError("iterator result is not an object"),t.delegate=null,f)}function k(e){var t={tryLoc:e[0]};1 in e&&(t.catchLoc=e[1]),2 in e&&(t.finallyLoc=e[2],t.afterLoc=e[3]),this.tryEntries.push(t)}function j(e){var t=e.completion||{};t.type="normal",delete t.arg,e.completion=t}function T(e){this.tryEntries=[{tryLoc:"root"}],e.forEach(k,this),this.reset(!0)}function I(e){if(e){var t=e[o];if(t)return t.call(e);if("function"==typeof e.next)return e;if(!isNaN(e.length)){var s=-1,r=function t(){for(;++s=0,r=i&&s.regeneratorRuntime;if(s.regeneratorRuntime=void 0,e.exports=n(5),i)s.regeneratorRuntime=r;else try{delete s.regeneratorRuntime}catch(e){s.regeneratorRuntime=void 0}},function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var s=c(n(2)),i=function(){function e(e,t){for(var n=0;n0&&void 0!==arguments[0]?arguments[0]:{};!function(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}(this,e),this.setOptions(t)}return i(e,[{key:"setOptions",value:function(e){var t={targetSize:1/0,quality:.75,minQuality:.5,qualityStepSize:.1,maxWidth:1920,maxHeight:1920,resize:!0,throwIfSizeNotReached:!1,autoRotate:!0},n=new Proxy(e,{get:function(e,n){return n in e?e[n]:t[n]}});this.options=n}},{key:"_compressFile",value:function(){var e=l(s.default.mark((function e(t){var n,i;return s.default.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return n=new a.default(t),(i={}).start=window.performance.now(),i.quality=this.options.quality,i.startType=n.type,e.next=7,n.load();case 7:return e.next=9,this._compressImage(n,i);case 9:return e.abrupt("return",e.sent);case 10:case"end":return e.stop()}}),e,this)})));return function(t){return e.apply(this,arguments)}}()},{key:"_compressImage",value:function(){var e=l(s.default.mark((function e(t,n){var i,a,c,l,d;return s.default.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return n.startWidth=t.width,n.startHeight=t.height,i=void 0,a=void 0,this.options.resize?(c=(0,o.resize)(t.width,t.height,this.options.maxWidth,this.options.maxHeight),i=c.width,a=c.height):(i=t.width,a=t.height),n.endWidth=i,n.endHeight=a,l=this.doAutoRotation?void 0:1,d=t.getCanvas(i,a,l),n.iterations=0,n.startSizeMB=r.size(t.size).MB,e.next=12,this._loopCompression(d,t,n);case 12:return n.endSizeMB=r.size(t.size).MB,n.sizeReducedInPercent=(n.startSizeMB-n.endSizeMB)/n.startSizeMB*100,n.end=window.performance.now(),n.elapsedTimeInSeconds=(n.end-n.start)/1e3,n.endType=t.type,e.abrupt("return",{photo:t,info:n});case 18:case"end":return e.stop()}}),e,this)})));return function(t,n){return e.apply(this,arguments)}}()},{key:"_loopCompression",value:function(){var e=l(s.default.mark((function e(t,n,i){var o;return s.default.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return i.iterations++,e.t0=n,e.next=4,r.canvasToBlob(t,i.quality);case 4:if(e.t1=e.sent,e.t0.setData.call(e.t0,e.t1),1==i.iterations&&(n.width=i.endWidth,n.height=i.endHeight),!(r.size(n.size).MB>this.options.targetSize)){e.next=24;break}if(!(i.quality.toFixed(10)-.1{"use strict";e.exports=function(e){var t=[];return t.toString=function(){return this.map((function(t){var n="",s=void 0!==t[5];return t[4]&&(n+="@supports (".concat(t[4],") {")),t[2]&&(n+="@media ".concat(t[2]," {")),s&&(n+="@layer".concat(t[5].length>0?" ".concat(t[5]):""," {")),n+=e(t),s&&(n+="}"),t[2]&&(n+="}"),t[4]&&(n+="}"),n})).join("")},t.i=function(e,n,s,i,r){"string"==typeof e&&(e=[[null,e,void 0]]);var o={};if(s)for(var a=0;a0?" ".concat(d[5]):""," {").concat(d[1],"}")),d[5]=r),n&&(d[2]?(d[1]="@media ".concat(d[2]," {").concat(d[1],"}"),d[2]=n):d[2]=n),i&&(d[4]?(d[1]="@supports (".concat(d[4],") {").concat(d[1],"}"),d[4]=i):d[4]="".concat(i)),t.push(d))}},t}},9518:e=>{"use strict";e.exports=function(e){var t=e[1],n=e[3];if(!n)return t;if("function"==typeof btoa){var s=btoa(unescape(encodeURIComponent(JSON.stringify(n)))),i="sourceMappingURL=data:application/json;charset=utf-8;base64,".concat(s),r="/*# ".concat(i," */");return[t].concat([r]).join("\n")}return[t].join("\n")}},4794:function(e){e.exports=function(){"use strict";var e=1e3,t=6e4,n=36e5,s="millisecond",i="second",r="minute",o="hour",a="day",c="week",l="month",d="quarter",u="year",h="date",m="Invalid Date",g=/^(\d{4})[-/]?(\d{1,2})?[-/]?(\d{0,2})[Tt\s]*(\d{1,2})?:?(\d{1,2})?:?(\d{1,2})?[.:]?(\d+)?$/,f=/\[([^\]]+)]|Y{1,4}|M{1,4}|D{1,2}|d{1,4}|H{1,2}|h{1,2}|a|A|m{1,2}|s{1,2}|Z{1,2}|SSS/g,p={name:"en",weekdays:"Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday".split("_"),months:"January_February_March_April_May_June_July_August_September_October_November_December".split("_"),ordinal:function(e){var t=["th","st","nd","rd"],n=e%100;return"["+e+(t[(n-20)%10]||t[n]||t[0])+"]"}},v=function(e,t,n){var s=String(e);return!s||s.length>=t?e:""+Array(t+1-s.length).join(n)+e},y={s:v,z:function(e){var t=-e.utcOffset(),n=Math.abs(t),s=Math.floor(n/60),i=n%60;return(t<=0?"+":"-")+v(s,2,"0")+":"+v(i,2,"0")},m:function e(t,n){if(t.date()1)return e(o[0])}else{var a=t.name;b[a]=t,i=a}return!s&&i&&(_=i),i||!s&&_},x=function(e,t){if(w(e))return e.clone();var n="object"==typeof t?t:{};return n.date=e,n.args=arguments,new E(n)},A=y;A.l=S,A.i=w,A.w=function(e,t){return x(e,{locale:t.$L,utc:t.$u,x:t.$x,$offset:t.$offset})};var E=function(){function p(e){this.$L=S(e.locale,null,!0),this.parse(e)}var v=p.prototype;return v.parse=function(e){this.$d=function(e){var t=e.date,n=e.utc;if(null===t)return new Date(NaN);if(A.u(t))return new Date;if(t instanceof Date)return new Date(t);if("string"==typeof t&&!/Z$/i.test(t)){var s=t.match(g);if(s){var i=s[2]-1||0,r=(s[7]||"0").substring(0,3);return n?new Date(Date.UTC(s[1],i,s[3]||1,s[4]||0,s[5]||0,s[6]||0,r)):new Date(s[1],i,s[3]||1,s[4]||0,s[5]||0,s[6]||0,r)}}return new Date(t)}(e),this.$x=e.x||{},this.init()},v.init=function(){var e=this.$d;this.$y=e.getFullYear(),this.$M=e.getMonth(),this.$D=e.getDate(),this.$W=e.getDay(),this.$H=e.getHours(),this.$m=e.getMinutes(),this.$s=e.getSeconds(),this.$ms=e.getMilliseconds()},v.$utils=function(){return A},v.isValid=function(){return!(this.$d.toString()===m)},v.isSame=function(e,t){var n=x(e);return this.startOf(t)<=n&&n<=this.endOf(t)},v.isAfter=function(e,t){return x(e)e.length)&&(t=e.length);for(var n=0,s=new Array(t);n1?n-1:0),i=1;i/gm),J=p(/\${[\w\W]*}/gm),K=p(/^data-[\-\w.\u00B7-\uFFFF]/),Y=p(/^aria-[\-\w]+$/),X=p(/^(?:(?:(?:f|ht)tps?|mailto|tel|callto|cid|xmpp):|[^a-z]|[a-z+.\-]+(?:[^a-z+.\-:]|$))/i),ee=p(/^(?:\w+script|data):/i),te=p(/[\u0000-\u0020\u00A0\u1680\u180E\u2000-\u2029\u205F\u3000]/g),ne=p(/^html$/i),se=function(){return"undefined"==typeof window?null:window},ie=function(t,n){if("object"!==e(t)||"function"!=typeof t.createPolicy)return null;var s=null,i="data-tt-policy-suffix";n.currentScript&&n.currentScript.hasAttribute(i)&&(s=n.currentScript.getAttribute(i));var r="dompurify"+(s?"#"+s:"");try{return t.createPolicy(r,{createHTML:function(e){return e},createScriptURL:function(e){return e}})}catch(e){return console.warn("TrustedTypes policy "+r+" could not be created."),null}};function re(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:se(),n=function(e){return re(e)};if(n.version="2.4.5",n.removed=[],!t||!t.document||9!==t.document.nodeType)return n.isSupported=!1,n;var s=t.document,r=t.document,o=t.DocumentFragment,a=t.HTMLTemplateElement,c=t.Node,l=t.Element,d=t.NodeFilter,u=t.NamedNodeMap,h=void 0===u?t.NamedNodeMap||t.MozNamedAttrMap:u,m=t.HTMLFormElement,g=t.DOMParser,p=t.trustedTypes,v=l.prototype,y=D(v,"cloneNode"),_=D(v,"nextSibling"),b=D(v,"childNodes"),N=D(v,"parentNode");if("function"==typeof a){var M=r.createElement("template");M.content&&M.content.ownerDocument&&(r=M.content.ownerDocument)}var oe=ie(p,s),ae=oe?oe.createHTML(""):"",ce=r,le=ce.implementation,de=ce.createNodeIterator,ue=ce.createDocumentFragment,he=ce.getElementsByTagName,me=s.importNode,ge={};try{ge=R(r).documentMode?r.documentMode:{}}catch(e){}var fe={};n.isSupported="function"==typeof N&&le&&void 0!==le.createHTMLDocument&&9!==ge;var pe,ve,ye=Z,_e=Q,be=J,we=K,Se=Y,xe=ee,Ae=te,Ee=X,$e=null,Ce=O({},[].concat(i(z),i(P),i(L),i(U),i(q))),ke=null,je=O({},[].concat(i(H),i(G),i(W),i(V))),Te=Object.seal(Object.create(null,{tagNameCheck:{writable:!0,configurable:!1,enumerable:!0,value:null},attributeNameCheck:{writable:!0,configurable:!1,enumerable:!0,value:null},allowCustomizedBuiltInElements:{writable:!0,configurable:!1,enumerable:!0,value:!1}})),Ie=null,Ne=null,Me=!0,Oe=!0,Re=!1,De=!0,ze=!1,Pe=!1,Le=!1,Fe=!1,Ue=!1,Be=!1,qe=!1,He=!0,Ge=!1,We="user-content-",Ve=!0,Ze=!1,Qe={},Je=null,Ke=O({},["annotation-xml","audio","colgroup","desc","foreignobject","head","iframe","math","mi","mn","mo","ms","mtext","noembed","noframes","noscript","plaintext","script","style","svg","template","thead","title","video","xmp"]),Ye=null,Xe=O({},["audio","video","img","source","image","track"]),et=null,tt=O({},["alt","class","for","id","label","name","pattern","placeholder","role","summary","title","value","style","xmlns"]),nt="http://www.w3.org/1998/Math/MathML",st="http://www.w3.org/2000/svg",it="http://www.w3.org/1999/xhtml",rt=it,ot=!1,at=null,ct=O({},[nt,st,it],E),lt=["application/xhtml+xml","text/html"],dt="text/html",ut=null,ht=r.createElement("form"),mt=function(e){return e instanceof RegExp||e instanceof Function},gt=function(t){ut&&ut===t||(t&&"object"===e(t)||(t={}),t=R(t),pe=pe=-1===lt.indexOf(t.PARSER_MEDIA_TYPE)?dt:t.PARSER_MEDIA_TYPE,ve="application/xhtml+xml"===pe?E:A,$e="ALLOWED_TAGS"in t?O({},t.ALLOWED_TAGS,ve):Ce,ke="ALLOWED_ATTR"in t?O({},t.ALLOWED_ATTR,ve):je,at="ALLOWED_NAMESPACES"in t?O({},t.ALLOWED_NAMESPACES,E):ct,et="ADD_URI_SAFE_ATTR"in t?O(R(tt),t.ADD_URI_SAFE_ATTR,ve):tt,Ye="ADD_DATA_URI_TAGS"in t?O(R(Xe),t.ADD_DATA_URI_TAGS,ve):Xe,Je="FORBID_CONTENTS"in t?O({},t.FORBID_CONTENTS,ve):Ke,Ie="FORBID_TAGS"in t?O({},t.FORBID_TAGS,ve):{},Ne="FORBID_ATTR"in t?O({},t.FORBID_ATTR,ve):{},Qe="USE_PROFILES"in t&&t.USE_PROFILES,Me=!1!==t.ALLOW_ARIA_ATTR,Oe=!1!==t.ALLOW_DATA_ATTR,Re=t.ALLOW_UNKNOWN_PROTOCOLS||!1,De=!1!==t.ALLOW_SELF_CLOSE_IN_ATTR,ze=t.SAFE_FOR_TEMPLATES||!1,Pe=t.WHOLE_DOCUMENT||!1,Ue=t.RETURN_DOM||!1,Be=t.RETURN_DOM_FRAGMENT||!1,qe=t.RETURN_TRUSTED_TYPE||!1,Fe=t.FORCE_BODY||!1,He=!1!==t.SANITIZE_DOM,Ge=t.SANITIZE_NAMED_PROPS||!1,Ve=!1!==t.KEEP_CONTENT,Ze=t.IN_PLACE||!1,Ee=t.ALLOWED_URI_REGEXP||Ee,rt=t.NAMESPACE||it,Te=t.CUSTOM_ELEMENT_HANDLING||{},t.CUSTOM_ELEMENT_HANDLING&&mt(t.CUSTOM_ELEMENT_HANDLING.tagNameCheck)&&(Te.tagNameCheck=t.CUSTOM_ELEMENT_HANDLING.tagNameCheck),t.CUSTOM_ELEMENT_HANDLING&&mt(t.CUSTOM_ELEMENT_HANDLING.attributeNameCheck)&&(Te.attributeNameCheck=t.CUSTOM_ELEMENT_HANDLING.attributeNameCheck),t.CUSTOM_ELEMENT_HANDLING&&"boolean"==typeof t.CUSTOM_ELEMENT_HANDLING.allowCustomizedBuiltInElements&&(Te.allowCustomizedBuiltInElements=t.CUSTOM_ELEMENT_HANDLING.allowCustomizedBuiltInElements),ze&&(Oe=!1),Be&&(Ue=!0),Qe&&($e=O({},i(q)),ke=[],!0===Qe.html&&(O($e,z),O(ke,H)),!0===Qe.svg&&(O($e,P),O(ke,G),O(ke,V)),!0===Qe.svgFilters&&(O($e,L),O(ke,G),O(ke,V)),!0===Qe.mathMl&&(O($e,U),O(ke,W),O(ke,V))),t.ADD_TAGS&&($e===Ce&&($e=R($e)),O($e,t.ADD_TAGS,ve)),t.ADD_ATTR&&(ke===je&&(ke=R(ke)),O(ke,t.ADD_ATTR,ve)),t.ADD_URI_SAFE_ATTR&&O(et,t.ADD_URI_SAFE_ATTR,ve),t.FORBID_CONTENTS&&(Je===Ke&&(Je=R(Je)),O(Je,t.FORBID_CONTENTS,ve)),Ve&&($e["#text"]=!0),Pe&&O($e,["html","head","body"]),$e.table&&(O($e,["tbody"]),delete Ie.tbody),f&&f(t),ut=t)},ft=O({},["mi","mo","mn","ms","mtext"]),pt=O({},["foreignobject","desc","title","annotation-xml"]),vt=O({},["title","style","font","a","script"]),yt=O({},P);O(yt,L),O(yt,F);var _t=O({},U);O(_t,B);var bt=function(e){var t=N(e);t&&t.tagName||(t={namespaceURI:rt,tagName:"template"});var n=A(e.tagName),s=A(t.tagName);return!!at[e.namespaceURI]&&(e.namespaceURI===st?t.namespaceURI===it?"svg"===n:t.namespaceURI===nt?"svg"===n&&("annotation-xml"===s||ft[s]):Boolean(yt[n]):e.namespaceURI===nt?t.namespaceURI===it?"math"===n:t.namespaceURI===st?"math"===n&&pt[s]:Boolean(_t[n]):e.namespaceURI===it?!(t.namespaceURI===st&&!pt[s])&&!(t.namespaceURI===nt&&!ft[s])&&!_t[n]&&(vt[n]||!yt[n]):!("application/xhtml+xml"!==pe||!at[e.namespaceURI]))},wt=function(e){x(n.removed,{element:e});try{e.parentNode.removeChild(e)}catch(t){try{e.outerHTML=ae}catch(t){e.remove()}}},St=function(e,t){try{x(n.removed,{attribute:t.getAttributeNode(e),from:t})}catch(e){x(n.removed,{attribute:null,from:t})}if(t.removeAttribute(e),"is"===e&&!ke[e])if(Ue||Be)try{wt(t)}catch(e){}else try{t.setAttribute(e,"")}catch(e){}},xt=function(e){var t,n;if(Fe)e=""+e;else{var s=$(e,/^[\r\n\t ]+/);n=s&&s[0]}"application/xhtml+xml"===pe&&rt===it&&(e=''+e+"");var i=oe?oe.createHTML(e):e;if(rt===it)try{t=(new g).parseFromString(i,pe)}catch(e){}if(!t||!t.documentElement){t=le.createDocument(rt,"template",null);try{t.documentElement.innerHTML=ot?ae:i}catch(e){}}var o=t.body||t.documentElement;return e&&n&&o.insertBefore(r.createTextNode(n),o.childNodes[0]||null),rt===it?he.call(t,Pe?"html":"body")[0]:Pe?t.documentElement:o},At=function(e){return de.call(e.ownerDocument||e,e,d.SHOW_ELEMENT|d.SHOW_COMMENT|d.SHOW_TEXT,null,!1)},Et=function(e){return e instanceof m&&("string"!=typeof e.nodeName||"string"!=typeof e.textContent||"function"!=typeof e.removeChild||!(e.attributes instanceof h)||"function"!=typeof e.removeAttribute||"function"!=typeof e.setAttribute||"string"!=typeof e.namespaceURI||"function"!=typeof e.insertBefore||"function"!=typeof e.hasChildNodes)},$t=function(t){return"object"===e(c)?t instanceof c:t&&"object"===e(t)&&"number"==typeof t.nodeType&&"string"==typeof t.nodeName},Ct=function(e,t,s){fe[e]&&w(fe[e],(function(e){e.call(n,t,s,ut)}))},kt=function(e){var t;if(Ct("beforeSanitizeElements",e,null),Et(e))return wt(e),!0;if(T(/[\u0080-\uFFFF]/,e.nodeName))return wt(e),!0;var s=ve(e.nodeName);if(Ct("uponSanitizeElement",e,{tagName:s,allowedTags:$e}),e.hasChildNodes()&&!$t(e.firstElementChild)&&(!$t(e.content)||!$t(e.content.firstElementChild))&&T(/<[/\w]/g,e.innerHTML)&&T(/<[/\w]/g,e.textContent))return wt(e),!0;if("select"===s&&T(/