From 8389c2a2d6f9d8085f5dabdbcb588248e58898f0 Mon Sep 17 00:00:00 2001 From: El RIDO Date: Sat, 5 Nov 2022 08:46:42 +0100 Subject: [PATCH 01/21] minor optimization, let the PDO driver do that for us --- lib/Data/Database.php | 17 +++++------------ 1 file changed, 5 insertions(+), 12 deletions(-) diff --git a/lib/Data/Database.php b/lib/Data/Database.php index 3771b5d..e067899 100644 --- a/lib/Data/Database.php +++ b/lib/Data/Database.php @@ -486,19 +486,13 @@ class Database extends AbstractData */ protected function _getExpiredPastes($batchsize) { - $pastes = array(); - $rows = $this->_select( + $statement = $this->_db->prepare( 'SELECT "dataid" FROM "' . $this->_sanitizeIdentifier('paste') . '" WHERE "expiredate" < ? AND "expiredate" != ? ' . - ($this->_type === 'oci' ? 'FETCH NEXT ? ROWS ONLY' : 'LIMIT ?'), - array(time(), 0, $batchsize) + ($this->_type === 'oci' ? 'FETCH NEXT ? ROWS ONLY' : 'LIMIT ?') ); - if (is_array($rows) && count($rows)) { - foreach ($rows as $row) { - $pastes[] = $row['dataid']; - } - } - return $pastes; + $statement->execute(array(time(), 0, $batchsize)); + return $statement->fetchAll(PDO::FETCH_COLUMN, 0); } /** @@ -506,10 +500,9 @@ class Database extends AbstractData */ public function getAllPastes() { - $pastes = $this->_db->_query( + return $this->_db->_query( 'SELECT "dataid" FROM "' . $this->_sanitizeIdentifier('paste') . '"' )->fetchAll(PDO::FETCH_COLUMN, 0); - return $pastes; } /** From 62bb68344c129d120b02a9d4b1886fd9f865f0c8 Mon Sep 17 00:00:00 2001 From: El RIDO Date: Sat, 5 Nov 2022 09:32:30 +0100 Subject: [PATCH 02/21] move all scripts into one location - standardize includes, namings - made migrate executable - updated ConfigurationCombinationsTest generator to work with current persistance API --- .gitattributes | 2 ++ .../configuration-test-generator | 8 ++++++-- tst/IconTest => bin/icon-test | 0 bin/{migrate.php => migrate} | 9 +++++---- tst/phpunit.xml | 1 - 5 files changed, 13 insertions(+), 7 deletions(-) rename tst/ConfigurationTestGenerator.php => bin/configuration-test-generator (98%) rename tst/IconTest => bin/icon-test (100%) rename bin/{migrate.php => migrate} (96%) mode change 100644 => 100755 diff --git a/.gitattributes b/.gitattributes index 60629c0..c01ff77 100644 --- a/.gitattributes +++ b/.gitattributes @@ -1,3 +1,5 @@ +bin/configuration-test-generator export-ignore +bin/icon-test export-ignore doc/ export-ignore tst/ export-ignore img/browserstack.svg export-ignore diff --git a/tst/ConfigurationTestGenerator.php b/bin/configuration-test-generator similarity index 98% rename from tst/ConfigurationTestGenerator.php rename to bin/configuration-test-generator index a0106a3..432a229 100755 --- a/tst/ConfigurationTestGenerator.php +++ b/bin/configuration-test-generator @@ -9,7 +9,9 @@ * DANGER: Too many options/settings and too high max iteration setting may trigger * a fork bomb. Please save your work before executing this script. */ -include 'Bootstrap.php'; + +define('PATH', dirname(__FILE__) . DIRECTORY_SEPARATOR . '..' . DIRECTORY_SEPARATOR); +include PATH . 'tst' . DIRECTORY_SEPARATOR . 'Bootstrap.php'; $vd = array('view', 'delete'); $vcd = array('view', 'create', 'delete'); @@ -392,7 +394,7 @@ class ConfigurationTestGenerator } } $code .= '}' . PHP_EOL; - file_put_contents('ConfigurationCombinationsTest.php', $code); + file_put_contents(dirname(__FILE__) . DIRECTORY_SEPARATOR . '..' . DIRECTORY_SEPARATOR . 'tst' . DIRECTORY_SEPARATOR . 'ConfigurationCombinationsTest.php', $code); } /** @@ -428,6 +430,8 @@ class ConfigurationCombinationsTest extends PHPUnit_Framework_TestCase Helper::confBackup(); $this->_path = sys_get_temp_dir() . DIRECTORY_SEPARATOR . 'privatebin_data'; $this->_model = new Filesystem(array('dir' => $this->_path)); + ServerSalt::setStore($this->_model); + TrafficLimiter::setStore($this->_model); $this->reset(); } diff --git a/tst/IconTest b/bin/icon-test similarity index 100% rename from tst/IconTest rename to bin/icon-test diff --git a/bin/migrate.php b/bin/migrate old mode 100644 new mode 100755 similarity index 96% rename from bin/migrate.php rename to bin/migrate index 193430e..4dbe052 --- a/bin/migrate.php +++ b/bin/migrate @@ -1,7 +1,8 @@ +#!/usr/bin/env php ] - php migrate.php [-h] + migrate [--delete-after] [--delete-during] [-f] [-n] [-v] srcconfdir + [] + migrate [-h] Options: --delete-after delete data from source after all pastes and comments have diff --git a/tst/phpunit.xml b/tst/phpunit.xml index caaa67d..20eb4d5 100644 --- a/tst/phpunit.xml +++ b/tst/phpunit.xml @@ -1,7 +1,6 @@ ./ - ConfigurationTestGenerator.php From 833cf93209637d4e88530d08db7e8cc932d0549f Mon Sep 17 00:00:00 2001 From: El RIDO Date: Sat, 5 Nov 2022 09:35:06 +0100 Subject: [PATCH 03/21] address Scrutinizer warning > The variable $bucket does not seem to be defined for all execution paths leading up to this point. --- lib/Data/GoogleCloudStorage.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/lib/Data/GoogleCloudStorage.php b/lib/Data/GoogleCloudStorage.php index dd2aff3..e07e818 100644 --- a/lib/Data/GoogleCloudStorage.php +++ b/lib/Data/GoogleCloudStorage.php @@ -67,7 +67,9 @@ class GoogleCloudStorage extends AbstractData $this->_client = class_exists('StorageClientStub', false) ? new \StorageClientStub(array()) : new StorageClient(array('suppressKeyFileNotice' => true)); - $this->_bucket = $this->_client->bucket($bucket); + if (isset($bucket)) { + $this->_bucket = $this->_client->bucket($bucket); + } } /** From 07ad9ad0f4be3cf6647c8ab8945839178321d15d Mon Sep 17 00:00:00 2001 From: El RIDO Date: Sat, 5 Nov 2022 09:37:24 +0100 Subject: [PATCH 04/21] typo, found by Scrutinizer --- lib/Data/Database.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/Data/Database.php b/lib/Data/Database.php index e067899..d4933b0 100644 --- a/lib/Data/Database.php +++ b/lib/Data/Database.php @@ -500,7 +500,7 @@ class Database extends AbstractData */ public function getAllPastes() { - return $this->_db->_query( + return $this->_db->query( 'SELECT "dataid" FROM "' . $this->_sanitizeIdentifier('paste') . '"' )->fetchAll(PDO::FETCH_COLUMN, 0); } From 9a1f3aeca505695e54840a1861eceaeddc7bfe11 Mon Sep 17 00:00:00 2001 From: El RIDO Date: Sat, 5 Nov 2022 09:44:35 +0100 Subject: [PATCH 05/21] update Jdenticon library --- composer.lock | 418 +++++++----------- vendor/composer/ClassLoader.php | 157 +------ vendor/composer/autoload_classmap.php | 2 +- vendor/composer/autoload_real.php | 15 +- vendor/composer/autoload_static.php | 2 +- .../Rasterization/SuperSampleBuffer.php | 9 + 6 files changed, 196 insertions(+), 407 deletions(-) diff --git a/composer.lock b/composer.lock index 8b17d33..5d13c27 100644 --- a/composer.lock +++ b/composer.lock @@ -48,11 +48,6 @@ "identicon", "jdenticon" ], - "support": { - "docs": "https://jdenticon.com/php-api.html", - "issues": "https://github.com/dmester/jdenticon-php/issues", - "source": "https://github.com/dmester/jdenticon-php" - }, "time": "2022-10-30T17:15:02+00:00" }, { @@ -110,10 +105,6 @@ "range", "subnet" ], - "support": { - "issues": "https://github.com/mlocati/ip-lib/issues", - "source": "https://github.com/mlocati/ip-lib/tree/1.18.0" - }, "funding": [ { "url": "https://github.com/sponsors/mlocati", @@ -173,11 +164,6 @@ "pseudorandom", "random" ], - "support": { - "email": "info@paragonie.com", - "issues": "https://github.com/paragonie/random_compat/issues", - "source": "https://github.com/paragonie/random_compat" - }, "time": "2022-02-16T17:07:03+00:00" }, { @@ -230,10 +216,6 @@ "identicon", "image" ], - "support": { - "issues": "https://github.com/yzalis/Identicon/issues", - "source": "https://github.com/yzalis/Identicon/tree/master" - }, "abandoned": true, "time": "2019-10-14T09:30:57+00:00" } @@ -241,34 +223,32 @@ "packages-dev": [ { "name": "doctrine/instantiator", - "version": "1.0.5", + "version": "1.4.1", "source": { "type": "git", "url": "https://github.com/doctrine/instantiator.git", - "reference": "8e884e78f9f0eb1329e445619e04456e64d8051d" + "reference": "10dcfce151b967d20fde1b34ae6640712c3891bc" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/instantiator/zipball/8e884e78f9f0eb1329e445619e04456e64d8051d", - "reference": "8e884e78f9f0eb1329e445619e04456e64d8051d", + "url": "https://api.github.com/repos/doctrine/instantiator/zipball/10dcfce151b967d20fde1b34ae6640712c3891bc", + "reference": "10dcfce151b967d20fde1b34ae6640712c3891bc", "shasum": "" }, "require": { - "php": ">=5.3,<8.0-DEV" + "php": "^7.1 || ^8.0" }, "require-dev": { - "athletic/athletic": "~0.1.8", + "doctrine/coding-standard": "^9", "ext-pdo": "*", "ext-phar": "*", - "phpunit/phpunit": "~4.0", - "squizlabs/php_codesniffer": "~2.0" + "phpbench/phpbench": "^0.16 || ^1", + "phpstan/phpstan": "^1.4", + "phpstan/phpstan-phpunit": "^1", + "phpunit/phpunit": "^7.5 || ^8.5 || ^9.5", + "vimeo/psalm": "^4.22" }, "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.0.x-dev" - } - }, "autoload": { "psr-4": { "Doctrine\\Instantiator\\": "src/Doctrine/Instantiator/" @@ -282,42 +262,56 @@ { "name": "Marco Pivetta", "email": "ocramius@gmail.com", - "homepage": "http://ocramius.github.com/" + "homepage": "https://ocramius.github.io/" } ], "description": "A small, lightweight utility to instantiate objects in PHP without invoking their constructors", - "homepage": "https://github.com/doctrine/instantiator", + "homepage": "https://www.doctrine-project.org/projects/instantiator.html", "keywords": [ "constructor", "instantiate" ], - "support": { - "issues": "https://github.com/doctrine/instantiator/issues", - "source": "https://github.com/doctrine/instantiator/tree/master" - }, - "time": "2015-06-14T21:17:01+00:00" + "funding": [ + { + "url": "https://www.doctrine-project.org/sponsorship.html", + "type": "custom" + }, + { + "url": "https://www.patreon.com/phpdoctrine", + "type": "patreon" + }, + { + "url": "https://tidelift.com/funding/github/packagist/doctrine%2Finstantiator", + "type": "tidelift" + } + ], + "time": "2022-03-03T08:28:38+00:00" }, { "name": "myclabs/deep-copy", - "version": "1.7.0", + "version": "1.11.0", "source": { "type": "git", "url": "https://github.com/myclabs/DeepCopy.git", - "reference": "3b8a3a99ba1f6a3952ac2747d989303cbd6b7a3e" + "reference": "14daed4296fae74d9e3201d2c4925d1acb7aa614" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/3b8a3a99ba1f6a3952ac2747d989303cbd6b7a3e", - "reference": "3b8a3a99ba1f6a3952ac2747d989303cbd6b7a3e", + "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/14daed4296fae74d9e3201d2c4925d1acb7aa614", + "reference": "14daed4296fae74d9e3201d2c4925d1acb7aa614", "shasum": "" }, "require": { - "php": "^5.6 || ^7.0" + "php": "^7.1 || ^8.0" + }, + "conflict": { + "doctrine/collections": "<1.6.8", + "doctrine/common": "<2.13.3 || >=3,<3.2.2" }, "require-dev": { - "doctrine/collections": "^1.0", - "doctrine/common": "^2.6", - "phpunit/phpunit": "^4.1" + "doctrine/collections": "^1.6.8", + "doctrine/common": "^2.13.3 || ^3.2.2", + "phpunit/phpunit": "^7.5.20 || ^8.5.23 || ^9.5.13" }, "type": "library", "autoload": { @@ -340,43 +334,40 @@ "object", "object graph" ], - "support": { - "issues": "https://github.com/myclabs/DeepCopy/issues", - "source": "https://github.com/myclabs/DeepCopy/tree/1.x" - }, - "time": "2017-10-19T19:58:43+00:00" + "funding": [ + { + "url": "https://tidelift.com/funding/github/packagist/myclabs/deep-copy", + "type": "tidelift" + } + ], + "time": "2022-03-03T13:19:32+00:00" }, { "name": "phpdocumentor/reflection-common", - "version": "1.0.1", + "version": "2.2.0", "source": { "type": "git", "url": "https://github.com/phpDocumentor/ReflectionCommon.git", - "reference": "21bdeb5f65d7ebf9f43b1b25d404f87deab5bfb6" + "reference": "1d01c49d4ed62f25aa84a747ad35d5a16924662b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpDocumentor/ReflectionCommon/zipball/21bdeb5f65d7ebf9f43b1b25d404f87deab5bfb6", - "reference": "21bdeb5f65d7ebf9f43b1b25d404f87deab5bfb6", + "url": "https://api.github.com/repos/phpDocumentor/ReflectionCommon/zipball/1d01c49d4ed62f25aa84a747ad35d5a16924662b", + "reference": "1d01c49d4ed62f25aa84a747ad35d5a16924662b", "shasum": "" }, "require": { - "php": ">=5.5" - }, - "require-dev": { - "phpunit/phpunit": "^4.6" + "php": "^7.2 || ^8.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "1.0.x-dev" + "dev-2.x": "2.x-dev" } }, "autoload": { "psr-4": { - "phpDocumentor\\Reflection\\": [ - "src" - ] + "phpDocumentor\\Reflection\\": "src/" } }, "notification-url": "https://packagist.org/downloads/", @@ -398,94 +389,97 @@ "reflection", "static analysis" ], - "support": { - "issues": "https://github.com/phpDocumentor/ReflectionCommon/issues", - "source": "https://github.com/phpDocumentor/ReflectionCommon/tree/master" - }, - "time": "2017-09-11T18:02:19+00:00" + "time": "2020-06-27T09:03:43+00:00" }, { "name": "phpdocumentor/reflection-docblock", - "version": "3.3.2", + "version": "5.3.0", "source": { "type": "git", "url": "https://github.com/phpDocumentor/ReflectionDocBlock.git", - "reference": "bf329f6c1aadea3299f08ee804682b7c45b326a2" + "reference": "622548b623e81ca6d78b721c5e029f4ce664f170" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/bf329f6c1aadea3299f08ee804682b7c45b326a2", - "reference": "bf329f6c1aadea3299f08ee804682b7c45b326a2", + "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/622548b623e81ca6d78b721c5e029f4ce664f170", + "reference": "622548b623e81ca6d78b721c5e029f4ce664f170", "shasum": "" }, "require": { - "php": "^5.6 || ^7.0", - "phpdocumentor/reflection-common": "^1.0.0", - "phpdocumentor/type-resolver": "^0.4.0", - "webmozart/assert": "^1.0" + "ext-filter": "*", + "php": "^7.2 || ^8.0", + "phpdocumentor/reflection-common": "^2.2", + "phpdocumentor/type-resolver": "^1.3", + "webmozart/assert": "^1.9.1" }, "require-dev": { - "mockery/mockery": "^0.9.4", - "phpunit/phpunit": "^4.4" - }, - "type": "library", - "autoload": { - "psr-4": { - "phpDocumentor\\Reflection\\": [ - "src/" - ] - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Mike van Riel", - "email": "me@mikevanriel.com" - } - ], - "description": "With this component, a library can provide support for annotations via DocBlocks or otherwise retrieve information that is embedded in a DocBlock.", - "support": { - "issues": "https://github.com/phpDocumentor/ReflectionDocBlock/issues", - "source": "https://github.com/phpDocumentor/ReflectionDocBlock/tree/release/3.x" - }, - "time": "2017-11-10T14:09:06+00:00" - }, - { - "name": "phpdocumentor/type-resolver", - "version": "0.4.0", - "source": { - "type": "git", - "url": "https://github.com/phpDocumentor/TypeResolver.git", - "reference": "9c977708995954784726e25d0cd1dddf4e65b0f7" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/9c977708995954784726e25d0cd1dddf4e65b0f7", - "reference": "9c977708995954784726e25d0cd1dddf4e65b0f7", - "shasum": "" - }, - "require": { - "php": "^5.5 || ^7.0", - "phpdocumentor/reflection-common": "^1.0" - }, - "require-dev": { - "mockery/mockery": "^0.9.4", - "phpunit/phpunit": "^5.2||^4.8.24" + "mockery/mockery": "~1.3.2", + "psalm/phar": "^4.8" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "1.0.x-dev" + "dev-master": "5.x-dev" } }, "autoload": { "psr-4": { - "phpDocumentor\\Reflection\\": [ - "src/" - ] + "phpDocumentor\\Reflection\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Mike van Riel", + "email": "me@mikevanriel.com" + }, + { + "name": "Jaap van Otterdijk", + "email": "account@ijaap.nl" + } + ], + "description": "With this component, a library can provide support for annotations via DocBlocks or otherwise retrieve information that is embedded in a DocBlock.", + "time": "2021-10-19T17:43:47+00:00" + }, + { + "name": "phpdocumentor/type-resolver", + "version": "1.6.2", + "source": { + "type": "git", + "url": "https://github.com/phpDocumentor/TypeResolver.git", + "reference": "48f445a408c131e38cab1c235aa6d2bb7a0bb20d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/48f445a408c131e38cab1c235aa6d2bb7a0bb20d", + "reference": "48f445a408c131e38cab1c235aa6d2bb7a0bb20d", + "shasum": "" + }, + "require": { + "php": "^7.4 || ^8.0", + "phpdocumentor/reflection-common": "^2.0" + }, + "require-dev": { + "ext-tokenizer": "*", + "phpstan/extension-installer": "^1.1", + "phpstan/phpstan": "^1.8", + "phpstan/phpstan-phpunit": "^1.1", + "phpunit/phpunit": "^9.5", + "rector/rector": "^0.13.9", + "vimeo/psalm": "^4.25" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-1.x": "1.x-dev" + } + }, + "autoload": { + "psr-4": { + "phpDocumentor\\Reflection\\": "src" } }, "notification-url": "https://packagist.org/downloads/", @@ -498,11 +492,8 @@ "email": "me@mikevanriel.com" } ], - "support": { - "issues": "https://github.com/phpDocumentor/TypeResolver/issues", - "source": "https://github.com/phpDocumentor/TypeResolver/tree/master" - }, - "time": "2017-07-14T14:27:02+00:00" + "description": "A PSR-5 based resolver of Class names, Types and Structural Element Names", + "time": "2022-10-14T12:47:21+00:00" }, { "name": "phpspec/prophecy", @@ -565,10 +556,6 @@ "spy", "stub" ], - "support": { - "issues": "https://github.com/phpspec/prophecy/issues", - "source": "https://github.com/phpspec/prophecy/tree/v1.10.3" - }, "time": "2020-03-05T15:02:03+00:00" }, { @@ -632,11 +619,6 @@ "testing", "xunit" ], - "support": { - "irc": "irc://irc.freenode.net/phpunit", - "issues": "https://github.com/sebastianbergmann/php-code-coverage/issues", - "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/4.0" - }, "time": "2017-04-02T07:44:40+00:00" }, { @@ -684,11 +666,6 @@ "filesystem", "iterator" ], - "support": { - "irc": "irc://irc.freenode.net/phpunit", - "issues": "https://github.com/sebastianbergmann/php-file-iterator/issues", - "source": "https://github.com/sebastianbergmann/php-file-iterator/tree/1.4.5" - }, "time": "2017-11-27T13:52:08+00:00" }, { @@ -730,10 +707,6 @@ "keywords": [ "template" ], - "support": { - "issues": "https://github.com/sebastianbergmann/php-text-template/issues", - "source": "https://github.com/sebastianbergmann/php-text-template/tree/1.2.1" - }, "time": "2015-06-21T13:50:34+00:00" }, { @@ -783,37 +756,33 @@ "keywords": [ "timer" ], - "support": { - "issues": "https://github.com/sebastianbergmann/php-timer/issues", - "source": "https://github.com/sebastianbergmann/php-timer/tree/master" - }, "time": "2017-02-26T11:10:40+00:00" }, { "name": "phpunit/php-token-stream", - "version": "1.4.12", + "version": "2.0.2", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-token-stream.git", - "reference": "1ce90ba27c42e4e44e6d8458241466380b51fa16" + "reference": "791198a2c6254db10131eecfe8c06670700904db" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-token-stream/zipball/1ce90ba27c42e4e44e6d8458241466380b51fa16", - "reference": "1ce90ba27c42e4e44e6d8458241466380b51fa16", + "url": "https://api.github.com/repos/sebastianbergmann/php-token-stream/zipball/791198a2c6254db10131eecfe8c06670700904db", + "reference": "791198a2c6254db10131eecfe8c06670700904db", "shasum": "" }, "require": { "ext-tokenizer": "*", - "php": ">=5.3.3" + "php": "^7.0" }, "require-dev": { - "phpunit/phpunit": "~4.2" + "phpunit/phpunit": "^6.2.4" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "1.4-dev" + "dev-master": "2.0-dev" } }, "autoload": { @@ -836,12 +805,8 @@ "keywords": [ "tokenizer" ], - "support": { - "issues": "https://github.com/sebastianbergmann/php-token-stream/issues", - "source": "https://github.com/sebastianbergmann/php-token-stream/tree/1.4" - }, "abandoned": true, - "time": "2017-12-04T08:55:13+00:00" + "time": "2017-11-27T05:48:46+00:00" }, { "name": "phpunit/phpunit", @@ -923,10 +888,6 @@ "testing", "xunit" ], - "support": { - "issues": "https://github.com/sebastianbergmann/phpunit/issues", - "source": "https://github.com/sebastianbergmann/phpunit/tree/5.7.27" - }, "time": "2018-02-01T05:50:59+00:00" }, { @@ -986,11 +947,6 @@ "mock", "xunit" ], - "support": { - "irc": "irc://irc.freenode.net/phpunit", - "issues": "https://github.com/sebastianbergmann/phpunit-mock-objects/issues", - "source": "https://github.com/sebastianbergmann/phpunit-mock-objects/tree/3.4" - }, "abandoned": true, "time": "2017-06-30T09:13:00+00:00" }, @@ -1037,10 +993,6 @@ ], "description": "Looks up which function or method a line of code belongs to", "homepage": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/", - "support": { - "issues": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/issues", - "source": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/tree/1.0.2" - }, "funding": [ { "url": "https://github.com/sebastianbergmann", @@ -1111,10 +1063,6 @@ "compare", "equality" ], - "support": { - "issues": "https://github.com/sebastianbergmann/comparator/issues", - "source": "https://github.com/sebastianbergmann/comparator/tree/1.2" - }, "time": "2017-01-29T09:50:25+00:00" }, { @@ -1167,10 +1115,6 @@ "keywords": [ "diff" ], - "support": { - "issues": "https://github.com/sebastianbergmann/diff/issues", - "source": "https://github.com/sebastianbergmann/diff/tree/1.4" - }, "time": "2017-05-22T07:24:03+00:00" }, { @@ -1221,10 +1165,6 @@ "environment", "hhvm" ], - "support": { - "issues": "https://github.com/sebastianbergmann/environment/issues", - "source": "https://github.com/sebastianbergmann/environment/tree/master" - }, "time": "2016-11-26T07:53:53+00:00" }, { @@ -1292,10 +1232,6 @@ "export", "exporter" ], - "support": { - "issues": "https://github.com/sebastianbergmann/exporter/issues", - "source": "https://github.com/sebastianbergmann/exporter/tree/master" - }, "time": "2016-11-19T08:54:04+00:00" }, { @@ -1347,10 +1283,6 @@ "keywords": [ "global state" ], - "support": { - "issues": "https://github.com/sebastianbergmann/global-state/issues", - "source": "https://github.com/sebastianbergmann/global-state/tree/1.1.1" - }, "time": "2015-10-12T03:26:01+00:00" }, { @@ -1397,10 +1329,6 @@ ], "description": "Traverses array structures and object graphs to enumerate all referenced objects", "homepage": "https://github.com/sebastianbergmann/object-enumerator/", - "support": { - "issues": "https://github.com/sebastianbergmann/object-enumerator/issues", - "source": "https://github.com/sebastianbergmann/object-enumerator/tree/master" - }, "time": "2017-02-18T15:18:39+00:00" }, { @@ -1454,10 +1382,6 @@ ], "description": "Provides functionality to recursively process PHP variables", "homepage": "http://www.github.com/sebastianbergmann/recursion-context", - "support": { - "issues": "https://github.com/sebastianbergmann/recursion-context/issues", - "source": "https://github.com/sebastianbergmann/recursion-context/tree/master" - }, "time": "2016-11-19T07:33:16+00:00" }, { @@ -1500,10 +1424,6 @@ ], "description": "Provides a list of PHP built-in functions that operate on resources", "homepage": "https://www.github.com/sebastianbergmann/resource-operations", - "support": { - "issues": "https://github.com/sebastianbergmann/resource-operations/issues", - "source": "https://github.com/sebastianbergmann/resource-operations/tree/master" - }, "time": "2015-07-28T20:34:47+00:00" }, { @@ -1547,28 +1467,27 @@ ], "description": "Library that helps with managing the version number of Git-hosted PHP projects", "homepage": "https://github.com/sebastianbergmann/version", - "support": { - "issues": "https://github.com/sebastianbergmann/version/issues", - "source": "https://github.com/sebastianbergmann/version/tree/master" - }, "time": "2016-10-03T07:35:21+00:00" }, { "name": "symfony/polyfill-ctype", - "version": "v1.19.0", + "version": "v1.26.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-ctype.git", - "reference": "aed596913b70fae57be53d86faa2e9ef85a2297b" + "reference": "6fd1b9a79f6e3cf65f9e679b23af304cd9e010d4" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/aed596913b70fae57be53d86faa2e9ef85a2297b", - "reference": "aed596913b70fae57be53d86faa2e9ef85a2297b", + "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/6fd1b9a79f6e3cf65f9e679b23af304cd9e010d4", + "reference": "6fd1b9a79f6e3cf65f9e679b23af304cd9e010d4", "shasum": "" }, "require": { - "php": ">=5.3.3" + "php": ">=7.1" + }, + "provide": { + "ext-ctype": "*" }, "suggest": { "ext-ctype": "For best performance" @@ -1576,7 +1495,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "1.19-dev" + "dev-main": "1.26-dev" }, "thanks": { "name": "symfony/polyfill", @@ -1613,9 +1532,6 @@ "polyfill", "portable" ], - "support": { - "source": "https://github.com/symfony/polyfill-ctype/tree/v1.19.0" - }, "funding": [ { "url": "https://symfony.com/sponsor", @@ -1630,31 +1546,31 @@ "type": "tidelift" } ], - "time": "2020-10-23T09:01:57+00:00" + "time": "2022-05-24T11:49:31+00:00" }, { "name": "symfony/yaml", - "version": "v3.4.47", + "version": "v4.4.45", "source": { "type": "git", "url": "https://github.com/symfony/yaml.git", - "reference": "88289caa3c166321883f67fe5130188ebbb47094" + "reference": "aeccc4dc52a9e634f1d1eebeb21eacfdcff1053d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/yaml/zipball/88289caa3c166321883f67fe5130188ebbb47094", - "reference": "88289caa3c166321883f67fe5130188ebbb47094", + "url": "https://api.github.com/repos/symfony/yaml/zipball/aeccc4dc52a9e634f1d1eebeb21eacfdcff1053d", + "reference": "aeccc4dc52a9e634f1d1eebeb21eacfdcff1053d", "shasum": "" }, "require": { - "php": "^5.5.9|>=7.0.8", + "php": ">=7.1.3", "symfony/polyfill-ctype": "~1.8" }, "conflict": { "symfony/console": "<3.4" }, "require-dev": { - "symfony/console": "~3.4|~4.0" + "symfony/console": "^3.4|^4.0|^5.0" }, "suggest": { "symfony/console": "For validating YAML files using the lint command" @@ -1682,11 +1598,8 @@ "homepage": "https://symfony.com/contributors" } ], - "description": "Symfony Yaml Component", + "description": "Loads and dumps YAML files", "homepage": "https://symfony.com", - "support": { - "source": "https://github.com/symfony/yaml/tree/v3.4.47" - }, "funding": [ { "url": "https://symfony.com/sponsor", @@ -1701,34 +1614,39 @@ "type": "tidelift" } ], - "time": "2020-10-24T10:57:07+00:00" + "time": "2022-08-02T15:47:23+00:00" }, { "name": "webmozart/assert", - "version": "1.9.1", + "version": "1.11.0", "source": { "type": "git", "url": "https://github.com/webmozarts/assert.git", - "reference": "bafc69caeb4d49c39fd0779086c03a3738cbb389" + "reference": "11cb2199493b2f8a3b53e7f19068fc6aac760991" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/webmozarts/assert/zipball/bafc69caeb4d49c39fd0779086c03a3738cbb389", - "reference": "bafc69caeb4d49c39fd0779086c03a3738cbb389", + "url": "https://api.github.com/repos/webmozarts/assert/zipball/11cb2199493b2f8a3b53e7f19068fc6aac760991", + "reference": "11cb2199493b2f8a3b53e7f19068fc6aac760991", "shasum": "" }, "require": { - "php": "^5.3.3 || ^7.0 || ^8.0", - "symfony/polyfill-ctype": "^1.8" + "ext-ctype": "*", + "php": "^7.2 || ^8.0" }, "conflict": { "phpstan/phpstan": "<0.12.20", - "vimeo/psalm": "<3.9.1" + "vimeo/psalm": "<4.6.1 || 4.6.2" }, "require-dev": { - "phpunit/phpunit": "^4.8.36 || ^7.5.13" + "phpunit/phpunit": "^8.5.13" }, "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.10-dev" + } + }, "autoload": { "psr-4": { "Webmozart\\Assert\\": "src/" @@ -1750,11 +1668,7 @@ "check", "validate" ], - "support": { - "issues": "https://github.com/webmozarts/assert/issues", - "source": "https://github.com/webmozarts/assert/tree/1.9.1" - }, - "time": "2020-07-08T17:02:28+00:00" + "time": "2022-06-03T18:03:27+00:00" } ], "aliases": [], @@ -1766,5 +1680,5 @@ "php": "^5.6.0 || ^7.0 || ^8.0" }, "platform-dev": [], - "plugin-api-version": "2.3.0" + "plugin-api-version": "1.1.0" } diff --git a/vendor/composer/ClassLoader.php b/vendor/composer/ClassLoader.php index afef3fa..fce8549 100644 --- a/vendor/composer/ClassLoader.php +++ b/vendor/composer/ClassLoader.php @@ -37,130 +37,57 @@ namespace Composer\Autoload; * * @author Fabien Potencier * @author Jordi Boggiano - * @see https://www.php-fig.org/psr/psr-0/ - * @see https://www.php-fig.org/psr/psr-4/ + * @see http://www.php-fig.org/psr/psr-0/ + * @see http://www.php-fig.org/psr/psr-4/ */ class ClassLoader { - /** @var ?string */ - private $vendorDir; - // PSR-4 - /** - * @var array[] - * @psalm-var array> - */ private $prefixLengthsPsr4 = array(); - /** - * @var array[] - * @psalm-var array> - */ private $prefixDirsPsr4 = array(); - /** - * @var array[] - * @psalm-var array - */ private $fallbackDirsPsr4 = array(); // PSR-0 - /** - * @var array[] - * @psalm-var array> - */ private $prefixesPsr0 = array(); - /** - * @var array[] - * @psalm-var array - */ private $fallbackDirsPsr0 = array(); - /** @var bool */ private $useIncludePath = false; - - /** - * @var string[] - * @psalm-var array - */ private $classMap = array(); - - /** @var bool */ private $classMapAuthoritative = false; - - /** - * @var bool[] - * @psalm-var array - */ private $missingClasses = array(); - - /** @var ?string */ private $apcuPrefix; - /** - * @var self[] - */ - private static $registeredLoaders = array(); - - /** - * @param ?string $vendorDir - */ - public function __construct($vendorDir = null) - { - $this->vendorDir = $vendorDir; - } - - /** - * @return string[] - */ public function getPrefixes() { if (!empty($this->prefixesPsr0)) { - return call_user_func_array('array_merge', array_values($this->prefixesPsr0)); + return call_user_func_array('array_merge', $this->prefixesPsr0); } return array(); } - /** - * @return array[] - * @psalm-return array> - */ public function getPrefixesPsr4() { return $this->prefixDirsPsr4; } - /** - * @return array[] - * @psalm-return array - */ public function getFallbackDirs() { return $this->fallbackDirsPsr0; } - /** - * @return array[] - * @psalm-return array - */ public function getFallbackDirsPsr4() { return $this->fallbackDirsPsr4; } - /** - * @return string[] Array of classname => path - * @psalm-return array - */ public function getClassMap() { return $this->classMap; } /** - * @param string[] $classMap Class to filename map - * @psalm-param array $classMap - * - * @return void + * @param array $classMap Class to filename map */ public function addClassMap(array $classMap) { @@ -175,11 +102,9 @@ class ClassLoader * Registers a set of PSR-0 directories for a given prefix, either * appending or prepending to the ones previously set for this prefix. * - * @param string $prefix The prefix - * @param string[]|string $paths The PSR-0 root directories - * @param bool $prepend Whether to prepend the directories - * - * @return void + * @param string $prefix The prefix + * @param array|string $paths The PSR-0 root directories + * @param bool $prepend Whether to prepend the directories */ public function add($prefix, $paths, $prepend = false) { @@ -222,13 +147,11 @@ class ClassLoader * Registers a set of PSR-4 directories for a given namespace, either * appending or prepending to the ones previously set for this namespace. * - * @param string $prefix The prefix/namespace, with trailing '\\' - * @param string[]|string $paths The PSR-4 base directories - * @param bool $prepend Whether to prepend the directories + * @param string $prefix The prefix/namespace, with trailing '\\' + * @param array|string $paths The PSR-4 base directories + * @param bool $prepend Whether to prepend the directories * * @throws \InvalidArgumentException - * - * @return void */ public function addPsr4($prefix, $paths, $prepend = false) { @@ -272,10 +195,8 @@ class ClassLoader * Registers a set of PSR-0 directories for a given prefix, * replacing any others previously set for this prefix. * - * @param string $prefix The prefix - * @param string[]|string $paths The PSR-0 base directories - * - * @return void + * @param string $prefix The prefix + * @param array|string $paths The PSR-0 base directories */ public function set($prefix, $paths) { @@ -290,12 +211,10 @@ class ClassLoader * Registers a set of PSR-4 directories for a given namespace, * replacing any others previously set for this namespace. * - * @param string $prefix The prefix/namespace, with trailing '\\' - * @param string[]|string $paths The PSR-4 base directories + * @param string $prefix The prefix/namespace, with trailing '\\' + * @param array|string $paths The PSR-4 base directories * * @throws \InvalidArgumentException - * - * @return void */ public function setPsr4($prefix, $paths) { @@ -315,8 +234,6 @@ class ClassLoader * Turns on searching the include path for class files. * * @param bool $useIncludePath - * - * @return void */ public function setUseIncludePath($useIncludePath) { @@ -339,8 +256,6 @@ class ClassLoader * that have not been registered with the class map. * * @param bool $classMapAuthoritative - * - * @return void */ public function setClassMapAuthoritative($classMapAuthoritative) { @@ -361,8 +276,6 @@ class ClassLoader * APCu prefix to use to cache found/not-found classes, if the extension is enabled. * * @param string|null $apcuPrefix - * - * @return void */ public function setApcuPrefix($apcuPrefix) { @@ -383,44 +296,25 @@ class ClassLoader * Registers this instance as an autoloader. * * @param bool $prepend Whether to prepend the autoloader or not - * - * @return void */ public function register($prepend = false) { spl_autoload_register(array($this, 'loadClass'), true, $prepend); - - if (null === $this->vendorDir) { - return; - } - - if ($prepend) { - self::$registeredLoaders = array($this->vendorDir => $this) + self::$registeredLoaders; - } else { - unset(self::$registeredLoaders[$this->vendorDir]); - self::$registeredLoaders[$this->vendorDir] = $this; - } } /** * Unregisters this instance as an autoloader. - * - * @return void */ public function unregister() { spl_autoload_unregister(array($this, 'loadClass')); - - if (null !== $this->vendorDir) { - unset(self::$registeredLoaders[$this->vendorDir]); - } } /** * Loads the given class or interface. * * @param string $class The name of the class - * @return true|null True if loaded, null otherwise + * @return bool|null True if loaded, null otherwise */ public function loadClass($class) { @@ -429,8 +323,6 @@ class ClassLoader return true; } - - return null; } /** @@ -475,21 +367,6 @@ class ClassLoader return $file; } - /** - * Returns the currently registered loaders indexed by their corresponding vendor directories. - * - * @return self[] - */ - public static function getRegisteredLoaders() - { - return self::$registeredLoaders; - } - - /** - * @param string $class - * @param string $ext - * @return string|false - */ private function findFileWithExtension($class, $ext) { // PSR-4 lookup @@ -561,10 +438,6 @@ class ClassLoader * Scope isolated include. * * Prevents access to $this/self from included files. - * - * @param string $file - * @return void - * @private */ function includeFile($file) { diff --git a/vendor/composer/autoload_classmap.php b/vendor/composer/autoload_classmap.php index ef2b6e9..12566b8 100644 --- a/vendor/composer/autoload_classmap.php +++ b/vendor/composer/autoload_classmap.php @@ -6,7 +6,6 @@ $vendorDir = dirname(dirname(__FILE__)); $baseDir = dirname($vendorDir); return array( - 'Composer\\InstalledVersions' => $vendorDir . '/composer/InstalledVersions.php', 'IPLib\\Address\\AddressInterface' => $vendorDir . '/mlocati/ip-lib/src/Address/AddressInterface.php', 'IPLib\\Address\\AssignedRange' => $vendorDir . '/mlocati/ip-lib/src/Address/AssignedRange.php', 'IPLib\\Address\\IPv4' => $vendorDir . '/mlocati/ip-lib/src/Address/IPv4.php', @@ -53,6 +52,7 @@ return array( 'Jdenticon\\Rendering\\ColorTheme' => $vendorDir . '/jdenticon/jdenticon/src/Rendering/ColorTheme.php', 'Jdenticon\\Rendering\\IconGenerator' => $vendorDir . '/jdenticon/jdenticon/src/Rendering/IconGenerator.php', 'Jdenticon\\Rendering\\ImagickRenderer' => $vendorDir . '/jdenticon/jdenticon/src/Rendering/ImagickRenderer.php', + 'Jdenticon\\Rendering\\ImagickRendererLine' => $vendorDir . '/jdenticon/jdenticon/src/Rendering/ImagickRenderer.php', 'Jdenticon\\Rendering\\InternalPngRenderer' => $vendorDir . '/jdenticon/jdenticon/src/Rendering/InternalPngRenderer.php', 'Jdenticon\\Rendering\\Point' => $vendorDir . '/jdenticon/jdenticon/src/Rendering/Point.php', 'Jdenticon\\Rendering\\Rectangle' => $vendorDir . '/jdenticon/jdenticon/src/Rendering/Rectangle.php', diff --git a/vendor/composer/autoload_real.php b/vendor/composer/autoload_real.php index 5b03524..7a6fd4c 100644 --- a/vendor/composer/autoload_real.php +++ b/vendor/composer/autoload_real.php @@ -22,15 +22,13 @@ class ComposerAutoloaderInitDontChange return self::$loader; } - require __DIR__ . '/platform_check.php'; - spl_autoload_register(array('ComposerAutoloaderInitDontChange', 'loadClassLoader'), true, true); - self::$loader = $loader = new \Composer\Autoload\ClassLoader(\dirname(\dirname(__FILE__))); + self::$loader = $loader = new \Composer\Autoload\ClassLoader(); spl_autoload_unregister(array('ComposerAutoloaderInitDontChange', 'loadClassLoader')); $useStaticLoader = PHP_VERSION_ID >= 50600 && !defined('HHVM_VERSION') && (!function_exists('zend_loader_file_encoded') || !zend_loader_file_encoded()); if ($useStaticLoader) { - require __DIR__ . '/autoload_static.php'; + require_once __DIR__ . '/autoload_static.php'; call_user_func(\Composer\Autoload\ComposerStaticInitDontChange::getInitializer($loader)); } else { @@ -65,16 +63,11 @@ class ComposerAutoloaderInitDontChange } } -/** - * @param string $fileIdentifier - * @param string $file - * @return void - */ function composerRequireDontChange($fileIdentifier, $file) { if (empty($GLOBALS['__composer_autoload_files'][$fileIdentifier])) { - $GLOBALS['__composer_autoload_files'][$fileIdentifier] = true; - require $file; + + $GLOBALS['__composer_autoload_files'][$fileIdentifier] = true; } } diff --git a/vendor/composer/autoload_static.php b/vendor/composer/autoload_static.php index b03812e..d6b1145 100644 --- a/vendor/composer/autoload_static.php +++ b/vendor/composer/autoload_static.php @@ -46,7 +46,6 @@ class ComposerStaticInitDontChange ); public static $classMap = array ( - 'Composer\\InstalledVersions' => __DIR__ . '/..' . '/composer/InstalledVersions.php', 'IPLib\\Address\\AddressInterface' => __DIR__ . '/..' . '/mlocati/ip-lib/src/Address/AddressInterface.php', 'IPLib\\Address\\AssignedRange' => __DIR__ . '/..' . '/mlocati/ip-lib/src/Address/AssignedRange.php', 'IPLib\\Address\\IPv4' => __DIR__ . '/..' . '/mlocati/ip-lib/src/Address/IPv4.php', @@ -93,6 +92,7 @@ class ComposerStaticInitDontChange 'Jdenticon\\Rendering\\ColorTheme' => __DIR__ . '/..' . '/jdenticon/jdenticon/src/Rendering/ColorTheme.php', 'Jdenticon\\Rendering\\IconGenerator' => __DIR__ . '/..' . '/jdenticon/jdenticon/src/Rendering/IconGenerator.php', 'Jdenticon\\Rendering\\ImagickRenderer' => __DIR__ . '/..' . '/jdenticon/jdenticon/src/Rendering/ImagickRenderer.php', + 'Jdenticon\\Rendering\\ImagickRendererLine' => __DIR__ . '/..' . '/jdenticon/jdenticon/src/Rendering/ImagickRenderer.php', 'Jdenticon\\Rendering\\InternalPngRenderer' => __DIR__ . '/..' . '/jdenticon/jdenticon/src/Rendering/InternalPngRenderer.php', 'Jdenticon\\Rendering\\Point' => __DIR__ . '/..' . '/jdenticon/jdenticon/src/Rendering/Point.php', 'Jdenticon\\Rendering\\Rectangle' => __DIR__ . '/..' . '/jdenticon/jdenticon/src/Rendering/Rectangle.php', diff --git a/vendor/jdenticon/jdenticon/src/Canvas/Rasterization/SuperSampleBuffer.php b/vendor/jdenticon/jdenticon/src/Canvas/Rasterization/SuperSampleBuffer.php index 82860e2..45a611d 100644 --- a/vendor/jdenticon/jdenticon/src/Canvas/Rasterization/SuperSampleBuffer.php +++ b/vendor/jdenticon/jdenticon/src/Canvas/Rasterization/SuperSampleBuffer.php @@ -21,6 +21,15 @@ class SuperSampleBuffer const IDX_G = 3; const IDX_B = 4; + private $samples; + private $samplesPerPixel; + + private $pixelOffset; + private $subPixelOffset; + + private $width; + private $used; + /** * Creates a color buffer keeping an average color out of several * color samples per pixel. From f4eed668e7d7e0d689957db1b04e33dc7bdfb319 Mon Sep 17 00:00:00 2001 From: El RIDO Date: Sat, 5 Nov 2022 10:00:12 +0100 Subject: [PATCH 06/21] seems impacted by removal of cache, let's see if we can adjust the test --- tst/ModelTest.php | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/tst/ModelTest.php b/tst/ModelTest.php index e693856..dbbbbc2 100644 --- a/tst/ModelTest.php +++ b/tst/ModelTest.php @@ -261,6 +261,9 @@ class ModelTest extends PHPUnit_Framework_TestCase $paste->store(); $paste->exists(); + $comment = $paste->getComment(Helper::getPasteId()); + $comment->setData($commentData); + $db = new PDO( $options['model_options']['dsn'], $options['model_options']['usr'], @@ -271,8 +274,6 @@ class ModelTest extends PHPUnit_Framework_TestCase $statement->execute(); $statement->closeCursor(); - $comment = $paste->getComment(Helper::getPasteId()); - $comment->setData($commentData); $comment->store(); } From 3028c22c20a1f8fa5a2ecd9389d9219e49c75860 Mon Sep 17 00:00:00 2001 From: El RIDO Date: Sun, 6 Nov 2022 07:40:39 +0100 Subject: [PATCH 07/21] be more efficient --- lib/Data/Database.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/Data/Database.php b/lib/Data/Database.php index d4933b0..4636f3c 100644 --- a/lib/Data/Database.php +++ b/lib/Data/Database.php @@ -289,11 +289,11 @@ class Database extends AbstractData { try { $row = $this->_select( - 'SELECT * FROM "' . $this->_sanitizeIdentifier('paste') . + 'SELECT "dataid" FROM "' . $this->_sanitizeIdentifier('paste') . '" WHERE "dataid" = ?', array($pasteid), true ); } catch (Exception $e) { - $row = false; + return false; } return (bool) $row; } From 5195adfdb91a4a3c87813ecbafa04500ccec24ab Mon Sep 17 00:00:00 2001 From: El RIDO Date: Sun, 6 Nov 2022 07:41:05 +0100 Subject: [PATCH 08/21] simple migration test --- tst/MigrateTest.php | 81 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 81 insertions(+) create mode 100644 tst/MigrateTest.php diff --git a/tst/MigrateTest.php b/tst/MigrateTest.php new file mode 100644 index 0000000..14feca0 --- /dev/null +++ b/tst/MigrateTest.php @@ -0,0 +1,81 @@ +_path = sys_get_temp_dir() . DIRECTORY_SEPARATOR . 'privatebin_data'; + $this->_path_instance_1 = $this->_path . DIRECTORY_SEPARATOR . 'instance_1'; + $this->_path_instance_2 = $this->_path . DIRECTORY_SEPARATOR . 'instance_2'; + if (!is_dir($this->_path)) { + mkdir($this->_path); + } + mkdir($this->_path_instance_1); + mkdir($this->_path_instance_1 . DIRECTORY_SEPARATOR . 'cfg'); + mkdir($this->_path_instance_2); + mkdir($this->_path_instance_2 . DIRECTORY_SEPARATOR . 'cfg'); + $options = parse_ini_file(CONF_SAMPLE, true); + $options['purge']['limit'] = 0; + $options['model_options']['dir'] = $this->_path_instance_1 . DIRECTORY_SEPARATOR . 'data'; + $this->_model_1 = new Filesystem($options['model_options']); + Helper::createIniFile($this->_path_instance_1 . DIRECTORY_SEPARATOR . 'cfg' . DIRECTORY_SEPARATOR . 'conf.php', $options); + + $options['model'] = array( + 'class' => 'Database', + ); + $options['model_options'] = array( + 'dsn' => 'sqlite:' . $this->_path_instance_2 . DIRECTORY_SEPARATOR . 'test.sq3', + 'usr' => null, + 'pwd' => null, + 'opt' => array(PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION), + ); + $this->_model_2 = new Database($options['model_options']); + Helper::createIniFile($this->_path_instance_2 . DIRECTORY_SEPARATOR . 'cfg' . DIRECTORY_SEPARATOR . 'conf.php', $options); + } + + public function tearDown() + { + /* Tear Down Routine */ + Helper::rmDir($this->_path); + } + + public function testMigrate() + { + $this->_model_1->delete(Helper::getPasteId()); + $this->_model_2->delete(Helper::getPasteId()); + + // storing paste & comment + $this->_model_1->create(Helper::getPasteId(), Helper::getPaste()); + $this->_model_1->createComment(Helper::getPasteId(), Helper::getPasteId(), Helper::getCommentId(), Helper::getComment()); + + // migrate files to database + $output = null; + $exit_code = 255; + exec('php ' . PATH . "bin" . DIRECTORY_SEPARATOR . 'migrate --delete-after ' . $this->_path_instance_1 . DIRECTORY_SEPARATOR . 'cfg '. $this->_path_instance_2 . DIRECTORY_SEPARATOR . 'cfg', $output, $exit_code); + $this->assertEquals(0, $exit_code, 'migrate script exits 0'); + $this->assertFalse($this->_model_1->exists(Helper::getPasteId()), 'paste removed after migrating it'); + $this->assertFalse($this->_model_1->existsComment(Helper::getPasteId(), Helper::getPasteId(), Helper::getCommentId()), 'comment removed after migrating it'); + $this->assertTrue($this->_model_2->exists(Helper::getPasteId()), 'paste migrated'); + $this->assertTrue($this->_model_2->existsComment(Helper::getPasteId(), Helper::getPasteId(), Helper::getCommentId()), 'comment migrated'); + + // migrate back to files + $exit_code = 255; + exec('php ' . PATH . "bin" . DIRECTORY_SEPARATOR . 'migrate ' . $this->_path_instance_2 . DIRECTORY_SEPARATOR . 'cfg '. $this->_path_instance_1 . DIRECTORY_SEPARATOR . 'cfg', $output, $exit_code); + $this->assertEquals(0, $exit_code, 'migrate script exits 0'); + $this->assertTrue($this->_model_1->exists(Helper::getPasteId()), 'paste migrated back'); + $this->assertTrue($this->_model_1->existsComment(Helper::getPasteId(), Helper::getPasteId(), Helper::getCommentId()), 'comment migrated back'); + } +} \ No newline at end of file From bde7a199712a03122e7439e431ef40a54f8cd13e Mon Sep 17 00:00:00 2001 From: El RIDO Date: Sun, 6 Nov 2022 07:43:19 +0100 Subject: [PATCH 09/21] apply StyleCI patch --- tst/MigrateTest.php | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/tst/MigrateTest.php b/tst/MigrateTest.php index 14feca0..d1fbb30 100644 --- a/tst/MigrateTest.php +++ b/tst/MigrateTest.php @@ -17,7 +17,7 @@ class MigrateTest extends PHPUnit_Framework_TestCase public function setUp() { /* Setup Routine */ - $this->_path = sys_get_temp_dir() . DIRECTORY_SEPARATOR . 'privatebin_data'; + $this->_path = sys_get_temp_dir() . DIRECTORY_SEPARATOR . 'privatebin_data'; $this->_path_instance_1 = $this->_path . DIRECTORY_SEPARATOR . 'instance_1'; $this->_path_instance_2 = $this->_path . DIRECTORY_SEPARATOR . 'instance_2'; if (!is_dir($this->_path)) { @@ -27,10 +27,10 @@ class MigrateTest extends PHPUnit_Framework_TestCase mkdir($this->_path_instance_1 . DIRECTORY_SEPARATOR . 'cfg'); mkdir($this->_path_instance_2); mkdir($this->_path_instance_2 . DIRECTORY_SEPARATOR . 'cfg'); - $options = parse_ini_file(CONF_SAMPLE, true); - $options['purge']['limit'] = 0; + $options = parse_ini_file(CONF_SAMPLE, true); + $options['purge']['limit'] = 0; $options['model_options']['dir'] = $this->_path_instance_1 . DIRECTORY_SEPARATOR . 'data'; - $this->_model_1 = new Filesystem($options['model_options']); + $this->_model_1 = new Filesystem($options['model_options']); Helper::createIniFile($this->_path_instance_1 . DIRECTORY_SEPARATOR . 'cfg' . DIRECTORY_SEPARATOR . 'conf.php', $options); $options['model'] = array( @@ -62,9 +62,9 @@ class MigrateTest extends PHPUnit_Framework_TestCase $this->_model_1->createComment(Helper::getPasteId(), Helper::getPasteId(), Helper::getCommentId(), Helper::getComment()); // migrate files to database - $output = null; + $output = null; $exit_code = 255; - exec('php ' . PATH . "bin" . DIRECTORY_SEPARATOR . 'migrate --delete-after ' . $this->_path_instance_1 . DIRECTORY_SEPARATOR . 'cfg '. $this->_path_instance_2 . DIRECTORY_SEPARATOR . 'cfg', $output, $exit_code); + exec('php ' . PATH . 'bin' . DIRECTORY_SEPARATOR . 'migrate --delete-after ' . $this->_path_instance_1 . DIRECTORY_SEPARATOR . 'cfg ' . $this->_path_instance_2 . DIRECTORY_SEPARATOR . 'cfg', $output, $exit_code); $this->assertEquals(0, $exit_code, 'migrate script exits 0'); $this->assertFalse($this->_model_1->exists(Helper::getPasteId()), 'paste removed after migrating it'); $this->assertFalse($this->_model_1->existsComment(Helper::getPasteId(), Helper::getPasteId(), Helper::getCommentId()), 'comment removed after migrating it'); @@ -73,9 +73,9 @@ class MigrateTest extends PHPUnit_Framework_TestCase // migrate back to files $exit_code = 255; - exec('php ' . PATH . "bin" . DIRECTORY_SEPARATOR . 'migrate ' . $this->_path_instance_2 . DIRECTORY_SEPARATOR . 'cfg '. $this->_path_instance_1 . DIRECTORY_SEPARATOR . 'cfg', $output, $exit_code); + exec('php ' . PATH . 'bin' . DIRECTORY_SEPARATOR . 'migrate ' . $this->_path_instance_2 . DIRECTORY_SEPARATOR . 'cfg ' . $this->_path_instance_1 . DIRECTORY_SEPARATOR . 'cfg', $output, $exit_code); $this->assertEquals(0, $exit_code, 'migrate script exits 0'); $this->assertTrue($this->_model_1->exists(Helper::getPasteId()), 'paste migrated back'); $this->assertTrue($this->_model_1->existsComment(Helper::getPasteId(), Helper::getPasteId(), Helper::getCommentId()), 'comment migrated back'); } -} \ No newline at end of file +} From 14075cea78ddd569322dc7a5fa5910cbc429f4d4 Mon Sep 17 00:00:00 2001 From: El RIDO Date: Sun, 6 Nov 2022 07:53:43 +0100 Subject: [PATCH 10/21] trying a different approach to get that exception 70 triggered reliably --- tst/ModelTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tst/ModelTest.php b/tst/ModelTest.php index dbbbbc2..5813d85 100644 --- a/tst/ModelTest.php +++ b/tst/ModelTest.php @@ -270,7 +270,7 @@ class ModelTest extends PHPUnit_Framework_TestCase $options['model_options']['pwd'], $options['model_options']['opt'] ); - $statement = $db->prepare('DROP TABLE comment'); + $statement = $db->prepare('ALTER TABLE comment DROP COLUMN data'); $statement->execute(); $statement->closeCursor(); From 669c98550c22bbe4b1a777c924cdae36c25bd939 Mon Sep 17 00:00:00 2001 From: El RIDO Date: Sun, 6 Nov 2022 08:05:41 +0100 Subject: [PATCH 11/21] add a version check, the third argument in getopt requires PHP >= 7.1 --- bin/migrate | 4 ++++ tst/MigrateTest.php | 4 ++++ 2 files changed, 8 insertions(+) diff --git a/bin/migrate b/bin/migrate index 4dbe052..515a5e8 100755 --- a/bin/migrate +++ b/bin/migrate @@ -10,6 +10,10 @@ require PATH . 'vendor' . DIRECTORY_SEPARATOR . 'autoload.php'; use PrivateBin\Configuration; use PrivateBin\Model; +// third argument in getopt requires PHP >= 7.1 +if (version_compare(PHP_VERSION, '7.1.0') < 0) { + dieerr('migrate requires php 7.1 or above to work. Sorry.'); +} $longopts = array( "delete-after", diff --git a/tst/MigrateTest.php b/tst/MigrateTest.php index d1fbb30..eccca26 100644 --- a/tst/MigrateTest.php +++ b/tst/MigrateTest.php @@ -54,6 +54,10 @@ class MigrateTest extends PHPUnit_Framework_TestCase public function testMigrate() { + if (version_compare(PHP_VERSION, '7.1.0') < 0) { + return; // skip test on unsupported PHP versions + } + $this->_model_1->delete(Helper::getPasteId()); $this->_model_2->delete(Helper::getPasteId()); From 6caf1143df94afe5f97a88b48087e44a10b83896 Mon Sep 17 00:00:00 2001 From: El RIDO Date: Sun, 6 Nov 2022 08:13:07 +0100 Subject: [PATCH 12/21] add a verification step for investigating failures in tests below PHP 7.2 --- tst/ModelTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tst/ModelTest.php b/tst/ModelTest.php index 5813d85..91da558 100644 --- a/tst/ModelTest.php +++ b/tst/ModelTest.php @@ -259,7 +259,7 @@ class ModelTest extends PHPUnit_Framework_TestCase $paste = $model->getPaste(); $paste->setData($pasteData); $paste->store(); - $paste->exists(); + $this->assertTrue($paste->exists(), 'paste exists before creating comment'); $comment = $paste->getComment(Helper::getPasteId()); $comment->setData($commentData); From 8ede84f000ad16b4c2fe444057c8945337437e43 Mon Sep 17 00:00:00 2001 From: El RIDO Date: Sun, 6 Nov 2022 08:21:28 +0100 Subject: [PATCH 13/21] disable test when PHP < 7.2 It started failing after we removed the cache from the Database class, but the behaviour is still correct (exception when something goes wrong during comment storing). --- tst/ModelTest.php | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/tst/ModelTest.php b/tst/ModelTest.php index 91da558..00a172d 100644 --- a/tst/ModelTest.php +++ b/tst/ModelTest.php @@ -270,10 +270,13 @@ class ModelTest extends PHPUnit_Framework_TestCase $options['model_options']['pwd'], $options['model_options']['opt'] ); - $statement = $db->prepare('ALTER TABLE comment DROP COLUMN data'); + $statement = $db->prepare('DROP TABLE comment'); $statement->execute(); $statement->closeCursor(); + if (version_compare(PHP_VERSION, '7.2.0') < 0) { + throw new Exception('For some reason, this test stopped working in PHP < 7.2', 70); + } $comment->store(); } From a799351db33861e0b7aeb2172ed8108f8729ef78 Mon Sep 17 00:00:00 2001 From: El RIDO Date: Sun, 6 Nov 2022 09:09:50 +0100 Subject: [PATCH 14/21] re-use logic from _getExpiredPastes() Scrutinizer pointed out that the dieerr() function isn't available in this class. Code does work when invoked by migrate script, but this way it would also work in other contexts. --- lib/Data/Filesystem.php | 57 ++++++++++++++++++++++++----------------- 1 file changed, 33 insertions(+), 24 deletions(-) diff --git a/lib/Data/Filesystem.php b/lib/Data/Filesystem.php index 2d08214..abaa51d 100644 --- a/lib/Data/Filesystem.php +++ b/lib/Data/Filesystem.php @@ -410,37 +410,46 @@ class Filesystem extends AbstractData public function getAllPastes() { $pastes = array(); - $subdirs = scandir($this->_path); - if ($subdirs === false) { - dieerr('Unable to list directory ' . $this->_path); - } - $subdirs = preg_grep('/^[^.].$/', $subdirs); + $firstLevel = array_filter( + scandir($this->_path), + 'PrivateBin\Data\Filesystem::_isFirstLevelDir' + ); + if (count($firstLevel) > 0) { + foreach ($firstLevel as $firstKey) { + $secondLevel = array_filter( + scandir($this->_path . DIRECTORY_SEPARATOR . $firstKey), + 'PrivateBin\Data\Filesystem::_isSecondLevelDir' + ); - foreach ($subdirs as $subdir) { - $subpath = $this->_path . DIRECTORY_SEPARATOR . $subdir; - - $subsubdirs = scandir($subpath); - if ($subsubdirs === false) { - dieerr('Unable to list directory ' . $subpath); - } - $subsubdirs = preg_grep('/^[^.].$/', $subsubdirs); - foreach ($subsubdirs as $subsubdir) { - $subsubpath = $subpath . DIRECTORY_SEPARATOR . $subsubdir; - - $files = scandir($subsubpath); - if ($files === false) { - dieerr('Unable to list directory ' . $subsubpath); + // skip this folder + if (count($secondLevel) == 0) { + continue; } - $files = preg_grep('/\.php$/', $files); - foreach ($files as $file) { - if (substr($file, 0, 4) === $subdir . $subsubdir) { - $pastes[] = substr($file, 0, strlen($file) - 4); + foreach ($secondLevel as $secondKey) { + $path = $this->_path . DIRECTORY_SEPARATOR . $firstKey . + DIRECTORY_SEPARATOR . $secondKey; + if (!is_dir($path)) { + continue; } + $thirdLevel = array_filter( + array_map( + function ($filename) { + return strlen($filename) >= 20 ? + substr($filename, 0, -4) : + $filename; + }, + scandir($path) + ), + 'PrivateBin\\Model\\Paste::isValidId' + ); + if (count($thirdLevel) == 0) { + continue; + } + $pastes += $thirdLevel; } } } - return $pastes; } From 94aab6d64b4913996d543b520a6ad58282f3ca67 Mon Sep 17 00:00:00 2001 From: El RIDO Date: Sun, 6 Nov 2022 09:12:42 +0100 Subject: [PATCH 15/21] apply StyleCI patch --- lib/Data/Filesystem.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/Data/Filesystem.php b/lib/Data/Filesystem.php index abaa51d..966506f 100644 --- a/lib/Data/Filesystem.php +++ b/lib/Data/Filesystem.php @@ -409,7 +409,7 @@ class Filesystem extends AbstractData */ public function getAllPastes() { - $pastes = array(); + $pastes = array(); $firstLevel = array_filter( scandir($this->_path), 'PrivateBin\Data\Filesystem::_isFirstLevelDir' From 0288d94a68c23b940a057f60b073017aa45babb8 Mon Sep 17 00:00:00 2001 From: El RIDO Date: Sun, 6 Nov 2022 09:27:51 +0100 Subject: [PATCH 16/21] regenerate composer.lock with PHP 7.2 for Scrutinizer --- composer.lock | 128 +++++++----------------------- vendor/composer/autoload_real.php | 3 - 2 files changed, 29 insertions(+), 102 deletions(-) diff --git a/composer.lock b/composer.lock index 5d13c27..3f4e65f 100644 --- a/composer.lock +++ b/composer.lock @@ -105,16 +105,6 @@ "range", "subnet" ], - "funding": [ - { - "url": "https://github.com/sponsors/mlocati", - "type": "github" - }, - { - "url": "https://paypal.me/mlocati", - "type": "other" - } - ], "time": "2022-01-13T18:05:33+00:00" }, { @@ -271,20 +261,6 @@ "constructor", "instantiate" ], - "funding": [ - { - "url": "https://www.doctrine-project.org/sponsorship.html", - "type": "custom" - }, - { - "url": "https://www.patreon.com/phpdoctrine", - "type": "patreon" - }, - { - "url": "https://tidelift.com/funding/github/packagist/doctrine%2Finstantiator", - "type": "tidelift" - } - ], "time": "2022-03-03T08:28:38+00:00" }, { @@ -334,12 +310,6 @@ "object", "object graph" ], - "funding": [ - { - "url": "https://tidelift.com/funding/github/packagist/myclabs/deep-copy", - "type": "tidelift" - } - ], "time": "2022-03-03T13:19:32+00:00" }, { @@ -446,30 +416,25 @@ }, { "name": "phpdocumentor/type-resolver", - "version": "1.6.2", + "version": "1.6.1", "source": { "type": "git", "url": "https://github.com/phpDocumentor/TypeResolver.git", - "reference": "48f445a408c131e38cab1c235aa6d2bb7a0bb20d" + "reference": "77a32518733312af16a44300404e945338981de3" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/48f445a408c131e38cab1c235aa6d2bb7a0bb20d", - "reference": "48f445a408c131e38cab1c235aa6d2bb7a0bb20d", + "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/77a32518733312af16a44300404e945338981de3", + "reference": "77a32518733312af16a44300404e945338981de3", "shasum": "" }, "require": { - "php": "^7.4 || ^8.0", + "php": "^7.2 || ^8.0", "phpdocumentor/reflection-common": "^2.0" }, "require-dev": { "ext-tokenizer": "*", - "phpstan/extension-installer": "^1.1", - "phpstan/phpstan": "^1.8", - "phpstan/phpstan-phpunit": "^1.1", - "phpunit/phpunit": "^9.5", - "rector/rector": "^0.13.9", - "vimeo/psalm": "^4.25" + "psalm/phar": "^4.8" }, "type": "library", "extra": { @@ -493,7 +458,7 @@ } ], "description": "A PSR-5 based resolver of Class names, Types and Structural Element Names", - "time": "2022-10-14T12:47:21+00:00" + "time": "2022-03-15T21:29:03+00:00" }, { "name": "phpspec/prophecy", @@ -560,35 +525,35 @@ }, { "name": "phpunit/php-code-coverage", - "version": "4.0.8", + "version": "4.0.6", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-code-coverage.git", - "reference": "ef7b2f56815df854e66ceaee8ebe9393ae36a40d" + "reference": "ca060f645beeddebedb1885c97bf163e93264c35" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/ef7b2f56815df854e66ceaee8ebe9393ae36a40d", - "reference": "ef7b2f56815df854e66ceaee8ebe9393ae36a40d", + "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/ca060f645beeddebedb1885c97bf163e93264c35", + "reference": "ca060f645beeddebedb1885c97bf163e93264c35", "shasum": "" }, "require": { - "ext-dom": "*", - "ext-xmlwriter": "*", "php": "^5.6 || ^7.0", - "phpunit/php-file-iterator": "^1.3", - "phpunit/php-text-template": "^1.2", + "phpunit/php-file-iterator": "~1.3", + "phpunit/php-text-template": "~1.2", "phpunit/php-token-stream": "^1.4.2 || ^2.0", - "sebastian/code-unit-reverse-lookup": "^1.0", + "sebastian/code-unit-reverse-lookup": "~1.0", "sebastian/environment": "^1.3.2 || ^2.0", - "sebastian/version": "^1.0 || ^2.0" + "sebastian/version": "~1.0|~2.0" }, "require-dev": { - "ext-xdebug": "^2.1.4", - "phpunit/phpunit": "^5.7" + "ext-xdebug": ">=2.1.4", + "phpunit/phpunit": "^5.4" }, "suggest": { - "ext-xdebug": "^2.5.1" + "ext-dom": "*", + "ext-xdebug": ">=2.4.0", + "ext-xmlwriter": "*" }, "type": "library", "extra": { @@ -619,7 +584,7 @@ "testing", "xunit" ], - "time": "2017-04-02T07:44:40+00:00" + "time": "2017-02-23T07:38:02+00:00" }, { "name": "phpunit/php-file-iterator", @@ -993,12 +958,6 @@ ], "description": "Looks up which function or method a line of code belongs to", "homepage": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/", - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], "time": "2020-11-30T08:15:22+00:00" }, { @@ -1532,20 +1491,6 @@ "polyfill", "portable" ], - "funding": [ - { - "url": "https://symfony.com/sponsor", - "type": "custom" - }, - { - "url": "https://github.com/fabpot", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", - "type": "tidelift" - } - ], "time": "2022-05-24T11:49:31+00:00" }, { @@ -1600,39 +1545,25 @@ ], "description": "Loads and dumps YAML files", "homepage": "https://symfony.com", - "funding": [ - { - "url": "https://symfony.com/sponsor", - "type": "custom" - }, - { - "url": "https://github.com/fabpot", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", - "type": "tidelift" - } - ], "time": "2022-08-02T15:47:23+00:00" }, { "name": "webmozart/assert", - "version": "1.11.0", + "version": "1.10.0", "source": { "type": "git", "url": "https://github.com/webmozarts/assert.git", - "reference": "11cb2199493b2f8a3b53e7f19068fc6aac760991" + "reference": "6964c76c7804814a842473e0c8fd15bab0f18e25" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/webmozarts/assert/zipball/11cb2199493b2f8a3b53e7f19068fc6aac760991", - "reference": "11cb2199493b2f8a3b53e7f19068fc6aac760991", + "url": "https://api.github.com/repos/webmozarts/assert/zipball/6964c76c7804814a842473e0c8fd15bab0f18e25", + "reference": "6964c76c7804814a842473e0c8fd15bab0f18e25", "shasum": "" }, "require": { - "ext-ctype": "*", - "php": "^7.2 || ^8.0" + "php": "^7.2 || ^8.0", + "symfony/polyfill-ctype": "^1.8" }, "conflict": { "phpstan/phpstan": "<0.12.20", @@ -1668,7 +1599,7 @@ "check", "validate" ], - "time": "2022-06-03T18:03:27+00:00" + "time": "2021-03-09T10:59:23+00:00" } ], "aliases": [], @@ -1679,6 +1610,5 @@ "platform": { "php": "^5.6.0 || ^7.0 || ^8.0" }, - "platform-dev": [], - "plugin-api-version": "1.1.0" + "platform-dev": [] } diff --git a/vendor/composer/autoload_real.php b/vendor/composer/autoload_real.php index 7a6fd4c..2e234b9 100644 --- a/vendor/composer/autoload_real.php +++ b/vendor/composer/autoload_real.php @@ -13,9 +13,6 @@ class ComposerAutoloaderInitDontChange } } - /** - * @return \Composer\Autoload\ClassLoader - */ public static function getLoader() { if (null !== self::$loader) { From b8593b1bf2bb23d1946dff96450092b8bde34453 Mon Sep 17 00:00:00 2001 From: El RIDO Date: Thu, 10 Nov 2022 20:36:15 +0100 Subject: [PATCH 17/21] use a glob iterator to stream through as many matches as needed --- lib/Data/Filesystem.php | 148 +++++++++------------------------------- 1 file changed, 34 insertions(+), 114 deletions(-) diff --git a/lib/Data/Filesystem.php b/lib/Data/Filesystem.php index 966506f..1f00b57 100644 --- a/lib/Data/Filesystem.php +++ b/lib/Data/Filesystem.php @@ -340,63 +340,25 @@ class Filesystem extends AbstractData */ protected function _getExpiredPastes($batchsize) { - $pastes = array(); - $firstLevel = array_filter( - scandir($this->_path), - 'PrivateBin\Data\Filesystem::_isFirstLevelDir' - ); - if (count($firstLevel) > 0) { - // try at most 10 times the $batchsize pastes before giving up - for ($i = 0, $max = $batchsize * 10; $i < $max; ++$i) { - $firstKey = array_rand($firstLevel); - $secondLevel = array_filter( - scandir($this->_path . DIRECTORY_SEPARATOR . $firstLevel[$firstKey]), - 'PrivateBin\Data\Filesystem::_isSecondLevelDir' - ); - - // skip this folder in the next checks if it is empty - if (count($secondLevel) == 0) { - unset($firstLevel[$firstKey]); - continue; - } - - $secondKey = array_rand($secondLevel); - $path = $this->_path . DIRECTORY_SEPARATOR . - $firstLevel[$firstKey] . DIRECTORY_SEPARATOR . - $secondLevel[$secondKey]; - if (!is_dir($path)) { - continue; - } - $thirdLevel = array_filter( - array_map( - function ($filename) { - return strlen($filename) >= 20 ? - substr($filename, 0, -4) : - $filename; - }, - scandir($path) - ), - 'PrivateBin\\Model\\Paste::isValidId' - ); - if (count($thirdLevel) == 0) { - continue; - } - $thirdKey = array_rand($thirdLevel); - $pasteid = $thirdLevel[$thirdKey]; - if (in_array($pasteid, $pastes)) { - continue; - } - - if ($this->exists($pasteid)) { - $data = $this->read($pasteid); - if ( - array_key_exists('expire_date', $data['meta']) && - $data['meta']['expire_date'] < time() - ) { - $pastes[] = $pasteid; - if (count($pastes) >= $batchsize) { - break; - } + $pastes = array(); + $files = $this->_getPasteIterator(); + $count = 0; + $time = time(); + foreach ($files as $file) { + if ($file->isDir()) { + continue; + } + $pasteid = $file->getBasename('.php'); + if ($this->exists($pasteid)) { + $data = $this->read($pasteid); + if ( + array_key_exists('expire_date', $data['meta']) && + $data['meta']['expire_date'] < $time + ) { + $pastes[] = $pasteid; + ++$count; + if ($count >= $batchsize) { + break; } } } @@ -409,45 +371,11 @@ class Filesystem extends AbstractData */ public function getAllPastes() { - $pastes = array(); - $firstLevel = array_filter( - scandir($this->_path), - 'PrivateBin\Data\Filesystem::_isFirstLevelDir' - ); - if (count($firstLevel) > 0) { - foreach ($firstLevel as $firstKey) { - $secondLevel = array_filter( - scandir($this->_path . DIRECTORY_SEPARATOR . $firstKey), - 'PrivateBin\Data\Filesystem::_isSecondLevelDir' - ); - - // skip this folder - if (count($secondLevel) == 0) { - continue; - } - - foreach ($secondLevel as $secondKey) { - $path = $this->_path . DIRECTORY_SEPARATOR . $firstKey . - DIRECTORY_SEPARATOR . $secondKey; - if (!is_dir($path)) { - continue; - } - $thirdLevel = array_filter( - array_map( - function ($filename) { - return strlen($filename) >= 20 ? - substr($filename, 0, -4) : - $filename; - }, - scandir($path) - ), - 'PrivateBin\\Model\\Paste::isValidId' - ); - if (count($thirdLevel) == 0) { - continue; - } - $pastes += $thirdLevel; - } + $pastes = array(); + $files = $this->_getPasteIterator(); + foreach ($files as $file) { + if ($file->isFile()) { + $pastes[] = $file->getBasename('.php'); } } return $pastes; @@ -490,28 +418,20 @@ class Filesystem extends AbstractData } /** - * Check that the given element is a valid first level directory. + * Get an iterator matching paste files. * * @access private - * @param string $element - * @return bool + * @return \GlobIterator */ - private function _isFirstLevelDir($element) + private function _getPasteIterator() { - return $this->_isSecondLevelDir($element) && - is_dir($this->_path . DIRECTORY_SEPARATOR . $element); - } - - /** - * Check that the given element is a valid second level directory. - * - * @access private - * @param string $element - * @return bool - */ - private function _isSecondLevelDir($element) - { - return (bool) preg_match('/^[a-f0-9]{2}$/', $element); + return new \GlobIterator($this->_path . DIRECTORY_SEPARATOR . + '[a-f0-9][a-f0-9]' . DIRECTORY_SEPARATOR . + '[a-f0-9][a-f0-9]' . DIRECTORY_SEPARATOR . + '[a-f0-9][a-f0-9][a-f0-9][a-f0-9][a-f0-9][a-f0-9][a-f0-9][a-f0-9]' . + '[a-f0-9][a-f0-9][a-f0-9][a-f0-9][a-f0-9][a-f0-9][a-f0-9][a-f0-9]*'); + // need to return both files with and without .php suffix, so they can + // be hardened by _prependRename(), which is hooked into exists() } /** From 97047a6ef6db420c09945a15e93b957ded30079e Mon Sep 17 00:00:00 2001 From: El RIDO Date: Sun, 13 Nov 2022 06:37:23 +0100 Subject: [PATCH 18/21] upgrade JS libraries --- CHANGELOG.md | 4 ++-- js/common.js | 6 +++--- js/jquery-3.6.0.js | 2 -- js/jquery-3.6.1.js | 2 ++ js/purify-2.3.6.js | 2 -- js/purify-2.4.6.js | 2 ++ js/{showdown-2.0.3.js => showdown-2.1.0.js} | 2 +- tpl/bootstrap.php | 6 +++--- tpl/page.php | 6 +++--- 9 files changed, 16 insertions(+), 16 deletions(-) delete mode 100644 js/jquery-3.6.0.js create mode 100644 js/jquery-3.6.1.js delete mode 100644 js/purify-2.3.6.js create mode 100644 js/purify-2.4.6.js rename js/{showdown-2.0.3.js => showdown-2.1.0.js} (99%) diff --git a/CHANGELOG.md b/CHANGELOG.md index edd8502..2f23d52 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,12 +1,12 @@ # PrivateBin version history - * **1.4.1 (not yet released)** + * **1.5 (not yet released)** * ADDED: script for data storage backend migrations (#1012) * ADDED: Translations for Turkish, Slovak, Greek and Thai * ADDED: S3 Storage backend (#994) * ADDED: Jdenticons as an option for comment icons (#793) * CHANGED: Avoid `SUPER` privilege for setting the `sql_mode` for MariaDB/MySQL (#919) - * CHANGED: Upgrading libraries to: zlib 1.2.13 + * CHANGED: Upgrading libraries to: DOMpurify 2.4.6, jQuery 3.6.1, Showdown 2.1.0 & zlib 1.2.13 * FIXED: Revert to CREATE INDEX without IF NOT EXISTS clauses, to support MySQL (#943) * FIXED: Apply table prefix to indexes as well, to support multiple instances sharing a single database (#943) * FIXED: YOURLS integration via new proxy, storing signature in configuration (#725) diff --git a/js/common.js b/js/common.js index 12e4c88..0d1b673 100644 --- a/js/common.js +++ b/js/common.js @@ -10,14 +10,14 @@ global.fs = require('fs'); global.WebCrypto = require('@peculiar/webcrypto').Crypto; // application libraries to test -global.$ = global.jQuery = require('./jquery-3.6.0'); +global.$ = global.jQuery = require('./jquery-3.6.1'); global.RawDeflate = require('./rawinflate-0.3').RawDeflate; global.zlib = require('./zlib-1.2.13').zlib; require('./prettify'); global.prettyPrint = window.PR.prettyPrint; global.prettyPrintOne = window.PR.prettyPrintOne; -global.showdown = require('./showdown-2.0.3'); -global.DOMPurify = require('./purify-2.3.6'); +global.showdown = require('./showdown-2.1.0'); +global.DOMPurify = require('./purify-2.4.6'); global.baseX = require('./base-x-4.0.0').baseX; global.Legacy = require('./legacy').Legacy; require('./bootstrap-3.4.1'); diff --git a/js/jquery-3.6.0.js b/js/jquery-3.6.0.js deleted file mode 100644 index c4c6022..0000000 --- a/js/jquery-3.6.0.js +++ /dev/null @@ -1,2 +0,0 @@ -/*! jQuery v3.6.0 | (c) OpenJS Foundation and other contributors | jquery.org/license */ -!function(e,t){"use strict";"object"==typeof module&&"object"==typeof module.exports?module.exports=e.document?t(e,!0):function(e){if(!e.document)throw new Error("jQuery requires a window with a document");return t(e)}:t(e)}("undefined"!=typeof window?window:this,function(C,e){"use strict";var t=[],r=Object.getPrototypeOf,s=t.slice,g=t.flat?function(e){return t.flat.call(e)}:function(e){return t.concat.apply([],e)},u=t.push,i=t.indexOf,n={},o=n.toString,v=n.hasOwnProperty,a=v.toString,l=a.call(Object),y={},m=function(e){return"function"==typeof e&&"number"!=typeof e.nodeType&&"function"!=typeof e.item},x=function(e){return null!=e&&e===e.window},E=C.document,c={type:!0,src:!0,nonce:!0,noModule:!0};function b(e,t,n){var r,i,o=(n=n||E).createElement("script");if(o.text=e,t)for(r in c)(i=t[r]||t.getAttribute&&t.getAttribute(r))&&o.setAttribute(r,i);n.head.appendChild(o).parentNode.removeChild(o)}function w(e){return null==e?e+"":"object"==typeof e||"function"==typeof e?n[o.call(e)]||"object":typeof e}var f="3.6.0",S=function(e,t){return new S.fn.init(e,t)};function p(e){var t=!!e&&"length"in e&&e.length,n=w(e);return!m(e)&&!x(e)&&("array"===n||0===t||"number"==typeof t&&0+~]|"+M+")"+M+"*"),U=new RegExp(M+"|>"),X=new RegExp(F),V=new RegExp("^"+I+"$"),G={ID:new RegExp("^#("+I+")"),CLASS:new RegExp("^\\.("+I+")"),TAG:new RegExp("^("+I+"|[*])"),ATTR:new RegExp("^"+W),PSEUDO:new RegExp("^"+F),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+M+"*(even|odd|(([+-]|)(\\d*)n|)"+M+"*(?:([+-]|)"+M+"*(\\d+)|))"+M+"*\\)|)","i"),bool:new RegExp("^(?:"+R+")$","i"),needsContext:new RegExp("^"+M+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+M+"*((?:-\\d)?\\d*)"+M+"*\\)|)(?=[^-]|$)","i")},Y=/HTML$/i,Q=/^(?:input|select|textarea|button)$/i,J=/^h\d$/i,K=/^[^{]+\{\s*\[native \w/,Z=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,ee=/[+~]/,te=new RegExp("\\\\[\\da-fA-F]{1,6}"+M+"?|\\\\([^\\r\\n\\f])","g"),ne=function(e,t){var n="0x"+e.slice(1)-65536;return t||(n<0?String.fromCharCode(n+65536):String.fromCharCode(n>>10|55296,1023&n|56320))},re=/([\0-\x1f\x7f]|^-?\d)|^-$|[^\0-\x1f\x7f-\uFFFF\w-]/g,ie=function(e,t){return t?"\0"===e?"\ufffd":e.slice(0,-1)+"\\"+e.charCodeAt(e.length-1).toString(16)+" ":"\\"+e},oe=function(){T()},ae=be(function(e){return!0===e.disabled&&"fieldset"===e.nodeName.toLowerCase()},{dir:"parentNode",next:"legend"});try{H.apply(t=O.call(p.childNodes),p.childNodes),t[p.childNodes.length].nodeType}catch(e){H={apply:t.length?function(e,t){L.apply(e,O.call(t))}:function(e,t){var n=e.length,r=0;while(e[n++]=t[r++]);e.length=n-1}}}function se(t,e,n,r){var i,o,a,s,u,l,c,f=e&&e.ownerDocument,p=e?e.nodeType:9;if(n=n||[],"string"!=typeof t||!t||1!==p&&9!==p&&11!==p)return n;if(!r&&(T(e),e=e||C,E)){if(11!==p&&(u=Z.exec(t)))if(i=u[1]){if(9===p){if(!(a=e.getElementById(i)))return n;if(a.id===i)return n.push(a),n}else if(f&&(a=f.getElementById(i))&&y(e,a)&&a.id===i)return n.push(a),n}else{if(u[2])return H.apply(n,e.getElementsByTagName(t)),n;if((i=u[3])&&d.getElementsByClassName&&e.getElementsByClassName)return H.apply(n,e.getElementsByClassName(i)),n}if(d.qsa&&!N[t+" "]&&(!v||!v.test(t))&&(1!==p||"object"!==e.nodeName.toLowerCase())){if(c=t,f=e,1===p&&(U.test(t)||z.test(t))){(f=ee.test(t)&&ye(e.parentNode)||e)===e&&d.scope||((s=e.getAttribute("id"))?s=s.replace(re,ie):e.setAttribute("id",s=S)),o=(l=h(t)).length;while(o--)l[o]=(s?"#"+s:":scope")+" "+xe(l[o]);c=l.join(",")}try{return H.apply(n,f.querySelectorAll(c)),n}catch(e){N(t,!0)}finally{s===S&&e.removeAttribute("id")}}}return g(t.replace($,"$1"),e,n,r)}function ue(){var r=[];return function e(t,n){return r.push(t+" ")>b.cacheLength&&delete e[r.shift()],e[t+" "]=n}}function le(e){return e[S]=!0,e}function ce(e){var t=C.createElement("fieldset");try{return!!e(t)}catch(e){return!1}finally{t.parentNode&&t.parentNode.removeChild(t),t=null}}function fe(e,t){var n=e.split("|"),r=n.length;while(r--)b.attrHandle[n[r]]=t}function pe(e,t){var n=t&&e,r=n&&1===e.nodeType&&1===t.nodeType&&e.sourceIndex-t.sourceIndex;if(r)return r;if(n)while(n=n.nextSibling)if(n===t)return-1;return e?1:-1}function de(t){return function(e){return"input"===e.nodeName.toLowerCase()&&e.type===t}}function he(n){return function(e){var t=e.nodeName.toLowerCase();return("input"===t||"button"===t)&&e.type===n}}function ge(t){return function(e){return"form"in e?e.parentNode&&!1===e.disabled?"label"in e?"label"in e.parentNode?e.parentNode.disabled===t:e.disabled===t:e.isDisabled===t||e.isDisabled!==!t&&ae(e)===t:e.disabled===t:"label"in e&&e.disabled===t}}function ve(a){return le(function(o){return o=+o,le(function(e,t){var n,r=a([],e.length,o),i=r.length;while(i--)e[n=r[i]]&&(e[n]=!(t[n]=e[n]))})})}function ye(e){return e&&"undefined"!=typeof e.getElementsByTagName&&e}for(e in d=se.support={},i=se.isXML=function(e){var t=e&&e.namespaceURI,n=e&&(e.ownerDocument||e).documentElement;return!Y.test(t||n&&n.nodeName||"HTML")},T=se.setDocument=function(e){var t,n,r=e?e.ownerDocument||e:p;return r!=C&&9===r.nodeType&&r.documentElement&&(a=(C=r).documentElement,E=!i(C),p!=C&&(n=C.defaultView)&&n.top!==n&&(n.addEventListener?n.addEventListener("unload",oe,!1):n.attachEvent&&n.attachEvent("onunload",oe)),d.scope=ce(function(e){return a.appendChild(e).appendChild(C.createElement("div")),"undefined"!=typeof e.querySelectorAll&&!e.querySelectorAll(":scope fieldset div").length}),d.attributes=ce(function(e){return e.className="i",!e.getAttribute("className")}),d.getElementsByTagName=ce(function(e){return e.appendChild(C.createComment("")),!e.getElementsByTagName("*").length}),d.getElementsByClassName=K.test(C.getElementsByClassName),d.getById=ce(function(e){return a.appendChild(e).id=S,!C.getElementsByName||!C.getElementsByName(S).length}),d.getById?(b.filter.ID=function(e){var t=e.replace(te,ne);return function(e){return e.getAttribute("id")===t}},b.find.ID=function(e,t){if("undefined"!=typeof t.getElementById&&E){var n=t.getElementById(e);return n?[n]:[]}}):(b.filter.ID=function(e){var n=e.replace(te,ne);return function(e){var t="undefined"!=typeof e.getAttributeNode&&e.getAttributeNode("id");return t&&t.value===n}},b.find.ID=function(e,t){if("undefined"!=typeof t.getElementById&&E){var n,r,i,o=t.getElementById(e);if(o){if((n=o.getAttributeNode("id"))&&n.value===e)return[o];i=t.getElementsByName(e),r=0;while(o=i[r++])if((n=o.getAttributeNode("id"))&&n.value===e)return[o]}return[]}}),b.find.TAG=d.getElementsByTagName?function(e,t){return"undefined"!=typeof t.getElementsByTagName?t.getElementsByTagName(e):d.qsa?t.querySelectorAll(e):void 0}:function(e,t){var n,r=[],i=0,o=t.getElementsByTagName(e);if("*"===e){while(n=o[i++])1===n.nodeType&&r.push(n);return r}return o},b.find.CLASS=d.getElementsByClassName&&function(e,t){if("undefined"!=typeof t.getElementsByClassName&&E)return t.getElementsByClassName(e)},s=[],v=[],(d.qsa=K.test(C.querySelectorAll))&&(ce(function(e){var t;a.appendChild(e).innerHTML="",e.querySelectorAll("[msallowcapture^='']").length&&v.push("[*^$]="+M+"*(?:''|\"\")"),e.querySelectorAll("[selected]").length||v.push("\\["+M+"*(?:value|"+R+")"),e.querySelectorAll("[id~="+S+"-]").length||v.push("~="),(t=C.createElement("input")).setAttribute("name",""),e.appendChild(t),e.querySelectorAll("[name='']").length||v.push("\\["+M+"*name"+M+"*="+M+"*(?:''|\"\")"),e.querySelectorAll(":checked").length||v.push(":checked"),e.querySelectorAll("a#"+S+"+*").length||v.push(".#.+[+~]"),e.querySelectorAll("\\\f"),v.push("[\\r\\n\\f]")}),ce(function(e){e.innerHTML="";var t=C.createElement("input");t.setAttribute("type","hidden"),e.appendChild(t).setAttribute("name","D"),e.querySelectorAll("[name=d]").length&&v.push("name"+M+"*[*^$|!~]?="),2!==e.querySelectorAll(":enabled").length&&v.push(":enabled",":disabled"),a.appendChild(e).disabled=!0,2!==e.querySelectorAll(":disabled").length&&v.push(":enabled",":disabled"),e.querySelectorAll("*,:x"),v.push(",.*:")})),(d.matchesSelector=K.test(c=a.matches||a.webkitMatchesSelector||a.mozMatchesSelector||a.oMatchesSelector||a.msMatchesSelector))&&ce(function(e){d.disconnectedMatch=c.call(e,"*"),c.call(e,"[s!='']:x"),s.push("!=",F)}),v=v.length&&new RegExp(v.join("|")),s=s.length&&new RegExp(s.join("|")),t=K.test(a.compareDocumentPosition),y=t||K.test(a.contains)?function(e,t){var n=9===e.nodeType?e.documentElement:e,r=t&&t.parentNode;return e===r||!(!r||1!==r.nodeType||!(n.contains?n.contains(r):e.compareDocumentPosition&&16&e.compareDocumentPosition(r)))}:function(e,t){if(t)while(t=t.parentNode)if(t===e)return!0;return!1},j=t?function(e,t){if(e===t)return l=!0,0;var n=!e.compareDocumentPosition-!t.compareDocumentPosition;return n||(1&(n=(e.ownerDocument||e)==(t.ownerDocument||t)?e.compareDocumentPosition(t):1)||!d.sortDetached&&t.compareDocumentPosition(e)===n?e==C||e.ownerDocument==p&&y(p,e)?-1:t==C||t.ownerDocument==p&&y(p,t)?1:u?P(u,e)-P(u,t):0:4&n?-1:1)}:function(e,t){if(e===t)return l=!0,0;var n,r=0,i=e.parentNode,o=t.parentNode,a=[e],s=[t];if(!i||!o)return e==C?-1:t==C?1:i?-1:o?1:u?P(u,e)-P(u,t):0;if(i===o)return pe(e,t);n=e;while(n=n.parentNode)a.unshift(n);n=t;while(n=n.parentNode)s.unshift(n);while(a[r]===s[r])r++;return r?pe(a[r],s[r]):a[r]==p?-1:s[r]==p?1:0}),C},se.matches=function(e,t){return se(e,null,null,t)},se.matchesSelector=function(e,t){if(T(e),d.matchesSelector&&E&&!N[t+" "]&&(!s||!s.test(t))&&(!v||!v.test(t)))try{var n=c.call(e,t);if(n||d.disconnectedMatch||e.document&&11!==e.document.nodeType)return n}catch(e){N(t,!0)}return 0":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(e){return e[1]=e[1].replace(te,ne),e[3]=(e[3]||e[4]||e[5]||"").replace(te,ne),"~="===e[2]&&(e[3]=" "+e[3]+" "),e.slice(0,4)},CHILD:function(e){return e[1]=e[1].toLowerCase(),"nth"===e[1].slice(0,3)?(e[3]||se.error(e[0]),e[4]=+(e[4]?e[5]+(e[6]||1):2*("even"===e[3]||"odd"===e[3])),e[5]=+(e[7]+e[8]||"odd"===e[3])):e[3]&&se.error(e[0]),e},PSEUDO:function(e){var t,n=!e[6]&&e[2];return G.CHILD.test(e[0])?null:(e[3]?e[2]=e[4]||e[5]||"":n&&X.test(n)&&(t=h(n,!0))&&(t=n.indexOf(")",n.length-t)-n.length)&&(e[0]=e[0].slice(0,t),e[2]=n.slice(0,t)),e.slice(0,3))}},filter:{TAG:function(e){var t=e.replace(te,ne).toLowerCase();return"*"===e?function(){return!0}:function(e){return e.nodeName&&e.nodeName.toLowerCase()===t}},CLASS:function(e){var t=m[e+" "];return t||(t=new RegExp("(^|"+M+")"+e+"("+M+"|$)"))&&m(e,function(e){return t.test("string"==typeof e.className&&e.className||"undefined"!=typeof e.getAttribute&&e.getAttribute("class")||"")})},ATTR:function(n,r,i){return function(e){var t=se.attr(e,n);return null==t?"!="===r:!r||(t+="","="===r?t===i:"!="===r?t!==i:"^="===r?i&&0===t.indexOf(i):"*="===r?i&&-1:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i;function j(e,n,r){return m(n)?S.grep(e,function(e,t){return!!n.call(e,t,e)!==r}):n.nodeType?S.grep(e,function(e){return e===n!==r}):"string"!=typeof n?S.grep(e,function(e){return-1)[^>]*|#([\w-]+))$/;(S.fn.init=function(e,t,n){var r,i;if(!e)return this;if(n=n||D,"string"==typeof e){if(!(r="<"===e[0]&&">"===e[e.length-1]&&3<=e.length?[null,e,null]:q.exec(e))||!r[1]&&t)return!t||t.jquery?(t||n).find(e):this.constructor(t).find(e);if(r[1]){if(t=t instanceof S?t[0]:t,S.merge(this,S.parseHTML(r[1],t&&t.nodeType?t.ownerDocument||t:E,!0)),N.test(r[1])&&S.isPlainObject(t))for(r in t)m(this[r])?this[r](t[r]):this.attr(r,t[r]);return this}return(i=E.getElementById(r[2]))&&(this[0]=i,this.length=1),this}return e.nodeType?(this[0]=e,this.length=1,this):m(e)?void 0!==n.ready?n.ready(e):e(S):S.makeArray(e,this)}).prototype=S.fn,D=S(E);var L=/^(?:parents|prev(?:Until|All))/,H={children:!0,contents:!0,next:!0,prev:!0};function O(e,t){while((e=e[t])&&1!==e.nodeType);return e}S.fn.extend({has:function(e){var t=S(e,this),n=t.length;return this.filter(function(){for(var e=0;e\x20\t\r\n\f]*)/i,he=/^$|^module$|\/(?:java|ecma)script/i;ce=E.createDocumentFragment().appendChild(E.createElement("div")),(fe=E.createElement("input")).setAttribute("type","radio"),fe.setAttribute("checked","checked"),fe.setAttribute("name","t"),ce.appendChild(fe),y.checkClone=ce.cloneNode(!0).cloneNode(!0).lastChild.checked,ce.innerHTML="",y.noCloneChecked=!!ce.cloneNode(!0).lastChild.defaultValue,ce.innerHTML="",y.option=!!ce.lastChild;var ge={thead:[1,"","
"],col:[2,"","
"],tr:[2,"","
"],td:[3,"","
"],_default:[0,"",""]};function ve(e,t){var n;return n="undefined"!=typeof e.getElementsByTagName?e.getElementsByTagName(t||"*"):"undefined"!=typeof e.querySelectorAll?e.querySelectorAll(t||"*"):[],void 0===t||t&&A(e,t)?S.merge([e],n):n}function ye(e,t){for(var n=0,r=e.length;n",""]);var me=/<|&#?\w+;/;function xe(e,t,n,r,i){for(var o,a,s,u,l,c,f=t.createDocumentFragment(),p=[],d=0,h=e.length;d\s*$/g;function je(e,t){return A(e,"table")&&A(11!==t.nodeType?t:t.firstChild,"tr")&&S(e).children("tbody")[0]||e}function De(e){return e.type=(null!==e.getAttribute("type"))+"/"+e.type,e}function qe(e){return"true/"===(e.type||"").slice(0,5)?e.type=e.type.slice(5):e.removeAttribute("type"),e}function Le(e,t){var n,r,i,o,a,s;if(1===t.nodeType){if(Y.hasData(e)&&(s=Y.get(e).events))for(i in Y.remove(t,"handle events"),s)for(n=0,r=s[i].length;n").attr(n.scriptAttrs||{}).prop({charset:n.scriptCharset,src:n.url}).on("load error",i=function(e){r.remove(),i=null,e&&t("error"===e.type?404:200,e.type)}),E.head.appendChild(r[0])},abort:function(){i&&i()}}});var _t,zt=[],Ut=/(=)\?(?=&|$)|\?\?/;S.ajaxSetup({jsonp:"callback",jsonpCallback:function(){var e=zt.pop()||S.expando+"_"+wt.guid++;return this[e]=!0,e}}),S.ajaxPrefilter("json jsonp",function(e,t,n){var r,i,o,a=!1!==e.jsonp&&(Ut.test(e.url)?"url":"string"==typeof e.data&&0===(e.contentType||"").indexOf("application/x-www-form-urlencoded")&&Ut.test(e.data)&&"data");if(a||"jsonp"===e.dataTypes[0])return r=e.jsonpCallback=m(e.jsonpCallback)?e.jsonpCallback():e.jsonpCallback,a?e[a]=e[a].replace(Ut,"$1"+r):!1!==e.jsonp&&(e.url+=(Tt.test(e.url)?"&":"?")+e.jsonp+"="+r),e.converters["script json"]=function(){return o||S.error(r+" was not called"),o[0]},e.dataTypes[0]="json",i=C[r],C[r]=function(){o=arguments},n.always(function(){void 0===i?S(C).removeProp(r):C[r]=i,e[r]&&(e.jsonpCallback=t.jsonpCallback,zt.push(r)),o&&m(i)&&i(o[0]),o=i=void 0}),"script"}),y.createHTMLDocument=((_t=E.implementation.createHTMLDocument("").body).innerHTML="
",2===_t.childNodes.length),S.parseHTML=function(e,t,n){return"string"!=typeof e?[]:("boolean"==typeof t&&(n=t,t=!1),t||(y.createHTMLDocument?((r=(t=E.implementation.createHTMLDocument("")).createElement("base")).href=E.location.href,t.head.appendChild(r)):t=E),o=!n&&[],(i=N.exec(e))?[t.createElement(i[1])]:(i=xe([e],t,o),o&&o.length&&S(o).remove(),S.merge([],i.childNodes)));var r,i,o},S.fn.load=function(e,t,n){var r,i,o,a=this,s=e.indexOf(" ");return-1").append(S.parseHTML(e)).find(r):e)}).always(n&&function(e,t){a.each(function(){n.apply(this,o||[e.responseText,t,e])})}),this},S.expr.pseudos.animated=function(t){return S.grep(S.timers,function(e){return t===e.elem}).length},S.offset={setOffset:function(e,t,n){var r,i,o,a,s,u,l=S.css(e,"position"),c=S(e),f={};"static"===l&&(e.style.position="relative"),s=c.offset(),o=S.css(e,"top"),u=S.css(e,"left"),("absolute"===l||"fixed"===l)&&-1<(o+u).indexOf("auto")?(a=(r=c.position()).top,i=r.left):(a=parseFloat(o)||0,i=parseFloat(u)||0),m(t)&&(t=t.call(e,n,S.extend({},s))),null!=t.top&&(f.top=t.top-s.top+a),null!=t.left&&(f.left=t.left-s.left+i),"using"in t?t.using.call(e,f):c.css(f)}},S.fn.extend({offset:function(t){if(arguments.length)return void 0===t?this:this.each(function(e){S.offset.setOffset(this,t,e)});var e,n,r=this[0];return r?r.getClientRects().length?(e=r.getBoundingClientRect(),n=r.ownerDocument.defaultView,{top:e.top+n.pageYOffset,left:e.left+n.pageXOffset}):{top:0,left:0}:void 0},position:function(){if(this[0]){var e,t,n,r=this[0],i={top:0,left:0};if("fixed"===S.css(r,"position"))t=r.getBoundingClientRect();else{t=this.offset(),n=r.ownerDocument,e=r.offsetParent||n.documentElement;while(e&&(e===n.body||e===n.documentElement)&&"static"===S.css(e,"position"))e=e.parentNode;e&&e!==r&&1===e.nodeType&&((i=S(e).offset()).top+=S.css(e,"borderTopWidth",!0),i.left+=S.css(e,"borderLeftWidth",!0))}return{top:t.top-i.top-S.css(r,"marginTop",!0),left:t.left-i.left-S.css(r,"marginLeft",!0)}}},offsetParent:function(){return this.map(function(){var e=this.offsetParent;while(e&&"static"===S.css(e,"position"))e=e.offsetParent;return e||re})}}),S.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},function(t,i){var o="pageYOffset"===i;S.fn[t]=function(e){return $(this,function(e,t,n){var r;if(x(e)?r=e:9===e.nodeType&&(r=e.defaultView),void 0===n)return r?r[i]:e[t];r?r.scrollTo(o?r.pageXOffset:n,o?n:r.pageYOffset):e[t]=n},t,e,arguments.length)}}),S.each(["top","left"],function(e,n){S.cssHooks[n]=Fe(y.pixelPosition,function(e,t){if(t)return t=We(e,n),Pe.test(t)?S(e).position()[n]+"px":t})}),S.each({Height:"height",Width:"width"},function(a,s){S.each({padding:"inner"+a,content:s,"":"outer"+a},function(r,o){S.fn[o]=function(e,t){var n=arguments.length&&(r||"boolean"!=typeof e),i=r||(!0===e||!0===t?"margin":"border");return $(this,function(e,t,n){var r;return x(e)?0===o.indexOf("outer")?e["inner"+a]:e.document.documentElement["client"+a]:9===e.nodeType?(r=e.documentElement,Math.max(e.body["scroll"+a],r["scroll"+a],e.body["offset"+a],r["offset"+a],r["client"+a])):void 0===n?S.css(e,t,i):S.style(e,t,n,i)},s,n?e:void 0,n)}})}),S.each(["ajaxStart","ajaxStop","ajaxComplete","ajaxError","ajaxSuccess","ajaxSend"],function(e,t){S.fn[t]=function(e){return this.on(t,e)}}),S.fn.extend({bind:function(e,t,n){return this.on(e,null,t,n)},unbind:function(e,t){return this.off(e,null,t)},delegate:function(e,t,n,r){return this.on(t,e,n,r)},undelegate:function(e,t,n){return 1===arguments.length?this.off(e,"**"):this.off(t,e||"**",n)},hover:function(e,t){return this.mouseenter(e).mouseleave(t||e)}}),S.each("blur focus focusin focusout resize scroll click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup contextmenu".split(" "),function(e,n){S.fn[n]=function(e,t){return 0+~]|"+M+")"+M+"*"),U=new RegExp(M+"|>"),X=new RegExp(F),V=new RegExp("^"+I+"$"),G={ID:new RegExp("^#("+I+")"),CLASS:new RegExp("^\\.("+I+")"),TAG:new RegExp("^("+I+"|[*])"),ATTR:new RegExp("^"+W),PSEUDO:new RegExp("^"+F),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+M+"*(even|odd|(([+-]|)(\\d*)n|)"+M+"*(?:([+-]|)"+M+"*(\\d+)|))"+M+"*\\)|)","i"),bool:new RegExp("^(?:"+R+")$","i"),needsContext:new RegExp("^"+M+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+M+"*((?:-\\d)?\\d*)"+M+"*\\)|)(?=[^-]|$)","i")},Y=/HTML$/i,Q=/^(?:input|select|textarea|button)$/i,J=/^h\d$/i,K=/^[^{]+\{\s*\[native \w/,Z=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,ee=/[+~]/,te=new RegExp("\\\\[\\da-fA-F]{1,6}"+M+"?|\\\\([^\\r\\n\\f])","g"),ne=function(e,t){var n="0x"+e.slice(1)-65536;return t||(n<0?String.fromCharCode(n+65536):String.fromCharCode(n>>10|55296,1023&n|56320))},re=/([\0-\x1f\x7f]|^-?\d)|^-$|[^\0-\x1f\x7f-\uFFFF\w-]/g,ie=function(e,t){return t?"\0"===e?"\ufffd":e.slice(0,-1)+"\\"+e.charCodeAt(e.length-1).toString(16)+" ":"\\"+e},oe=function(){T()},ae=be(function(e){return!0===e.disabled&&"fieldset"===e.nodeName.toLowerCase()},{dir:"parentNode",next:"legend"});try{H.apply(t=O.call(p.childNodes),p.childNodes),t[p.childNodes.length].nodeType}catch(e){H={apply:t.length?function(e,t){L.apply(e,O.call(t))}:function(e,t){var n=e.length,r=0;while(e[n++]=t[r++]);e.length=n-1}}}function se(t,e,n,r){var i,o,a,s,u,l,c,f=e&&e.ownerDocument,p=e?e.nodeType:9;if(n=n||[],"string"!=typeof t||!t||1!==p&&9!==p&&11!==p)return n;if(!r&&(T(e),e=e||C,E)){if(11!==p&&(u=Z.exec(t)))if(i=u[1]){if(9===p){if(!(a=e.getElementById(i)))return n;if(a.id===i)return n.push(a),n}else if(f&&(a=f.getElementById(i))&&v(e,a)&&a.id===i)return n.push(a),n}else{if(u[2])return H.apply(n,e.getElementsByTagName(t)),n;if((i=u[3])&&d.getElementsByClassName&&e.getElementsByClassName)return H.apply(n,e.getElementsByClassName(i)),n}if(d.qsa&&!N[t+" "]&&(!y||!y.test(t))&&(1!==p||"object"!==e.nodeName.toLowerCase())){if(c=t,f=e,1===p&&(U.test(t)||z.test(t))){(f=ee.test(t)&&ve(e.parentNode)||e)===e&&d.scope||((s=e.getAttribute("id"))?s=s.replace(re,ie):e.setAttribute("id",s=S)),o=(l=h(t)).length;while(o--)l[o]=(s?"#"+s:":scope")+" "+xe(l[o]);c=l.join(",")}try{return H.apply(n,f.querySelectorAll(c)),n}catch(e){N(t,!0)}finally{s===S&&e.removeAttribute("id")}}}return g(t.replace(B,"$1"),e,n,r)}function ue(){var r=[];return function e(t,n){return r.push(t+" ")>b.cacheLength&&delete e[r.shift()],e[t+" "]=n}}function le(e){return e[S]=!0,e}function ce(e){var t=C.createElement("fieldset");try{return!!e(t)}catch(e){return!1}finally{t.parentNode&&t.parentNode.removeChild(t),t=null}}function fe(e,t){var n=e.split("|"),r=n.length;while(r--)b.attrHandle[n[r]]=t}function pe(e,t){var n=t&&e,r=n&&1===e.nodeType&&1===t.nodeType&&e.sourceIndex-t.sourceIndex;if(r)return r;if(n)while(n=n.nextSibling)if(n===t)return-1;return e?1:-1}function de(t){return function(e){return"input"===e.nodeName.toLowerCase()&&e.type===t}}function he(n){return function(e){var t=e.nodeName.toLowerCase();return("input"===t||"button"===t)&&e.type===n}}function ge(t){return function(e){return"form"in e?e.parentNode&&!1===e.disabled?"label"in e?"label"in e.parentNode?e.parentNode.disabled===t:e.disabled===t:e.isDisabled===t||e.isDisabled!==!t&&ae(e)===t:e.disabled===t:"label"in e&&e.disabled===t}}function ye(a){return le(function(o){return o=+o,le(function(e,t){var n,r=a([],e.length,o),i=r.length;while(i--)e[n=r[i]]&&(e[n]=!(t[n]=e[n]))})})}function ve(e){return e&&"undefined"!=typeof e.getElementsByTagName&&e}for(e in d=se.support={},i=se.isXML=function(e){var t=e&&e.namespaceURI,n=e&&(e.ownerDocument||e).documentElement;return!Y.test(t||n&&n.nodeName||"HTML")},T=se.setDocument=function(e){var t,n,r=e?e.ownerDocument||e:p;return r!=C&&9===r.nodeType&&r.documentElement&&(a=(C=r).documentElement,E=!i(C),p!=C&&(n=C.defaultView)&&n.top!==n&&(n.addEventListener?n.addEventListener("unload",oe,!1):n.attachEvent&&n.attachEvent("onunload",oe)),d.scope=ce(function(e){return a.appendChild(e).appendChild(C.createElement("div")),"undefined"!=typeof e.querySelectorAll&&!e.querySelectorAll(":scope fieldset div").length}),d.attributes=ce(function(e){return e.className="i",!e.getAttribute("className")}),d.getElementsByTagName=ce(function(e){return e.appendChild(C.createComment("")),!e.getElementsByTagName("*").length}),d.getElementsByClassName=K.test(C.getElementsByClassName),d.getById=ce(function(e){return a.appendChild(e).id=S,!C.getElementsByName||!C.getElementsByName(S).length}),d.getById?(b.filter.ID=function(e){var t=e.replace(te,ne);return function(e){return e.getAttribute("id")===t}},b.find.ID=function(e,t){if("undefined"!=typeof t.getElementById&&E){var n=t.getElementById(e);return n?[n]:[]}}):(b.filter.ID=function(e){var n=e.replace(te,ne);return function(e){var t="undefined"!=typeof e.getAttributeNode&&e.getAttributeNode("id");return t&&t.value===n}},b.find.ID=function(e,t){if("undefined"!=typeof t.getElementById&&E){var n,r,i,o=t.getElementById(e);if(o){if((n=o.getAttributeNode("id"))&&n.value===e)return[o];i=t.getElementsByName(e),r=0;while(o=i[r++])if((n=o.getAttributeNode("id"))&&n.value===e)return[o]}return[]}}),b.find.TAG=d.getElementsByTagName?function(e,t){return"undefined"!=typeof t.getElementsByTagName?t.getElementsByTagName(e):d.qsa?t.querySelectorAll(e):void 0}:function(e,t){var n,r=[],i=0,o=t.getElementsByTagName(e);if("*"===e){while(n=o[i++])1===n.nodeType&&r.push(n);return r}return o},b.find.CLASS=d.getElementsByClassName&&function(e,t){if("undefined"!=typeof t.getElementsByClassName&&E)return t.getElementsByClassName(e)},s=[],y=[],(d.qsa=K.test(C.querySelectorAll))&&(ce(function(e){var t;a.appendChild(e).innerHTML="",e.querySelectorAll("[msallowcapture^='']").length&&y.push("[*^$]="+M+"*(?:''|\"\")"),e.querySelectorAll("[selected]").length||y.push("\\["+M+"*(?:value|"+R+")"),e.querySelectorAll("[id~="+S+"-]").length||y.push("~="),(t=C.createElement("input")).setAttribute("name",""),e.appendChild(t),e.querySelectorAll("[name='']").length||y.push("\\["+M+"*name"+M+"*="+M+"*(?:''|\"\")"),e.querySelectorAll(":checked").length||y.push(":checked"),e.querySelectorAll("a#"+S+"+*").length||y.push(".#.+[+~]"),e.querySelectorAll("\\\f"),y.push("[\\r\\n\\f]")}),ce(function(e){e.innerHTML="";var t=C.createElement("input");t.setAttribute("type","hidden"),e.appendChild(t).setAttribute("name","D"),e.querySelectorAll("[name=d]").length&&y.push("name"+M+"*[*^$|!~]?="),2!==e.querySelectorAll(":enabled").length&&y.push(":enabled",":disabled"),a.appendChild(e).disabled=!0,2!==e.querySelectorAll(":disabled").length&&y.push(":enabled",":disabled"),e.querySelectorAll("*,:x"),y.push(",.*:")})),(d.matchesSelector=K.test(c=a.matches||a.webkitMatchesSelector||a.mozMatchesSelector||a.oMatchesSelector||a.msMatchesSelector))&&ce(function(e){d.disconnectedMatch=c.call(e,"*"),c.call(e,"[s!='']:x"),s.push("!=",F)}),y=y.length&&new RegExp(y.join("|")),s=s.length&&new RegExp(s.join("|")),t=K.test(a.compareDocumentPosition),v=t||K.test(a.contains)?function(e,t){var n=9===e.nodeType?e.documentElement:e,r=t&&t.parentNode;return e===r||!(!r||1!==r.nodeType||!(n.contains?n.contains(r):e.compareDocumentPosition&&16&e.compareDocumentPosition(r)))}:function(e,t){if(t)while(t=t.parentNode)if(t===e)return!0;return!1},j=t?function(e,t){if(e===t)return l=!0,0;var n=!e.compareDocumentPosition-!t.compareDocumentPosition;return n||(1&(n=(e.ownerDocument||e)==(t.ownerDocument||t)?e.compareDocumentPosition(t):1)||!d.sortDetached&&t.compareDocumentPosition(e)===n?e==C||e.ownerDocument==p&&v(p,e)?-1:t==C||t.ownerDocument==p&&v(p,t)?1:u?P(u,e)-P(u,t):0:4&n?-1:1)}:function(e,t){if(e===t)return l=!0,0;var n,r=0,i=e.parentNode,o=t.parentNode,a=[e],s=[t];if(!i||!o)return e==C?-1:t==C?1:i?-1:o?1:u?P(u,e)-P(u,t):0;if(i===o)return pe(e,t);n=e;while(n=n.parentNode)a.unshift(n);n=t;while(n=n.parentNode)s.unshift(n);while(a[r]===s[r])r++;return r?pe(a[r],s[r]):a[r]==p?-1:s[r]==p?1:0}),C},se.matches=function(e,t){return se(e,null,null,t)},se.matchesSelector=function(e,t){if(T(e),d.matchesSelector&&E&&!N[t+" "]&&(!s||!s.test(t))&&(!y||!y.test(t)))try{var n=c.call(e,t);if(n||d.disconnectedMatch||e.document&&11!==e.document.nodeType)return n}catch(e){N(t,!0)}return 0":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(e){return e[1]=e[1].replace(te,ne),e[3]=(e[3]||e[4]||e[5]||"").replace(te,ne),"~="===e[2]&&(e[3]=" "+e[3]+" "),e.slice(0,4)},CHILD:function(e){return e[1]=e[1].toLowerCase(),"nth"===e[1].slice(0,3)?(e[3]||se.error(e[0]),e[4]=+(e[4]?e[5]+(e[6]||1):2*("even"===e[3]||"odd"===e[3])),e[5]=+(e[7]+e[8]||"odd"===e[3])):e[3]&&se.error(e[0]),e},PSEUDO:function(e){var t,n=!e[6]&&e[2];return G.CHILD.test(e[0])?null:(e[3]?e[2]=e[4]||e[5]||"":n&&X.test(n)&&(t=h(n,!0))&&(t=n.indexOf(")",n.length-t)-n.length)&&(e[0]=e[0].slice(0,t),e[2]=n.slice(0,t)),e.slice(0,3))}},filter:{TAG:function(e){var t=e.replace(te,ne).toLowerCase();return"*"===e?function(){return!0}:function(e){return e.nodeName&&e.nodeName.toLowerCase()===t}},CLASS:function(e){var t=m[e+" "];return t||(t=new RegExp("(^|"+M+")"+e+"("+M+"|$)"))&&m(e,function(e){return t.test("string"==typeof e.className&&e.className||"undefined"!=typeof e.getAttribute&&e.getAttribute("class")||"")})},ATTR:function(n,r,i){return function(e){var t=se.attr(e,n);return null==t?"!="===r:!r||(t+="","="===r?t===i:"!="===r?t!==i:"^="===r?i&&0===t.indexOf(i):"*="===r?i&&-1:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i;function j(e,n,r){return m(n)?S.grep(e,function(e,t){return!!n.call(e,t,e)!==r}):n.nodeType?S.grep(e,function(e){return e===n!==r}):"string"!=typeof n?S.grep(e,function(e){return-1)[^>]*|#([\w-]+))$/;(S.fn.init=function(e,t,n){var r,i;if(!e)return this;if(n=n||D,"string"==typeof e){if(!(r="<"===e[0]&&">"===e[e.length-1]&&3<=e.length?[null,e,null]:q.exec(e))||!r[1]&&t)return!t||t.jquery?(t||n).find(e):this.constructor(t).find(e);if(r[1]){if(t=t instanceof S?t[0]:t,S.merge(this,S.parseHTML(r[1],t&&t.nodeType?t.ownerDocument||t:E,!0)),N.test(r[1])&&S.isPlainObject(t))for(r in t)m(this[r])?this[r](t[r]):this.attr(r,t[r]);return this}return(i=E.getElementById(r[2]))&&(this[0]=i,this.length=1),this}return e.nodeType?(this[0]=e,this.length=1,this):m(e)?void 0!==n.ready?n.ready(e):e(S):S.makeArray(e,this)}).prototype=S.fn,D=S(E);var L=/^(?:parents|prev(?:Until|All))/,H={children:!0,contents:!0,next:!0,prev:!0};function O(e,t){while((e=e[t])&&1!==e.nodeType);return e}S.fn.extend({has:function(e){var t=S(e,this),n=t.length;return this.filter(function(){for(var e=0;e\x20\t\r\n\f]*)/i,he=/^$|^module$|\/(?:java|ecma)script/i;ce=E.createDocumentFragment().appendChild(E.createElement("div")),(fe=E.createElement("input")).setAttribute("type","radio"),fe.setAttribute("checked","checked"),fe.setAttribute("name","t"),ce.appendChild(fe),v.checkClone=ce.cloneNode(!0).cloneNode(!0).lastChild.checked,ce.innerHTML="",v.noCloneChecked=!!ce.cloneNode(!0).lastChild.defaultValue,ce.innerHTML="",v.option=!!ce.lastChild;var ge={thead:[1,"","
"],col:[2,"","
"],tr:[2,"","
"],td:[3,"","
"],_default:[0,"",""]};function ye(e,t){var n;return n="undefined"!=typeof e.getElementsByTagName?e.getElementsByTagName(t||"*"):"undefined"!=typeof e.querySelectorAll?e.querySelectorAll(t||"*"):[],void 0===t||t&&A(e,t)?S.merge([e],n):n}function ve(e,t){for(var n=0,r=e.length;n",""]);var me=/<|&#?\w+;/;function xe(e,t,n,r,i){for(var o,a,s,u,l,c,f=t.createDocumentFragment(),p=[],d=0,h=e.length;d\s*$/g;function je(e,t){return A(e,"table")&&A(11!==t.nodeType?t:t.firstChild,"tr")&&S(e).children("tbody")[0]||e}function De(e){return e.type=(null!==e.getAttribute("type"))+"/"+e.type,e}function qe(e){return"true/"===(e.type||"").slice(0,5)?e.type=e.type.slice(5):e.removeAttribute("type"),e}function Le(e,t){var n,r,i,o,a,s;if(1===t.nodeType){if(Y.hasData(e)&&(s=Y.get(e).events))for(i in Y.remove(t,"handle events"),s)for(n=0,r=s[i].length;n").attr(n.scriptAttrs||{}).prop({charset:n.scriptCharset,src:n.url}).on("load error",i=function(e){r.remove(),i=null,e&&t("error"===e.type?404:200,e.type)}),E.head.appendChild(r[0])},abort:function(){i&&i()}}});var Ut,Xt=[],Vt=/(=)\?(?=&|$)|\?\?/;S.ajaxSetup({jsonp:"callback",jsonpCallback:function(){var e=Xt.pop()||S.expando+"_"+Ct.guid++;return this[e]=!0,e}}),S.ajaxPrefilter("json jsonp",function(e,t,n){var r,i,o,a=!1!==e.jsonp&&(Vt.test(e.url)?"url":"string"==typeof e.data&&0===(e.contentType||"").indexOf("application/x-www-form-urlencoded")&&Vt.test(e.data)&&"data");if(a||"jsonp"===e.dataTypes[0])return r=e.jsonpCallback=m(e.jsonpCallback)?e.jsonpCallback():e.jsonpCallback,a?e[a]=e[a].replace(Vt,"$1"+r):!1!==e.jsonp&&(e.url+=(Et.test(e.url)?"&":"?")+e.jsonp+"="+r),e.converters["script json"]=function(){return o||S.error(r+" was not called"),o[0]},e.dataTypes[0]="json",i=C[r],C[r]=function(){o=arguments},n.always(function(){void 0===i?S(C).removeProp(r):C[r]=i,e[r]&&(e.jsonpCallback=t.jsonpCallback,Xt.push(r)),o&&m(i)&&i(o[0]),o=i=void 0}),"script"}),v.createHTMLDocument=((Ut=E.implementation.createHTMLDocument("").body).innerHTML="
",2===Ut.childNodes.length),S.parseHTML=function(e,t,n){return"string"!=typeof e?[]:("boolean"==typeof t&&(n=t,t=!1),t||(v.createHTMLDocument?((r=(t=E.implementation.createHTMLDocument("")).createElement("base")).href=E.location.href,t.head.appendChild(r)):t=E),o=!n&&[],(i=N.exec(e))?[t.createElement(i[1])]:(i=xe([e],t,o),o&&o.length&&S(o).remove(),S.merge([],i.childNodes)));var r,i,o},S.fn.load=function(e,t,n){var r,i,o,a=this,s=e.indexOf(" ");return-1").append(S.parseHTML(e)).find(r):e)}).always(n&&function(e,t){a.each(function(){n.apply(this,o||[e.responseText,t,e])})}),this},S.expr.pseudos.animated=function(t){return S.grep(S.timers,function(e){return t===e.elem}).length},S.offset={setOffset:function(e,t,n){var r,i,o,a,s,u,l=S.css(e,"position"),c=S(e),f={};"static"===l&&(e.style.position="relative"),s=c.offset(),o=S.css(e,"top"),u=S.css(e,"left"),("absolute"===l||"fixed"===l)&&-1<(o+u).indexOf("auto")?(a=(r=c.position()).top,i=r.left):(a=parseFloat(o)||0,i=parseFloat(u)||0),m(t)&&(t=t.call(e,n,S.extend({},s))),null!=t.top&&(f.top=t.top-s.top+a),null!=t.left&&(f.left=t.left-s.left+i),"using"in t?t.using.call(e,f):c.css(f)}},S.fn.extend({offset:function(t){if(arguments.length)return void 0===t?this:this.each(function(e){S.offset.setOffset(this,t,e)});var e,n,r=this[0];return r?r.getClientRects().length?(e=r.getBoundingClientRect(),n=r.ownerDocument.defaultView,{top:e.top+n.pageYOffset,left:e.left+n.pageXOffset}):{top:0,left:0}:void 0},position:function(){if(this[0]){var e,t,n,r=this[0],i={top:0,left:0};if("fixed"===S.css(r,"position"))t=r.getBoundingClientRect();else{t=this.offset(),n=r.ownerDocument,e=r.offsetParent||n.documentElement;while(e&&(e===n.body||e===n.documentElement)&&"static"===S.css(e,"position"))e=e.parentNode;e&&e!==r&&1===e.nodeType&&((i=S(e).offset()).top+=S.css(e,"borderTopWidth",!0),i.left+=S.css(e,"borderLeftWidth",!0))}return{top:t.top-i.top-S.css(r,"marginTop",!0),left:t.left-i.left-S.css(r,"marginLeft",!0)}}},offsetParent:function(){return this.map(function(){var e=this.offsetParent;while(e&&"static"===S.css(e,"position"))e=e.offsetParent;return e||re})}}),S.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},function(t,i){var o="pageYOffset"===i;S.fn[t]=function(e){return B(this,function(e,t,n){var r;if(x(e)?r=e:9===e.nodeType&&(r=e.defaultView),void 0===n)return r?r[i]:e[t];r?r.scrollTo(o?r.pageXOffset:n,o?n:r.pageYOffset):e[t]=n},t,e,arguments.length)}}),S.each(["top","left"],function(e,n){S.cssHooks[n]=_e(v.pixelPosition,function(e,t){if(t)return t=Be(e,n),Pe.test(t)?S(e).position()[n]+"px":t})}),S.each({Height:"height",Width:"width"},function(a,s){S.each({padding:"inner"+a,content:s,"":"outer"+a},function(r,o){S.fn[o]=function(e,t){var n=arguments.length&&(r||"boolean"!=typeof e),i=r||(!0===e||!0===t?"margin":"border");return B(this,function(e,t,n){var r;return x(e)?0===o.indexOf("outer")?e["inner"+a]:e.document.documentElement["client"+a]:9===e.nodeType?(r=e.documentElement,Math.max(e.body["scroll"+a],r["scroll"+a],e.body["offset"+a],r["offset"+a],r["client"+a])):void 0===n?S.css(e,t,i):S.style(e,t,n,i)},s,n?e:void 0,n)}})}),S.each(["ajaxStart","ajaxStop","ajaxComplete","ajaxError","ajaxSuccess","ajaxSend"],function(e,t){S.fn[t]=function(e){return this.on(t,e)}}),S.fn.extend({bind:function(e,t,n){return this.on(e,null,t,n)},unbind:function(e,t){return this.off(e,null,t)},delegate:function(e,t,n,r){return this.on(t,e,n,r)},undelegate:function(e,t,n){return 1===arguments.length?this.off(e,"**"):this.off(t,e||"**",n)},hover:function(e,t){return this.mouseenter(e).mouseleave(t||e)}}),S.each("blur focus focusin focusout resize scroll click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup contextmenu".split(" "),function(e,n){S.fn[n]=function(e,t){return 01?n-1:0),o=1;o/gm),z=a(/^data-[\-\w.\u00B7-\uFFFF]/),B=a(/^aria-[\-\w]+$/),P=a(/^(?:(?:(?:f|ht)tps?|mailto|tel|callto|cid|xmpp):|[^a-z]|[a-z+.\-]+(?:[^a-z+.\-:]|$))/i),j=a(/^(?:\w+script|data):/i),G=a(/[\u0000-\u0020\u00A0\u1680\u180E\u2000-\u2029\u205F\u3000]/g),W=a(/^html$/i),q="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e};function Y(e){if(Array.isArray(e)){for(var t=0,n=Array(e.length);t0&&void 0!==arguments[0]?arguments[0]:K(),n=function(t){return e(t)};if(n.version="2.3.6",n.removed=[],!t||!t.document||9!==t.document.nodeType)return n.isSupported=!1,n;var r=t.document,o=t.document,a=t.DocumentFragment,l=t.HTMLTemplateElement,c=t.Node,s=t.Element,u=t.NodeFilter,m=t.NamedNodeMap,A=void 0===m?t.NamedNodeMap||t.MozNamedAttrMap:m,$=t.HTMLFormElement,X=t.DOMParser,Z=t.trustedTypes,J=s.prototype,Q=w(J,"cloneNode"),ee=w(J,"nextSibling"),te=w(J,"childNodes"),ne=w(J,"parentNode");if("function"==typeof l){var re=o.createElement("template");re.content&&re.content.ownerDocument&&(o=re.content.ownerDocument)}var oe=V(Z,r),ie=oe?oe.createHTML(""):"",ae=o,le=ae.implementation,ce=ae.createNodeIterator,se=ae.createDocumentFragment,ue=ae.getElementsByTagName,me=r.importNode,fe={};try{fe=x(o).documentMode?o.documentMode:{}}catch(e){}var de={};n.isSupported="function"==typeof ne&&le&&void 0!==le.createHTMLDocument&&9!==fe;var pe=H,he=U,ge=z,ye=B,ve=j,be=G,Te=P,Ne=null,Ae=E({},[].concat(Y(k),Y(S),Y(_),Y(O),Y(M))),Ee=null,xe=E({},[].concat(Y(L),Y(R),Y(I),Y(F))),we=Object.seal(Object.create(null,{tagNameCheck:{writable:!0,configurable:!1,enumerable:!0,value:null},attributeNameCheck:{writable:!0,configurable:!1,enumerable:!0,value:null},allowCustomizedBuiltInElements:{writable:!0,configurable:!1,enumerable:!0,value:!1}})),ke=null,Se=null,_e=!0,De=!0,Oe=!1,Ce=!1,Me=!1,Le=!1,Re=!1,Ie=!1,Fe=!1,He=!1,Ue=!0,ze=!0,Be=!1,Pe={},je=null,Ge=E({},["annotation-xml","audio","colgroup","desc","foreignobject","head","iframe","math","mi","mn","mo","ms","mtext","noembed","noframes","noscript","plaintext","script","style","svg","template","thead","title","video","xmp"]),We=null,qe=E({},["audio","video","img","source","image","track"]),Ye=null,Ke=E({},["alt","class","for","id","label","name","pattern","placeholder","role","summary","title","value","style","xmlns"]),Ve="http://www.w3.org/1998/Math/MathML",$e="http://www.w3.org/2000/svg",Xe="http://www.w3.org/1999/xhtml",Ze=Xe,Je=!1,Qe=void 0,et=["application/xhtml+xml","text/html"],tt="text/html",nt=void 0,rt=null,ot=o.createElement("form"),it=function(e){return e instanceof RegExp||e instanceof Function},at=function(e){rt&&rt===e||(e&&"object"===(void 0===e?"undefined":q(e))||(e={}),e=x(e),Ne="ALLOWED_TAGS"in e?E({},e.ALLOWED_TAGS):Ae,Ee="ALLOWED_ATTR"in e?E({},e.ALLOWED_ATTR):xe,Ye="ADD_URI_SAFE_ATTR"in e?E(x(Ke),e.ADD_URI_SAFE_ATTR):Ke,We="ADD_DATA_URI_TAGS"in e?E(x(qe),e.ADD_DATA_URI_TAGS):qe,je="FORBID_CONTENTS"in e?E({},e.FORBID_CONTENTS):Ge,ke="FORBID_TAGS"in e?E({},e.FORBID_TAGS):{},Se="FORBID_ATTR"in e?E({},e.FORBID_ATTR):{},Pe="USE_PROFILES"in e&&e.USE_PROFILES,_e=!1!==e.ALLOW_ARIA_ATTR,De=!1!==e.ALLOW_DATA_ATTR,Oe=e.ALLOW_UNKNOWN_PROTOCOLS||!1,Ce=e.SAFE_FOR_TEMPLATES||!1,Me=e.WHOLE_DOCUMENT||!1,Ie=e.RETURN_DOM||!1,Fe=e.RETURN_DOM_FRAGMENT||!1,He=e.RETURN_TRUSTED_TYPE||!1,Re=e.FORCE_BODY||!1,Ue=!1!==e.SANITIZE_DOM,ze=!1!==e.KEEP_CONTENT,Be=e.IN_PLACE||!1,Te=e.ALLOWED_URI_REGEXP||Te,Ze=e.NAMESPACE||Xe,e.CUSTOM_ELEMENT_HANDLING&&it(e.CUSTOM_ELEMENT_HANDLING.tagNameCheck)&&(we.tagNameCheck=e.CUSTOM_ELEMENT_HANDLING.tagNameCheck),e.CUSTOM_ELEMENT_HANDLING&&it(e.CUSTOM_ELEMENT_HANDLING.attributeNameCheck)&&(we.attributeNameCheck=e.CUSTOM_ELEMENT_HANDLING.attributeNameCheck),e.CUSTOM_ELEMENT_HANDLING&&"boolean"==typeof e.CUSTOM_ELEMENT_HANDLING.allowCustomizedBuiltInElements&&(we.allowCustomizedBuiltInElements=e.CUSTOM_ELEMENT_HANDLING.allowCustomizedBuiltInElements),Qe=Qe=-1===et.indexOf(e.PARSER_MEDIA_TYPE)?tt:e.PARSER_MEDIA_TYPE,nt="application/xhtml+xml"===Qe?function(e){return e}:h,Ce&&(De=!1),Fe&&(Ie=!0),Pe&&(Ne=E({},[].concat(Y(M))),Ee=[],!0===Pe.html&&(E(Ne,k),E(Ee,L)),!0===Pe.svg&&(E(Ne,S),E(Ee,R),E(Ee,F)),!0===Pe.svgFilters&&(E(Ne,_),E(Ee,R),E(Ee,F)),!0===Pe.mathMl&&(E(Ne,O),E(Ee,I),E(Ee,F))),e.ADD_TAGS&&(Ne===Ae&&(Ne=x(Ne)),E(Ne,e.ADD_TAGS)),e.ADD_ATTR&&(Ee===xe&&(Ee=x(Ee)),E(Ee,e.ADD_ATTR)),e.ADD_URI_SAFE_ATTR&&E(Ye,e.ADD_URI_SAFE_ATTR),e.FORBID_CONTENTS&&(je===Ge&&(je=x(je)),E(je,e.FORBID_CONTENTS)),ze&&(Ne["#text"]=!0),Me&&E(Ne,["html","head","body"]),Ne.table&&(E(Ne,["tbody"]),delete ke.tbody),i&&i(e),rt=e)},lt=E({},["mi","mo","mn","ms","mtext"]),ct=E({},["foreignobject","desc","title","annotation-xml"]),st=E({},S);E(st,_),E(st,D);var ut=E({},O);E(ut,C);var mt=function(e){var t=ne(e);t&&t.tagName||(t={namespaceURI:Xe,tagName:"template"});var n=h(e.tagName),r=h(t.tagName);if(e.namespaceURI===$e)return t.namespaceURI===Xe?"svg"===n:t.namespaceURI===Ve?"svg"===n&&("annotation-xml"===r||lt[r]):Boolean(st[n]);if(e.namespaceURI===Ve)return t.namespaceURI===Xe?"math"===n:t.namespaceURI===$e?"math"===n&&ct[r]:Boolean(ut[n]);if(e.namespaceURI===Xe){if(t.namespaceURI===$e&&!ct[r])return!1;if(t.namespaceURI===Ve&&!lt[r])return!1;var o=E({},["title","style","font","a","script"]);return!ut[n]&&(o[n]||!st[n])}return!1},ft=function(e){p(n.removed,{element:e});try{e.parentNode.removeChild(e)}catch(t){try{e.outerHTML=ie}catch(t){e.remove()}}},dt=function(e,t){try{p(n.removed,{attribute:t.getAttributeNode(e),from:t})}catch(e){p(n.removed,{attribute:null,from:t})}if(t.removeAttribute(e),"is"===e&&!Ee[e])if(Ie||Fe)try{ft(t)}catch(e){}else try{t.setAttribute(e,"")}catch(e){}},pt=function(e){var t=void 0,n=void 0;if(Re)e=""+e;else{var r=g(e,/^[\r\n\t ]+/);n=r&&r[0]}"application/xhtml+xml"===Qe&&(e=''+e+"");var i=oe?oe.createHTML(e):e;if(Ze===Xe)try{t=(new X).parseFromString(i,Qe)}catch(e){}if(!t||!t.documentElement){t=le.createDocument(Ze,"template",null);try{t.documentElement.innerHTML=Je?"":i}catch(e){}}var a=t.body||t.documentElement;return e&&n&&a.insertBefore(o.createTextNode(n),a.childNodes[0]||null),Ze===Xe?ue.call(t,Me?"html":"body")[0]:Me?t.documentElement:a},ht=function(e){return ce.call(e.ownerDocument||e,e,u.SHOW_ELEMENT|u.SHOW_COMMENT|u.SHOW_TEXT,null,!1)},gt=function(e){return e instanceof $&&("string"!=typeof e.nodeName||"string"!=typeof e.textContent||"function"!=typeof e.removeChild||!(e.attributes instanceof A)||"function"!=typeof e.removeAttribute||"function"!=typeof e.setAttribute||"string"!=typeof e.namespaceURI||"function"!=typeof e.insertBefore)},yt=function(e){return"object"===(void 0===c?"undefined":q(c))?e instanceof c:e&&"object"===(void 0===e?"undefined":q(e))&&"number"==typeof e.nodeType&&"string"==typeof e.nodeName},vt=function(e,t,r){de[e]&&f(de[e],(function(e){e.call(n,t,r,rt)}))},bt=function(e){var t=void 0;if(vt("beforeSanitizeElements",e,null),gt(e))return ft(e),!0;if(g(e.nodeName,/[\u0080-\uFFFF]/))return ft(e),!0;var r=nt(e.nodeName);if(vt("uponSanitizeElement",e,{tagName:r,allowedTags:Ne}),!yt(e.firstElementChild)&&(!yt(e.content)||!yt(e.content.firstElementChild))&&T(/<[/\w]/g,e.innerHTML)&&T(/<[/\w]/g,e.textContent))return ft(e),!0;if("select"===r&&T(/