diff --git a/composer.json b/composer.json index 73b3c8b3512..999de25194a 100644 --- a/composer.json +++ b/composer.json @@ -47,6 +47,7 @@ "require": { "php": ">=8.2", "ahand/mobileesp": "dev-master", + "altcha-org/altcha": "^1.1", "browscap/browscap-php": "^7.2", "cap60552/php-sip2": "1.0.0", "colinmollenhour/credis": "1.17.0", diff --git a/composer.lock b/composer.lock index 52696d407e1..a31b428e8b5 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "c1acd10657b55d6f4bd1f3adc346bc23", + "content-hash": "0efe38b39c83894efb5bfbe6b5e39893", "packages": [ { "name": "ahand/mobileesp", @@ -65,18 +65,64 @@ }, "time": "2017-06-06T22:20:56+00:00" }, + { + "name": "altcha-org/altcha", + "version": "v1.3.3", + "source": { + "type": "git", + "url": "https://github.com/altcha-org/altcha-lib-php.git", + "reference": "9a9b98c48dea0b2e8c353ea991d5f5627cbdab36" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/altcha-org/altcha-lib-php/zipball/9a9b98c48dea0b2e8c353ea991d5f5627cbdab36", + "reference": "9a9b98c48dea0b2e8c353ea991d5f5627cbdab36", + "shasum": "" + }, + "require": { + "php": ">=8.2" + }, + "require-dev": { + "friendsofphp/php-cs-fixer": "^3.72", + "phpstan/extension-installer": "^1.4", + "phpstan/phpstan": "^2.1", + "phpstan/phpstan-phpunit": "^2.0", + "phpunit/phpunit": "^11.5.50" + }, + "type": "library", + "autoload": { + "psr-4": { + "AltchaOrg\\Altcha\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Daniel Regeci", + "email": "536331+ovx@users.noreply.github.com" + } + ], + "support": { + "issues": "https://github.com/altcha-org/altcha-lib-php/issues", + "source": "https://github.com/altcha-org/altcha-lib-php/tree/v1.3.3" + }, + "time": "2026-04-02T12:13:35+00:00" + }, { "name": "bacon/bacon-qr-code", - "version": "v3.0.4", + "version": "v3.1.1", "source": { "type": "git", "url": "https://github.com/Bacon/BaconQrCode.git", - "reference": "3feed0e212b8412cc5d2612706744789b0615824" + "reference": "4da2233e72eeecd9be3b62e0dc2cc9ed8e2e31c2" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/Bacon/BaconQrCode/zipball/3feed0e212b8412cc5d2612706744789b0615824", - "reference": "3feed0e212b8412cc5d2612706744789b0615824", + "url": "https://api.github.com/repos/Bacon/BaconQrCode/zipball/4da2233e72eeecd9be3b62e0dc2cc9ed8e2e31c2", + "reference": "4da2233e72eeecd9be3b62e0dc2cc9ed8e2e31c2", "shasum": "" }, "require": { @@ -116,9 +162,9 @@ "homepage": "https://github.com/Bacon/BaconQrCode", "support": { "issues": "https://github.com/Bacon/BaconQrCode/issues", - "source": "https://github.com/Bacon/BaconQrCode/tree/v3.0.4" + "source": "https://github.com/Bacon/BaconQrCode/tree/v3.1.1" }, - "time": "2026-03-16T01:01:30+00:00" + "time": "2026-04-05T21:06:35+00:00" }, { "name": "brick/math", @@ -231,39 +277,39 @@ }, { "name": "browscap/browscap-php", - "version": "7.2.0", + "version": "7.2.1", "source": { "type": "git", "url": "https://github.com/browscap/browscap-php.git", - "reference": "a033f938b136ecbd5f2e5818d186b4c3b0afb9dd" + "reference": "21c560dac8158dc07581ac30e87cf09179385882" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/browscap/browscap-php/zipball/a033f938b136ecbd5f2e5818d186b4c3b0afb9dd", - "reference": "a033f938b136ecbd5f2e5818d186b4c3b0afb9dd", + "url": "https://api.github.com/repos/browscap/browscap-php/zipball/21c560dac8158dc07581ac30e87cf09179385882", + "reference": "21c560dac8158dc07581ac30e87cf09179385882", "shasum": "" }, "require": { "ext-json": "*", - "guzzlehttp/guzzle": "^7.4.5", - "league/flysystem": "^2.4.5 || ^3.0.18", - "matthiasmullie/scrapbook": "^1.4.8", - "monolog/monolog": "^2.5.0 || ^3.0.0", + "guzzlehttp/guzzle": "^7.5.0", + "league/flysystem": "^2.5.0 || ^3.12.0", + "matthiasmullie/scrapbook": "^1.4.9", + "monolog/monolog": "^2.8.0 || ^3.2.0", "php": ">=7.4.3,<8.3.0", "psr/log": "^1.1.4 || ^2.0.0 || ^3.0.0", "psr/simple-cache": "^1.0.1 || ^2.0.0 || ^3.0.0", - "symfony/console": "^v5.4.8 || ^v6.0.8", - "symfony/filesystem": "^v5.4.7 || ^v6.0.7" + "symfony/console": "^v5.4.17 || ^v6.2.3", + "symfony/filesystem": "^v5.4.13 || ^v6.2.0" }, "require-dev": { - "doctrine/coding-standard": "^9.0.0", - "mikey179/vfsstream": "^v1.6.10", - "phpstan/extension-installer": "^1.1.0", - "phpstan/phpstan": "^1.6.3", + "doctrine/coding-standard": "^11.0.0", + "mikey179/vfsstream": "^v1.6.11", + "phpstan/extension-installer": "^1.2.0", + "phpstan/phpstan": "^1.9.4", "phpstan/phpstan-beberlei-assert": "^1.0.1", - "phpstan/phpstan-deprecation-rules": "^1.0.0", - "phpstan/phpstan-phpunit": "^1.1.1", - "phpunit/phpunit": "^9.5.20" + "phpstan/phpstan-deprecation-rules": "^1.1.1", + "phpstan/phpstan-phpunit": "^1.3.3", + "phpunit/phpunit": "^9.5.27" }, "suggest": { "ext-curl": "to use curl requests to get the ini file" @@ -307,7 +353,7 @@ "issues": "https://github.com/browscap/browscap-php/issues", "source": "https://github.com/browscap/browscap-php" }, - "time": "2022-12-30T11:27:45+00:00" + "time": "2022-12-30T16:04:59+00:00" }, { "name": "cap60552/php-sip2", @@ -1850,16 +1896,16 @@ }, { "name": "doctrine/orm", - "version": "2.20.9", + "version": "2.20.10", "source": { "type": "git", "url": "https://github.com/doctrine/orm.git", - "reference": "87f1ba74e04c8694ca00099f3c64706ebac0b114" + "reference": "9fe8ce4bf75fbb7342f35835d9a90640902164db" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/orm/zipball/87f1ba74e04c8694ca00099f3c64706ebac0b114", - "reference": "87f1ba74e04c8694ca00099f3c64706ebac0b114", + "url": "https://api.github.com/repos/doctrine/orm/zipball/9fe8ce4bf75fbb7342f35835d9a90640902164db", + "reference": "9fe8ce4bf75fbb7342f35835d9a90640902164db", "shasum": "" }, "require": { @@ -1945,22 +1991,22 @@ ], "support": { "issues": "https://github.com/doctrine/orm/issues", - "source": "https://github.com/doctrine/orm/tree/2.20.9" + "source": "https://github.com/doctrine/orm/tree/2.20.10" }, - "time": "2025-11-29T14:03:56+00:00" + "time": "2026-04-02T06:18:54+00:00" }, { "name": "doctrine/persistence", - "version": "3.4.3", + "version": "3.4.4", "source": { "type": "git", "url": "https://github.com/doctrine/persistence.git", - "reference": "d59e6ef7caffe6a30f4b6f9e9079a75f52c64ae0" + "reference": "5785dc79a0553ba41b0dda8a7ee792053e6186c8" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/persistence/zipball/d59e6ef7caffe6a30f4b6f9e9079a75f52c64ae0", - "reference": "d59e6ef7caffe6a30f4b6f9e9079a75f52c64ae0", + "url": "https://api.github.com/repos/doctrine/persistence/zipball/5785dc79a0553ba41b0dda8a7ee792053e6186c8", + "reference": "5785dc79a0553ba41b0dda8a7ee792053e6186c8", "shasum": "" }, "require": { @@ -1983,7 +2029,7 @@ "type": "library", "autoload": { "psr-4": { - "Doctrine\\Persistence\\": "src/Persistence" + "Doctrine\\Persistence\\": "src" } }, "notification-url": "https://packagist.org/downloads/", @@ -2027,7 +2073,7 @@ ], "support": { "issues": "https://github.com/doctrine/persistence/issues", - "source": "https://github.com/doctrine/persistence/tree/3.4.3" + "source": "https://github.com/doctrine/persistence/tree/3.4.4" }, "funding": [ { @@ -2043,7 +2089,7 @@ "type": "tidelift" } ], - "time": "2025-10-21T15:21:39+00:00" + "time": "2026-04-04T19:40:43+00:00" }, { "name": "egulias/email-validator", @@ -2318,16 +2364,16 @@ }, { "name": "firebase/php-jwt", - "version": "v7.0.3", + "version": "v7.0.5", "source": { "type": "git", - "url": "https://github.com/firebase/php-jwt.git", - "reference": "28aa0694bcfdfa5e2959c394d5a1ee7a5083629e" + "url": "https://github.com/googleapis/php-jwt.git", + "reference": "47ad26bab5e7c70ae8a6f08ed25ff83631121380" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/firebase/php-jwt/zipball/28aa0694bcfdfa5e2959c394d5a1ee7a5083629e", - "reference": "28aa0694bcfdfa5e2959c394d5a1ee7a5083629e", + "url": "https://api.github.com/repos/googleapis/php-jwt/zipball/47ad26bab5e7c70ae8a6f08ed25ff83631121380", + "reference": "47ad26bab5e7c70ae8a6f08ed25ff83631121380", "shasum": "" }, "require": { @@ -2335,6 +2381,7 @@ }, "require-dev": { "guzzlehttp/guzzle": "^7.4", + "phpfastcache/phpfastcache": "^9.2", "phpspec/prophecy-phpunit": "^2.0", "phpunit/phpunit": "^9.5", "psr/cache": "^2.0||^3.0", @@ -2374,10 +2421,10 @@ "php" ], "support": { - "issues": "https://github.com/firebase/php-jwt/issues", - "source": "https://github.com/firebase/php-jwt/tree/v7.0.3" + "issues": "https://github.com/googleapis/php-jwt/issues", + "source": "https://github.com/googleapis/php-jwt/tree/v7.0.5" }, - "time": "2026-02-25T22:16:40+00:00" + "time": "2026-04-01T20:38:03+00:00" }, { "name": "guzzlehttp/guzzle", @@ -2707,23 +2754,23 @@ }, { "name": "jaybizzle/crawler-detect", - "version": "v1.3.7", + "version": "v1.3.9", "source": { "type": "git", "url": "https://github.com/JayBizzle/Crawler-Detect.git", - "reference": "7f7a45b5d5df9c95ba6b2008544e6cf8e66de6f5" + "reference": "5edf2e43d9f42e5baa6f844826213257c247b309" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/JayBizzle/Crawler-Detect/zipball/7f7a45b5d5df9c95ba6b2008544e6cf8e66de6f5", - "reference": "7f7a45b5d5df9c95ba6b2008544e6cf8e66de6f5", + "url": "https://api.github.com/repos/JayBizzle/Crawler-Detect/zipball/5edf2e43d9f42e5baa6f844826213257c247b309", + "reference": "5edf2e43d9f42e5baa6f844826213257c247b309", "shasum": "" }, "require": { "php": ">=7.1.0" }, "require-dev": { - "phpunit/phpunit": "^4.8|^5.5|^6.5|^7.5|^8.5|^9.4" + "phpunit/phpunit": "^4.8|^5.5|^6.5|^7.5|^8.5.52|^9.4" }, "type": "library", "autoload": { @@ -2753,9 +2800,9 @@ ], "support": { "issues": "https://github.com/JayBizzle/Crawler-Detect/issues", - "source": "https://github.com/JayBizzle/Crawler-Detect/tree/v1.3.7" + "source": "https://github.com/JayBizzle/Crawler-Detect/tree/v1.3.9" }, - "time": "2026-02-02T19:15:54+00:00" + "time": "2026-04-14T19:32:41+00:00" }, { "name": "laminas/laminas-authentication", @@ -3952,16 +3999,16 @@ }, { "name": "laminas/laminas-hydrator", - "version": "4.18.0", + "version": "4.18.1", "source": { "type": "git", "url": "https://github.com/laminas/laminas-hydrator.git", - "reference": "ab208d1b8a2dc4251182a6cd2d123ccbc56eda50" + "reference": "93a8ea33dccd2639ab8f07fbbfbc40911774aa9b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/laminas/laminas-hydrator/zipball/ab208d1b8a2dc4251182a6cd2d123ccbc56eda50", - "reference": "ab208d1b8a2dc4251182a6cd2d123ccbc56eda50", + "url": "https://api.github.com/repos/laminas/laminas-hydrator/zipball/93a8ea33dccd2639ab8f07fbbfbc40911774aa9b", + "reference": "93a8ea33dccd2639ab8f07fbbfbc40911774aa9b", "shasum": "" }, "require": { @@ -4025,7 +4072,7 @@ "type": "community_bridge" } ], - "time": "2026-01-13T10:10:41+00:00" + "time": "2026-05-04T08:00:40+00:00" }, { "name": "laminas/laminas-i18n", @@ -9980,16 +10027,16 @@ }, { "name": "symfony/event-dispatcher", - "version": "v7.4.4", + "version": "v7.4.9", "source": { "type": "git", "url": "https://github.com/symfony/event-dispatcher.git", - "reference": "dc2c0eba1af673e736bb851d747d266108aea746" + "reference": "e4a2e29753c7801f7a8340e066cfa788f3bc8101" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/dc2c0eba1af673e736bb851d747d266108aea746", - "reference": "dc2c0eba1af673e736bb851d747d266108aea746", + "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/e4a2e29753c7801f7a8340e066cfa788f3bc8101", + "reference": "e4a2e29753c7801f7a8340e066cfa788f3bc8101", "shasum": "" }, "require": { @@ -10041,7 +10088,7 @@ "description": "Provides tools that allow your application components to communicate with each other by dispatching events and listening to them", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/event-dispatcher/tree/v7.4.4" + "source": "https://github.com/symfony/event-dispatcher/tree/v7.4.9" }, "funding": [ { @@ -10061,7 +10108,7 @@ "type": "tidelift" } ], - "time": "2026-01-05T11:45:34+00:00" + "time": "2026-04-18T13:18:21+00:00" }, { "name": "symfony/event-dispatcher-contracts", @@ -10141,16 +10188,16 @@ }, { "name": "symfony/filesystem", - "version": "v6.4.34", + "version": "v6.4.37", "source": { "type": "git", "url": "https://github.com/symfony/filesystem.git", - "reference": "01ffe0411b842f93c571e5c391f289c3fdd498c3" + "reference": "29f792d7dc30cc670fc4cdd50d7c6653d067ce7b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/filesystem/zipball/01ffe0411b842f93c571e5c391f289c3fdd498c3", - "reference": "01ffe0411b842f93c571e5c391f289c3fdd498c3", + "url": "https://api.github.com/repos/symfony/filesystem/zipball/29f792d7dc30cc670fc4cdd50d7c6653d067ce7b", + "reference": "29f792d7dc30cc670fc4cdd50d7c6653d067ce7b", "shasum": "" }, "require": { @@ -10187,7 +10234,7 @@ "description": "Provides basic utilities for the filesystem", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/filesystem/tree/v6.4.34" + "source": "https://github.com/symfony/filesystem/tree/v6.4.37" }, "funding": [ { @@ -10207,7 +10254,7 @@ "type": "tidelift" } ], - "time": "2026-02-24T17:51:06+00:00" + "time": "2026-04-13T15:27:04+00:00" }, { "name": "symfony/mailer", @@ -10295,16 +10342,16 @@ }, { "name": "symfony/mime", - "version": "v7.4.7", + "version": "v7.4.9", "source": { "type": "git", "url": "https://github.com/symfony/mime.git", - "reference": "da5ab4fde3f6c88ab06e96185b9922f48b677cd1" + "reference": "2d550c4758ba4c47519a6667c36553d535705b0c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/mime/zipball/da5ab4fde3f6c88ab06e96185b9922f48b677cd1", - "reference": "da5ab4fde3f6c88ab06e96185b9922f48b677cd1", + "url": "https://api.github.com/repos/symfony/mime/zipball/2d550c4758ba4c47519a6667c36553d535705b0c", + "reference": "2d550c4758ba4c47519a6667c36553d535705b0c", "shasum": "" }, "require": { @@ -10360,7 +10407,7 @@ "mime-type" ], "support": { - "source": "https://github.com/symfony/mime/tree/v7.4.7" + "source": "https://github.com/symfony/mime/tree/v7.4.9" }, "funding": [ { @@ -10380,20 +10427,20 @@ "type": "tidelift" } ], - "time": "2026-03-05T15:24:09+00:00" + "time": "2026-04-29T13:21:53+00:00" }, { "name": "symfony/options-resolver", - "version": "v7.4.0", + "version": "v7.4.8", "source": { "type": "git", "url": "https://github.com/symfony/options-resolver.git", - "reference": "b38026df55197f9e39a44f3215788edf83187b80" + "reference": "2888fcdc4dc2fd5f7c7397be78631e8af12e02b4" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/options-resolver/zipball/b38026df55197f9e39a44f3215788edf83187b80", - "reference": "b38026df55197f9e39a44f3215788edf83187b80", + "url": "https://api.github.com/repos/symfony/options-resolver/zipball/2888fcdc4dc2fd5f7c7397be78631e8af12e02b4", + "reference": "2888fcdc4dc2fd5f7c7397be78631e8af12e02b4", "shasum": "" }, "require": { @@ -10431,7 +10478,7 @@ "options" ], "support": { - "source": "https://github.com/symfony/options-resolver/tree/v7.4.0" + "source": "https://github.com/symfony/options-resolver/tree/v7.4.8" }, "funding": [ { @@ -10451,20 +10498,20 @@ "type": "tidelift" } ], - "time": "2025-11-12T15:39:26+00:00" + "time": "2026-03-24T13:12:05+00:00" }, { "name": "symfony/polyfill-ctype", - "version": "v1.33.0", + "version": "v1.37.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-ctype.git", - "reference": "a3cc8b044a6ea513310cbd48ef7333b384945638" + "reference": "141046a8f9477948ff284fa65be2095baafb94f2" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/a3cc8b044a6ea513310cbd48ef7333b384945638", - "reference": "a3cc8b044a6ea513310cbd48ef7333b384945638", + "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/141046a8f9477948ff284fa65be2095baafb94f2", + "reference": "141046a8f9477948ff284fa65be2095baafb94f2", "shasum": "" }, "require": { @@ -10514,7 +10561,7 @@ "portable" ], "support": { - "source": "https://github.com/symfony/polyfill-ctype/tree/v1.33.0" + "source": "https://github.com/symfony/polyfill-ctype/tree/v1.37.0" }, "funding": [ { @@ -10534,20 +10581,20 @@ "type": "tidelift" } ], - "time": "2024-09-09T11:45:10+00:00" + "time": "2026-04-10T16:19:22+00:00" }, { "name": "symfony/polyfill-intl-grapheme", - "version": "v1.33.0", + "version": "v1.37.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-intl-grapheme.git", - "reference": "380872130d3a5dd3ace2f4010d95125fde5d5c70" + "reference": "4864388bfbd3001ce88e234fab652acd91fdc57e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-intl-grapheme/zipball/380872130d3a5dd3ace2f4010d95125fde5d5c70", - "reference": "380872130d3a5dd3ace2f4010d95125fde5d5c70", + "url": "https://api.github.com/repos/symfony/polyfill-intl-grapheme/zipball/4864388bfbd3001ce88e234fab652acd91fdc57e", + "reference": "4864388bfbd3001ce88e234fab652acd91fdc57e", "shasum": "" }, "require": { @@ -10596,7 +10643,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-intl-grapheme/tree/v1.33.0" + "source": "https://github.com/symfony/polyfill-intl-grapheme/tree/v1.37.0" }, "funding": [ { @@ -10616,11 +10663,11 @@ "type": "tidelift" } ], - "time": "2025-06-27T09:58:17+00:00" + "time": "2026-04-26T13:13:48+00:00" }, { "name": "symfony/polyfill-intl-idn", - "version": "v1.33.0", + "version": "v1.37.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-intl-idn.git", @@ -10683,7 +10730,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-intl-idn/tree/v1.33.0" + "source": "https://github.com/symfony/polyfill-intl-idn/tree/v1.37.0" }, "funding": [ { @@ -10707,7 +10754,7 @@ }, { "name": "symfony/polyfill-intl-normalizer", - "version": "v1.33.0", + "version": "v1.37.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-intl-normalizer.git", @@ -10768,7 +10815,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-intl-normalizer/tree/v1.33.0" + "source": "https://github.com/symfony/polyfill-intl-normalizer/tree/v1.37.0" }, "funding": [ { @@ -10792,16 +10839,16 @@ }, { "name": "symfony/polyfill-mbstring", - "version": "v1.33.0", + "version": "v1.37.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-mbstring.git", - "reference": "6d857f4d76bd4b343eac26d6b539585d2bc56493" + "reference": "6a21eb99c6973357967f6ce3708cd55a6bec6315" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/6d857f4d76bd4b343eac26d6b539585d2bc56493", - "reference": "6d857f4d76bd4b343eac26d6b539585d2bc56493", + "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/6a21eb99c6973357967f6ce3708cd55a6bec6315", + "reference": "6a21eb99c6973357967f6ce3708cd55a6bec6315", "shasum": "" }, "require": { @@ -10853,7 +10900,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.33.0" + "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.37.0" }, "funding": [ { @@ -10873,7 +10920,7 @@ "type": "tidelift" } ], - "time": "2024-12-23T08:48:59+00:00" + "time": "2026-04-10T17:25:58+00:00" }, { "name": "symfony/polyfill-php72", @@ -10942,16 +10989,16 @@ }, { "name": "symfony/polyfill-php80", - "version": "v1.33.0", + "version": "v1.37.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-php80.git", - "reference": "0cc9dd0f17f61d8131e7df6b84bd344899fe2608" + "reference": "dfb55726c3a76ea3b6459fcfda1ec2d80a682411" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/0cc9dd0f17f61d8131e7df6b84bd344899fe2608", - "reference": "0cc9dd0f17f61d8131e7df6b84bd344899fe2608", + "url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/dfb55726c3a76ea3b6459fcfda1ec2d80a682411", + "reference": "dfb55726c3a76ea3b6459fcfda1ec2d80a682411", "shasum": "" }, "require": { @@ -11002,7 +11049,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-php80/tree/v1.33.0" + "source": "https://github.com/symfony/polyfill-php80/tree/v1.37.0" }, "funding": [ { @@ -11022,20 +11069,20 @@ "type": "tidelift" } ], - "time": "2025-01-02T08:10:11+00:00" + "time": "2026-04-10T16:19:22+00:00" }, { "name": "symfony/polyfill-php84", - "version": "v1.33.0", + "version": "v1.37.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-php84.git", - "reference": "d8ced4d875142b6a7426000426b8abc631d6b191" + "reference": "88486db2c389b290bf87ff1de7ebc1e13e42bb06" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php84/zipball/d8ced4d875142b6a7426000426b8abc631d6b191", - "reference": "d8ced4d875142b6a7426000426b8abc631d6b191", + "url": "https://api.github.com/repos/symfony/polyfill-php84/zipball/88486db2c389b290bf87ff1de7ebc1e13e42bb06", + "reference": "88486db2c389b290bf87ff1de7ebc1e13e42bb06", "shasum": "" }, "require": { @@ -11082,7 +11129,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-php84/tree/v1.33.0" + "source": "https://github.com/symfony/polyfill-php84/tree/v1.37.0" }, "funding": [ { @@ -11102,20 +11149,20 @@ "type": "tidelift" } ], - "time": "2025-06-24T13:30:11+00:00" + "time": "2026-04-10T18:47:49+00:00" }, { "name": "symfony/rate-limiter", - "version": "v7.4.7", + "version": "v7.4.10", "source": { "type": "git", "url": "https://github.com/symfony/rate-limiter.git", - "reference": "c2ff01c8d5ed54f0721f046fde14a94f2df09666" + "reference": "778c5239c7fd6bf9b886dedf3d84ddb156ddb888" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/rate-limiter/zipball/c2ff01c8d5ed54f0721f046fde14a94f2df09666", - "reference": "c2ff01c8d5ed54f0721f046fde14a94f2df09666", + "url": "https://api.github.com/repos/symfony/rate-limiter/zipball/778c5239c7fd6bf9b886dedf3d84ddb156ddb888", + "reference": "778c5239c7fd6bf9b886dedf3d84ddb156ddb888", "shasum": "" }, "require": { @@ -11156,7 +11203,7 @@ "rate-limiter" ], "support": { - "source": "https://github.com/symfony/rate-limiter/tree/v7.4.7" + "source": "https://github.com/symfony/rate-limiter/tree/v7.4.10" }, "funding": [ { @@ -11176,7 +11223,7 @@ "type": "tidelift" } ], - "time": "2026-03-04T13:54:41+00:00" + "time": "2026-05-04T13:25:50+00:00" }, { "name": "symfony/service-contracts", @@ -11267,16 +11314,16 @@ }, { "name": "symfony/string", - "version": "v7.4.6", + "version": "v7.4.8", "source": { "type": "git", "url": "https://github.com/symfony/string.git", - "reference": "9f209231affa85aa930a5e46e6eb03381424b30b" + "reference": "114ac57257d75df748eda23dd003878080b8e688" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/string/zipball/9f209231affa85aa930a5e46e6eb03381424b30b", - "reference": "9f209231affa85aa930a5e46e6eb03381424b30b", + "url": "https://api.github.com/repos/symfony/string/zipball/114ac57257d75df748eda23dd003878080b8e688", + "reference": "114ac57257d75df748eda23dd003878080b8e688", "shasum": "" }, "require": { @@ -11334,7 +11381,7 @@ "utf8" ], "support": { - "source": "https://github.com/symfony/string/tree/v7.4.6" + "source": "https://github.com/symfony/string/tree/v7.4.8" }, "funding": [ { @@ -11354,7 +11401,7 @@ "type": "tidelift" } ], - "time": "2026-02-09T09:33:46+00:00" + "time": "2026-03-24T13:12:05+00:00" }, { "name": "symfony/var-dumper", @@ -15695,16 +15742,16 @@ }, { "name": "symfony/css-selector", - "version": "v7.4.6", + "version": "v7.4.9", "source": { "type": "git", "url": "https://github.com/symfony/css-selector.git", - "reference": "2e7c52c647b406e2107dd867db424a4dbac91864" + "reference": "b75663ed96cf4756e28e3105476f220f92886cc4" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/css-selector/zipball/2e7c52c647b406e2107dd867db424a4dbac91864", - "reference": "2e7c52c647b406e2107dd867db424a4dbac91864", + "url": "https://api.github.com/repos/symfony/css-selector/zipball/b75663ed96cf4756e28e3105476f220f92886cc4", + "reference": "b75663ed96cf4756e28e3105476f220f92886cc4", "shasum": "" }, "require": { @@ -15740,7 +15787,7 @@ "description": "Converts CSS selectors to XPath expressions", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/css-selector/tree/v7.4.6" + "source": "https://github.com/symfony/css-selector/tree/v7.4.9" }, "funding": [ { @@ -15760,20 +15807,20 @@ "type": "tidelift" } ], - "time": "2026-02-17T07:53:42+00:00" + "time": "2026-04-18T13:18:21+00:00" }, { "name": "symfony/dependency-injection", - "version": "v7.4.7", + "version": "v7.4.10", "source": { "type": "git", "url": "https://github.com/symfony/dependency-injection.git", - "reference": "0f651e58f4917fb0e2cd261ccbfe3d71e6e0f5db" + "reference": "4eb0d9dfa9d4f7c59216baf49b3ed6b1fb72293d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/dependency-injection/zipball/0f651e58f4917fb0e2cd261ccbfe3d71e6e0f5db", - "reference": "0f651e58f4917fb0e2cd261ccbfe3d71e6e0f5db", + "url": "https://api.github.com/repos/symfony/dependency-injection/zipball/4eb0d9dfa9d4f7c59216baf49b3ed6b1fb72293d", + "reference": "4eb0d9dfa9d4f7c59216baf49b3ed6b1fb72293d", "shasum": "" }, "require": { @@ -15824,7 +15871,7 @@ "description": "Allows you to standardize and centralize the way objects are constructed in your application", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/dependency-injection/tree/v7.4.7" + "source": "https://github.com/symfony/dependency-injection/tree/v7.4.10" }, "funding": [ { @@ -15844,20 +15891,20 @@ "type": "tidelift" } ], - "time": "2026-03-03T07:48:48+00:00" + "time": "2026-05-06T11:55:30+00:00" }, { "name": "symfony/finder", - "version": "v7.4.6", + "version": "v7.4.8", "source": { "type": "git", "url": "https://github.com/symfony/finder.git", - "reference": "8655bf1076b7a3a346cb11413ffdabff50c7ffcf" + "reference": "e0be088d22278583a82da281886e8c3592fbf149" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/finder/zipball/8655bf1076b7a3a346cb11413ffdabff50c7ffcf", - "reference": "8655bf1076b7a3a346cb11413ffdabff50c7ffcf", + "url": "https://api.github.com/repos/symfony/finder/zipball/e0be088d22278583a82da281886e8c3592fbf149", + "reference": "e0be088d22278583a82da281886e8c3592fbf149", "shasum": "" }, "require": { @@ -15892,7 +15939,7 @@ "description": "Finds files and directories via an intuitive fluent interface", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/finder/tree/v7.4.6" + "source": "https://github.com/symfony/finder/tree/v7.4.8" }, "funding": [ { @@ -15912,11 +15959,11 @@ "type": "tidelift" } ], - "time": "2026-01-29T09:40:50+00:00" + "time": "2026-03-24T13:12:05+00:00" }, { "name": "symfony/polyfill-php81", - "version": "v1.33.0", + "version": "v1.37.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-php81.git", @@ -15972,7 +16019,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-php81/tree/v1.33.0" + "source": "https://github.com/symfony/polyfill-php81/tree/v1.37.0" }, "funding": [ { @@ -15996,16 +16043,16 @@ }, { "name": "symfony/process", - "version": "v7.4.5", + "version": "v7.4.8", "source": { "type": "git", "url": "https://github.com/symfony/process.git", - "reference": "608476f4604102976d687c483ac63a79ba18cc97" + "reference": "60f19cd3badc8de688421e21e4305eba50f8089a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/process/zipball/608476f4604102976d687c483ac63a79ba18cc97", - "reference": "608476f4604102976d687c483ac63a79ba18cc97", + "url": "https://api.github.com/repos/symfony/process/zipball/60f19cd3badc8de688421e21e4305eba50f8089a", + "reference": "60f19cd3badc8de688421e21e4305eba50f8089a", "shasum": "" }, "require": { @@ -16037,7 +16084,7 @@ "description": "Executes commands in sub-processes", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/process/tree/v7.4.5" + "source": "https://github.com/symfony/process/tree/v7.4.8" }, "funding": [ { @@ -16057,20 +16104,20 @@ "type": "tidelift" } ], - "time": "2026-01-26T15:07:59+00:00" + "time": "2026-03-24T13:12:05+00:00" }, { "name": "symfony/stopwatch", - "version": "v7.4.0", + "version": "v7.4.8", "source": { "type": "git", "url": "https://github.com/symfony/stopwatch.git", - "reference": "8a24af0a2e8a872fb745047180649b8418303084" + "reference": "70a852d72fec4d51efb1f48dcd968efcaf5ccb89" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/stopwatch/zipball/8a24af0a2e8a872fb745047180649b8418303084", - "reference": "8a24af0a2e8a872fb745047180649b8418303084", + "url": "https://api.github.com/repos/symfony/stopwatch/zipball/70a852d72fec4d51efb1f48dcd968efcaf5ccb89", + "reference": "70a852d72fec4d51efb1f48dcd968efcaf5ccb89", "shasum": "" }, "require": { @@ -16103,7 +16150,7 @@ "description": "Provides a way to profile code", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/stopwatch/tree/v7.4.0" + "source": "https://github.com/symfony/stopwatch/tree/v7.4.8" }, "funding": [ { @@ -16123,20 +16170,20 @@ "type": "tidelift" } ], - "time": "2025-08-04T07:05:15+00:00" + "time": "2026-03-24T13:12:05+00:00" }, { "name": "symfony/var-exporter", - "version": "v7.4.0", + "version": "v7.4.9", "source": { "type": "git", "url": "https://github.com/symfony/var-exporter.git", - "reference": "03a60f169c79a28513a78c967316fbc8bf17816f" + "reference": "22e03a49c95ef054a43601cd159b222bfab1c701" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/var-exporter/zipball/03a60f169c79a28513a78c967316fbc8bf17816f", - "reference": "03a60f169c79a28513a78c967316fbc8bf17816f", + "url": "https://api.github.com/repos/symfony/var-exporter/zipball/22e03a49c95ef054a43601cd159b222bfab1c701", + "reference": "22e03a49c95ef054a43601cd159b222bfab1c701", "shasum": "" }, "require": { @@ -16184,7 +16231,7 @@ "serialize" ], "support": { - "source": "https://github.com/symfony/var-exporter/tree/v7.4.0" + "source": "https://github.com/symfony/var-exporter/tree/v7.4.9" }, "funding": [ { @@ -16204,7 +16251,7 @@ "type": "tidelift" } ], - "time": "2025-09-11T10:15:23+00:00" + "time": "2026-04-18T13:18:21+00:00" }, { "name": "theseer/tokenizer", @@ -16267,9 +16314,9 @@ "platform": { "php": ">=8.2" }, - "platform-dev": {}, + "platform-dev": [], "platform-overrides": { "php": "8.2" }, - "plugin-api-version": "2.9.0" + "plugin-api-version": "2.6.0" } diff --git a/config/vufind/config.ini b/config/vufind/config.ini index 1f30905ca63..7af3d6e668f 100644 --- a/config/vufind/config.ini +++ b/config/vufind/config.ini @@ -2601,6 +2601,7 @@ validateHierarchySequences = true ; your instance. ;[Captcha] ; Valid type values: +; - altcha (proof of work bot deterrent) ; - dumb (ask the user to reverse a random string; only recommended for testing) ; - image (generate a local image for the user to interpret) ; - interval (allow an action after a specified time has elapsed from session start @@ -2619,6 +2620,24 @@ validateHierarchySequences = true ; form-by-form basis with the useCaptcha setting in FeedbackForms.yaml. ;forms = * + +; Altcha +;altcha_secret = "secret hmac hey that should be a long hash" + +; Altcha Challenge Options +; @link https://github.com/altcha-org/altcha-lib-php/blob/main/src/ChallengeOptions.php +; - Hashing algorithm to use (`SHA-1`, `SHA-256`, `SHA-512`, default: `SHA-256`). +;altcha_algorithm = 'SHA-256' +; - Maximum number for the random number generator (default: 1000000) +;altcha_max_number = 1000000 +; - Length of the random salt (default: 12 bytes). +;altcha_salt_len = 12 +; - Optional interval to generate expiration time for the challenge. +; MUST be valid string for DateInterval::createFromDateString. +;altcha_expires_interval = +; - Optional URL-encoded query parameters. +;altcha_params = + ; Image options, see: ; https://docs.laminas.dev/laminas-captcha/adapters/#laminascaptchaimage ;image_length = 8 diff --git a/config/vufind/contentsecuritypolicy.ini b/config/vufind/contentsecuritypolicy.ini index ad869948524..d0c605f9add 100644 --- a/config/vufind/contentsecuritypolicy.ini +++ b/config/vufind/contentsecuritypolicy.ini @@ -46,8 +46,11 @@ connect-src[] = "'self'" ;connect-src[] = "https://*.google-analytics.com" ; If you are using Matomo, fix the URL for your installation and uncomment the line below ;connect-src[] = "https://server.address/matomo/matomo.php" -; worker-src required for jsTree with browsers that don't support 'strict-dynamic' (e.g. Safari): +; worker-src (permission to load web worker JS files) +; (blob) required for jsTree with browsers that don't support 'strict-dynamic' (e.g. Safari): worker-src[] = "blob:" +; (self) required for proof of work (PoW) Captcha web worker +worker-src[] = "'self'" style-src[] = "'self'" style-src[] = "'unsafe-inline'" img-src[] = "'self'" @@ -77,7 +80,7 @@ base-uri[] = "'self'" ; Provide both report-uri and report-to headers to capture CSP violations. Each is supported ; by different browsers. See ; https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy/report-uri -; +; ; Set URI that some browsers use to report CSP violation. ;report-uri[] = 'https://example.report-uri.com' ; Set the named endpoint that other borwsers use to report CSP violations. The endpoint name diff --git a/module/VuFind/src/VuFind/Captcha/Altcha.php b/module/VuFind/src/VuFind/Captcha/Altcha.php new file mode 100644 index 00000000000..6d76b17dfe9 --- /dev/null +++ b/module/VuFind/src/VuFind/Captcha/Altcha.php @@ -0,0 +1,113 @@ +. + * + * @category VuFind + * @package CAPTCHA + * @author Chris Hallberg + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @link https://vufind.org Main Page + */ + +namespace VuFind\Captcha; + +use AltchaOrg\Altcha\ChallengeOptions; +use AltchaOrg\Altcha\Hasher\Algorithm; +use Laminas\Mvc\Controller\Plugin\Params; + +use function is_array; + +/** + * Altcha proof-of-work CAPTCHA. + * + * @category VuFind + * @package CAPTCHA + * @author Chris Hallberg + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @link https://vufind.org/wiki/development Wiki + */ +class Altcha extends AbstractBase +{ + /** + * Constructor. + * + * @param \AltchaOrg\Altcha\Altcha $altcha Required HMAC key for challenge calculation/solution verification. + * @param Algorithm $algorithm Hashing algorithm to use (SHA-1, SHA-256, SHA-512, default: SHA-256). + * @param int $maxNumber Maximum number for the random number generator (default: 1,000,000) + * @param null|\DateTimeInterface $expires Optional expiration time for the challenge. + * @param array $params Optional URL-encoded query parameters. + * @param int<1, max> $saltLength Length of the random salt (default: 12 bytes). + */ + public function __construct( + protected \AltchaOrg\Altcha\Altcha $altcha, + // Options for creation of a new challenge + protected Algorithm $algorithm = Algorithm::SHA256, + protected int $maxNumber = 1000000, + protected ?\DateTimeInterface $expires = null, + protected array $params = [], + protected int $saltLength = 12, + ) { + } + + /** + * Get list of URLs with JS dependencies to load for the active CAPTCHA type. + * + * @return array + */ + public function getJsIncludes(): array + { + return ['vendor/altcha.js', 'vendor/altcha-i18n.js']; + } + + /** + * Generate challenge. + * + * @return Challenge + */ + public function getChallenge() + { + $options = new ChallengeOptions( + algorithm: $this->algorithm, + maxNumber: $this->maxNumber, + expires: $this->expires, + params: $this->params, + saltLength: $this->saltLength, + ); + + return json_encode($this->altcha->createChallenge($options)); + } + + /** + * Pull the captcha field from controller params and check them for accuracy + * We pull from the form in case config changed since challenge was sent. + * + * @param Params $params Controller params + * + * @return bool + */ + public function verify(Params $params): bool + { + $encoded = $params->fromPost('altcha', null); + $json = base64_decode($encoded); + $payload = json_decode($json, true); + return is_array($payload) ? $this->altcha->verifySolution($payload, checkExpires: true) : false; + } +} diff --git a/module/VuFind/src/VuFind/Captcha/AltchaFactory.php b/module/VuFind/src/VuFind/Captcha/AltchaFactory.php new file mode 100644 index 00000000000..e7e7d29f533 --- /dev/null +++ b/module/VuFind/src/VuFind/Captcha/AltchaFactory.php @@ -0,0 +1,105 @@ +. + * + * @category VuFind + * @package CAPTCHA + * @author Chris Hallberg + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @link https://vufind.org/wiki/development Wiki + */ + +namespace VuFind\Captcha; + +use AltchaOrg\Altcha\Hasher\Algorithm; +use Laminas\ServiceManager\Exception\ServiceNotCreatedException; +use Laminas\ServiceManager\Exception\ServiceNotFoundException; +use Laminas\ServiceManager\Factory\FactoryInterface; +use Psr\Container\ContainerExceptionInterface as ContainerException; +use Psr\Container\ContainerInterface; + +/** + * Altcha proof-of-work CAPTCHA factory. + * + * @category VuFind + * @package CAPTCHA + * @author Chris Hallberg + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @link https://vufind.org/wiki/development Wiki + */ +class AltchaFactory implements FactoryInterface +{ + /** + * Create an object. + * + * @param ContainerInterface $container Service manager + * @param string $requestedName Service being created + * @param null|array $options Extra options (optional) + * + * @return object + * + * @throws ServiceNotFoundException if unable to resolve the service. + * @throws ServiceNotCreatedException if an exception is raised when + * creating a service. + * @throws ContainerException&\Throwable if any other error occurs + */ + public function __invoke( + ContainerInterface $container, + $requestedName, + ?array $options = null + ) { + if (!empty($options)) { + throw new \Exception('Unexpected options passed to factory.'); + } + + $config = $container + ->get(\VuFind\Config\PluginManager::class) + ->get('config'); + + $secret = $config['Captcha']['altcha_secret'] ?? null; + + if (empty($secret)) { + throw new \Exception('Secret key needed for Altcha. See config.ini.'); + } + + $algorithm = Algorithm::from($config['Captcha']['altcha_algorithm'] ?? 'SHA-256'); + $maxNumber = $config['Captcha']['altcha_max_number'] ?? 100000; + $saltLength = $config['Captcha']['altcha_salt_len'] ?? 12; + $expiresInterval = $config['Captcha']['altcha_expires_interval'] ?? null; + $params = $config['Captcha']['altcha_params'] ?? []; + + $expires = !empty($expiresInterval) + ? (new \DateTimeImmutable())->add(new \DateInterval($expiresInterval)) + : null; + + $altcha = new \AltchaOrg\Altcha\Altcha($secret); + + return new $requestedName( + $altcha, + // challenge options + $algorithm, + $maxNumber, + $expires, + $params, + $saltLength, + ); + } +} diff --git a/module/VuFind/src/VuFind/Captcha/PluginManager.php b/module/VuFind/src/VuFind/Captcha/PluginManager.php index 5a863ac9a73..3d7665cd226 100644 --- a/module/VuFind/src/VuFind/Captcha/PluginManager.php +++ b/module/VuFind/src/VuFind/Captcha/PluginManager.php @@ -48,6 +48,7 @@ class PluginManager extends \VuFind\ServiceManager\AbstractPluginManager * @var array */ protected $aliases = [ + 'altcha' => Altcha::class, 'demo' => Demo::class, 'dumb' => Dumb::class, 'image' => Image::class, @@ -61,6 +62,7 @@ class PluginManager extends \VuFind\ServiceManager\AbstractPluginManager * @var array */ protected $factories = [ + Altcha::class => AltchaFactory::class, Demo::class => InvokableFactory::class, Dumb::class => DumbFactory::class, Image::class => ImageFactory::class, diff --git a/module/VuFind/src/VuFind/Controller/Plugin/Captcha.php b/module/VuFind/src/VuFind/Controller/Plugin/Captcha.php index b4c19f4e27e..3cdab9897b4 100644 --- a/module/VuFind/src/VuFind/Controller/Plugin/Captcha.php +++ b/module/VuFind/src/VuFind/Controller/Plugin/Captcha.php @@ -138,6 +138,7 @@ public function verify(): bool $errorMessage = $captcha->getErrorMessage(); } } catch (\Exception $e) { + error_log($e); $captchaPassed = false; $errorMessage = $this->translate('captcha_technical_difficulties'); } diff --git a/themes/bootstrap5/templates/Helpers/captcha.phtml b/themes/bootstrap5/templates/Helpers/captcha.phtml index 34c9ce15137..0847e23b36a 100644 --- a/themes/bootstrap5/templates/Helpers/captcha.phtml +++ b/themes/bootstrap5/templates/Helpers/captcha.phtml @@ -5,7 +5,7 @@ captchas) == 1):?> captcha()->getHtmlForCaptcha($this->captchas[0])): ?> -

+
diff --git a/themes/bootstrap5/templates/RecordTab/usercomments.phtml b/themes/bootstrap5/templates/RecordTab/usercomments.phtml index a8541b7b75e..cc72dd1075a 100644 --- a/themes/bootstrap5/templates/RecordTab/usercomments.phtml +++ b/themes/bootstrap5/templates/RecordTab/usercomments.phtml @@ -20,10 +20,10 @@ component('star-rating', ['ratingData' => $ratingData, 'allowClear' => 0 === $ratingData['count'] || $this->accountCapabilities()->isRatingRemovalAllowed()]);?> +
tab->isCaptchaActive()): ?> captcha()->html(true, false) ?> -
diff --git a/themes/root/js/vendor/altcha-LICENSE.txt b/themes/root/js/vendor/altcha-LICENSE.txt new file mode 100644 index 00000000000..9f2bcf1a66b --- /dev/null +++ b/themes/root/js/vendor/altcha-LICENSE.txt @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2023 Daniel Regeci, BAU Software s.r.o. + +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. \ No newline at end of file diff --git a/themes/root/js/vendor/altcha-i18n.js b/themes/root/js/vendor/altcha-i18n.js new file mode 100644 index 00000000000..be64e9e4f7d --- /dev/null +++ b/themes/root/js/vendor/altcha-i18n.js @@ -0,0 +1 @@ +(function(o){typeof define=="function"&&define.amd?define(o):o()})(function(){"use strict";const o=()=>{};function u(e,a){return e!=e?a==a:e!==a||e!==null&&typeof e=="object"||typeof e=="function"}let d=!1;function v(e){var a=d;try{return d=!0,e()}finally{d=a}}function b(e,a,r){if(e==null)return a(void 0),o;const t=v(()=>e.subscribe(a,r));return t.unsubscribe?()=>t.unsubscribe():t}const n=[];function A(e,a=o){let r=null;const t=new Set;function g(l){if(u(e,l)&&(e=l,r)){const c=!n.length;for(const i of t)i[1](),n.push(i,e);if(c){for(let i=0;i{t.delete(i),t.size===0&&r&&(r(),r=null)}}return{set:g,update:f,subscribe:ve}}function s(e){let a;return b(e,r=>a=r)(),a}globalThis.altchaPlugins=globalThis.altchaPlugins||[],globalThis.altchaI18n=globalThis.altchaI18n||{get:e=>s(globalThis.altchaI18n.store)[e],set:(e,a)=>{Object.assign(s(globalThis.altchaI18n.store),{[e]:a}),globalThis.altchaI18n.store.set(s(globalThis.altchaI18n.store))},store:A({})};const k={ariaLinkLabel:"Besoek Altcha.org",enterCode:"Voer kode in",enterCodeAria:"Voer die kode in wat jy hoor. Druk Spasie om die klank af te speel.",error:"Verifikasie het misluk. Probeer later weer.",expired:"Verifikasie het verval. Probeer weer.",footer:'Beskerm deur ALTCHA',getAudioChallenge:"Kry 'n klankuitdaging",label:"Ek is nie 'n robot nie",loading:"Laai...",reload:"Laai weer",verify:"Verifieer",verificationRequired:"Verifikasie is vereis!",verified:"Geverifieer",verifying:"Verifieer...",waitAlert:"Verifieer... wag asseblief."};globalThis.altchaI18n.set("af",k);const p={ariaLinkLabel:"زور Altcha.org",enterCode:"أدخل الرمز",enterCodeAria:"أدخل الرمز الذي تسمعه. اضغط على المسافة لتشغيل الصوت.",error:"فشل التحقق. حاول مرة أخرى لاحقاً.",expired:"انتهت صلاحية التحقق. حاول مرة أخرى.",verificationRequired:"مطلوب التحقق!",footer:'محمي بواسطة ALTCHA',getAudioChallenge:"احصل على تحدي صوتي",label:"أنا لست روبوتاً",loading:"جارٍ التحميل...",reload:"إعادة تحميل",verify:"تحقق",verified:"تم التحقق",verifying:"جارٍ التحقق...",waitAlert:"جارٍ التحقق... يرجى الانتظار."};globalThis.altchaI18n.set("ar",p);const C={ariaLinkLabel:"Посетете Altcha.org",enterCode:"Въведете код",enterCodeAria:"Въведете кода, който чувате. Натиснете Space за възпроизвеждане на аудио.",error:"Проверката неуспешна. Моля, опитайте по-късно.",expired:"Времето за проверка изтече. Моля, опитайте отново.",verificationRequired:"Изисква се проверка!",footer:'Защитено от ALTCHA',getAudioChallenge:"Аудио проверка",label:"Аз не съм робот",loading:"Зареждане...",reload:"Презареди",verify:"Провери",verified:"Проверено",verifying:"Проверява се...",waitAlert:"Проверката е в процес... моля изчакайте."};globalThis.altchaI18n.set("bg",C);const y={ariaLinkLabel:"Наведаць Altcha.org",enterCode:"Увядзіце код",enterCodeAria:"Увядзіце код, які вы чуеце. Націсніце прабел, каб прайграць аўдыё.",error:"Праверка не прайшла. Паспрабуйце пазней.",expired:"Тэрмін праверкі скончыўся. Паспрабуйце зноў.",footer:'Абаронена ALTCHA',getAudioChallenge:"Атрымаць аўдыё выклік",label:"Я не робат",loading:"Загрузка...",reload:"Перазагрузіць",verify:"Праверыць",verificationRequired:"Патрабуецца праверка!",verified:"Праверана",verifying:"Правяраем...",waitAlert:"Праверка... калі ласка, пачакайце."};globalThis.altchaI18n.set("be",y);const L={ariaLinkLabel:"Posjetite Altcha.org",enterCode:"Unesite kod",enterCodeAria:"Unesite kod koji čujete. Pritisnite Space da biste pustili zvuk.",error:"Verifikacija nije uspjela. Pokušajte ponovo kasnije.",expired:"Verifikacija je istekla. Pokušajte ponovo.",footer:'Zaštićeno od strane ALTCHA',getAudioChallenge:"Dohvatite audio izazov",label:"Nisam robot",loading:"Učitavanje...",reload:"Ponovno učitaj",verify:"Verifikuj",verificationRequired:"Verifikacija je obavezna!",verified:"Verifikovano",verifying:"Verifikacija u toku...",waitAlert:"Verifikacija u toku... molimo vas da sačekate."};globalThis.altchaI18n.set("bs",L);const V={ariaLinkLabel:"Visita Altcha.org",enterCode:"Introdueix el codi",enterCodeAria:"Introdueix el codi que escoltes. Prem Espai per reproduir l’àudio.",error:"Verificació fallida. Torna-ho a provar més tard.",expired:"Verificació expirada. Torna-ho a provar.",footer:'Protegit per ALTCHA',getAudioChallenge:"Obtenir un desafiament d’àudio",label:"No sóc un robot",loading:"Carregant...",reload:"Torna a carregar",verify:"Verificar",verificationRequired:"Es requereix verificació!",verified:"Verificat",verifying:"Verificant...",waitAlert:"Verificant... si us plau, espera."};globalThis.altchaI18n.set("ca",V);const j={ariaLinkLabel:"Navštivte Altcha.org",enterCode:"Zadejte kód",enterCodeAria:"Zadejte kód, který slyšíte. Stisknutím mezerníku přehrajete zvuk.",error:"Ověření selhalo. Zkuste to prosím později.",expired:"Ověření vypršelo. Zkuste to prosím znovu.",verificationRequired:"Vyžaduje se ověření!",footer:'Chráněno pomocí ALTCHA',getAudioChallenge:"Získat audio výzvu",label:"Nejsem robot",loading:"Načítání...",reload:"Znovu načíst",verify:"Ověřit",verified:"Ověřeno",verifying:"Ověřování...",waitAlert:"Probíhá ověření... prosím počkejte."};globalThis.altchaI18n.set("cs",j);const m={ariaLinkLabel:"Besøg Altcha.org",enterCode:"Indtast kode",enterCodeAria:"Indtast den kode, du hører. Tryk på mellemrumstasten for at afspille lyd.",error:"Verificering mislykkedes. Prøv venligst igen senere.",expired:"Verificering udløbet. Prøv venligst igen.",verificationRequired:"Verificering kræves!",footer:'Beskyttet af ALTCHA',getAudioChallenge:"Hent lydudfordring",label:"Jeg er ikke en robot",loading:"Indlæser...",reload:"Genindlæs",verify:"Verificer",verified:"Verificeret",verifying:"Verificerer...",waitAlert:"Verificerer... vent venligst."};globalThis.altchaI18n.set("da",m);const T={ariaLinkLabel:"Besuche Altcha.org",enterCode:"Code eingeben",enterCodeAria:"Geben Sie den Code ein, den Sie hören. Drücken Sie die Leertaste, um die Audio abzuspielen.",error:"Überprüfung fehlgeschlagen. Bitte versuchen Sie es später erneut.",expired:"Überprüfung abgelaufen. Bitte versuchen Sie es erneut.",verificationRequired:"Überprüfung erforderlich!",footer:'Geschützt durch ALTCHA',getAudioChallenge:"Audio-Herausforderung anfordern",label:"Ich bin kein Roboter",loading:"Lade...",reload:"Neu laden",verify:"Überprüfen",verified:"Überprüft",verifying:"Wird überprüft...",waitAlert:"Überprüfung läuft... bitte warten."};globalThis.altchaI18n.set("de",T);const z={ariaLinkLabel:"Επισκεφθείτε το Altcha.org",enterCode:"Εισαγάγετε κωδικό",enterCodeAria:"Εισαγάγετε τον κωδικό που ακούτε. Πατήστε Space για να παίξετε τον ήχο.",error:"Η επαλήθευση απέτυχε. Δοκιμάστε ξανά αργότερα.",expired:"Η επαλήθευση έληξε. Δοκιμάστε ξανά.",verificationRequired:"Απαιτείται έλεγχος!",footer:'Προστατεύεται από το ALTCHA',getAudioChallenge:"Λήψη ηχητικής δοκιμασίας",label:"Δεν είμαι ρομπότ",loading:"Φόρτωση...",reload:"Επαναφόρτωση",verify:"Επαλήθευση",verified:"Επαληθεύτηκε",verifying:"Γίνεται επαλήθευση...",waitAlert:"Γίνεται επαλήθευση... παρακαλώ περιμένετε."};globalThis.altchaI18n.set("el",z);const I={ariaLinkLabel:"Visitar Altcha.org",enterCode:"Introduce el código",enterCodeAria:"Introduce el código que escuchas. Pulsa Espacio para reproducir el audio.",error:"Falló la verificación. Por favor intente nuevamente más tarde.",expired:"Verificación expirada. Por favor intente nuevamente.",verificationRequired:"¡Verificación requerida!",footer:'Protegido por ALTCHA',getAudioChallenge:"Obtener un desafío de audio",label:"No soy un robot",loading:"Cargando...",reload:"Recargar",verify:"Verificar",verified:"Verificado",verifying:"Verificando...",waitAlert:"Verificando... por favor espere."};globalThis.altchaI18n.set("es-es",I);const P={ariaLinkLabel:"Visitar Altcha.org",enterCode:"Ingresa el código",enterCodeAria:"Ingresa el código que escuchas. Presiona Espacio para reproducir el audio.",error:"Falló la verificación. Por favor vuelve a intentarlo más tarde.",expired:"La verificación expiró. Por favor inténtalo de nuevo.",verificationRequired:"¡Verificación requerida!",footer:'Protegido por ALTCHA',getAudioChallenge:"Obtener un reto de audio",label:"No soy un robot",loading:"Cargando...",reload:"Volver a cargar",verify:"Verificar",verified:"Verificado",verifying:"Verificando...",waitAlert:"Verificando... por favor espera."};globalThis.altchaI18n.set("es-419",P);const w={ariaLinkLabel:"Külasta Altcha.org",enterCode:"Sisesta kood",enterCodeAria:"Sisestage kuuldu kood. Vajutage tühikut, et esitada heli.",error:"Kinnitamine ebaõnnestus. Proovi hiljem uuesti.",expired:"Kinnitamine aegus. Proovi uuesti.",verificationRequired:"Kontroll on vajalik!",footer:'Kaitstud ALTCHA poolt',getAudioChallenge:"Hangi heliülesanne",label:"Ma ei ole robot",loading:"Laadimine...",reload:"Laadi uuesti",verify:"Kinnita",verified:"Kinnitatud",verifying:"Kinnitamine...",waitAlert:"Kinnitamine... palun oota."};globalThis.altchaI18n.set("et",w);const x={ariaLinkLabel:"Bisitatu Altcha.org",enterCode:"Sartu kodea",enterCodeAria:"Sartu entzun duzun kodea. Sakatu Espazioa audioa erreproduzitzeko.",error:"Egiaztatzeak huts egin du. Saiatu berriro geroago.",expired:"Egiaztatzea iraungi da. Saiatu berriro.",verificationRequired:"Egiaztatzea beharrezkoa da!",footer:'ALTCHAk babestuta',getAudioChallenge:"Jaso audio-erronka bat",label:"Ez naiz robot bat",loading:"Kargatzen...",reload:"Birkargatu",verify:"Egiaztatu",verified:"Egiaztatuta",verifying:"Egiaztatzen...",waitAlert:"Egiaztatzen... itxaron mesedez."};globalThis.altchaI18n.set("eu",x);const q={ariaLinkLabel:"Vieraile sivulla Altcha.org",enterCode:"Syötä koodi",enterCodeAria:"Kirjoita kuulemasi koodi. Paina välilyöntiä toistaaksesi äänen.",error:"Varmennus epäonnistui. Yritä myöhemmin uudelleen.",expired:"Varmennus vanhentui. Yritä uudelleen.",verificationRequired:"Vahvistus vaaditaan!",footer:'Suojattu ALTCHA:lla',getAudioChallenge:"Hae äänitehtävä",label:"En ole robotti",loading:"Ladataan...",reload:"Lataa uudelleen",verify:"Vahvista",verified:"Vahvistettu",verifying:"Vahvistetaan...",waitAlert:"Vahvistetaan... odota hetki."};globalThis.altchaI18n.set("fi",q);const R={ariaLinkLabel:"Visitez Altcha.org",enterCode:"Entrez le code",enterCodeAria:"Entrez le code que vous entendez. Appuyez sur la barre d'espace pour écouter l'audio.",error:"Échec de la vérification. Réessayez plus tard.",expired:"La vérification a expiré. Réessayez.",verificationRequired:"Vérification requise !",footer:'Protégé par ALTCHA',getAudioChallenge:"Obtenir un défi audio",label:"Pas un robot",loading:"Chargement...",reload:"Recharger",verify:"Vérifier",verified:"Vérifié",verifying:"Vérification en cours...",waitAlert:"Vérification en cours... veuillez patienter."};globalThis.altchaI18n.set("fr-ca",R);const H={ariaLinkLabel:"Visitez Altcha.org",enterCode:"Entrez le code",enterCodeAria:"Entrez le code que vous entendez. Appuyez sur Espace pour écouter l'audio.",error:"Échec de la vérification. Essayez à nouveau plus tard.",expired:"La vérification a expiré. Essayez à nouveau.",verificationRequired:"Vérification requise !",footer:'Protégé par ALTCHA',getAudioChallenge:"Obtenir un défi audio",label:"Pas un robot",loading:"Chargement...",reload:"Recharger",verify:"Vérifier",verified:"Vérifié",verifying:"Vérification en cours...",waitAlert:"Vérification en cours... veuillez patienter."};globalThis.altchaI18n.set("fr-fr",H);const _={ariaLinkLabel:"Tabhair cuairt ar Altcha.org",enterCode:"Iontráil cód",enterCodeAria:"Cuir isteach an cód a chloiseann tú. Brúigh Spás chun an fuaime a sheinm.",error:"Theip ar an bhfíorú. Bain triail eile as níos déanaí.",expired:"Tá an fíorú as feidhm. Bain triail eile as.",verificationRequired:"Fíorú riachtanach!",footer:'Cosanta ag ALTCHA',getAudioChallenge:"Faigh dúshlán fuaime",label:"Níl mé i mo róbat",loading:"Á luchtú...",reload:"Athluchtaigh",verify:"Fíoraigh",verified:"Fíoraithe",verifying:"Fíorú ar siúl...",waitAlert:"Fíorú ar siúl... fan go fóill."};globalThis.altchaI18n.set("ga",_);const S={ariaLinkLabel:"Posjetite Altcha.org",enterCode:"Unesite kod",enterCodeAria:"Unesite kod koji čujete. Pritisnite razmaknicu za reprodukciju zvuka.",error:"Provjera nije uspjela. Molimo pokušajte kasnije.",expired:"Provjera je istekla. Molimo pokušajte ponovo.",verificationRequired:"Potrebna je provjera!",footer:'Zaštićeno od strane ALTCHA',getAudioChallenge:"Audio provjera",label:"Ja nisam robot",loading:"Učitavanje...",reload:"Ponovno učitaj",verify:"Provjeri",verified:"Provjereno",verifying:"Provjeravanje...",waitAlert:"Provjera je u tijeku... molimo pričekajte."};globalThis.altchaI18n.set("hr",S);const $={ariaLinkLabel:"Látogass el az Altcha.org oldalra",enterCode:"Írja be a kódot",enterCodeAria:"Írja be a hallott kódot. Nyomja meg a Szóköz billentyűt a hang lejátszásához.",error:"A hitelesítés nem sikerült. Próbáld meg később újra.",expired:"A hitelesítés lejárt. Próbáld újra.",verificationRequired:"Ellenőrzés szükséges!",footer:'Védve a következő által: ALTCHA',getAudioChallenge:"Hangalapú kihívás kérése",label:"Nem vagyok robot",loading:"Betöltés...",reload:"Újratöltés",verify:"Ellenőrzés",verified:"Ellenőrizve",verifying:"Ellenőrzés folyamatban...",waitAlert:"Ellenőrzés folyamatban... kérlek várj."};globalThis.altchaI18n.set("hu",$);const E={ariaLinkLabel:"Heimsækja Altcha.org",enterCode:"Sláðu inn kóða",enterCodeAria:"Sláðu inn kóðann sem þú heyrir. Ýttu á Space til að spila hljóðið.",error:"Staðfesting mistókst. Reyndu aftur síðar.",expired:"Staðfesting er útrunnin. Reyndu aftur.",footer:'Verndað af ALTCHA',getAudioChallenge:"Fá hljóðáskorun",label:"Ég er ekki robot",loading:"Hleður...",reload:"Hleð aftur",verify:"Staðfesta",verificationRequired:"Staðfesting er nauðsynleg!",verified:"Staðfest",verifying:"Að staðfesta...",waitAlert:"Að staðfesta... vinsamlegast bíða."};globalThis.altchaI18n.set("is",E);const N={ariaLinkLabel:"Visita Altcha.org",enterCode:"Inserisci il codice",enterCodeAria:"Inserisci il codice che senti. Premi Spazio per riprodurre l'audio.",error:"Verifica fallita. Riprova più tardi.",expired:"Verifica scaduta. Riprova.",verificationRequired:"Verifica richiesta!",footer:'Protetto da ALTCHA',getAudioChallenge:"Ottieni una sfida audio",label:"Non sono un robot",loading:"Caricamento...",reload:"Ricarica",verify:"Verifica",verified:"Verificato",verifying:"Verifica in corso...",waitAlert:"Verifica in corso... attendere."};globalThis.altchaI18n.set("it",N);const B={ariaLinkLabel:"Apsilankykite Altcha.org",enterCode:"Įveskite kodą",enterCodeAria:"Įveskite girdimą kodą. Paspauskite tarpo klavišą, kad grotumėte garso įrašą.",error:"Patvirtinimas nepavyko. Bandykite vėliau.",expired:"Patvirtinimo laikas baigėsi. Bandykite dar kartą.",verificationRequired:"Reikalingas patvirtinimas!",footer:'Apsaugota ALTCHA',getAudioChallenge:"Gauti garso užduotį",label:"Aš nesu robotas",loading:"Įkeliama...",reload:"Įkelti iš naujo",verify:"Patvirtinti",verified:"Patvirtinta",verifying:"Tikrinama...",waitAlert:"Tikrinama... prašome palaukti."};globalThis.altchaI18n.set("lt",B);const O={ariaLinkLabel:"Apmeklējiet Altcha.org",enterCode:"Ievadiet kodu",enterCodeAria:"Ievadiet dzirdamo kodu. Nospiediet atstarpes taustiņu, lai atskaņotu audio.",error:"Verifikācija neizdevās. Mēģiniet vēlāk vēlreiz.",expired:"Verifikācijas laiks ir beidzies. Mēģiniet vēlreiz.",verificationRequired:"Nepieciešama verifikācija!",footer:'Aizsargāts ar ALTCHA',getAudioChallenge:"Saņemt audio izaicinājumu",label:"Es neesmu robots",loading:"Notiek ielāde...",reload:"Pārlādēt",verify:"Verificēt",verified:"Verificēts",verifying:"Notiek verifikācija...",waitAlert:"Notiek verifikācija... lūdzu, uzgaidiet."};globalThis.altchaI18n.set("lv",O);const D={ariaLinkLabel:"Żur Altcha.org",enterCode:"Idħol il-kodiċi",enterCodeAria:"Idħol il-kodiċi li tisma'. Agħfas Spazju biex tindaqq l-awdjo.",error:"Il-verifika falliet. Erġa’ pprova aktar tard.",expired:"Il-verifika skadiet. Erġa’ pprova.",verificationRequired:"Verifika meħtieġa!",footer:'Protett minn ALTCHA',getAudioChallenge:"Ikseb sfida bl-awdjo",label:"M’inix robot",loading:"Qed jitgħabba...",reload:"Ittella’ mill-ġdid",verify:"Ivverifika",verified:"Ivverifikat",verifying:"Verifika għaddejja...",waitAlert:"Verifika għaddejja... stenna ftit."};globalThis.altchaI18n.set("mt",D);const h={ariaLinkLabel:"Besøk Altcha.org",enterCode:"Skriv inn kode",enterCodeAria:"Skriv inn koden du hører. Trykk på Space for å spille av lyden.",error:"Verifisering mislyktes. Prøv igjen senere.",expired:"Verifiseringen utløp. Prøv igjen.",footer:'Beskyttet av ALTCHA',getAudioChallenge:"Få en lydutfordring",label:"Jeg er ikke en robot",loading:"Laster...",reload:"Last på nytt",verify:"Verifiser",verificationRequired:"Verifisering kreves!",verified:"Verifisert",verifying:"Verifiserer...",waitAlert:"Verifiserer... vennligst vent."};globalThis.altchaI18n.set("nb",h),globalThis.altchaI18n.set("no",h);const K={ariaLinkLabel:"Bezoek Altcha.org",enterCode:"Voer code in",enterCodeAria:"Voer de code in die je hoort. Druk op Spatie om de audio af te spelen.",error:"Verificatie mislukt. Probeer het later opnieuw.",expired:"Verificatie verlopen. Probeer het opnieuw.",verificationRequired:"Verificatie vereist!",footer:'Beschermd door ALTCHA',getAudioChallenge:"Audio-uitdaging ontvangen",label:"Ik ben geen robot",loading:"Laden...",reload:"Herladen",verify:"Verifiëren",verified:"Geverifieerd",verifying:"Bezig met verifiëren...",waitAlert:"Bezig met verifiëren... even geduld a.u.b."};globalThis.altchaI18n.set("nl",K);const F={ariaLinkLabel:"Odwiedź Altcha.org",enterCode:"Wprowadź kod",enterCodeAria:"Wpisz kod, który słyszysz. Naciśnij Spację, aby odtworzyć dźwięk.",error:"Weryfikacja nie powiodła się. Spróbuj ponownie później.",expired:"Weryfikacja wygasła. Spróbuj ponownie.",verificationRequired:"Wymagana weryfikacja!",footer:'Chronione przez ALTCHA',getAudioChallenge:"Pobierz zadanie dźwiękowe",label:"Nie jestem robotem",loading:"Ładowanie...",reload:"Odśwież",verify:"Zweryfikuj",verified:"Zweryfikowano",verifying:"Weryfikacja...",waitAlert:"Trwa weryfikacja... proszę czekać."};globalThis.altchaI18n.set("pl",F);const Z={ariaLinkLabel:"Visitar Altcha.org",enterCode:"Introduza o código",enterCodeAria:"Introduza o código que ouve. Prima Espaço para reproduzir o áudio.",error:"A verificação falhou. Por favor, tente novamente mais tarde.",expired:"Verificação expirada. Por favor, tente novamente.",verificationRequired:"Verificação necessária!",footer:'Protegido por ALTCHA',getAudioChallenge:"Obter desafio de áudio",label:"Não sou um robô",loading:"A carregar...",reload:"Recarregar",verify:"Verificar",verified:"Verificado",verifying:"A verificar...",waitAlert:"A verificar... por favor aguarde."};globalThis.altchaI18n.set("pt-pt",Z);const M={ariaLinkLabel:"Visitar Altcha.org",enterCode:"Digite o código",enterCodeAria:"Digite o código que você ouve. Pressione Espaço para reproduzir o áudio.",error:"Falha na verificação. Por favor, tente novamente mais tarde.",expired:"Verificação expirada. Por favor, tente novamente.",verificationRequired:"Verificação necessária!",footer:'Protegido por ALTCHA',getAudioChallenge:"Obter desafio de áudio",label:"Eu não sou um robô",loading:"Carregando...",reload:"Recarregar",verify:"Verificar",verified:"Verificado",verifying:"Verificando...",waitAlert:"Verificando... por favor aguarde."};globalThis.altchaI18n.set("pt-br",M);const U={ariaLinkLabel:"Vizitează Altcha.org",enterCode:"Introduceți codul",enterCodeAria:"Introduceți codul pe care îl auziți. Apăsați Spațiu pentru a reda audio.",error:"Verificarea a eșuat. Încearcă din nou mai târziu.",expired:"Verificarea a expirat. Încearcă din nou.",verificationRequired:"Verificare necesară!",footer:'Protejat de ALTCHA',getAudioChallenge:"Obține o provocare audio",label:"Nu sunt un robot",loading:"Se încarcă...",reload:"Reîncarcă",verify:"Verifică",verified:"Verificat",verifying:"Se verifică...",waitAlert:"Se verifică... te rugăm să aștepți."};globalThis.altchaI18n.set("ro",U);const G={ariaLinkLabel:"Перейти на Altcha.org",enterCode:"Введите код",enterCodeAria:"Введите код, который слышите. Нажмите пробел для воспроизведения аудио.",error:"Ошибка верификации. Попробуйте позже.",expired:"Срок действия верификации истек. Попробуйте снова.",verificationRequired:"Требуется проверка!",footer:'Защищено ALTCHA',getAudioChallenge:"Получить аудио задачу",label:"Я не робот",loading:"Загрузка...",reload:"Перезагрузить",verify:"Проверить",verified:"Проверено",verifying:"Идет проверка...",waitAlert:"Идет проверка... Пожалуйста, подождите."};globalThis.altchaI18n.set("ru",G);const W={ariaLinkLabel:"Navštívte Altcha.org",enterCode:"Zadajte kód",enterCodeAria:"Zadajte kód, ktorý počujete. Stlačením medzerníka prehráte zvuk.",error:"Verifikácia zlyhala. Skúste to znova neskôr.",expired:"Verifikácia vypršala. Skúste to znova.",verificationRequired:"Vyžaduje sa overenie!",footer:'Chránené ALTCHA',getAudioChallenge:"Získať audio výzvu",label:"Nie som robot",loading:"Načítava sa...",reload:"Obnoviť",verify:"Verifikovať",verified:"Verifikované",verifying:"Prebieha verifikácia...",waitAlert:"Prebieha verifikácia... prosím čakajte."};globalThis.altchaI18n.set("sk",W);const J={ariaLinkLabel:"Obiščite Altcha.org",enterCode:"Vnesite kodo",enterCodeAria:"Vnesite kodo, ki jo slišite. Pritisnite preslednico za predvajanje zvoka.",error:"Preverjanje ni uspelo. Poskusite znova kasneje.",expired:"Preverjanje je poteklo. Poskusite znova.",verificationRequired:"Potrebna je preveritev!",footer:'Zaščiteno z ALTCHA',getAudioChallenge:"Pridobite zvočni izziv",label:"Nisem robot",loading:"Nalagam...",reload:"Ponovno naloži",verify:"Preveri",verified:"Preverjeno",verifying:"Preverjanje...",waitAlert:"Preverjanje... prosim počakajte."};globalThis.altchaI18n.set("sl",J);const Y={ariaLinkLabel:"Posetite Altcha.org",enterCode:"Unesite kod",enterCodeAria:"Unesite kod koji čujete. Pritisnite Space da biste pustili zvuk.",error:"Verifikacija nije uspela. Pokušajte ponovo kasnije.",expired:"Verifikacija je istekla. Pokušajte ponovo.",footer:'Zaštićeno od strane ALTCHA',getAudioChallenge:"Dohvatite audio izazov",label:"Nisam robot",loading:"Učitavanje...",reload:"Ponovo učitaj",verify:"Verifikuj",verificationRequired:"Verifikacija je obavezna!",verified:"Verifikovano",verifying:"Verifikacija u toku...",waitAlert:"Verifikacija u toku... molimo vas da sačekate."};globalThis.altchaI18n.set("sr",Y);const X={ariaLinkLabel:"Besök Altcha.org",enterCode:"Ange kod",enterCodeAria:"Ange koden du hör. Tryck på mellanslag för att spela upp ljudet.",error:"Verifiering misslyckades. Försök igen senare.",expired:"Verifieringen har gått ut. Försök igen.",verificationRequired:"Verifiering krävs!",footer:'Skyddad av ALTCHA',getAudioChallenge:"Få ljudutmaning",label:"Jag är inte en robot",loading:"Laddar...",reload:"Ladda om",verify:"Verifiera",verified:"Verifierad",verifying:"Verifierar...",waitAlert:"Verifierar... vänligen vänta."};globalThis.altchaI18n.set("sv",X);const Q={ariaLinkLabel:"Altcha.org'yu ziyaret edin",enterCode:"Kodu girin",enterCodeAria:"Duyduğunuz kodu girin. Ses dosyasını oynatmak için Boşluk tuşuna basın.",error:"Doğrulama başarısız oldu. Lütfen daha sonra tekrar deneyin.",expired:"Doğrulama süresi doldu. Lütfen tekrar deneyin.",verificationRequired:"Doğrulama gerekli!",footer:`ALTCHA tarafından korunuyor ALTCHA`,getAudioChallenge:"Sesli doğrulama al",label:"Ben robot değilim",loading:"Yükleniyor...",reload:"Yeniden yükle",verify:"Doğrula",verified:"Doğrulandı",verifying:"Doğrulama yapılıyor...",waitAlert:"Doğrulama yapılıyor... lütfen bekleyin."};globalThis.altchaI18n.set("tr",Q);const ee={ariaLinkLabel:"Відвідати Altcha.org",enterCode:"Введіть код",enterCodeAria:"Введіть код, який ви чуєте. Натисніть пробіл, щоб відтворити аудіо.",error:"Перевірка не вдалася. Спробуйте пізніше.",expired:"Перевірка прострочена. Спробуйте знову.",verificationRequired:"Потрібна перевірка!",footer:'Захищено ALTCHA',getAudioChallenge:"Отримати аудіо-челлендж",label:"Я не робот",loading:"Завантаження...",reload:"Перезавантажити",verify:"Перевірити",verified:"Перевірено",verifying:"Перевіряється...",waitAlert:"Перевірка... будь ласка, зачекайте."};globalThis.altchaI18n.set("uk",ee);const ae={ariaLinkLabel:"Altcha.org পরিদর্শন করুন",enterCode:"কোড লিখুন",enterCodeAria:"আপনি যে কোড শুনতে পান তা লিখুন। অডিও প্লে করতে স্পেস বাটন টিপুন।",error:"যাচাইকরণ ব্যর্থ হয়েছে। পরে আবার চেষ্টা করুন।",expired:"যাচাইকরণ সময়সীমা শেষ হয়েছে। আবার চেষ্টা করুন।",verificationRequired:"যাচাই প্রয়োজন!",footer:'দ্বারা সুরক্ষিত ALTCHA',getAudioChallenge:"অডিও চ্যালেঞ্জ নিন",label:"আমি রোবট নই",loading:"লোড হচ্ছে...",reload:"পুনরায় লোড করুন",verify:"যাচাই করুন",verified:"যাচাই করা হয়েছে",verifying:"যাচাই করা হচ্ছে...",waitAlert:"যাচাই করা হচ্ছে... দয়া করে অপেক্ষা করুন।"};globalThis.altchaI18n.set("bn",ae);const ie={ariaLinkLabel:"בקר באתר Altcha.org",enterCode:"הזן קוד",enterCodeAria:"הזן את הקוד שאתה שומע. לחץ על רווח להפעלת השמע.",error:"האימות נכשל. נסה שוב מאוחר יותר.",expired:"תוקף האימות פג. נסה שוב.",verificationRequired:"נדרש אימות!",footer:'מוגן על ידי ALTCHA',getAudioChallenge:"קבל אתגר שמע",label:"אני לא רובוט",loading:"טוען...",reload:"טען מחדש",verify:"אמת",verified:"אומת",verifying:"מאמת...",waitAlert:"מבצע אימות... אנא המתן."};globalThis.altchaI18n.set("he",ie);const re={ariaLinkLabel:"Altcha.org पर जाएं",enterCode:"कोड दर्ज करेंं",enterCodeAria:"आप जो कोड सुनते हैं उसे दर्ज करें। ऑडियो चलाने के लिए स्पेस दबाएं।",error:"सत्यापन विफल। कृपया बाद में फिर से प्रयास करें।",expired:"सत्यापन समाप्त हो गया है। कृपया पुनः प्रयास करें।",verificationRequired:"सत्यापन आवश्यक है!",footer:'द्वारा संरक्षित ALTCHA',getAudioChallenge:"ऑडियो चुनौती प्राप्त करें",label:"मैं रोबोट नहीं हूँ",loading:"लोड हो रहा है...",reload:"पुनः लोड करें",verify:"सत्यापित करें",verified:"सत्यापित",verifying:"सत्यापित कर रहे हैं...",waitAlert:"सत्यापित किया जा रहा है... कृपया प्रतीक्षा करें।"};globalThis.altchaI18n.set("hi",re);const te={ariaLinkLabel:"Kunjungi Altcha.org",enterCode:"Masukkan kode",enterCodeAria:"Masukkan kode yang Anda dengar. Tekan Spasi untuk memutar audio.",error:"Verifikasi gagal. Coba lagi nanti.",expired:"Verifikasi telah kedaluwarsa. Coba lagi.",verificationRequired:"Verifikasi diperlukan!",footer:'Dilindungi oleh ALTCHA',getAudioChallenge:"Dapatkan tantangan audio",label:"Saya bukan robot",loading:"Memuat...",reload:"Muat ulang",verify:"Verifikasi",verified:"Terverifikasi",verifying:"Memverifikasi...",waitAlert:"Memverifikasi... harap tunggu."};globalThis.altchaI18n.set("id",te);const oe={ariaLinkLabel:"Altcha.orgを訪問",enterCode:"コードを入力",enterCodeAria:"聞こえるコードを入力してください。スペースキーを押して音声を再生します。",error:"認証に失敗しました。後でもう一度試してください。",expired:"認証が期限切れです。再試行してください。",verificationRequired:"認証が必要です!",footer:'保護されています ALTCHA',getAudioChallenge:"音声チャレンジを取得",label:"私はロボットではありません",loading:"読み込み中...",reload:"再読み込み",verify:"確認",verified:"確認済み",verifying:"確認中...",waitAlert:"確認中...少々お待ちください。"};globalThis.altchaI18n.set("ja",oe);const le={ariaLinkLabel:"Altcha.org 방문하기",enterCode:"코드 입력",enterCodeAria:"들리는 코드를 입력하세요. 스페이스 바를 눌러 오디오를 재생합니다.",error:"인증 실패. 나중에 다시 시도해주세요.",expired:"인증이 만료되었습니다. 다시 시도해주세요.",verificationRequired:"인증이 필요합니다!",footer:'ALTCHA에서 보호됨 ALTCHA',getAudioChallenge:"오디오 챌린지 받기",label:"저는 로봇이 아닙니다",loading:"로딩 중...",reload:"새로 고침",verify:"확인",verified:"확인됨",verifying:"확인 중...",waitAlert:"확인 중... 잠시만 기다려주세요."};globalThis.altchaI18n.set("ko",le);const ne={ariaLinkLabel:"Altcha.org भेट द्या",enterCode:"कोड टाकाा",enterCodeAria:"तुम्ही ऐकत असलेला कोड टाका. ऑडिओ प्ले करण्यासाठी स्पेस दाबा.",error:"पुष्टीकरण अयशस्वी झाले. कृपया नंतर पुन्हा प्रयत्न करा.",expired:"पुष्टीकरण कालबाह्य झाले आहे. कृपया पुन्हा प्रयत्न करा.",verificationRequired:"पडताळणी आवश्यक आहे!",footer:'द्वारे संरक्षित ALTCHA',getAudioChallenge:"ऑडिओ चॅलेंज मिळवा",label:"मी रोबोट नाही",loading:"लोड होत आहे...",reload:"पुन्हा लोड करा",verify:"पुष्टीकरण करा",verified:"पुष्टीकरण झाले",verifying:"पुष्टीकरण करत आहे...",waitAlert:"पुष्टीकरण करत आहे... कृपया थोडा वेळ थांबा."};globalThis.altchaI18n.set("mr",ne);const de={ariaLinkLabel:"Altcha.org ஐ பார்வையிடவும்",enterCode:"குறியீட்டை உள்ளிடவும்",enterCodeAria:"நீங்கள் கேட்கும் குறியீட்டை உள்ளிடவும். ஆடியோவை இயக்க Space ஐ அழுத்தவும்.",error:"சரிபார்ப்பு தோல்வி. பிறகு மீண்டும் முயற்சிக்கவும்.",expired:"சரிபார்ப்பு காலாவதியானது. மீண்டும் முயற்சிக்கவும்.",verificationRequired:"சரிபார்ப்பு தேவை!",footer:'மூலமாக பாதுகாக்கப்பட்டவை ALTCHA',getAudioChallenge:"ஒலி சவாலை பெறவும்",label:"நான் ரோபோடான அல்ல",loading:"செயலாக்கம்...",reload:"மீண்டும் புதுப்பிக்கவும்",verify:"சரிபார்க்கவும்",verified:"சரிபார்க்கப்பட்டது",verifying:"சரிபார்க்கப்படுகிறது...",waitAlert:"சரிபார்க்கப்படுகிறது... தயவுசெய்து காத்திருக்கவும்."};globalThis.altchaI18n.set("ta",de);const se={ariaLinkLabel:"Altcha.org సందర్శించండి",enterCode:"కోడ్‌ని నమోదు చేయండి",enterCodeAria:"మీరు విన్న కోడ్‌ని నమోదు చేయండి. ఆడియో ప్లే చేయడానికి స్పేస్‌ను నొక్కండి.",error:"చెకింగ్ విఫలమైంది. దయచేసి మరల ప్రయత్నించండి.",expired:"చెకింగ్ కాలం ముగిసింది. దయచేసి మరల ప్రయత్నించండి.",verificationRequired:"ధృవీకరణ అవసరం!",footer:'ఈ సైట్ రక్షించబడింది ALTCHA',getAudioChallenge:"ఆడియో ఛాలెంజ్ పొందండి",label:"నేను రోబోట్ కాదు",loading:"లోడ్ అవుతోంది...",reload:"మళ్ళీ లోడ్ చేయండి",verify:"ధ్రువీకరించు",verified:"ధ్రువీకరించబడింది",verifying:"ధ్రువీకరణ జరుగుతుంది...",waitAlert:"ధ్రువీకరణ జరుగుతుంది... దయచేసి వేచి ఉండండి."};globalThis.altchaI18n.set("te",se);const ge={ariaLinkLabel:"เยี่ยมชม Altcha.org",enterCode:"ป้อนรหัส",enterCodeAria:"ป้อนรหัสที่คุณได้ยิน กด Space เพื่อเล่นเสียง",error:"การตรวจสอบล้มเหลว กรุณาลองอีกครั้งภายหลัง",expired:"การตรวจสอบหมดอายุ กรุณาลองใหม่",verificationRequired:"จำเป็นต้องตรวจสอบ!",footer:'ป้องกันโดย ALTCHA',getAudioChallenge:"รับการท้าทายเสียง",label:"ฉันไม่ใช่บอท",loading:"กำลังโหลด...",reload:"โหลดใหม่",verify:"ตรวจสอบ",verified:"ตรวจสอบแล้ว",verifying:"กำลังตรวจสอบ...",waitAlert:"กำลังตรวจสอบ... กรุณารอ"};globalThis.altchaI18n.set("th",ge);const ce={ariaLinkLabel:"Altcha.org پر جائیں",enterCode:"کوڈ درج کریں",enterCodeAria:"جو کوڈ آپ سنتے ہیں وہ درج کریں۔ آڈیو چلانے کے لیے اسپیس دبائیں۔",error:"توثیق ناکام ہو گئی۔ براہ کرم بعد میں دوبارہ کوشش کریں۔",expired:"توثیق کی مدت ختم ہو گئی ہے۔ براہ کرم دوبارہ کوشش کریں۔",verificationRequired:"تصدیق ضروری ہے!",footer:'کے ذریعے محفوظ ALTCHA',getAudioChallenge:"آڈیو چیلنج حاصل کریں",label:"میں روبوٹ نہیں ہوں",loading:"لوڈ ہو رہا ہے...",reload:"دوبارہ لوڈ کریں",verify:"توثیق کریں",verified:"توثیق شدہ",verifying:"توثیق ہو رہی ہے...",waitAlert:"توثیق ہو رہی ہے... براہ کرم انتظار کریں۔"};globalThis.altchaI18n.set("ur",ce);const he={ariaLinkLabel:"Truy cập Altcha.org",enterCode:"Nhập mã",enterCodeAria:"Nhập mã bạn nghe được. Nhấn Phím cách để phát âm thanh.",error:"Xác minh thất bại. Vui lòng thử lại sau.",expired:"Xác minh đã hết hạn. Vui lòng thử lại.",verificationRequired:"Yêu cầu xác minh!",footer:'Được bảo vệ bởi ALTCHA',getAudioChallenge:"Nhận thử thách âm thanh",label:"Tôi không phải là robot",loading:"Đang tải...",reload:"Tải lại",verify:"Xác minh",verified:"Đã xác minh",verifying:"Đang xác minh...",waitAlert:"Đang xác minh... vui lòng chờ."};globalThis.altchaI18n.set("vi",he);const fe={ariaLinkLabel:"访问 Altcha.org",enterCode:"输入代码",enterCodeAria:"输入您听到的代码。按空格键播放音频。",error:"验证失败。稍后再试。",expired:"验证已过期。请重试。",verificationRequired:"需要验证!",footer:'由 ALTCHA 保护',getAudioChallenge:"获取音频挑战",label:"我不是机器人",loading:"加载中...",reload:"重新加载",verify:"验证",verified:"已验证",verifying:"正在验证...",waitAlert:"正在验证... 请稍等。"};globalThis.altchaI18n.set("zh-cn",fe);const ue={ariaLinkLabel:"訪問 Altcha.org",enterCode:"輸入代碼",enterCodeAria:"輸入您聽到的代碼。按空格鍵播放音頻。",error:"驗證失敗。稍後再試。",expired:"驗證已過期。請重試。",verificationRequired:"需要驗證!",footer:'由 ALTCHA 保護',getAudioChallenge:"獲取音頻挑戰",label:"我不是機器人",loading:"載入中...",reload:"重新載入",verify:"驗證",verified:"已驗證",verifying:"正在驗證...",waitAlert:"正在驗證... 請稍等。"};globalThis.altchaI18n.set("zh-tw",ue)}); diff --git a/themes/root/js/vendor/altcha.js b/themes/root/js/vendor/altcha.js new file mode 100644 index 00000000000..828a43be50f --- /dev/null +++ b/themes/root/js/vendor/altcha.js @@ -0,0 +1,4 @@ +(function($,N){typeof exports=="object"&&typeof module<"u"?N(exports):typeof define=="function"&&define.amd?define(["exports"],N):($=typeof globalThis<"u"?globalThis:$||self,N($.altcha={}))})(this,function($){"use strict";var Ol=Object.defineProperty;var Qi=$=>{throw TypeError($)};var Pl=($,N,W)=>N in $?Ol($,N,{enumerable:!0,configurable:!0,writable:!0,value:W}):$[N]=W;var Re=($,N,W)=>Pl($,typeof N!="symbol"?N+"":N,W),eo=($,N,W)=>N.has($)||Qi("Cannot "+W);var he=($,N,W)=>(eo($,N,"read from private field"),W?W.call($):N.get($)),tn=($,N,W)=>N.has($)?Qi("Cannot add the same private member more than once"):N instanceof WeakSet?N.add($):N.set($,W),rn=($,N,W,Zt)=>(eo($,N,"write to private field"),Zt?Zt.call($,W):N.set($,W),W);var gi,Me,ye;const N=`(function(){"use strict";const d=new TextEncoder;function p(e){return[...new Uint8Array(e)].map(t=>t.toString(16).padStart(2,"0")).join("")}async function b(e,t,r){if(typeof crypto>"u"||!("subtle"in crypto)||!("digest"in crypto.subtle))throw new Error("Web Crypto is not available. Secure context is required (https://developer.mozilla.org/en-US/docs/Web/Security/Secure_Contexts).");return p(await crypto.subtle.digest(r.toUpperCase(),d.encode(e+t)))}function w(e,t,r="SHA-256",n=1e6,s=0){const o=new AbortController,a=Date.now();return{promise:(async()=>{for(let c=s;c<=n;c+=1){if(o.signal.aborted)return null;if(await b(t,c,r)===e)return{number:c,took:Date.now()-a}}return null})(),controller:o}}function h(e){const t=atob(e),r=new Uint8Array(t.length);for(let n=0;n{for(let u=n;u<=r;u+=1){if(o.signal.aborted||!c||!y)return null;try{const f=await crypto.subtle.decrypt({name:s,iv:g(u)},c,y);if(f)return{clearText:new TextDecoder().decode(f),took:Date.now()-a}}catch{}}return null};let c=null,y=null;try{y=h(e);const u=await crypto.subtle.digest("SHA-256",d.encode(t));c=await crypto.subtle.importKey("raw",u,s,!1,["decrypt"])}catch{return{promise:Promise.reject(),controller:o}}return{promise:l(),controller:o}}let i;onmessage=async e=>{const{type:t,payload:r,start:n,max:s}=e.data;let o=null;if(t==="abort")i==null||i.abort(),i=void 0;else if(t==="work"){if("obfuscated"in r){const{key:a,obfuscated:l}=r||{};o=await m(l,a,s,n)}else{const{algorithm:a,challenge:l,salt:c}=r||{};o=w(l,c,a,s,n)}i=o.controller,o.promise.then(a=>{self.postMessage(a&&{...a,worker:!0})})}}})(); +`,W=typeof self<"u"&&self.Blob&&new Blob([N],{type:"text/javascript;charset=utf-8"});function Zt(e){let t;try{if(t=W&&(self.URL||self.webkitURL).createObjectURL(W),!t)throw"";const r=new Worker(t,{name:e==null?void 0:e.name});return r.addEventListener("error",()=>{(self.URL||self.webkitURL).revokeObjectURL(t)}),r}catch{return new Worker("data:text/javascript;charset=utf-8,"+encodeURIComponent(N),{name:e==null?void 0:e.name})}finally{t&&(self.URL||self.webkitURL).revokeObjectURL(t)}}const to="5";typeof window<"u"&&((gi=window.__svelte??(window.__svelte={})).v??(gi.v=new Set)).add(to);const ro=1,no=4,io=8,oo=16,ao=1,lo=2,Cr="[",nn="[!",on="]",ct={},ue=Symbol(),so="http://www.w3.org/1999/xhtml",an=!1;function ln(e){throw new Error("https://svelte.dev/e/lifecycle_outside_component")}var sn=Array.isArray,uo=Array.prototype.indexOf,fo=Array.from,zt=Object.keys,It=Object.defineProperty,Qe=Object.getOwnPropertyDescriptor,co=Object.getOwnPropertyDescriptors,ho=Object.prototype,vo=Array.prototype,un=Object.getPrototypeOf,fn=Object.isExtensible;const dt=()=>{};function cn(e){for(var t=0;t{var c=L;De(o);var d=s();return De(c),d};return i&&r.set("length",V(e.length)),new Proxy(e,{defineProperty(s,c,d){(!("value"in d)||d.configurable===!1||d.enumerable===!1||d.writable===!1)&&ko();var _=r.get(c);return _===void 0?(_=u(()=>V(d.value)),r.set(c,_)):b(_,u(()=>qe(d.value))),!0},deleteProperty(s,c){var d=r.get(c);if(d===void 0)c in s&&(r.set(c,u(()=>V(ue))),Ir(a));else{if(i&&typeof c=="string"){var _=r.get("length"),h=Number(c);Number.isInteger(h)&&h<_.v&&b(_,h)}b(d,ue),Ir(a)}return!0},get(s,c,d){var w;if(c===Rt)return e;var _=r.get(c),h=c in s;if(_===void 0&&(!h||(w=Qe(s,c))!=null&&w.writable)&&(_=u(()=>V(qe(h?s[c]:ue))),r.set(c,_)),_!==void 0){var m=l(_);return m===ue?void 0:m}return Reflect.get(s,c,d)},getOwnPropertyDescriptor(s,c){var d=Reflect.getOwnPropertyDescriptor(s,c);if(d&&"value"in d){var _=r.get(c);_&&(d.value=l(_))}else if(d===void 0){var h=r.get(c),m=h==null?void 0:h.v;if(h!==void 0&&m!==ue)return{enumerable:!0,configurable:!0,value:m,writable:!0}}return d},has(s,c){var m;if(c===Rt)return!0;var d=r.get(c),_=d!==void 0&&d.v!==ue||Reflect.has(s,c);if(d!==void 0||O!==null&&(!_||(m=Qe(s,c))!=null&&m.writable)){d===void 0&&(d=u(()=>V(_?qe(s[c]):ue)),r.set(c,d));var h=l(d);if(h===ue)return!1}return _},set(s,c,d,_){var te;var h=r.get(c),m=c in s;if(i&&c==="length")for(var w=d;wV(ue)),r.set(w+"",D))}h===void 0?(!m||(te=Qe(s,c))!=null&&te.writable)&&(h=u(()=>V(void 0)),b(h,u(()=>qe(d))),r.set(c,h)):(m=h.v!==ue,b(h,u(()=>qe(d))));var C=Reflect.getOwnPropertyDescriptor(s,c);if(C!=null&&C.set&&C.set.call(_,d),!m){if(i&&typeof c=="string"){var q=r.get("length"),pe=Number(c);Number.isInteger(pe)&&pe>=q.v&&b(q,pe+1)}Ir(a)}return!0},ownKeys(s){l(a);var c=Reflect.ownKeys(s).filter(h=>{var m=r.get(h);return m===void 0||m.v!==ue});for(var[d,_]of r)_.v!==ue&&!(d in s)&&c.push(d);return c},setPrototypeOf(){Ao()}})}function Ir(e,t=1){b(e,e.v+t)}var gn,pn,mn,_n;function Rr(){if(gn===void 0){gn=window,pn=/Firefox/.test(navigator.userAgent);var e=Element.prototype,t=Node.prototype,r=Text.prototype;mn=Qe(t,"firstChild").get,_n=Qe(t,"nextSibling").get,fn(e)&&(e.__click=void 0,e.__className=void 0,e.__attributes=null,e.__style=void 0,e.__e=void 0),fn(r)&&(r.__t=void 0)}}function tr(e=""){return document.createTextNode(e)}function _e(e){return mn.call(e)}function Be(e){return _n.call(e)}function z(e,t){if(!F)return _e(e);var r=_e(M);return r===null&&(r=M.appendChild(tr())),je(r),r}function St(e,t){if(!F){var r=_e(e);return r instanceof Comment&&r.data===""?Be(r):r}return M}function J(e,t=1,r=!1){let i=F?M:e;for(var a;t--;)a=i,i=Be(i);if(!F)return i;var o=i==null?void 0:i.nodeType;if(r&&o!==3){var u=tr();return i===null?a==null||a.after(u):i.before(u),je(u),u}return je(i),i}function $o(e){e.textContent=""}function bn(e){return e===this.v}function yn(e,t){return e!=e?t==t:e!==t||e!==null&&typeof e=="object"||typeof e=="function"}function Sr(e){return!yn(e,this.v)}function rr(e){var t=Ee|Se,r=L!==null&&(L.f&Ee)!==0?L:null;return O===null||r!==null&&(r.f&ve)!==0?t|=ve:O.f|=hn,{ctx:ae,deps:null,effects:null,equals:bn,f:t,fn:e,reactions:null,rv:0,v:null,wv:0,parent:r??O}}function $t(e){const t=rr(e);return On(t),t}function To(e){const t=rr(e);return t.equals=Sr,t}function wn(e){var t=e.effects;if(t!==null){e.effects=null;for(var r=0;r{He(t)}}function Po(e){const t=rt(et,e,!0);return(r={})=>new Promise(i=>{r.outro?Or(t,()=>{He(t),i(void 0)}):(He(t),i(void 0))})}function Dr(e){return rt(dn,e,!1)}function Nr(e){return rt(Jt,e,!0)}function $e(e,t=[],r=rr){const i=t.map(r);return xn(()=>e(...i.map(l)))}function xn(e,t=0){return rt(Jt|xr|t,e,!0)}function Lr(e,t=!0){return rt(Jt|Fe,e,!0,t)}function kn(e){var t=e.teardown;if(t!==null){const r=Nt,i=L;Ln(!0),De(null);try{t.call(null)}finally{Ln(r),De(i)}}}function An(e,t=!1){var r=e.first;for(e.first=e.last=null;r!==null;){var i=r.next;(r.f&et)!==0?r.parent=null:He(r,t),r=i}}function Fo(e){for(var t=e.first;t!==null;){var r=t.next;(t.f&Fe)===0&&He(t),t=r}}function He(e,t=!0){var r=!1;(t||(e.f&mo)!==0)&&e.nodes_start!==null&&(In(e.nodes_start,e.nodes_end),r=!0),An(e,t&&!r),sr(e,0),Ce(e,Qt);var i=e.transitions;if(i!==null)for(const o of i)o.stop();kn(e);var a=e.parent;a!==null&&a.first!==null&&Rn(e),e.next=e.prev=e.teardown=e.ctx=e.deps=e.fn=e.nodes_start=e.nodes_end=null}function In(e,t){for(;e!==null;){var r=e===t?null:Be(e);e.remove(),e=r}}function Rn(e){var t=e.parent,r=e.prev,i=e.next;r!==null&&(r.next=i),i!==null&&(i.prev=r),t!==null&&(t.first===e&&(t.first=i),t.last===e&&(t.last=r))}function Or(e,t){var r=[];Sn(e,r,!0),Mo(r,()=>{He(e),t&&t()})}function Mo(e,t){var r=e.length;if(r>0){var i=()=>--r||t();for(var a of e)a.out(i)}else t()}function Sn(e,t,r){if((e.f&ht)===0){if(e.f^=ht,e.transitions!==null)for(const u of e.transitions)(u.is_global||r)&&t.push(u);for(var i=e.first;i!==null;){var a=i.next,o=(i.f&kr)!==0||(i.f&Fe)!==0;Sn(i,t,o?r:!1),i=a}}}function $n(e){Tn(e,!0)}function Tn(e,t){if((e.f&ht)!==0){e.f^=ht,(e.f&fe)===0&&(e.f^=fe),Ot(e)&&(Ce(e,Se),ur(e));for(var r=e.first;r!==null;){var i=r.next,a=(r.f&kr)!==0||(r.f&Fe)!==0;Tn(r,a?t:!1),r=i}if(e.transitions!==null)for(const o of e.transitions)(o.is_global||t)&&o.in()}}const Vo=typeof requestIdleCallback>"u"?e=>setTimeout(e,1):requestIdleCallback;let Tt=[],Dt=[];function Dn(){var e=Tt;Tt=[],cn(e)}function Nn(){var e=Dt;Dt=[],cn(e)}function Pr(e){Tt.length===0&&queueMicrotask(Dn),Tt.push(e)}function Uo(e){Dt.length===0&&Vo(Nn),Dt.push(e)}function jo(){Tt.length>0&&Dn(),Dt.length>0&&Nn()}let nr=!1,ir=!1,or=null,nt=!1,Nt=!1;function Ln(e){Nt=e}let Lt=[],Fl=[],L=null,Te=!1;function De(e){L=e}let O=null;function Ge(e){O=e}let ie=null;function On(e){L!==null&&L.f&Ar&&(ie===null?ie=[e]:ie.push(e))}let oe=null,ge=0,be=null;function qo(e){be=e}let Pn=1,ar=0,We=!1;function Fn(){return++Pn}function Ot(e){var h;var t=e.f;if((t&Se)!==0)return!0;if((t&tt)!==0){var r=e.deps,i=(t&ve)!==0;if(r!==null){var a,o,u=(t&Xt)!==0,s=i&&O!==null&&!We,c=r.length;if(u||s){var d=e,_=d.parent;for(a=0;ae.wv)return!0}(!i||O!==null&&!We)&&Ce(e,fe)}return!1}function Bo(e,t){for(var r=t;r!==null;){if((r.f&Kt)!==0)try{r.fn(e);return}catch{r.f^=Kt}r=r.parent}throw nr=!1,e}function Mn(e){return(e.f&Qt)===0&&(e.parent===null||(e.parent.f&Kt)===0)}function lr(e,t,r,i){if(nr){if(r===null&&(nr=!1),Mn(t))throw e;return}if(r!==null&&(nr=!0),Bo(e,t),Mn(t))throw e}function Vn(e,t,r=!0){var i=e.reactions;if(i!==null)for(var a=0;a0)for(h.length=ge+oe.length,m=0;m0;){t++>1e3&&Go();var r=Lt,i=r.length;Lt=[];for(var a=0;a{i.d=!0})}function Wn(e){const t=ae;if(t!==null){e!==void 0&&(t.x=e);const u=t.e;if(u!==null){var r=O,i=L;t.e=null;try{for(var a=0;a{document.activeElement===r&&e.focus()})}}let Zn=!1;function zn(){Zn||(Zn=!0,document.addEventListener("reset",e=>{Promise.resolve().then(()=>{var t;if(!e.defaultPrevented)for(const r of e.target.elements)(t=r.__on_r)==null||t.call(r)})},{capture:!0}))}function Jn(e){var t=L,r=O;De(null),Ge(null);try{return e()}finally{De(t),Ge(r)}}function Qo(e,t,r,i=r){e.addEventListener(t,()=>Jn(r));const a=e.__on_r;a?e.__on_r=()=>{a(),i(!0)}:e.__on_r=()=>i(!0),zn()}const Kn=new Set,Ur=new Set;function ea(e,t,r,i={}){function a(o){if(i.capture||Ft.call(t,o),!o.cancelBubble)return Jn(()=>r==null?void 0:r.call(this,o))}return e.startsWith("pointer")||e.startsWith("touch")||e==="wheel"?Pr(()=>{t.addEventListener(e,a,i)}):t.addEventListener(e,a,i),a}function Ye(e,t,r,i,a){var o={capture:i,passive:a},u=ea(e,t,r,o);(t===document.body||t===window||t===document)&&$r(()=>{t.removeEventListener(e,u,o)})}function ta(e){for(var t=0;t{throw le});throw m}}finally{e.__root=t,delete e.currentTarget,De(_),Ge(h)}}}function jr(e){var t=document.createElement("template");return t.innerHTML=e,t.content}function Ne(e,t){var r=O;r.nodes_start===null&&(r.nodes_start=e,r.nodes_end=t)}function xe(e,t){var r=(t&ao)!==0,i=(t&lo)!==0,a,o=!e.startsWith("");return()=>{if(F)return Ne(M,null),M;a===void 0&&(a=jr(o?e:""+e),r||(a=_e(a)));var u=i||pn?document.importNode(a,!0):a.cloneNode(!0);if(r){var s=_e(u),c=u.lastChild;Ne(s,c)}else Ne(u,u);return u}}function fr(e,t,r="svg"){var i=!e.startsWith(""),a=`<${r}>${i?e:""+e}`,o;return()=>{if(F)return Ne(M,null),M;if(!o){var u=jr(a),s=_e(u);o=_e(s)}var c=o.cloneNode(!0);return Ne(c,c),c}}function cr(){if(F)return Ne(M,null),M;var e=document.createDocumentFragment(),t=document.createComment(""),r=tr();return e.append(t,r),Ne(t,r),e}function B(e,t){if(F){O.nodes_end=M,gt();return}e!==null&&e.before(t)}function ra(e,t){var r=t==null?"":typeof t=="object"?t+"":t;r!==(e.__t??(e.__t=e.nodeValue))&&(e.__t=r,e.nodeValue=r+"")}function Xn(e,t){return Qn(e,t)}function na(e,t){Rr(),t.intro=t.intro??!1;const r=t.target,i=F,a=M;try{for(var o=_e(r);o&&(o.nodeType!==8||o.data!==Cr);)o=Be(o);if(!o)throw ct;vt(!0),je(o),gt();const u=Qn(e,{...t,anchor:o});if(M===null||M.nodeType!==8||M.data!==on)throw er(),ct;return vt(!1),u}catch(u){if(u===ct)return t.recover===!1&&Co(),Rr(),$o(r),vt(!1),Xn(e,t);throw u}finally{vt(i),je(a)}}const pt=new Map;function Qn(e,{target:t,anchor:r,props:i={},events:a,context:o,intro:u=!0}){Rr();var s=new Set,c=h=>{for(var m=0;m{var h=r??t.appendChild(tr());return Lr(()=>{if(o){Gn({});var m=ae;m.c=o}a&&(i.$$events=a),F&&Ne(h,null),d=e(h,i)||{},F&&(O.nodes_end=M),o&&Wn()}),()=>{var D;for(var m of s){t.removeEventListener(m,Ft);var w=pt.get(m);--w===0?(document.removeEventListener(m,Ft),pt.delete(m)):pt.set(m,w)}Ur.delete(c),h!==r&&((D=h.parentNode)==null||D.removeChild(h))}});return qr.set(d,_),d}let qr=new WeakMap;function ia(e,t){const r=qr.get(e);return r?(qr.delete(e),r(t)):Promise.resolve()}function K(e,t,[r,i]=[0,0]){F&&r===0&>();var a=e,o=null,u=null,s=ue,c=r>0?kr:0,d=!1;const _=(m,w=!0)=>{d=!0,h(w,m)},h=(m,w)=>{if(s===(s=m))return;let D=!1;if(F&&i!==-1){if(r===0){const q=a.data;q===Cr?i=0:q===nn?i=1/0:(i=parseInt(q.substring(1)),i!==i&&(i=s?1/0:-1))}const C=i>r;!!s===C&&(a=Ro(),je(a),vt(!1),D=!0,i=-1)}s?(o?$n(o):w&&(o=Lr(()=>w(a))),u&&Or(u,()=>{u=null})):(u?$n(u):w&&(u=Lr(()=>w(a,[r+1,i]))),o&&Or(o,()=>{o=null})),D&&vt(!0)};xn(()=>{d=!1,t(_),d||h(null,null)},c),F&&(a=M)}function ot(e,t,r=!1,i=!1,a=!1){var o=e,u="";$e(()=>{var s=O;if(u===(u=t()??"")){F&>();return}if(s.nodes_start!==null&&(In(s.nodes_start,s.nodes_end),s.nodes_start=s.nodes_end=null),u!==""){if(F){M.data;for(var c=gt(),d=c;c!==null&&(c.nodeType!==8||c.data!=="");)d=c,c=Be(c);if(c===null)throw er(),ct;Ne(M,d),o=je(c);return}var _=u+"";r?_=`${_}`:i&&(_=`${_}`);var h=jr(_);if((r||i)&&(h=_e(h)),Ne(_e(h),h.lastChild),r||i)for(;_e(h);)o.before(_e(h));else o.before(h)}})}function oa(e,t,r,i,a){var s;F&>();var o=(s=t.$$slots)==null?void 0:s[r],u=!1;o===!0&&(o=t.children,u=!0),o===void 0||o(e,u?()=>i:i)}const ei=[...` +\r\f \v\uFEFF`];function aa(e,t,r){var i=""+e;if(r){for(var a in r)if(r[a])i=i?i+" "+a:a;else if(i.length)for(var o=a.length,u=0;(u=i.indexOf(a,u))>=0;){var s=u+o;(u===0||ei.includes(i[u-1]))&&(s===i.length||ei.includes(i[s]))?i=(u===0?"":i.substring(0,u))+i.substring(s+1):u=s}}return i===""?null:i}function la(e,t,r,i,a,o){var u=e.__className;if(F||u!==r||u===void 0){var s=aa(r,i,o);(!F||s!==e.getAttribute("class"))&&(s==null?e.removeAttribute("class"):e.className=s),e.__className=r}else if(o&&a!==o)for(var c in o){var d=!!o[c];(a==null||d!==!!a[c])&&e.classList.toggle(c,d)}return o}const sa=Symbol("is custom element"),ua=Symbol("is html");function ti(e){if(F){var t=!1,r=()=>{if(!t){if(t=!0,e.hasAttribute("value")){var i=e.value;T(e,"value",null),e.value=i}if(e.hasAttribute("checked")){var a=e.checked;T(e,"checked",null),e.checked=a}}};e.__on_r=r,Uo(r),zn()}}function fa(e,t){var r=ri(e);r.value===(r.value=t??void 0)||e.value===t&&(t!==0||e.nodeName!=="PROGRESS")||(e.value=t??"")}function T(e,t,r,i){var a=ri(e);F&&(a[t]=e.getAttribute(t),t==="src"||t==="srcset"||t==="href"&&e.nodeName==="LINK")||a[t]!==(a[t]=r)&&(t==="loading"&&(e[_o]=r),r==null?e.removeAttribute(t):typeof r!="string"&&ca(e).includes(t)?e[t]=r:e.setAttribute(t,r))}function ri(e){return e.__attributes??(e.__attributes={[sa]:e.nodeName.includes("-"),[ua]:e.namespaceURI===so})}var ni=new Map;function ca(e){var t=ni.get(e.nodeName);if(t)return t;ni.set(e.nodeName,t=[]);for(var r,i=e,a=Element.prototype;a!==i;){r=co(i);for(var o in r)r[o].set&&t.push(o);i=un(i)}return t}function da(e,t,r=t){Qo(e,"change",i=>{var a=i?e.defaultChecked:e.checked;r(a)}),(F&&e.defaultChecked!==e.checked||it(t)==null)&&r(e.checked),Nr(()=>{var i=t();e.checked=!!i})}function ii(e,t){return e===t||(e==null?void 0:e[Rt])===t}function dr(e={},t,r,i){return Dr(()=>{var a,o;return Nr(()=>{a=o,o=[],it(()=>{e!==r(...o)&&(t(e,...o),a&&ii(r(...a),e)&&t(null,...a))})}),()=>{Pr(()=>{o&&ii(r(...o),e)&&t(null,...o)})}}),e}function oi(e){ae===null&&ln(),Tr(()=>{const t=it(e);if(typeof t=="function")return t})}function ha(e){ae===null&&ln(),oi(()=>()=>it(e))}function ai(e,t,r){if(e==null)return t(void 0),dt;const i=it(()=>e.subscribe(t,r));return i.unsubscribe?()=>i.unsubscribe():i}const mt=[];function va(e,t=dt){let r=null;const i=new Set;function a(s){if(yn(e,s)&&(e=s,r)){const c=!mt.length;for(const d of i)d[1](),mt.push(d,e);if(c){for(let d=0;d{i.delete(d),i.size===0&&r&&(r(),r=null)}}return{set:a,update:o,subscribe:u}}function hr(e){let t;return ai(e,r=>t=r)(),t}let vr=!1,Br=Symbol();function ga(e,t,r){const i=r[t]??(r[t]={store:null,source:Vr(void 0),unsubscribe:dt});if(i.store!==e&&!(Br in r))if(i.unsubscribe(),i.store=e??null,e==null)i.source.v=void 0,i.unsubscribe=dt;else{var a=!0;i.unsubscribe=ai(e,o=>{a?i.source.v=o:b(i.source,o)}),a=!1}return e&&Br in r?hr(e):l(i.source)}function pa(){const e={};function t(){$r(()=>{for(var r in e)e[r].unsubscribe();It(e,Br,{enumerable:!1,value:!0})})}return[e,t]}function ma(e){var t=vr;try{return vr=!1,[e(),vr]}finally{vr=t}}function li(e){var t;return((t=e.ctx)==null?void 0:t.d)??!1}function I(e,t,r,i){var _t;var a=(r&ro)!==0,o=!0,u=(r&io)!==0,s=(r&oo)!==0,c=!1,d;u?[d,c]=ma(()=>e[t]):d=e[t];var _=Rt in e||vn in e,h=u&&(((_t=Qe(e,t))==null?void 0:_t.set)??(_&&t in e&&(H=>e[t]=H)))||void 0,m=i,w=!0,D=!1,C=()=>(D=!0,w&&(w=!1,s?m=it(i):m=i),m);d===void 0&&i!==void 0&&(h&&o&&xo(),d=C(),h&&h(d));var q;if(q=()=>{var H=e[t];return H===void 0?C():(w=!0,D=!1,H)},(r&no)===0)return q;if(h){var pe=e.$$legacy;return function(H,ce){return arguments.length>0?((!ce||pe||c)&&h(ce?q():H),H):q()}}var te=!1,le=Vr(d),re=rr(()=>{var H=q(),ce=l(le);return te?(te=!1,ce):le.v=H});return u&&l(re),a||(re.equals=Sr),function(H,ce){if(arguments.length>0){const ke=ce?l(re):u?qe(H):H;if(!re.equals(ke)){if(te=!0,b(le,ke),D&&m!==void 0&&(m=ke),li(re))return H;it(()=>l(re))}return H}return li(re)?re.v:l(re)}}function _a(e){return new ba(e)}class ba{constructor(t){tn(this,Me);tn(this,ye);var o;var r=new Map,i=(u,s)=>{var c=Vr(s);return r.set(u,c),c};const a=new Proxy({...t.props||{},$$events:{}},{get(u,s){return l(r.get(s)??i(s,Reflect.get(u,s)))},has(u,s){return s===vn?!0:(l(r.get(s)??i(s,Reflect.get(u,s))),Reflect.has(u,s))},set(u,s,c){return b(r.get(s)??i(s,c),c),Reflect.set(u,s,c)}});rn(this,ye,(t.hydrate?na:Xn)(t.component,{target:t.target,anchor:t.anchor,props:a,context:t.context,intro:t.intro??!1,recover:t.recover})),(!((o=t==null?void 0:t.props)!=null&&o.$$host)||t.sync===!1)&&k(),rn(this,Me,a.$$events);for(const u of Object.keys(he(this,ye)))u==="$set"||u==="$destroy"||u==="$on"||It(this,u,{get(){return he(this,ye)[u]},set(s){he(this,ye)[u]=s},enumerable:!0});he(this,ye).$set=u=>{Object.assign(a,u)},he(this,ye).$destroy=()=>{ia(he(this,ye))}}$set(t){he(this,ye).$set(t)}$on(t,r){he(this,Me)[t]=he(this,Me)[t]||[];const i=(...a)=>r.call(this,...a);return he(this,Me)[t].push(i),()=>{he(this,Me)[t]=he(this,Me)[t].filter(a=>a!==i)}}$destroy(){he(this,ye).$destroy()}}Me=new WeakMap,ye=new WeakMap;let si;typeof HTMLElement=="function"&&(si=class extends HTMLElement{constructor(t,r,i){super();Re(this,"$$ctor");Re(this,"$$s");Re(this,"$$c");Re(this,"$$cn",!1);Re(this,"$$d",{});Re(this,"$$r",!1);Re(this,"$$p_d",{});Re(this,"$$l",{});Re(this,"$$l_u",new Map);Re(this,"$$me");this.$$ctor=t,this.$$s=r,i&&this.attachShadow({mode:"open"})}addEventListener(t,r,i){if(this.$$l[t]=this.$$l[t]||[],this.$$l[t].push(r),this.$$c){const a=this.$$c.$on(t,r);this.$$l_u.set(r,a)}super.addEventListener(t,r,i)}removeEventListener(t,r,i){if(super.removeEventListener(t,r,i),this.$$c){const a=this.$$l_u.get(r);a&&(a(),this.$$l_u.delete(r))}}async connectedCallback(){if(this.$$cn=!0,!this.$$c){let t=function(a){return o=>{const u=document.createElement("slot");a!=="default"&&(u.name=a),B(o,u)}};if(await Promise.resolve(),!this.$$cn||this.$$c)return;const r={},i=ya(this);for(const a of this.$$s)a in i&&(a==="default"&&!this.$$d.children?(this.$$d.children=t(a),r.default=!0):r[a]=t(a));for(const a of this.attributes){const o=this.$$g_p(a.name);o in this.$$d||(this.$$d[o]=gr(o,a.value,this.$$p_d,"toProp"))}for(const a in this.$$p_d)!(a in this.$$d)&&this[a]!==void 0&&(this.$$d[a]=this[a],delete this[a]);this.$$c=_a({component:this.$$ctor,target:this.shadowRoot||this,props:{...this.$$d,$$slots:r,$$host:this}}),this.$$me=Oo(()=>{Nr(()=>{var a;this.$$r=!0;for(const o of zt(this.$$c)){if(!((a=this.$$p_d[o])!=null&&a.reflect))continue;this.$$d[o]=this.$$c[o];const u=gr(o,this.$$d[o],this.$$p_d,"toAttribute");u==null?this.removeAttribute(this.$$p_d[o].attribute||o):this.setAttribute(this.$$p_d[o].attribute||o,u)}this.$$r=!1})});for(const a in this.$$l)for(const o of this.$$l[a]){const u=this.$$c.$on(a,o);this.$$l_u.set(o,u)}this.$$l={}}}attributeChangedCallback(t,r,i){var a;this.$$r||(t=this.$$g_p(t),this.$$d[t]=gr(t,i,this.$$p_d,"toProp"),(a=this.$$c)==null||a.$set({[t]:this.$$d[t]}))}disconnectedCallback(){this.$$cn=!1,Promise.resolve().then(()=>{!this.$$cn&&this.$$c&&(this.$$c.$destroy(),this.$$me(),this.$$c=void 0)})}$$g_p(t){return zt(this.$$p_d).find(r=>this.$$p_d[r].attribute===t||!this.$$p_d[r].attribute&&r.toLowerCase()===t)||t}});function gr(e,t,r,i){var o;const a=(o=r[e])==null?void 0:o.type;if(t=a==="Boolean"&&typeof t!="boolean"?t!=null:t,!i||!r[e])return t;if(i==="toAttribute")switch(a){case"Object":case"Array":return t==null?null:JSON.stringify(t);case"Boolean":return t?"":null;case"Number":return t??null;default:return t}else switch(a){case"Object":case"Array":return t&&JSON.parse(t);case"Boolean":return t;case"Number":return t!=null?+t:t;default:return t}}function ya(e){const t={};return e.childNodes.forEach(r=>{t[r.slot||"default"]=!0}),t}function wa(e,t,r,i,a,o){let u=class extends si{constructor(){super(e,r,a),this.$$p_d=t}static get observedAttributes(){return zt(t).map(s=>(t[s].attribute||s).toLowerCase())}};return zt(t).forEach(s=>{It(u.prototype,s,{get(){return this.$$c&&s in this.$$c?this.$$c[s]:this.$$d[s]},set(c){var h;c=gr(s,c,t),this.$$d[s]=c;var d=this.$$c;if(d){var _=(h=Qe(d,s))==null?void 0:h.get;_?d[s]=c:d.$set({[s]:c})}}})}),i.forEach(s=>{It(u.prototype,s,{get(){var c;return(c=this.$$c)==null?void 0:c[s]}})}),e.element=u,u}const ui=new TextEncoder;function Ea(e){return[...new Uint8Array(e)].map(t=>t.toString(16).padStart(2,"0")).join("")}async function Ca(e,t="SHA-256",r=1e5){const i=Date.now().toString(16);e||(e=Math.round(Math.random()*r));const a=await fi(i,e,t);return{algorithm:t,challenge:a,salt:i,signature:""}}async function fi(e,t,r){if(typeof crypto>"u"||!("subtle"in crypto)||!("digest"in crypto.subtle))throw new Error("Web Crypto is not available. Secure context is required (https://developer.mozilla.org/en-US/docs/Web/Security/Secure_Contexts).");return Ea(await crypto.subtle.digest(r.toUpperCase(),ui.encode(e+t)))}function xa(e,t,r="SHA-256",i=1e6,a=0){const o=new AbortController,u=Date.now();return{promise:(async()=>{for(let c=a;c<=i;c+=1){if(o.signal.aborted)return null;if(await fi(t,c,r)===e)return{number:c,took:Date.now()-u}}return null})(),controller:o}}function ci(){try{return Intl.DateTimeFormat().resolvedOptions().timeZone}catch{}}function ka(e){const t=atob(e),r=new Uint8Array(t.length);for(let i=0;i{for(let _=i;_<=r;_+=1){if(o.signal.aborted||!c||!d)return null;try{const h=await crypto.subtle.decrypt({name:a,iv:Aa(_)},c,d);if(h)return{clearText:new TextDecoder().decode(h),took:Date.now()-u}}catch{}}return null};let c=null,d=null;try{d=ka(e);const _=await crypto.subtle.digest("SHA-256",ui.encode(t));c=await crypto.subtle.importKey("raw",_,a,!1,["decrypt"])}catch{return{promise:Promise.reject(),controller:o}}return{promise:s(),controller:o}}var E=(e=>(e.CODE="code",e.ERROR="error",e.VERIFIED="verified",e.VERIFYING="verifying",e.UNVERIFIED="unverified",e.EXPIRED="expired",e))(E||{}),ee=(e=>(e.ERROR="error",e.LOADING="loading",e.PLAYING="playing",e.PAUSED="paused",e.READY="ready",e))(ee||{});globalThis.altchaPlugins=globalThis.altchaPlugins||[],globalThis.altchaI18n=globalThis.altchaI18n||{get:e=>hr(globalThis.altchaI18n.store)[e],set:(e,t)=>{Object.assign(hr(globalThis.altchaI18n.store),{[e]:t}),globalThis.altchaI18n.store.set(hr(globalThis.altchaI18n.store))},store:va({})};const Ra={ariaLinkLabel:"Visit Altcha.org",enterCode:"Enter code",enterCodeAria:"Enter code you hear. Press Space to play audio.",error:"Verification failed. Try again later.",expired:"Verification expired. Try again.",footer:'Protected by ALTCHA',getAudioChallenge:"Get an audio challenge",label:"I'm not a robot",loading:"Loading...",reload:"Reload",verify:"Verify",verificationRequired:"Verification required!",verified:"Verified",verifying:"Verifying...",waitAlert:"Verifying... please wait."};globalThis.altchaI18n.set("en",Ra);const Hr=(e,t)=>{let r=To(()=>go(t==null?void 0:t(),24));var i=Da();$e(()=>{T(i,"width",l(r)),T(i,"height",l(r))}),B(e,i)};function Sa(e,t){e.code==="Space"&&(e.preventDefault(),e.stopImmediatePropagation(),t())}function $a(e,t){e.preventDefault(),t()}function Ta(e,t,r,i,a,o,u,s){var c;[E.UNVERIFIED,E.ERROR,E.EXPIRED,E.CODE].includes(l(t))?r()!==!1&&((c=l(i))==null?void 0:c.reportValidity())===!1?b(a,!1):o()?u():s():b(a,!0)}var Da=fr(''),Na=xe(''),La=xe('
'),Oa=fr(''),Pa=fr(''),Fa=fr(''),Ma=xe(''),Va=xe(""),Ua=xe(''),ja=xe("
"),qa=xe("
"),Ba=xe('
'),Ha=xe(''),Ga=xe('
'),Wa=xe('
',1);function di(e,t){var Ki,Xi;Gn(t,!0);const[r,i]=pa(),a=()=>ga(Za,"$altchaI18nStore",r);let o=I(t,"auto",7,void 0),u=I(t,"blockspam",7,void 0),s=I(t,"challengeurl",7,void 0),c=I(t,"challengejson",7,void 0),d=I(t,"credentials",7,void 0),_=I(t,"customfetch",7,void 0),h=I(t,"debug",7,!1),m=I(t,"delay",7,0),w=I(t,"disableautofocus",7,!1),D=I(t,"expire",7,void 0),C=I(t,"floating",7,void 0),q=I(t,"floatinganchor",7,void 0),pe=I(t,"floatingoffset",7,void 0),te=I(t,"floatingpersist",7,!1),le=I(t,"hidefooter",7,!1),re=I(t,"hidelogo",7,!1),_t=I(t,"id",7,void 0),H=I(t,"language",7,void 0),ce=I(t,"name",7,"altcha"),ke=I(t,"maxnumber",7,1e6),Mt=I(t,"mockerror",7,!1),Ze=I(t,"obfuscated",7,void 0),Ae=I(t,"overlay",7,void 0),Vt=I(t,"overlaycontent",7,void 0),pr=I(t,"plugins",7,void 0),Ut=I(t,"refetchonexpire",7,!0),at=I(t,"sentinel",7,void 0),Le=I(t,"spamfilter",7,!1),bt=I(t,"strings",7,void 0),we=I(t,"test",7,!1),se=I(t,"verifyurl",7,void 0),yt=I(t,"workers",23,()=>Math.min(16,navigator.hardwareConcurrency||8)),jt=I(t,"workerurl",7,void 0);const{altchaI18n:Ya}=globalThis,Za=Ya.store,pi=["SHA-256","SHA-384","SHA-512"],za="https://altcha.org/",ze=(n,f)=>{t.$$host.dispatchEvent(new CustomEvent(n,{detail:f}))},mi=(Xi=(Ki=document.documentElement.lang)==null?void 0:Ki.split("-"))==null?void 0:Xi[0],Gr=$t(()=>{var n;return s()&&new URL(s(),location.origin).host.endsWith(".altcha.org")&&!!((n=s())!=null&&n.includes("apiKey=ckey_"))}),Wr=$t(()=>c()?Di(c()):void 0),Ja=$t(()=>bt()?Di(bt()):{}),U=$t(()=>({...wi(a()),...l(Ja)})),_i=$t(()=>`${_t()||ce()}_checkbox_${Math.round(Math.random()*1e8)}`);let qt=V(!1),Y=V(null),R=V(qe(E.UNVERIFIED)),j=V(void 0),Bt=V(null),Je=V(null),me=V(null),Yr=V(null),wt=V(null),P=V(null),Et=V(null),lt=V(null),Oe=null,X=V(null),st=V(!1),Ke=[],Zr=V(!1),Ve=V(null);Tr(()=>{ul(l(lt))}),Tr(()=>{fl(l(R))}),ha(()=>{Ka(),b(Et,null),l(P)&&(l(P).removeEventListener("submit",Ii),l(P).removeEventListener("reset",Ri),l(P).removeEventListener("focusin",Ai),b(P,null)),Oe&&(clearTimeout(Oe),Oe=null),document.removeEventListener("click",xi),document.removeEventListener("scroll",ki),window.removeEventListener("resize",Ti)}),oi(()=>{var n;S("mounted","2.1.0"),S("workers",yt()),tl(),S("plugins",Ke.length?Ke.map(f=>f.constructor.pluginName).join(", "):"none"),we()&&S("using test mode"),D()&&Jr(D()),o()!==void 0&&S("auto",o()),C()!==void 0&&Li(C()),b(P,(n=l(j))==null?void 0:n.closest("form"),!0),l(P)&&(l(P).addEventListener("submit",Ii,{capture:!0}),l(P).addEventListener("reset",Ri),(o()==="onfocus"||te()==="focus")&&l(P).addEventListener("focusin",Ai)),Ae()&&Oi(!0),o()==="onload"&&(Ze()?Ht():Ue()),l(Gr)&&(le()||re())&&S("Attributes hidefooter and hidelogo ignored because usage with free API Keys requires attribution."),requestAnimationFrame(()=>{ze("load")})});function mr(n,f){return btoa(JSON.stringify({algorithm:n.algorithm,challenge:n.challenge,number:f.number,salt:n.salt,signature:n.signature,test:we()?!0:void 0,took:f.took}))}function Ka(){for(const n of Ke)n.destroy()}function bi(){s()&&Ut()&&l(R)===E.VERIFIED?Ue():ut(E.EXPIRED,l(U).expired)}async function Xa(){var n;if(Mt())throw S("mocking error"),new Error("Mocked error.");if(l(Wr))return S("using provided json data"),l(Wr);if(we())return S("generating test challenge",{test:we()}),Ca(typeof we()!="boolean"?+we():void 0);{if(!s()&&l(P)){const A=l(P).getAttribute("action");A!=null&&A.includes("/form/")&&s(A+"/altcha")}if(!s())throw new Error("Attribute challengeurl not set.");S("fetching challenge from",s());const f={credentials:typeof d()=="boolean"?"include":d(),headers:Le()!==!1?{"x-altcha-spam-filter":"1"}:{}},v=await yi()(s(),f);if(!v||!(v instanceof Response))throw new Error("Custom fetch function did not return a response.");if(v.status!==200)throw new Error(`Server responded with ${v.status}.`);const p=v.headers.get("X-Altcha-Config"),g=await v.json(),x=new URLSearchParams((n=g.salt.split("?"))==null?void 0:n[1]),y=x.get("expires")||x.get("expire");if(y){const A=new Date(+y*1e3),G=isNaN(A.getTime())?0:A.getTime()-Date.now();G>0&&Jr(G)}if(p)try{const A=JSON.parse(p);A&&typeof A=="object"&&(A.verifyurl&&!A.verifyurl.startsWith("fn:")&&(A.verifyurl=Ci(A.verifyurl)),Mi(A))}catch(A){S("unable to configure from X-Altcha-Config",A)}return g}}function Qa(n){var v,p;const f=(v=l(P))==null?void 0:v.querySelector(typeof n=="string"?`input[name="${n}"]`:'input[type="email"]:not([data-no-spamfilter])');return((p=f==null?void 0:f.value)==null?void 0:p.slice(f.value.indexOf("@")))||void 0}function yi(){let n=fetch;if(_())if(S("using customfetch"),typeof _()=="string"){if(n=globalThis[_()]||null,!n)throw new Error(`Custom fetch function not found: ${_()}`)}else n=_();return n}function wi(n,f=[H()||"",document.documentElement.lang||"",...navigator.languages]){const v=Object.keys(n).map(g=>g.toLowerCase()),p=f.reduce((g,x)=>(x=x.toLowerCase(),g||(n[x]?x:null)||v.find(y=>x.split("-")[0]===y.split("-")[0])||null),null);return n[p||"en"]}function el(){return Le()==="ipAddress"?{blockedCountries:void 0,classifier:void 0,disableRules:void 0,email:!1,expectedCountries:void 0,expectedLanguages:void 0,fields:!1,ipAddress:void 0,text:void 0,timeZone:void 0}:typeof Le()=="object"?Le():{blockedCountries:void 0,classifier:void 0,disableRules:void 0,email:void 0,expectedCountries:void 0,expectedLanguages:void 0,fields:void 0,ipAddress:void 0,text:void 0,timeZone:void 0}}function Ei(n){var v;return[...((v=l(P))==null?void 0:v.querySelectorAll(n!=null&&n.length?n.map(p=>`input[name="${p}"]`).join(", "):'input[type="text"]:not([data-no-spamfilter]), textarea:not([data-no-spamfilter])'))||[]].reduce((p,g)=>{const x=g.name,y=g.value;return x&&y&&(p[x]=/\n/.test(y)?y.replace(new RegExp("(?f instanceof Error))&&console[n[0]instanceof Error?"error":"log"]("ALTCHA",`[name=${ce()}]`,...n)}function rl(){b(X,ee.PAUSED,!0)}function nl(n){b(X,ee.ERROR,!0)}function il(){b(X,ee.READY,!0)}function ol(){b(X,ee.LOADING,!0)}function al(){b(X,ee.PLAYING,!0)}function ll(){b(X,ee.PAUSED,!0)}function sl(n){var f;if(n.preventDefault(),n.stopPropagation(),l(Y)){const v=new FormData(n.target),p=String(v.get("code"));if((f=se())!=null&&f.startsWith("fn:")){const g=se().replace(/^fn:/,"");if(S(`calling ${g} function instead of verifyurl`),!(g in globalThis))throw new Error(`Global function "${g}" is undefined.`);return globalThis[g]({challenge:l(Y).challenge,code:p,solution:l(Y).solution})}b(st,!0),Ni(mr(l(Y).challenge,l(Y).solution),p).then(({reason:g,verified:x})=>{x?(b(Y,null),Pe(E.VERIFIED),S("verified"),Mr().then(()=>{var y;(y=l(Yr))==null||y.focus(),ze("verified",{payload:l(Ve)}),o()==="onsubmit"?zr(l(Et)):Ae()&&Gt()})):(ut(),b(lt,g||"Verification failed",!0))}).catch(g=>{b(Y,null),Pe(E.ERROR,g),S("sentinel verification failed:",g)}).finally(()=>{b(st,!1)})}}function xi(n){var v;const f=n.target;C()&&f&&!l(j).contains(f)&&(l(R)===E.VERIFIED&&te()===!1||l(R)===E.VERIFIED&&te()==="focus"&&!((v=l(P))!=null&&v.matches(":focus-within"))||o()==="off"&&l(R)===E.UNVERIFIED)&&Gt()}function ki(){C()&&l(R)!==E.UNVERIFIED&&Wt()}function ul(n){for(const f of Ke)typeof f.onErrorChange=="function"&&f.onErrorChange(l(lt))}function Ai(n){l(R)===E.UNVERIFIED?Ue():C()&&te()==="focus"&&l(R)===E.VERIFIED&&_r()}function Ii(n){var p;const f=n.target;f!=null&&f.hasAttribute("data-code-challenge-form")||(b(Et,n.submitter,!0),l(P)&&o()==="onsubmit"?((p=l(Et))==null||p.blur(),l(R)===E.UNVERIFIED?(n.preventDefault(),n.stopPropagation(),Ue().then(()=>{zr(l(Et))})):l(R)!==E.VERIFIED&&(n.preventDefault(),n.stopPropagation(),l(R)===E.VERIFYING&&Si())):l(P)&&C()&&o()==="off"&&l(R)===E.UNVERIFIED&&(n.preventDefault(),n.stopPropagation(),_r()))}function Ri(){ut()}function Si(){l(R)===E.VERIFYING&&l(U).waitAlert&&alert(l(U).waitAlert)}function $i(){l(Je)?l(Je).paused?(l(Je).currentTime=0,l(Je).play()):l(Je).pause():(b(Zr,!0),requestAnimationFrame(()=>{var n;(n=l(Je))==null||n.play()}))}function fl(n){for(const f of Ke)typeof f.onStateChange=="function"&&f.onStateChange(l(R));C()&&l(R)!==E.UNVERIFIED&&requestAnimationFrame(()=>{Wt()}),b(qt,l(R)===E.VERIFIED),Ae()&&l(me)&&(l(R)!==E.UNVERIFIED?_r():Gt())}function Ti(){C()&&Wt()}function Di(n){return JSON.parse(n)}async function cl(n){if(!se())throw new Error("Attribute verifyurl not set.");S("requesting server verification from",se());const f={payload:n};if(Le()!==!1){const{blockedCountries:g,classifier:x,disableRules:y,email:A,expectedLanguages:G,expectedCountries:ne,fields:de,ipAddress:Xe,text:Xr,timeZone:wr}=el();f.blockedCountries=g,f.classifier=x,f.disableRules=y,f.email=A===!1?void 0:Qa(A),f.expectedCountries=ne,f.expectedLanguages=G||(mi?[mi]:void 0),f.fields=de===!1?void 0:Ei(de),f.ipAddress=Xe===!1?void 0:Xe||"auto",f.text=Xr,f.timeZone=wr===!1?void 0:wr||ci()}const v=await yi()(se(),{body:JSON.stringify(f),headers:{"content-type":"application/json"},method:"POST"});if(!v||!(v instanceof Response))throw new Error("Custom fetch function did not return a response.");if(v.status!==200)throw new Error(`Server responded with ${v.status}.`);const p=await v.json();if(p!=null&&p.payload&&b(Ve,p.payload,!0),ze("serververification",p),u()&&p.classification==="BAD")throw new Error("SpamFilter returned negative classification.")}async function Ni(n,f){if(!se())throw new Error("Attribute verifyurl not set.");S("requesting sentinel verification from",se());const v={code:f,payload:n};at()&&(v.fields=at().fields?Ei():void 0,v.timeZone=at().timeZone?ci():void 0);const p=await fetch(se(),{body:JSON.stringify(v),headers:{"content-type":"application/json"},method:"POST"});if(!p||!(p instanceof Response))throw new Error("Fetch function did not return a response.");if(p.status!==200)throw new Error(`Server responded with ${p.status}.`);const g=await p.json();return g!=null&&g.payload&&b(Ve,g.payload,!0),ze("sentinelverification",g),g}function zr(n){var f;l(P)&&"requestSubmit"in l(P)?l(P).requestSubmit(n):(f=l(P))!=null&&f.reportValidity()&&(n?n.click():l(P).submit())}function Jr(n){S("expire",n),Oe&&(clearTimeout(Oe),Oe=null),n<1?bi():Oe=setTimeout(bi,n)}function Li(n){S("floating",n),C()!==n&&(l(j).style.left="",l(j).style.top=""),C(n===!0||n===""?"auto":n===!1||n==="false"?void 0:C()),C()?(o()||o("onsubmit"),document.addEventListener("scroll",ki),document.addEventListener("click",xi),window.addEventListener("resize",Ti)):o()==="onsubmit"&&o(void 0)}function Oi(n){var f,v;if(S("overlay",n),Ae(n),n){if(o()||o("onsubmit"),l(me)&&l(j).parentElement&&l(me).replaceWith(l(j).parentElement),(v=(f=l(j))==null?void 0:f.parentElement)!=null&&v.parentElement){b(me,document.createElement("div"),!0),l(j).parentElement.parentElement.appendChild(l(me));const p=document.createElement("div"),g=document.createElement("button");g.type="button",g.innerHTML="×",g.addEventListener("click",x=>{x.preventDefault(),ut()}),l(me).classList.add("altcha-overlay-backdrop"),g.classList.add("altcha-overlay-close-button"),p.classList.add("altcha-overlay"),l(me).append(p),p.append(g),Vt()&&p.append(...document.querySelectorAll(Vt())),p.append(l(j).parentElement)}}else l(me)&&l(j).parentElement&&(l(me).replaceWith(l(j).parentElement),l(j).style.display="block")}function Pi(n){if(!n.algorithm)throw new Error("Invalid challenge. Property algorithm is missing.");if(n.signature===void 0)throw new Error("Invalid challenge. Property signature is missing.");if(!pi.includes(n.algorithm.toUpperCase()))throw new Error(`Unknown algorithm value. Allowed values: ${pi.join(", ")}`);if(!n.challenge||n.challenge.length<40)throw new Error("Challenge is too short. Min. 40 chars.");if(!n.salt||n.salt.length<10)throw new Error("Salt is too short. Min. 10 chars.")}async function Fi(n){let f=null;if("Worker"in window){try{f=await dl(n,n.maxNumber||n.maxnumber||ke())}catch(v){S(v)}if((f==null?void 0:f.number)!==void 0||"obfuscated"in n)return{data:n,solution:f}}if("obfuscated"in n){const v=await Ia(n.obfuscated,n.key,n.maxNumber||n.maxnumber);return{data:n,solution:await v.promise}}return{data:n,solution:await xa(n.challenge,n.salt,n.algorithm,n.maxNumber||n.maxnumber||ke()).promise}}async function dl(n,f=typeof we()=="number"?we():n.maxNumber||n.maxnumber||ke(),v=Math.ceil(yt())){const p=[];v=Math.min(16,f,Math.max(1,v));for(let y=0;y{const G=A*g;return new Promise(ne=>{y.addEventListener("message",de=>{if(de.data)for(const Xe of p)Xe!==y&&Xe.postMessage({type:"abort"});ne(de.data)}),y.postMessage({payload:n,max:G+g,start:G,type:"work"})})}));for(const y of p)y.terminate();return x.find(y=>!!y)||null}async function Ht(){if(!Ze()){Pe(E.ERROR);return}const n=Ke.find(f=>f.constructor.pluginName==="obfuscation");if(!n||!("clarify"in n)){Pe(E.ERROR),S("Plugin `obfuscation` not found. Import `altcha/plugins/obfuscation` to load it.");return}if("clarify"in n&&typeof n.clarify=="function")return n.clarify()}function Mi(n){n.obfuscated!==void 0&&Ze(n.obfuscated),n.auto!==void 0&&(o(n.auto),o()==="onload"&&(Ze()?Ht():Ue())),n.blockspam!==void 0&&u(!!n.blockspam),n.customfetch!==void 0&&_(n.customfetch),n.floatinganchor!==void 0&&q(n.floatinganchor),n.delay!==void 0&&m(n.delay),n.floatingoffset!==void 0&&pe(n.floatingoffset),n.floating!==void 0&&Li(n.floating),n.expire!==void 0&&(Jr(n.expire),D(n.expire)),n.challenge&&(c(typeof n.challenge=="string"?n.challenge:JSON.stringify(n.challenge)),Pi(l(Wr))),n.challengeurl!==void 0&&s(n.challengeurl),n.debug!==void 0&&h(!!n.debug),n.hidefooter!==void 0&&le(!!n.hidefooter),n.hidelogo!==void 0&&re(!!n.hidelogo),n.language!==void 0&&bt(wi(a(),[n.language])),n.maxnumber!==void 0&&ke(+n.maxnumber),n.mockerror!==void 0&&Mt(!!n.mockerror),n.name!==void 0&&ce(n.name),n.overlaycontent!==void 0&&Vt(n.overlaycontent),n.overlay!==void 0&&Oi(n.overlay),n.refetchonexpire!==void 0&&Ut(!!n.refetchonexpire),n.sentinel!==void 0&&typeof n.sentinel=="object"&&at(n.sentinel),n.spamfilter!==void 0&&Le(typeof n.spamfilter=="object"?n.spamfilter:!!n.spamfilter),n.strings&&bt(typeof n.strings=="string"?n.strings:JSON.stringify(n.strings)),n.test!==void 0&&we(typeof n.test=="number"?n.test:!!n.test),n.verifyurl!==void 0&&se(n.verifyurl),n.workers!==void 0&&yt(+n.workers),n.workerurl!==void 0&&jt(n.workerurl)}function Vi(){return{auto:o(),blockspam:u(),challengeurl:s(),debug:h(),delay:m(),expire:D(),floating:C(),floatinganchor:q(),floatingoffset:pe(),hidefooter:le(),hidelogo:re(),name:ce(),maxnumber:ke(),mockerror:Mt(),obfuscated:Ze(),overlay:Ae(),refetchonexpire:Ut(),spamfilter:Le(),strings:l(U),test:we(),verifyurl:se(),workers:yt(),workerurl:jt()}}function Ui(){return l(wt)}function hl(n){return Ke.find(f=>f.constructor.pluginName===n)}function ji(){return l(R)}function Gt(){l(j).style.display="none",Ae()&&l(me)&&(l(me).style.display="none")}function Wt(n=20){var f;if(l(j))if(l(wt)||b(wt,(q()?document.querySelector(q()):(f=l(P))==null?void 0:f.querySelector('input[type="submit"], button[type="submit"], button:not([type="button"]):not([type="reset"])'))||l(P),!0),l(wt)){const v=parseInt(pe(),10)||12,p=l(wt).getBoundingClientRect(),g=l(j).getBoundingClientRect(),x=document.documentElement.clientHeight,y=document.documentElement.clientWidth,A=C()==="auto"?p.bottom+g.height+v+n>x:C()==="top",G=Math.max(n,Math.min(y-n-g.width,p.left+p.width/2-g.width/2));if(A?l(j).style.top=`${p.top-(g.height+v)}px`:l(j).style.top=`${p.bottom+v}px`,l(j).style.left=`${G}px`,l(j).setAttribute("data-floating",A?"top":"bottom"),l(Bt)){const ne=l(Bt).getBoundingClientRect();l(Bt).style.left=p.left-G+p.width/2-ne.width/2+"px"}}else S("unable to find floating anchor element")}function ut(n=E.UNVERIFIED,f=null){Oe&&(clearTimeout(Oe),Oe=null),b(qt,!1),b(Ve,null),b(Y,null),b(Zr,!1),b(X,null),Pe(n,f)}function qi(n){b(wt,n,!0)}function Pe(n,f=null){b(R,n,!0),b(lt,f,!0),ze("statechange",{payload:l(Ve),state:l(R)})}function _r(){l(j).style.display="block",C()&&Wt(),Ae()&&l(me)&&(l(me).style.display="flex")}async function Ue(){return ut(E.VERIFYING),await new Promise(n=>setTimeout(n,m()||0)),Xa().then(n=>(Pi(n),S("challenge",n),Fi(n))).then(({data:n,solution:f})=>{var v;if(S("solution",f),!f||n&&"challenge"in n&&!("clearText"in f))if((f==null?void 0:f.number)!==void 0&&"challenge"in n)if(se()&&"codeChallenge"in n)["INPUT","BUTTON","SELECT","TEXTAREA"].includes(((v=document.activeElement)==null?void 0:v.tagName)||"")&&w()===!1&&document.activeElement.blur(),b(Y,{challenge:n,solution:f},!0);else{if(se()&&at()!==void 0)return Ni(mr(n,f));if(se())return cl(mr(n,f));b(Ve,mr(n,f),!0),S("payload",l(Ve))}else throw S("Unable to find a solution. Ensure that the 'maxnumber' attribute is greater than the randomly generated number."),new Error("Unexpected result returned.")}).then(()=>{l(Y)?(Pe(E.CODE),Mr().then(()=>{ze("code",{codeChallenge:l(Y)})})):(Pe(E.VERIFIED),S("verified"),Mr().then(()=>{ze("verified",{payload:l(Ve)}),o()==="onsubmit"?zr(l(Et)):Ae()&&Gt()}))}).catch(n=>{S(n),Pe(E.ERROR,n.message)})}var Bi=Wa(),Hi=St(Bi);oa(Hi,t,"default",{});var Ct=J(Hi,2),Kr=z(Ct),br=z(Kr);let Gi;var Wi=z(br);{var vl=n=>{Hr(n)};K(Wi,n=>{l(R)===E.VERIFYING&&n(vl)})}var ft=J(Wi,2);ti(ft),ft.__change=[Ta,R,Le,P,qt,Ze,Ht,Ue],dr(ft,n=>b(Yr,n),()=>l(Yr)),Z(br);var yr=J(br,2),gl=z(yr);{var pl=n=>{var f=cr(),v=St(f);ot(v,()=>l(U).verified),B(n,f)},ml=(n,f)=>{{var v=g=>{var x=cr(),y=St(x);ot(y,()=>l(U).verifying),B(g,x)},p=(g,x)=>{{var y=G=>{var ne=cr(),de=St(ne);ot(de,()=>l(U).verificationRequired),B(G,ne)},A=G=>{var ne=cr(),de=St(ne);ot(de,()=>l(U).label),B(G,ne)};K(g,G=>{l(R)===E.CODE?G(y):G(A,!1)},x)}};K(n,g=>{l(R)===E.VERIFYING?g(v):g(p,!1)},f)}};K(gl,n=>{l(R)===E.VERIFIED?n(pl):n(ml,!1)})}Z(yr);var Yi=J(yr,2);{var _l=n=>{var f=Na();ti(f),$e(()=>{T(f,"name",ce()),fa(f,l(Ve))}),B(n,f)};K(Yi,n=>{l(R)===E.VERIFIED&&n(_l)})}var Zi=J(Yi,2);{var bl=n=>{var f=La(),v=z(f);T(v,"href",za),Z(f),$e(()=>T(v,"aria-label",l(U).ariaLinkLabel)),B(n,f)};K(Zi,n=>{(re()!==!0||l(Gr))&&n(bl)})}var yl=J(Zi,2);{var wl=n=>{var f=Ua(),v=J(z(f),2),p=z(v),g=J(p,2);Xo(g,!w()),g.__keydown=[Sa,$i];var x=J(g,2),y=z(x),A=z(y);{var G=Ie=>{var Q=Ma();Q.__click=$i;var Er=z(Q);{var Yt=xt=>{Hr(xt,()=>20)},Sl=(xt,$l)=>{{var Tl=kt=>{var Qr=Oa();B(kt,Qr)},Dl=(kt,Qr)=>{{var Nl=At=>{var en=Pa();B(At,en)},Ll=At=>{var en=Fa();B(At,en)};K(kt,At=>{l(X)===ee.PLAYING?At(Nl):At(Ll,!1)},Qr)}};K(xt,kt=>{l(X)===ee.ERROR?kt(Tl):kt(Dl,!1)},$l)}};K(Er,xt=>{l(X)===ee.LOADING?xt(Yt):xt(Sl,!1)})}Z(Q),$e(()=>{T(Q,"title",l(U).getAudioChallenge),Q.disabled=l(X)===ee.LOADING||l(X)===ee.ERROR||l(st),T(Q,"aria-label",l(X)===ee.LOADING?l(U).loading:l(U).getAudioChallenge)}),B(Ie,Q)};K(A,Ie=>{l(Y).challenge.codeChallenge.audio&&Ie(G)})}var ne=J(A,2);ne.__click=[$a,Ue],Z(y);var de=J(y,2),Xe=z(de);{var Xr=Ie=>{Hr(Ie,()=>16)};K(Xe,Ie=>{l(st)&&Ie(Xr)})}var wr=J(Xe);Z(de),Z(x);var Il=J(x,2);{var Rl=Ie=>{var Q=Va(),Er=z(Q);Z(Q),dr(Q,Yt=>b(Je,Yt),()=>l(Je)),$e(Yt=>T(Er,"src",Yt),[()=>Ci(l(Y).challenge.codeChallenge.audio,{language:H()})]),Ye("loadstart",Q,ol),Ye("canplay",Q,il),Ye("pause",Q,ll),Ye("playing",Q,al),Ye("ended",Q,rl),Ye("error",Er,nl),B(Ie,Q)};K(Il,Ie=>{l(Y).challenge.codeChallenge.audio&&l(Zr)&&Ie(Rl)})}Z(v),Z(f),$e(()=>{T(f,"aria-label",l(U).verificationRequired),T(p,"src",l(Y).challenge.codeChallenge.image),T(g,"minlength",l(Y).challenge.codeChallenge.length||1),T(g,"maxlength",l(Y).challenge.codeChallenge.length),T(g,"placeholder",l(U).enterCode),T(g,"aria-label",l(X)===ee.LOADING?l(U).loading:l(X)===ee.PLAYING?"":l(U).enterCodeAria),T(g,"aria-live",l(X)?"assertive":"polite"),T(g,"aria-busy",l(X)===ee.LOADING),g.disabled=l(st),T(ne,"aria-label",l(U).reload),T(ne,"title",l(U).reload),ne.disabled=l(st),de.disabled=l(st),T(de,"aria-label",l(U).verify),ra(wr,` ${l(U).verify??""}`)}),Ye("submit",v,sl,!0),B(n,f)};K(yl,n=>{var f;(f=l(Y))!=null&&f.challenge.codeChallenge&&n(wl)})}Z(Kr);var zi=J(Kr,2);{var El=n=>{var f=Ba(),v=J(z(f),2);{var p=x=>{var y=ja(),A=z(y);ot(A,()=>l(U).expired),Z(y),$e(()=>T(y,"title",l(lt))),B(x,y)},g=x=>{var y=qa(),A=z(y);ot(A,()=>l(U).error),Z(y),$e(()=>T(y,"title",l(lt))),B(x,y)};K(v,x=>{l(R)===E.EXPIRED?x(p):x(g,!1)})}Z(f),B(n,f)};K(zi,n=>{(l(lt)||l(R)===E.EXPIRED)&&n(El)})}var Ji=J(zi,2);{var Cl=n=>{var f=Ha(),v=z(f),p=z(v);ot(p,()=>l(U).footer),Z(v),Z(f),B(n,f)};K(Ji,n=>{l(U).footer&&(le()!==!0||l(Gr))&&n(Cl)})}var xl=J(Ji,2);{var kl=n=>{var f=Ga();dr(f,v=>b(Bt,v),()=>l(Bt)),B(n,f)};K(xl,n=>{C()&&n(kl)})}Z(Ct),dr(Ct,n=>b(j,n),()=>l(j)),$e(n=>{T(Ct,"data-state",l(R)),T(Ct,"data-floating",C()),T(Ct,"data-overlay",Ae()),Gi=la(br,1,"altcha-checkbox",null,Gi,n),T(ft,"id",l(_i)),ft.required=o()!=="onsubmit"&&(!C()||o()!=="off"),T(yr,"for",l(_i))},[()=>({"altcha-checkbox-verifying":l(R)===E.VERIFYING})]),Ye("invalid",ft,Si),da(ft,()=>l(qt),n=>b(qt,n)),B(e,Bi);var Al=Wn({clarify:Ht,configure:Mi,getConfiguration:Vi,getFloatingAnchor:Ui,getPlugin:hl,getState:ji,hide:Gt,repositionFloating:Wt,reset:ut,setFloatingAnchor:qi,setState:Pe,show:_r,verify:Ue,get auto(){return o()},set auto(n=void 0){o(n),k()},get blockspam(){return u()},set blockspam(n=void 0){u(n),k()},get challengeurl(){return s()},set challengeurl(n=void 0){s(n),k()},get challengejson(){return c()},set challengejson(n=void 0){c(n),k()},get credentials(){return d()},set credentials(n=void 0){d(n),k()},get customfetch(){return _()},set customfetch(n=void 0){_(n),k()},get debug(){return h()},set debug(n=!1){h(n),k()},get delay(){return m()},set delay(n=0){m(n),k()},get disableautofocus(){return w()},set disableautofocus(n=!1){w(n),k()},get expire(){return D()},set expire(n=void 0){D(n),k()},get floating(){return C()},set floating(n=void 0){C(n),k()},get floatinganchor(){return q()},set floatinganchor(n=void 0){q(n),k()},get floatingoffset(){return pe()},set floatingoffset(n=void 0){pe(n),k()},get floatingpersist(){return te()},set floatingpersist(n=!1){te(n),k()},get hidefooter(){return le()},set hidefooter(n=!1){le(n),k()},get hidelogo(){return re()},set hidelogo(n=!1){re(n),k()},get id(){return _t()},set id(n=void 0){_t(n),k()},get language(){return H()},set language(n=void 0){H(n),k()},get name(){return ce()},set name(n="altcha"){ce(n),k()},get maxnumber(){return ke()},set maxnumber(n=1e6){ke(n),k()},get mockerror(){return Mt()},set mockerror(n=!1){Mt(n),k()},get obfuscated(){return Ze()},set obfuscated(n=void 0){Ze(n),k()},get overlay(){return Ae()},set overlay(n=void 0){Ae(n),k()},get overlaycontent(){return Vt()},set overlaycontent(n=void 0){Vt(n),k()},get plugins(){return pr()},set plugins(n=void 0){pr(n),k()},get refetchonexpire(){return Ut()},set refetchonexpire(n=!0){Ut(n),k()},get sentinel(){return at()},set sentinel(n=void 0){at(n),k()},get spamfilter(){return Le()},set spamfilter(n=!1){Le(n),k()},get strings(){return bt()},set strings(n=void 0){bt(n),k()},get test(){return we()},set test(n=!1){we(n),k()},get verifyurl(){return se()},set verifyurl(n=void 0){se(n),k()},get workers(){return yt()},set workers(n=Math.min(16,navigator.hardwareConcurrency||8)){yt(n),k()},get workerurl(){return jt()},set workerurl(n=void 0){jt(n),k()}});return i(),Al}ta(["change","keydown","click"]),customElements.define("altcha-widget",wa(di,{blockspam:{type:"Boolean"},debug:{type:"Boolean"},delay:{type:"Number"},disableautofocus:{type:"Boolean"},expire:{type:"Number"},floatingoffset:{type:"Number"},hidefooter:{type:"Boolean"},hidelogo:{type:"Boolean"},maxnumber:{type:"Number"},mockerror:{type:"Boolean"},refetchonexpire:{type:"Boolean"},test:{type:"Boolean"},workers:{type:"Number"},auto:{},challengeurl:{},challengejson:{},credentials:{},customfetch:{},floating:{},floatinganchor:{},floatingpersist:{},id:{},language:{},name:{},obfuscated:{},overlay:{},overlaycontent:{},plugins:{},sentinel:{},spamfilter:{},strings:{},verifyurl:{},workerurl:{}},["default"],["clarify","configure","getConfiguration","getFloatingAnchor","getPlugin","getState","hide","repositionFloating","reset","setFloatingAnchor","setState","show","verify"],!1));const hi='@keyframes overlay-slidein{to{opacity:1;top:50%}}@keyframes altcha-spinner{to{transform:rotate(360deg)}}.altcha{background:var(--altcha-color-base, transparent);border:var(--altcha-border-width, 1px) solid var(--altcha-color-border, #a0a0a0);border-radius:var(--altcha-border-radius, 3px);color:var(--altcha-color-text, currentColor);display:flex;flex-direction:column;max-width:var(--altcha-max-width, 260px);position:relative}.altcha:focus-within{border-color:var(--altcha-color-border-focus, currentColor)}.altcha[data-floating]{background:var(--altcha-color-base, white);display:none;filter:drop-shadow(3px 3px 6px rgba(0,0,0,.2));left:-100%;position:fixed;top:-100%;width:var(--altcha-max-width, 260px);z-index:999999}.altcha[data-floating=top] .altcha-anchor-arrow{border-bottom-color:transparent;border-top-color:var(--altcha-color-border, #a0a0a0);bottom:-12px;top:auto}.altcha[data-floating=bottom]:focus-within::after{border-bottom-color:var(--altcha-color-border-focus, currentColor)}.altcha[data-floating=top]:focus-within::after{border-top-color:var(--altcha-color-border-focus, currentColor)}.altcha[data-floating]:not([data-state=unverified]){display:block}.altcha-anchor-arrow{border:6px solid transparent;border-bottom-color:var(--altcha-color-border, #a0a0a0);content:"";height:0;left:12px;position:absolute;top:-12px;width:0}.altcha-main{align-items:center;display:flex;gap:.4rem;padding:.7rem;position:relative}.altcha-code-challenge{background:var(--altcha-color-base, white);border:1px solid var(--altcha-color-border-focus, currentColor);border-radius:var(--altcha-border-radius, 3px);filter:drop-shadow(3px 3px 6px rgba(0,0,0,.2));padding:.5rem;position:absolute;top:2.5rem;z-index:9999999}.altcha-code-challenge>form{display:flex;flex-direction:column;gap:.5rem}.altcha-code-challenge-input{border:1px solid currentColor;border-radius:3px;box-sizing:border-box;outline:0;font-size:16px;padding:.35rem;width:220px}.altcha-code-challenge-input:focus{outline:2px solid color-mix(in srgb,var(--altcha-color-active, #1D1DC9) 20%,transparent)}.altcha-code-challenge-input:disabled{opacity:.7}.altcha-code-challenge-image{background-color:#fff;border:1px solid currentColor;border-radius:3px;box-sizing:border-box;object-fit:contain;height:50px;width:220px}.altcha-code-challenge-audio,.altcha-code-challenge-reload{background:color-mix(in srgb,var(--altcha-color-text, currentColor) 10%,transparent);border:0;border-radius:3px;color:var(--altcha-color-text, currentColor);cursor:pointer;display:flex;align-items:center;justify-content:center;padding:.35rem}.altcha-code-challenge-audio:disabled,.altcha-code-challenge-reload:disabled,.altcha-code-challenge-verify:disabled{opacity:.7;pointer-events:none}.altcha-code-challenge-audio>*,.altcha-code-challenge-reload>*{height:20px;width:20px}.altcha-code-challenge-buttons{display:flex;justify-content:space-between}.altcha-code-challenge-buttons-left{display:flex;gap:.25rem}.altcha-code-challenge-verify{align-items:center;background:var(--altcha-color-active, #1D1DC9);border:0;border-radius:3px;color:#fff;cursor:pointer;display:flex;gap:.5rem;font-size:100%;padding:.35rem 1rem}.altcha-code-challenge-arrow{border:6px solid transparent;border-bottom-color:var(--altcha-color-border, currentColor);content:"";height:0;left:.15rem;position:absolute;top:-12px;width:0}.altcha[data-floating=top] .altcha-code-challenge{top:-150px}.altcha[data-floating=top] .altcha-code-challenge-arrow{border-bottom-color:transparent;border-top-color:var(--altcha-color-border, currentColor);bottom:-12px;top:auto}.altcha-label{cursor:pointer;flex-grow:1}.altcha-logo{color:currentColor!important;opacity:.7}.altcha-footer:hover,.altcha-logo:hover{opacity:1}.altcha-error{color:var(--altcha-color-error-text, #f23939);display:flex;font-size:.85rem;gap:.3rem;padding:0 .7rem .7rem}.altcha-footer{align-items:center;background-color:var(--altcha-color-footer-bg, transparent);display:flex;font-size:.75rem;opacity:.7;justify-content:end;padding:.2rem .7rem}.altcha-footer a{color:currentColor}.altcha-checkbox{display:flex;align-items:center;justify-content:center;height:24px;position:relative;width:24px}.altcha-checkbox .altcha-spinner{bottom:0;left:0;position:absolute;right:0;top:0}.altcha-checkbox input{width:18px;height:18px;margin:0}.altcha-checkbox-verifying input{appearance:none;opacity:0;pointer-events:none}.altcha-spinner{animation:altcha-spinner .75s infinite linear;transform-origin:center}.altcha-overlay{--altcha-color-base:#fff;--altcha-color-text:#000;animation:overlay-slidein .5s forwards;display:flex;flex-direction:column;gap:.5rem;left:50%;width:260px;opacity:0;position:fixed;top:45%;transform:translate(-50%,-50%)}.altcha-overlay-backdrop{background:rgba(0,0,0,.5);bottom:0;display:none;left:0;position:fixed;right:0;top:0;z-index:99999999}.altcha-overlay-close-button{align-self:flex-end;background:0 0;border:0;padding:.25rem;cursor:pointer;color:currentColor;font-size:130%;line-height:1;opacity:.7}@media (max-height:450px){.altcha-overlay{top:10%!important;transform:translate(-50%,0)}}';function vi(e,t="__altcha-css"){if(!document.getElementById(t)){const r=document.createElement("style");r.id=t,r.textContent=e,document.head.appendChild(r)}}globalThis.altchaCreateWorker=e=>e?new Worker(new URL(e)):new Zt,vi(hi),vi(hi),$.Altcha=di,Object.defineProperty($,Symbol.toStringTag,{value:"Module"})}); diff --git a/themes/root/package.json b/themes/root/package.json new file mode 100644 index 00000000000..f837fcb4ae9 --- /dev/null +++ b/themes/root/package.json @@ -0,0 +1,11 @@ +{ + "name": "vufind-root", + "description": "Dependencies for the root theme", + "scripts": { + "installDeps": "npm install --no-audit && node tools/copyDependencies.mjs", + "updateDeps": "npm update && node tools/copyDependencies.mjs" + }, + "dependencies": { + "altcha": "^2.1.0" + } +} diff --git a/themes/root/templates/Captcha/altcha.phtml b/themes/root/templates/Captcha/altcha.phtml new file mode 100644 index 00000000000..499babd1ebc --- /dev/null +++ b/themes/root/templates/Captcha/altcha.phtml @@ -0,0 +1 @@ + diff --git a/themes/root/tools/copyDependencies.mjs b/themes/root/tools/copyDependencies.mjs new file mode 100644 index 00000000000..31d2dc62a87 --- /dev/null +++ b/themes/root/tools/copyDependencies.mjs @@ -0,0 +1,24 @@ +import { copyFile, mkdir } from 'node:fs/promises'; + +await mkdir('js/vendor', { recursive: true }); + +let buildDepsOnly = false; +process.argv.forEach(arg => { + if (arg === '--only-build-deps') { + buildDepsOnly = true; + } +}); + +console.log('Copying dependencies...'); + +if (buildDepsOnly) { + console.log('Done copying build dependencies.'); + process.exit(); +} + +// Altcha +await copyFile('node_modules/altcha/LICENSE.txt', 'js/vendor/altcha-LICENSE.txt'); +await copyFile('node_modules/altcha/dist/altcha.umd.cjs', 'js/vendor/altcha.js'); +await copyFile('node_modules/altcha/dist_i18n/all.umd.cjs', 'js/vendor/altcha-i18n.js'); + +console.log('Done copying dependencies.');