diff --git a/.appveyor.yml b/.appveyor.yml deleted file mode 100644 index a4fac799b21..00000000000 --- a/.appveyor.yml +++ /dev/null @@ -1,143 +0,0 @@ -build: false -clone_folder: c:\projects\phpbb -version: '{build}' - -services: - - iis - -environment: - matrix: - - db: mssql - db_version: sql2012sp1 - php: 7.0 - - db: mssql - db_version: sql2014 - php: 7.0 - - db: mssql - db_version: sql2016 - php: 7.1.12 -# - db: mssql -# db_version: sql2017 -# php: 7.1 -# - db: mariadb -# php: 7.1 -# - db: mysqli -# php: 7.1 -# - db: sqlite -# php: 7.1 -# - db: postgresql -# php: 7.1 - -hosts: - phpbb.test: 127.0.0.1 - -init: - - SET PATH=%systemroot%\system32\inetsrv\;C:\Program Files\OpenSSL;C:\tools\php;c:\php;%PATH% - - SET ANSICON=121x90 (121x90) - - REG ADD "HKEY_CURRENT_USER\Software\Microsoft\Command Processor" /v DelayedExpansion /t REG_DWORD /d 1 /f - -before_test: - - ps: | - Set-Service wuauserv -StartupType Manual - cinst -y php --version ((choco search php --exact --all-versions -r | select-string -pattern $env:php | sort { [version]($_ -split '\|' | select -last 1) } -Descending | Select-Object -first 1) -replace '[php|]','') - Get-ChildItem -Path "c:\tools\php$($env:php -replace '([0-9])[.]([0-9])[.]?([0-9]+)?','$1$2')" -Recurse | - Move-Item -destination "c:\tools\php" - cd c:\tools\php - cat php.ini-development | %{$_ -replace "memory_limit = 128M","memory_limit = 1024M"} | Out-File -Encoding "Default" php.ini - Add-Content php.ini "`n date.timezone=UTC" - Add-Content php.ini "`n display_errors=On" - Add-Content php.ini "`n extension_dir=ext" - Add-Content php.ini "`n extension=php_openssl.dll" - Add-Content php.ini "`n extension=php_mbstring.dll" - Add-Content php.ini "`n extension=php_curl.dll" - Add-Content php.ini "`n extension=php_gd2.dll" - Add-Content php.ini "`n extension=php_tidy.dll" - Add-Content php.ini "`n extension=php_fileinfo.dll" - Add-Content php.ini "`n extension=php_pdo_sqlite.dll" - Add-Content php.ini "`n extension=php_sqlite3.dll" - Add-Content php.ini "`n extension=php_pdo_mysql.dll" - Add-Content php.ini "`n extension=php_mysqli.dll" - Add-Content php.ini "`n extension=php_pdo_pgsql.dll" - Add-Content php.ini "`n extension=php_pgsql.dll" - - # Get MSSQL driver - if ($env:db -eq "mssql") { - cd c:\tools\php\ext - $DLLVersion = "4.1.6.1" - appveyor DownloadFile http://windows.php.net/downloads/pecl/releases/sqlsrv/$($:DLLVersion)/php_sqlsrv-$($DLLVersion)-$($env:php -replace '([0-9])[.]([0-9])[.]?([0-9]+)?','$1.$2')-nts-vc14-x64.zip - 7z x -y php_sqlsrv-$($DLLVersion)-$($env:php -replace '([0-9])[.]([0-9])[.]?([0-9]+)?','$1.$2')-nts-vc14-x64.zip > $null - appveyor-retry appveyor DownloadFile http://windows.php.net/downloads/pecl/releases/pdo_sqlsrv/$($DLLVersion)/php_pdo_sqlsrv-$($DLLVersion)-$($env:php -replace '([0-9])[.]([0-9])[.]?([0-9]+)?','$1.$2')-nts-vc14-x64.zip - 7z x -y php_pdo_sqlsrv-$($DLLVersion)-$($env:php -replace '([0-9])[.]([0-9])[.]?([0-9]+)?','$1.$2')-nts-vc14-x64.zip > $null - Remove-Item c:\tools\php\* -include .zip - cd c:\tools\php - Add-Content php.ini "`nextension=php_sqlsrv.dll" - Add-Content php.ini "`nextension=php_pdo_sqlsrv.dll" - Add-Content php.ini "`n" - - $instanceName = $env:db_version.ToUpper() - Start-Service "MSSQL`$$instanceName" - Set-Variable -Name "sqlServerPath" -Value "(local)\$($env:db_version.ToUpper())" - - # Create database write test config - sqlcmd -S $sqlServerPath -Q "Use [master]; CREATE DATABASE [phpbb_test] COLLATE Latin1_General_CI_AS" - $data = "", "`n`t`n`t`t`n`t") | Set-Content c:\projects\phpbb\phpBB\web.config - (Get-Content c:\projects\phpbb\phpBB\web.config).replace("`t", "`t`t`n`t") | Set-Content c:\projects\phpbb\phpBB\web.config - - cd c:\projects\phpbb\phpBB - - php ..\composer.phar install - - choco install -y urlrewrite - - ps: New-WebSite -Name 'phpBBTest' -PhysicalPath 'c:\projects\phpbb\phpBB' -Force - - ps: Import-Module WebAdministration; Set-ItemProperty 'IIS:\Sites\phpBBTest' -name Bindings -value @{protocol='http';bindingInformation='*:80:phpbb.test'} - - echo Change default anonymous user AUTH to ApplicationPool - - appcmd set config -section:anonymousAuthentication /username:"" --password - - echo Setup FAST-CGI configuration - - appcmd set config /section:system.webServer/fastCGI /+[fullPath='C:\tools\php\php-cgi.exe'] - - echo Setup FACT-CGI handler - - appcmd set config /section:system.webServer/handlers /+[name='PHP-FastCGI',path='*.php',verb='*',modules='FastCgiModule',scriptProcessor='C:\tools\php\php-cgi.exe',resourceType='Either'] - - iisreset - - NET START W3SVC - - mkdir "C:\projects\phpbb\phpBB\cache\test" - - mkdir "C:\projects\phpbb\phpBB\cache\installer" - - icacls "C:\projects\phpbb\phpBB\cache" /grant Users:F /T - - icacls "C:\projects\phpbb\phpBB\files" /grant Users:F /T - - icacls "C:\projects\phpbb\phpBB\store" /grant Users:F /T - - icacls "C:\projects\phpbb\phpBB\images\avatars\upload" /grant Users:F /T - -test_script: - - cd c:\projects\phpbb - - php -e phpBB\vendor\phpunit\phpunit\phpunit --verbose diff --git a/.devcontainer/Dockerfile b/.devcontainer/Dockerfile new file mode 100644 index 00000000000..9eaeefdb12d --- /dev/null +++ b/.devcontainer/Dockerfile @@ -0,0 +1,22 @@ +# Debian version +ARG VARIANT="bookworm" +FROM mcr.microsoft.com/vscode/devcontainers/base:0-${VARIANT} + +# Install PHP +RUN apt-get -y update && apt-get -y install software-properties-common +RUN add-apt-repository ppa:ondrej/php +RUN apt-get -y update +RUN apt-get -y install php8.4 php8.4-xml php8.4-mbstring php8.4-curl php8.4-zip php8.4-xdebug + +# Install Composer +RUN curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer + +# Install MySQL +RUN apt-get -y install mysql-server php8.4-mysql + +# Xdebug +ADD resources/xdebug.ini /etc/php/8.4/apache2/conf.d/xdebug.ini + +# Configure Apache +RUN echo "Listen 8080" >> /etc/apache2/ports.conf && \ + a2enmod rewrite diff --git a/.devcontainer/customisations-team/devcontainer.json b/.devcontainer/customisations-team/devcontainer.json new file mode 100644 index 00000000000..5a0803656e0 --- /dev/null +++ b/.devcontainer/customisations-team/devcontainer.json @@ -0,0 +1,37 @@ +// For format details, see https://aka.ms/devcontainer.json. For config options, see the README at: +// https://github.com/microsoft/vscode-dev-containers/tree/v0.238.1/containers/ubuntu +{ + "name": "phpBB (Customisations Team)", + "build": { + "dockerfile": "../Dockerfile", + "args": { + "VARIANT": "ubuntu-22.04" + } + }, + + // Configure tool-specific properties. + "customizations": { + // Configure properties specific to VS Code. + "vscode": { + "settings": { + // Allow Xdebug to listen to requests from remote (or container) + "remote.localPortHost": "allInterfaces" + }, + //"devPort": {}, + // Specify which VS Code extensions to install (List of IDs) + "extensions": ["xdebug.php-debug"] + } + }, + + // Use 'forwardPorts' to make a list of ports inside the container available locally. + "forwardPorts": [80, 9003], + + // Use 'postCreateCommand' to run commands after the container is created. + "postStartCommand": "bash .devcontainer/customisations-team/setup.sh", + + // Comment out to connect as root instead. More info: https://aka.ms/vscode-remote/containers/non-root. + "remoteUser": "vscode", + "features": { + "github-cli": "latest" + } +} diff --git a/.devcontainer/customisations-team/phpbb-config.yml b/.devcontainer/customisations-team/phpbb-config.yml new file mode 100644 index 00000000000..1ddc1f4247c --- /dev/null +++ b/.devcontainer/customisations-team/phpbb-config.yml @@ -0,0 +1,37 @@ +installer: + admin: + name: admin + password: adminadmin + email: admin@example.org + + board: + lang: en + name: My Board (with Titania) + description: My amazing new phpBB board (with Titania) + + database: + dbms: mysqli + dbhost: 127.0.0.1 + dbport: 3306 + dbuser: phpbb + dbpasswd: phpbb + dbname: phpbb + table_prefix: phpbb_ + + email: + enabled: false + smtp_delivery : ~ + smtp_host: ~ + smtp_port: ~ + smtp_user: ~ + smtp_pass: ~ + + server: + cookie_secure: false + server_protocol: http:// + force_server_vars: true + server_name: localhost + server_port: 80 + script_path: / + + extensions: ["phpbb/titania"] diff --git a/.devcontainer/customisations-team/setup.sh b/.devcontainer/customisations-team/setup.sh new file mode 100644 index 00000000000..a29d5681b61 --- /dev/null +++ b/.devcontainer/customisations-team/setup.sh @@ -0,0 +1,81 @@ +# setup.sh - Customisations Team +# Commands to install and configure phpBB +echo "[Codespaces] Customisations Team configuration..." + +# Start MySQL +echo "[Codespaces] Start MySQL" +sudo service mysql start + +# Start Apache +echo "[Codespaces] Start Apache" +sudo apache2ctl start + +# Create a MySQL user to use +echo "[Codespaces] Create MySQL user" +sudo mysql -u root< +# @license GNU General Public License, version 2 (GPL-2.0) +# +# For full copyright and license information, please see +# the docs/CREDITS.txt file. +# +set -e + +if [ ! -f doctum.phar ]; then + # Download the latest (5.x.x) release if the file does not exist + # Remove it to update your phar + curl -O https://doctum.long-term.support/releases/5/doctum.phar + rm -f doctum.phar.sha256 + curl -O https://doctum.long-term.support/releases/5/doctum.phar.sha256 + sha256sum --strict --check doctum.phar.sha256 + rm -f doctum.phar.sha256 + chmod +x ./doctum.phar + # You can fetch the latest (5.x.x) version code here: + # https://doctum.long-term.support/releases/5/VERSION +fi +# Show the version to inform users of the script +./doctum.phar version --text +./doctum.phar parse build/doctum-checkout.conf.php -v diff --git a/.github/check-executable-files.sh b/.github/check-executable-files.sh new file mode 100755 index 00000000000..d9d0800f00e --- /dev/null +++ b/.github/check-executable-files.sh @@ -0,0 +1,63 @@ +#!/bin/bash +# +# This file is part of the phpBB Forum Software package. +# +# @copyright (c) phpBB Limited +# @license GNU General Public License, version 2 (GPL-2.0) +# +# For full copyright and license information, please see +# the docs/CREDITS.txt file. +# +set -e + +root="$1" +path="${root}phpBB/" + +# Check the permissions of the files + +# The following variables MUST NOT contain any wildcard +# Directories to skip +directories_skipped="-path ${path}develop -o -path ${path}vendor" + +# Files to skip +files_skipped="-false" + +# Files which have to be executable +executable_files="-path ${path}bin/* -o -path ${path}install/phpbbcli.php" + +incorrect_files=$( \ + find ${path} \ + '(' \ + '(' \ + ${directories_skipped} \ + ')' \ + -a -type d -prune -a -type f \ + ')' -o \ + '(' \ + -type f -a \ + -not '(' \ + ${files_skipped} \ + ')' -a \ + '(' \ + '(' \ + '(' \ + ${executable_files} \ + ')' -a \ + -not -perm /100 \ + ')' -o \ + '(' \ + -not '(' \ + ${executable_files} \ + ')' -a \ + -perm /111 \ + ')' \ + ')' \ + ')' \ + ) + +if [ "${incorrect_files}" != '' ] +then + echo "The following files do not have proper permissions:"; + ls -la ${incorrect_files} + exit 1; +fi diff --git a/travis/check-image-icc-profiles.sh b/.github/check-image-icc-profiles.sh similarity index 54% rename from travis/check-image-icc-profiles.sh rename to .github/check-image-icc-profiles.sh index 05c7de2d27b..d0444dc7f50 100755 --- a/travis/check-image-icc-profiles.sh +++ b/.github/check-image-icc-profiles.sh @@ -10,12 +10,5 @@ # set -e -DB=$1 -TRAVIS_PHP_VERSION=$2 -NOTESTS=$3 - -if [ "$NOTESTS" == '1' ] -then - find . -type f -a -iregex '.*\.\(gif\|jpg\|jpeg\|png\)$' -a -not -wholename '*vendor/*' | \ - parallel --gnu --keep-order 'phpBB/develop/strip_icc_profiles.sh {}' -fi +find . -type f -a -iregex '.*\.\(gif\|jpg\|jpeg\|png\)$' -a -not -wholename '*vendor/*' | \ + parallel --gnu --keep-order 'phpBB/develop/strip_icc_profiles.sh {}' diff --git a/.github/check-js.sh b/.github/check-js.sh new file mode 100755 index 00000000000..85518ca5010 --- /dev/null +++ b/.github/check-js.sh @@ -0,0 +1,18 @@ +#!/bin/bash +# +# This file is part of the phpBB Forum Software package. +# +# @copyright (c) phpBB Limited +# @license GNU General Public License, version 2 (GPL-2.0) +# +# For full copyright and license information, please see +# the docs/CREDITS.txt file. +# +set -e +set +x + +sudo npm install -g > /dev/null +npm ci > /dev/null +set -x +node_modules/eslint/bin/eslint.js "phpBB/**/*.js" --ignore-pattern "phpBB/ext/" +node_modules/eslint/bin/eslint.js "phpBB/**/*.js.twig" --ignore-pattern "phpBB/ext/" diff --git a/.github/check-stylesheet.sh b/.github/check-stylesheet.sh new file mode 100755 index 00000000000..70a8a70d9b4 --- /dev/null +++ b/.github/check-stylesheet.sh @@ -0,0 +1,18 @@ +#!/bin/bash +# +# This file is part of the phpBB Forum Software package. +# +# @copyright (c) phpBB Limited +# @license GNU General Public License, version 2 (GPL-2.0) +# +# For full copyright and license information, please see +# the docs/CREDITS.txt file. +# +set -e +set +x + +sudo npm install -g > /dev/null +npm ci > /dev/null +set -x +node_modules/stylelint/bin/stylelint.js "phpBB/styles/prosilver/theme/*.css" +node_modules/stylelint/bin/stylelint.js "phpBB/adm/style/*.css" diff --git a/.github/ext-check-executable-files.sh b/.github/ext-check-executable-files.sh new file mode 100755 index 00000000000..09db25d40bd --- /dev/null +++ b/.github/ext-check-executable-files.sh @@ -0,0 +1,64 @@ +#!/bin/bash +# +# This file is part of the phpBB Forum Software package. +# +# @copyright (c) phpBB Limited +# @license GNU General Public License, version 2 (GPL-2.0) +# +# For full copyright and license information, please see +# the docs/CREDITS.txt file. +# +set -e + +root="$1" +extname="$2" +path="${root}phpBB/ext/${extname}/" + +# Check the permissions of the files + +# The following variables MUST NOT contain any wildcard +# Directories to skip +directories_skipped="-path ${path}develop -o -path ${path}vendor -o -path ${path}.git" + +# Files to skip +files_skipped="-false" + +# Files which have to be executable +executable_files="-path ${path}bin/* -o -path ${path}install/phpbbcli.php" + +incorrect_files=$( \ + find ${path} \ + '(' \ + '(' \ + ${directories_skipped} \ + ')' \ + -a -type d -prune -a -type f \ + ')' -o \ + '(' \ + -type f -a \ + -not '(' \ + ${files_skipped} \ + ')' -a \ + '(' \ + '(' \ + '(' \ + ${executable_files} \ + ')' -a \ + -not -perm /100 \ + ')' -o \ + '(' \ + -not '(' \ + ${executable_files} \ + ')' -a \ + -perm /111 \ + ')' \ + ')' \ + ')' \ + ) + +if [ "${incorrect_files}" != '' ] +then + echo "The following files do not have proper permissions:"; + ls -la ${incorrect_files} + exit 1; +fi diff --git a/travis/ext-sniff.sh b/.github/ext-sniff.sh similarity index 73% rename from travis/ext-sniff.sh rename to .github/ext-sniff.sh index ca4d2115bab..fc5bafc008c 100755 --- a/travis/ext-sniff.sh +++ b/.github/ext-sniff.sh @@ -11,10 +11,8 @@ set -e set -x -DB=$1 -TRAVIS_PHP_VERSION=$2 -EXTNAME=$3 -NOTESTS=$4 +EXTNAME=$1 +NOTESTS=$2 if [ "$NOTESTS" == "1" ] then @@ -22,7 +20,6 @@ then -s \ --extensions=php \ --standard=build/code_sniffer/ruleset-php-extensions.xml \ - "--ignore=phpBB/ext/$EXTNAME/tests/*" \ - "--ignore=phpBB/ext/$EXTNAME/vendor/*" \ - "phpBB/ext/$EXTNAME" + --ignore=*/"$EXTNAME"/tests/*,*/"$EXTNAME"/vendor/* \ + phpBB/ext/"$EXTNAME" fi diff --git a/.github/ldap/base.ldif b/.github/ldap/base.ldif new file mode 100644 index 00000000000..09fe7cecc69 --- /dev/null +++ b/.github/ldap/base.ldif @@ -0,0 +1,41 @@ +dn: dc=example,dc=com +objectClass: top +objectClass: dcObject +objectClass: organization +o: example +dc: example + +dn: ou=foo,dc=example,dc=com +objectClass: organizationalUnit +ou: foo + +dn: cn=admin,dc=example,dc=com +objectClass: simpleSecurityObject +objectClass: organizationalRole +cn: admin +description: LDAP administrator +userPassword:: e1NTSEF9NytMR2gveUxTMzdsc3RRd1V1dENZSVA0TWdYdm9SdDY= + +dn: ou=group,dc=example,dc=com +objectClass: organizationalUnit +ou: group + +dn: cn=admin,ou=foo,dc=example,dc=com +objectClass: posixAccount +objectClass: inetOrgPerson +objectClass: organizationalPerson +objectClass: person +loginShell: /bin/bash +homeDirectory: /home/admin +uid: admin +cn: admin +uidNumber: 10000 +gidNumber: 10000 +sn: admin +mail: admin@example.com +userPassword:: e1NTSEF9WHpueGZURHZZc21JSkl6czdMVXBjdCtWYTA1dlMzVlQ= + +dn: cn=admin,ou=group,dc=example,dc=com +objectClass: posixGroup +gidNumber: 10000 +cn: admin diff --git a/.github/ldap/slapd.conf b/.github/ldap/slapd.conf new file mode 100644 index 00000000000..9f6aa980f7b --- /dev/null +++ b/.github/ldap/slapd.conf @@ -0,0 +1,17 @@ +# See slapd.conf(5) for details on configuration options. +include /etc/ldap/schema/core.schema +include /etc/ldap/schema/cosine.schema +include /etc/ldap/schema/inetorgperson.schema +include /etc/ldap/schema/nis.schema + +pidfile /var/tmp/slapd/slapd.pid +argsfile /var/tmp/slapd/slapd.args + +modulepath /usr/lib/openldap + +database ldif +directory /var/tmp/slapd + +suffix "dc=example,dc=com" +rootdn "cn=admin,dc=example,dc=com" +rootpw adminadmin diff --git a/travis/phing-sniff.sh b/.github/phing-sniff.sh similarity index 70% rename from travis/phing-sniff.sh rename to .github/phing-sniff.sh index 3f43b64130e..7e1595c385e 100755 --- a/travis/phing-sniff.sh +++ b/.github/phing-sniff.sh @@ -11,13 +11,6 @@ set -e set -x -DB=$1 -TRAVIS_PHP_VERSION=$2 -NOTESTS=$3 - -if [ "$NOTESTS" == '1' ] -then - cd build - ../phpBB/vendor/bin/phing sniff - cd .. -fi +cd build +../phpBB/vendor/bin/phing sniff +cd .. diff --git a/.github/phpunit-mariadb-github.xml b/.github/phpunit-mariadb-github.xml new file mode 100644 index 00000000000..d5ab282b3d1 --- /dev/null +++ b/.github/phpunit-mariadb-github.xml @@ -0,0 +1,48 @@ + + + + + ../tests + ../tests/functional + ../tests/lint_test.php + + + ../tests/functional + + + + + slow + + + + + ../phpBB/ + ../tests/ + + + ../phpBB/vendor/ + ../phpBB/cache/ + ../phpBB/develop/ + ../phpBB/store/ + + + + + + + + + + + + + diff --git a/.github/phpunit-mssql-github.xml b/.github/phpunit-mssql-github.xml new file mode 100644 index 00000000000..bd240fa534b --- /dev/null +++ b/.github/phpunit-mssql-github.xml @@ -0,0 +1,50 @@ + + + + + ../tests + ../tests/functional + ../tests/lint_test.php + + + ../tests/functional + + + + + slow + + + + + ../phpBB/ + ../tests/ + + + ../phpBB/vendor/ + ../phpBB/cache/ + ../phpBB/develop/ + ../phpBB/store/ + + + + + + + + + + + + + + + diff --git a/.github/phpunit-mysql-github.xml b/.github/phpunit-mysql-github.xml new file mode 100644 index 00000000000..ff42cf36dfd --- /dev/null +++ b/.github/phpunit-mysql-github.xml @@ -0,0 +1,50 @@ + + + + + ../tests + ../tests/functional + ../tests/lint_test.php + + + ../tests/functional + + + + + slow + + + + + ../phpBB/ + ../tests/ + + + ../phpBB/vendor/ + ../phpBB/cache/ + ../phpBB/develop/ + ../phpBB/store/ + + + + + + + + + + + + + + + diff --git a/.github/phpunit-postgres-github.xml b/.github/phpunit-postgres-github.xml new file mode 100644 index 00000000000..1636901039f --- /dev/null +++ b/.github/phpunit-postgres-github.xml @@ -0,0 +1,50 @@ + + + + + ../tests + ../tests/functional + ../tests/lint_test.php + + + ../tests/functional + + + + + slow + + + + + ../phpBB/ + ../tests/ + + + ../phpBB/vendor/ + ../phpBB/cache/ + ../phpBB/develop/ + ../phpBB/store/ + + + + + + + + + + + + + + + diff --git a/.github/phpunit-psql-windows-github.xml b/.github/phpunit-psql-windows-github.xml new file mode 100644 index 00000000000..7e71405e484 --- /dev/null +++ b/.github/phpunit-psql-windows-github.xml @@ -0,0 +1,53 @@ + + + + + ../tests + ../tests/functional + ../tests/lint_test.php + + + ../tests/functional + + + + + slow + + + + + ../phpBB/ + ../tests/ + + + ../phpBB/vendor/ + ../phpBB/cache/ + ../phpBB/develop/ + ../phpBB/store/ + + + + + + + + + + + + + + + diff --git a/.github/phpunit-sqlite3-github.xml b/.github/phpunit-sqlite3-github.xml new file mode 100644 index 00000000000..1ade12292c3 --- /dev/null +++ b/.github/phpunit-sqlite3-github.xml @@ -0,0 +1,44 @@ + + + + + ../tests + ../tests/functional + ../tests/lint_test.php + + + ../tests/functional + + + + + slow + + + + + ../phpBB/ + ../tests/ + + + ../phpBB/vendor/ + ../phpBB/cache/ + ../phpBB/develop/ + ../phpBB/store/ + + + + + + + + + diff --git a/travis/prepare-extension.sh b/.github/prepare-extension.sh similarity index 74% rename from travis/prepare-extension.sh rename to .github/prepare-extension.sh index 4518f935f8a..d3adc95ec5d 100755 --- a/travis/prepare-extension.sh +++ b/.github/prepare-extension.sh @@ -12,11 +12,11 @@ set -e set -x EXTNAME=$1 -BRANCH=$2 # Move the extension in place mkdir --parents phpBB/ext/$EXTNAME cp -R ../tmp/* phpBB/ext/$EXTNAME -# Move the extensions travis/phpunit-*-travis.xml files in place -cp -R travis/* phpBB/ext/$EXTNAME/travis +# Move the test files for extensions in place +cp -R .github/*.xml phpBB/ext/$EXTNAME/.github +cp -R .github/*.sh phpBB/ext/$EXTNAME/.github diff --git a/travis/setup-database.sh b/.github/setup-database.sh similarity index 59% rename from travis/setup-database.sh rename to .github/setup-database.sh index cbd5e93e835..49af1a70e90 100755 --- a/travis/setup-database.sh +++ b/.github/setup-database.sh @@ -12,13 +12,7 @@ set -e set -x DB=$1 -TRAVIS_PHP_VERSION=$2 -NOTESTS=$3 - -if [ "$NOTESTS" == '1' ] -then - exit 0 -fi +MYISAM=$2 if [ "$DB" == "postgres" ] then @@ -26,12 +20,7 @@ then psql -c 'create database phpbb_tests;' -U postgres fi -if [ "$TRAVIS_PHP_VERSION" == "5.6" -a "$DB" == "mysqli" ] -then - mysql -e 'SET GLOBAL storage_engine=MyISAM;' -fi - -if [ "$DB" == "mysql" -o "$DB" == "mysqli" -o "$DB" == "mariadb" ] +if [ "$MYISAM" == '1' ] then - mysql -e 'create database IF NOT EXISTS phpbb_tests;' + mysql -h 127.0.0.1 -u root -e 'SET GLOBAL default_storage_engine=MyISAM;' fi diff --git a/travis/setup-exiftool.sh b/.github/setup-exiftool.sh similarity index 94% rename from travis/setup-exiftool.sh rename to .github/setup-exiftool.sh index 04999b86006..082e621c7bb 100755 --- a/travis/setup-exiftool.sh +++ b/.github/setup-exiftool.sh @@ -10,5 +10,4 @@ # set -e -sudo apt-get update sudo apt-get install -y parallel libimage-exiftool-perl diff --git a/.github/setup-ldap.sh b/.github/setup-ldap.sh new file mode 100755 index 00000000000..226c625ee10 --- /dev/null +++ b/.github/setup-ldap.sh @@ -0,0 +1,19 @@ +#!/bin/bash +# +# This file is part of the phpBB Forum Software package. +# +# @copyright (c) phpBB Limited +# @license GNU General Public License, version 2 (GPL-2.0) +# +# For full copyright and license information, please see +# the docs/CREDITS.txt file. +# +set -e +set -x + +sudo apt-get -y install ldap-utils slapd +mkdir /var/tmp/slapd +cp .github/ldap/slapd.conf /var/tmp/slapd/slapd.conf +slapd -d 256 -d 128 -f /var/tmp/slapd/slapd.conf -h ldap://localhost:3389 & +sleep 3 +ldapadd -H ldap://localhost:3389 -D "cn=admin,dc=example,dc=com" -w adminadmin -f .github/ldap/base.ldif diff --git a/travis/setup-phpbb.sh b/.github/setup-phpbb.sh similarity index 66% rename from travis/setup-phpbb.sh rename to .github/setup-phpbb.sh index be9eb703d52..cfec319f2e5 100755 --- a/travis/setup-phpbb.sh +++ b/.github/setup-phpbb.sh @@ -12,28 +12,18 @@ set -e set -x DB=$1 -TRAVIS_PHP_VERSION=$2 +PHP_VERSION=$2 NOTESTS=$3 if [ "$NOTESTS" == '1' ] then - travis/setup-exiftool.sh - travis/setup-unbuffer.sh -fi - -if [ "$DB" == "mariadb" ] -then - travis/setup-mariadb.sh -fi - -if [ "$NOTESTS" != '1' ] -then - travis/setup-php-extensions.sh + .github/setup-exiftool.sh + .github/setup-unbuffer.sh fi if [ "$NOTESTS" != '1' ] then - travis/setup-webserver.sh + .github/setup-webserver.sh fi cd phpBB diff --git a/.github/setup-sphinx.sh b/.github/setup-sphinx.sh new file mode 100755 index 00000000000..9e056aa1b89 --- /dev/null +++ b/.github/setup-sphinx.sh @@ -0,0 +1,143 @@ +#!/bin/bash +# +# This file is part of the phpBB Forum Software package. +# +# @copyright (c) phpBB Limited +# @license GNU General Public License, version 2 (GPL-2.0) +# +# For full copyright and license information, please see +# the docs/CREDITS.txt file. +# +set -e +set -x + +sudo apt-get install -q -y sphinxsearch + +DIR=$(dirname "$0") + +SPHINX_DAEMON_HOST="localhost" +SPHINX_DAEMON_PORT="9312" +SPHINX_CONF="$DIR/sphinx.conf" +SPHINX_DATA_DIR="/var/run/sphinxsearch" +SPHINX_LOG="$SPHINX_DATA_DIR/log/searchd.log" +SPHINX_QUERY_LOG="$SPHINX_DATA_DIR/log/sphinx-query.log" +ID="saw9zf2fdhp1goue" # Randomly generated via phpBB unique_id() + +PHPBB_TEST_DBHOST="0.0.0.0" +PHPBB_TEST_DBNAME="phpbb_tests" +PHPBB_TEST_DBUSER="root" +PHPBB_TEST_DBPASSWD="" + +sudo service sphinxsearch stop +sudo mkdir -p "$SPHINX_DATA_DIR/log" +sudo chown "sphinxsearch" "$SPHINX_DATA_DIR/log" + +# Generate configuration file for Sphinx +echo " +source source_phpbb_${ID}_main +{ + type = mysql # mysql or pgsql + sql_host = $PHPBB_TEST_DBHOST + sql_user = $PHPBB_TEST_DBUSER + sql_pass = $PHPBB_TEST_DBPASSWD + sql_db = $PHPBB_TEST_DBNAME + sql_port = + sql_query_pre = SET NAMES 'utf8' + sql_query_pre = UPDATE phpbb_sphinx SET max_doc_id = (SELECT MAX(post_id) FROM phpbb_posts) WHERE counter_id = 1 + sql_query_range = SELECT MIN(post_id), MAX(post_id) FROM phpbb_posts + sql_range_step = 5000 + sql_query = SELECT \ + p.post_id AS id, \ + p.forum_id, \ + p.topic_id, \ + p.poster_id, \ + p.post_visibility, \ + CASE WHEN p.post_id = t.topic_first_post_id THEN 1 ELSE 0 END as topic_first_post, \ + p.post_time, \ + p.post_subject, \ + p.post_subject as title, \ + p.post_text as data, \ + t.topic_last_post_time, \ + 0 as deleted \ + FROM phpbb_posts p, phpbb_topics t \ + WHERE \ + p.topic_id = t.topic_id \ + AND p.post_id >= \$start AND p.post_id <= \$end + sql_query_post = + sql_query_post_index = UPDATE phpbb_sphinx SET max_doc_id = \$maxid WHERE counter_id = 1 + sql_attr_uint = forum_id + sql_attr_uint = topic_id + sql_attr_uint = poster_id + sql_attr_uint = post_visibility + sql_attr_bool = topic_first_post + sql_attr_bool = deleted + sql_attr_timestamp = post_time + sql_attr_timestamp = topic_last_post_time + sql_attr_string = post_subject +} +source source_phpbb_${ID}_delta : source_phpbb_${ID}_main +{ + sql_query_pre = SET NAMES 'utf8' + sql_query_range = + sql_range_step = + sql_query = SELECT \ + p.post_id AS id, \ + p.forum_id, \ + p.topic_id, \ + p.poster_id, \ + p.post_visibility, \ + CASE WHEN p.post_id = t.topic_first_post_id THEN 1 ELSE 0 END as topic_first_post, \ + p.post_time, \ + p.post_subject, \ + p.post_subject as title, \ + p.post_text as data, \ + t.topic_last_post_time, \ + 0 as deleted \ + FROM phpbb_posts p, phpbb_topics t \ + WHERE \ + p.topic_id = t.topic_id \ + AND p.post_id >= ( SELECT max_doc_id FROM phpbb_sphinx WHERE counter_id=1 ) + sql_query_post_index = +} +index index_phpbb_${ID}_main +{ + path = $SPHINX_DATA_DIR/index_phpbb_${ID}_main + source = source_phpbb_${ID}_main + docinfo = extern + morphology = none + stopwords = + wordforms = + exceptions = + min_word_len = 2 + charset_table = U+FF10..U+FF19->0..9, 0..9, U+FF41..U+FF5A->a..z, U+FF21..U+FF3A->a..z, A..Z->a..z, a..z, U+0149, U+017F, U+0138, U+00DF, U+00FF, U+00C0..U+00D6->U+00E0..U+00F6, U+00E0..U+00F6, U+00D8..U+00DE->U+00F8..U+00FE, U+00F8..U+00FE, U+0100->U+0101, U+0101, U+0102->U+0103, U+0103, U+0104->U+0105, U+0105, U+0106->U+0107, U+0107, U+0108->U+0109, U+0109, U+010A->U+010B, U+010B, U+010C->U+010D, U+010D, U+010E->U+010F, U+010F, U+0110->U+0111, U+0111, U+0112->U+0113, U+0113, U+0114->U+0115, U+0115, U+0116->U+0117, U+0117, U+0118->U+0119, U+0119, U+011A->U+011B, U+011B, U+011C->U+011D, U+011D, U+011E->U+011F, U+011F, U+0130->U+0131, U+0131, U+0132->U+0133, U+0133, U+0134->U+0135, U+0135, U+0136->U+0137, U+0137, U+0139->U+013A, U+013A, U+013B->U+013C, U+013C, U+013D->U+013E, U+013E, U+013F->U+0140, U+0140, U+0141->U+0142, U+0142, U+0143->U+0144, U+0144, U+0145->U+0146, U+0146, U+0147->U+0148, U+0148, U+014A->U+014B, U+014B, U+014C->U+014D, U+014D, U+014E->U+014F, U+014F, U+0150->U+0151, U+0151, U+0152->U+0153, U+0153, U+0154->U+0155, U+0155, U+0156->U+0157, U+0157, U+0158->U+0159, U+0159, U+015A->U+015B, U+015B, U+015C->U+015D, U+015D, U+015E->U+015F, U+015F, U+0160->U+0161, U+0161, U+0162->U+0163, U+0163, U+0164->U+0165, U+0165, U+0166->U+0167, U+0167, U+0168->U+0169, U+0169, U+016A->U+016B, U+016B, U+016C->U+016D, U+016D, U+016E->U+016F, U+016F, U+0170->U+0171, U+0171, U+0172->U+0173, U+0173, U+0174->U+0175, U+0175, U+0176->U+0177, U+0177, U+0178->U+00FF, U+00FF, U+0179->U+017A, U+017A, U+017B->U+017C, U+017C, U+017D->U+017E, U+017E, U+0410..U+042F->U+0430..U+044F, U+0430..U+044F, U+4E00..U+9FFF + ignore_chars = U+0027, U+002C + min_prefix_len = 3 + min_infix_len = 0 + html_strip = 1 + index_exact_words = 0 + blend_chars = U+23, U+24, U+25, U+26, U+40 +} +index index_phpbb_${ID}_delta : index_phpbb_${ID}_main +{ + path = $SPHINX_DATA_DIR/index_phpbb_${ID}_delta + source = source_phpbb_${ID}_delta +} +indexer +{ + mem_limit = 512M +} +searchd +{ + listen = $SPHINX_DAEMON_PORT + log = $SPHINX_LOG + query_log = $SPHINX_QUERY_LOG + read_timeout = 5 + max_children = 30 + pid_file = $SPHINX_DATA_DIR/searchd.pid + binlog_path = $SPHINX_DATA_DIR +} +" > $SPHINX_CONF + +sudo mv "$SPHINX_CONF" "/etc/sphinxsearch/sphinx.conf" +sudo sed -i "s/START=no/START=yes/g" "/etc/default/sphinxsearch" +sudo chmod 777 "/var/run/sphinxsearch" diff --git a/travis/setup-unbuffer.sh b/.github/setup-unbuffer.sh similarity index 94% rename from travis/setup-unbuffer.sh rename to .github/setup-unbuffer.sh index 4423d1b8b6b..4828a88997c 100755 --- a/travis/setup-unbuffer.sh +++ b/.github/setup-unbuffer.sh @@ -10,5 +10,4 @@ # set -e -sudo apt-get update sudo apt-get install -y expect-dev diff --git a/.github/setup-webserver.sh b/.github/setup-webserver.sh new file mode 100755 index 00000000000..7232807e3ef --- /dev/null +++ b/.github/setup-webserver.sh @@ -0,0 +1,80 @@ +#!/bin/bash +# +# This file is part of the phpBB Forum Software package. +# +# @copyright (c) phpBB Limited +# @license GNU General Public License, version 2 (GPL-2.0) +# +# For full copyright and license information, please see +# the docs/CREDITS.txt file. +# +set -e +set -x + +sudo apt-get install -y nginx coreutils + +sudo service nginx stop + +DIR=$(dirname "$0") +USER=$(whoami) +PHPBB_ROOT_PATH=$(realpath "$DIR/../phpBB") +NGINX_SITE_CONF="/etc/nginx/sites-enabled/default" +NGINX_CONF="/etc/nginx/nginx.conf" +APP_SOCK=$(realpath "$DIR")/php-app.sock +NGINX_PHP_CONF="$DIR/nginx-php.conf" + +# php-fpm +PHP_FPM_BIN="/usr/sbin/php-fpm$PHP_VERSION" +PHP_FPM_CONF="$DIR/php-fpm.conf" + +if [ ! -f $PHP_FPM_BIN ] && [ -f "/usr/bin/php-fpm" ] +then + PHP_FPM_BIN="/usr/bin/php-fpm" +fi + +if [ ! -f $PHP_FPM_BIN ] +then + sudo apt-get install php$PHP_VERSION-fpm php$PHP_VERSION-cli \ + php$PHP_VERSION-curl php$PHP_VERSION-xml php$PHP_VERSION-mbstring \ + php$PHP_VERSION-zip php$PHP_VERSION-mysql php$PHP_VERSION-sqlite3 \ + php$PHP_VERSION-intl php$PHP_VERSION-gd php$PHP_VERSION-pgsql + sudo service php$PHP_VERSION-fpm start + sudo service php$PHP_VERSION-fpm status +fi + +echo " + [global] + + [ci] + user = $USER + group = $USER + listen = $APP_SOCK + listen.mode = 0666 + pm = static + pm.max_children = 2 + + php_admin_value[memory_limit] = 128M +" > $PHP_FPM_CONF + +sudo $PHP_FPM_BIN \ + --fpm-config "$DIR/php-fpm.conf" + +# nginx +sudo sed -i "s/user www-data;/user $USER;/g" $NGINX_CONF +sudo cp "$DIR/../phpBB/docs/nginx.sample.conf" "$NGINX_SITE_CONF" +sudo sed -i \ + -e "s/example\.com/localhost/g" \ + -e "s|root /path/to/phpbb;|root $PHPBB_ROOT_PATH;|g" \ + $NGINX_SITE_CONF + +# Generate FastCGI configuration for Nginx +echo " +upstream php { + server unix:$APP_SOCK; +} +" > $NGINX_PHP_CONF + +sudo mv "$NGINX_PHP_CONF" /etc/nginx/conf.d/php.conf + +sudo nginx -T +sudo service nginx start diff --git a/.github/workflows/check_merge_to_master.yml b/.github/workflows/check_merge_to_master.yml new file mode 100644 index 00000000000..45288a072a9 --- /dev/null +++ b/.github/workflows/check_merge_to_master.yml @@ -0,0 +1,70 @@ +name: Check merge to master + +on: + pull_request_target: + types: [ opened, synchronize, reopened ] + branches: + - 3.3.x + +jobs: + merge-check: + if: github.event_name == 'pull_request_target' && github.event.pull_request.base.ref == '3.3.x' + runs-on: ubuntu-latest + steps: + - name: Checkout the repository + uses: actions/checkout@v3 + with: + fetch-depth: 0 # Ensure full history is fetched + + - name: Set up Git user + run: | + git config --global user.name "github-actions" + git config --global user.email "github-actions@github.com" + + - name: Fetch all branches + run: git fetch origin + + - name: Simulate merging PR into 3.3.x + id: simulate_merge + run: | + git checkout 3.3.x + git fetch origin pull/${{ github.event.pull_request.number }}/head + git merge --no-ff FETCH_HEAD || exit 1 + + - name: Attempt to merge updated 3.3.x into master + id: merge_master + run: | + git checkout master + if git merge --no-ff 3.3.x --no-commit; then + echo "mergeable=true" >> $GITHUB_OUTPUT + else + echo "mergeable=false" >> $GITHUB_OUTPUT + git merge --abort + fi + + - name: Find Comment + uses: peter-evans/find-comment@v3 + id: fc + with: + issue-number: ${{ github.event.pull_request.number }} + comment-author: 'github-actions[bot]' + body-includes: The attempt to merge branch `3.3.x` into `master` has completed + + - name: Post comment on PR + if: always() # Ensure this step always runs, regardless of merge result + uses: peter-evans/create-or-update-comment@v4 + with: + token: ${{ secrets.GITHUB_TOKEN }} + issue-number: ${{ github.event.pull_request.number }} + comment-id: ${{ steps.fc.outputs.comment-id }} + edit-mode: replace + body: | + The attempt to merge branch `3.3.x` into `master` has completed after considering the changes in this PR. + + - Merge result: ${{ steps.merge_master.outputs.mergeable == 'true' && 'Success ✅' || 'Conflict ❌' }} + + ${{ steps.merge_master.outputs.mergeable == 'true' && 'This PR is ready to be merged.' || 'A separate PR will be needed to merge `3.3.x` into `master`.' }} + + - name: Mark job as succeeded + if: always() + run: echo "Merge check completed. Ignoring the result to avoid failed status." diff --git a/.github/workflows/merge_3.3.x_to_master.yml b/.github/workflows/merge_3.3.x_to_master.yml new file mode 100644 index 00000000000..9aea009c3a3 --- /dev/null +++ b/.github/workflows/merge_3.3.x_to_master.yml @@ -0,0 +1,60 @@ +name: Merge 3.3.x into master + +on: + push: + branches: + - 3.3.x + +jobs: + merge-branch: + runs-on: ubuntu-latest + + steps: + - uses: actions/create-github-app-token@v1 + id: app-token + with: + app-id: ${{ vars.MERGE_MASTER_APP_ID }} + private-key: ${{ secrets.MERGE_MASTER_SECRET }} + + - name: Checkout the repository + uses: actions/checkout@v4 + with: + fetch-depth: 0 # Fetch full history for proper merging + ref: 3.3.x # Checkout the 3.3.x branch + token: ${{ steps.app-token.outputs.token }} + + - name: Fetch the latest commit information + id: get-commit-info + run: | + # Get the latest commit SHA and its author details + COMMIT_SHA=$(git rev-parse HEAD) + COMMIT_AUTHOR_NAME=$(git log -1 --pretty=format:'%an' $COMMIT_SHA) + COMMIT_AUTHOR_EMAIL=$(git log -1 --pretty=format:'%ae' $COMMIT_SHA) + + # Save them as output for later steps + echo "commit_sha=$COMMIT_SHA" >> $GITHUB_ENV + echo "commit_author_name=$COMMIT_AUTHOR_NAME" >> $GITHUB_ENV + echo "commit_author_email=$COMMIT_AUTHOR_EMAIL" >> $GITHUB_ENV + + - name: Set up Git with the pull request author's info + run: | + git config --global user.name "${{ env.commit_author_name }}" + git config --global user.email "${{ env.commit_author_email }}" + + - name: Fetch all branches + run: git fetch --all + + - name: Merge 3.3.x into master + run: | + git checkout master + if git merge --no-ff 3.3.x; then + echo "merge_failed=false" >> $GITHUB_ENV + else + echo "merge_failed=true" >> $GITHUB_ENV + fi + + - name: Push changes to master if merge was successful + if: env.merge_failed == 'false' + run: git push origin master + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml new file mode 100644 index 00000000000..319ddaf4edd --- /dev/null +++ b/.github/workflows/tests.yml @@ -0,0 +1,636 @@ +name: Tests + +on: + push: + branches: + - 3.3.x + - master + - 'prep-release-*' + tags: + - 'release-*' + pull_request: + branches: + - 3.3.x + - master + - 'prep-release-*' + +jobs: + # Basic checks, e.g. parse errors, commit messages, etc. + basic-checks: + runs-on: ubuntu-latest + strategy: + matrix: + include: + - db: 'none' + php: '8.2' + NOTESTS: 1 + + name: PHP ${{ matrix.php }} - ${{ matrix.db }} + + steps: + - name: Update Ubuntu package lists + run: | + sudo apt-get update -y --allow-releaseinfo-change + + - name: Checkout repository + uses: actions/checkout@v4 + with: + fetch-depth: 100 + + - name: Setup PHP + uses: shivammathur/setup-php@v2 + with: + php-version: ${{ matrix.php }} + extensions: dom, curl, libxml, mbstring, zip, pcntl, intl, gd, exif, iconv + coverage: none + + - name: Get Composer Cache Directory + id: composer-cache + run: | + cd phpBB + echo "dir=$(composer config cache-files-dir)" >> $GITHUB_OUTPUT + cd .. + + - name: Cache Composer dependencies + uses: actions/cache@v4 + with: + path: ${{ steps.composer-cache.outputs.dir }} + key: composer-${{ matrix.php }}-${{ hashFiles('phpBB/composer.lock') }} + + - name: Setup environment for phpBB + env: + DB: ${{ matrix.db }} + PHP_VERSION: ${{ matrix.php }} + NOTESTS: '1' + run: | + .github/setup-phpbb.sh $DB $PHP_VERSION $NOTESTS + + - name: Phing sniff + run: | + .github/phing-sniff.sh + + - name: Check doctum parse errors + run: | + .github/check-doctum-parse-errors.sh + + - name: Check code with psalm + run: | + phpBB/vendor/bin/psalm --output-format=github + + - name: Check image ICC profiles + run: | + .github/check-image-icc-profiles.sh + + - name: Check executable files + run: | + .github/check-executable-files.sh ./ + + - name: Check stylesheets + run: | + .github/check-stylesheet.sh + + - name: Lint JavaScript files + run: | + .github/check-js.sh + + - name: Check commit message + if: github.event_name == 'pull_request' + run: | + git fetch origin $GITHUB_BASE_REF &> /dev/null + git-tools/commit-msg-hook-range.sh $(git rev-parse origin/$GITHUB_BASE_REF)..$GITHUB_SHA + + # Tests for MySQL and MariaDB + mysql-tests: + runs-on: ubuntu-latest + strategy: + matrix: + include: + - php: '8.2' + db: "mariadb:10.2" + - php: '8.2' + db: "mariadb:10.3" + - php: '8.2' + db: "mariadb:10.4" + - php: '8.2' + db: "mariadb:10.6" + - php: '8.2' + db: "mariadb:10.9" + - php: '8.2' + db: "mariadb:10.10" + - php: '8.2' + db: "mariadb:10.11" + - php: '8.2' + db: "mysql:8.0" + db_alias: "MySQL Slow Tests" + SLOWTESTS: 1 + - php: '8.2' + db: "mysql:8.0" + db_alias: "MyISAM Tests" + MYISAM: 1 + - php: '8.2' + db: "mysql:8.0" + - php: '8.2' + db: "mysql:8.4" + - php: '8.2' + db: "mysql:9.4" + - php: '8.3' + db: "mysql:8.0" + - php: '8.4' + db: "mysql:8.4" + - php: '8.5' + db: "mysql:8.4" + - php: '8.5' + db: "mysql:9.4" + + name: PHP ${{ matrix.php }} - ${{ matrix.db_alias != '' && matrix.db_alias || matrix.db }} + + services: + mysql: + image: ${{ matrix.db }} + env: + MYSQL_ALLOW_EMPTY_PASSWORD: yes + MYSQL_DATABASE: phpbb_tests + ports: + - 3306:3306 + options: >- + --health-cmd="mysqladmin ping" + --health-interval=10s + --health-timeout=5s + --health-retries=3 + + redis: + image: redis + options: >- + --health-cmd "redis-cli ping" + --health-interval 10s + --health-timeout 5s + --health-retries 5 + ports: + - 6379:6379 + + steps: + - name: Update Ubuntu package lists + run: | + sudo apt-get update -y --allow-releaseinfo-change + + - name: Checkout repository + uses: actions/checkout@v4 + + - id: database-type + env: + MATRIX_DB: ${{ matrix.db }} + run: | + db=$(echo "${MATRIX_DB%%:*}") + echo "db=$db" >> $GITHUB_OUTPUT + + - name: Setup PHP + uses: shivammathur/setup-php@v2 + with: + php-version: ${{ matrix.php }} + extensions: dom, curl, libxml, mbstring, zip, pcntl, intl, gd, exif, iconv, mysqli, pdo, pdo_mysql, ldap + coverage: none + + - name: Get Composer Cache Directory + id: composer-cache + env: + PHP_VERSION: ${{ matrix.php }} + run: | + cd phpBB + echo "dir=$(composer config cache-files-dir)" >> $GITHUB_OUTPUT + cd .. + + - name: Cache Composer dependencies + uses: actions/cache@v4 + with: + path: ${{ steps.composer-cache.outputs.dir }} + key: composer-${{ matrix.php }}-${{ hashFiles('phpBB/composer.lock') }} + + - name: Setup environment for phpBB + env: + DB: ${{steps.database-type.outputs.db}} + PHP_VERSION: ${{ matrix.php }} + NOTESTS: '0' + run: | + .github/setup-phpbb.sh $DB $PHP_VERSION ${NOTESTS:-0} + + - name: Setup database + env: + DB: ${{steps.database-type.outputs.db}} + MYISAM: ${{ matrix.MYISAM != 1 && '0' || '1' }} + run: | + .github/setup-database.sh $DB $MYISAM + + - name: Setup LDAP + if: ${{ matrix.SLOWTESTS == 1 }} + run: | + .github/setup-ldap.sh + + - name: Setup node + uses: actions/setup-node@v6 + with: + node-version: 20 + - name: Setup node dependencies + run: npm ci + + - name: Setup SPHINX + run: | + .github/setup-sphinx.sh + + - name: Lint tests + if: ${{ matrix.SLOWTESTS != 1 && steps.database-type.outputs.db == 'mysql' }} + run: phpBB/vendor/bin/phpunit tests/lint_test.php + + - name: Run unit tests + env: + DB: ${{steps.database-type.outputs.db}} + if: ${{ matrix.SLOWTESTS != 1 && matrix.NOTESTS != 1 }} + run: | + phpBB/vendor/bin/phpunit --configuration .github/phpunit-$DB-github.xml --display-all-issues --stop-on-error + + - name: Slow tests + env: + DB: ${{steps.database-type.outputs.db}} + if: ${{ matrix.SLOWTESTS == 1 }} + run: | + phpBB/vendor/bin/phpunit --configuration .github/phpunit-$DB-github.xml --group slow + + # Tests for PostgreSQL + postgres-tests: + runs-on: ubuntu-latest + strategy: + matrix: + include: + - php: '8.2' + db: "postgres:9.5" + - php: '8.2' + db: "postgres:9.6" + - php: '8.2' + db: "postgres:10" + - php: '8.2' + db: "postgres:11" + - php: '8.2' + db: "postgres:12" + - php: '8.2' + db: "postgres:13" + - php: '8.2' + db: "postgres:14" + - php: '8.2' + db: "postgres:15" + - php: '8.3' + db: "postgres:9.5" + - php: '8.4' + db: "postgres:9.5" + - php: '8.5' + db: "postgres:9.5" + + name: PHP ${{ matrix.php }} - ${{ matrix.db }} + + services: + postgres: + image: ${{ matrix.db != 'postgres:9.5' && matrix.db != 'postgres:9.6' && matrix.db != 'postgres:10' && matrix.db != 'postgres:11' && matrix.db != 'postgres:12' && matrix.db != 'postgres:13' && matrix.db != 'postgres:14' && matrix.db != 'postgres:15' && 'postgres:10' || matrix.db }} + env: + POSTGRES_HOST: localhost + POSTGRES_USER: postgres + POSTGRES_PASSWORD: postgres + ports: + - 5432:5432 + options: >- + -v /var/run/postgresql:/var/run/postgresql + --health-cmd pg_isready + --health-interval 10s + --health-timeout 5s + --health-retries 5 + + redis: + image: redis + options: >- + --health-cmd "redis-cli ping" + --health-interval 10s + --health-timeout 5s + --health-retries 5 + ports: + - 6379:6379 + + steps: + - name: Update Ubuntu package lists + run: | + sudo apt-get update -y --allow-releaseinfo-change + + - name: Checkout repository + uses: actions/checkout@v4 + + - id: database-type + env: + MATRIX_DB: ${{ matrix.db }} + run: | + db=$(echo "${MATRIX_DB%%:*}") + echo "db=$db" >> $GITHUB_OUTPUT + + - name: Setup PHP + uses: shivammathur/setup-php@v2 + with: + php-version: ${{ matrix.php }} + extensions: dom, curl, libxml, mbstring, zip, pcntl, intl, gd, exif, iconv, pgsql, pdo, pdo_pgsql + coverage: none + + - name: Get Composer Cache Directory + id: composer-cache + env: + PHP_VERSION: ${{ matrix.php }} + run: | + cd phpBB + echo "dir=$(composer config cache-files-dir)" >> $GITHUB_OUTPUT + cd .. + + - name: Cache Composer dependencies + uses: actions/cache@v4 + with: + path: ${{ steps.composer-cache.outputs.dir }} + key: composer-${{ matrix.php }}-${{ hashFiles('phpBB/composer.lock') }} + + - name: Setup environment for phpBB + env: + DB: ${{steps.database-type.outputs.db}} + PHP_VERSION: ${{ matrix.php }} + NOTESTS: '0' + run: | + .github/setup-phpbb.sh $DB $PHP_VERSION ${NOTESTS:-0} + + - name: Setup database + env: + DB: ${{steps.database-type.outputs.db}} + MYISAM: '0' + run: | + .github/setup-database.sh $DB $MYISAM + + - name: Setup node + uses: actions/setup-node@v6 + with: + node-version: 20 + - name: Setup node dependencies + run: npm ci + + - name: Run unit tests + env: + DB: ${{steps.database-type.outputs.db}} + run: | + phpBB/vendor/bin/phpunit --configuration .github/phpunit-$DB-github.xml --display-all-issues --stop-on-error + + # Other database types, namely sqlite3 and mssql + other-tests: + runs-on: ubuntu-22.04 + strategy: + matrix: + include: + - php: '8.2' + db: "sqlite3" + - php: '8.2' + db: "mcr.microsoft.com/mssql/server:2019-CU27-ubuntu-20.04" + db_alias: 'MSSQL 2019' + - php: '8.2' + db: "mcr.microsoft.com/mssql/server:2022-CU13-ubuntu-22.04" + db_alias: 'MSSQL 2022' + + name: PHP ${{ matrix.php }} - ${{ matrix.db_alias != '' && matrix.db_alias || matrix.db }} + + services: + mssql: + image: ${{ matrix.db != 'mcr.microsoft.com/mssql/server:2019-CU27-ubuntu-20.04' && matrix.db != 'mcr.microsoft.com/mssql/server:2022-CU13-ubuntu-22.04' && 'mcr.microsoft.com/mssql/server:2022-CU13-ubuntu-22.04' || matrix.db }} + env: + SA_PASSWORD: "Pssw0rd_12" + ACCEPT_EULA: "y" + ports: + - 1433:1433 + options: >- + --health-cmd="/opt/mssql-tools/bin/sqlcmd -S localhost -U sa -P 'Pssw0rd_12' -Q \"Use [master]; CREATE DATABASE [phpbb_tests] COLLATE Latin1_General_CI_AS\" || exit 1" + --health-interval 10s + --health-timeout 5s + --health-retries 5 + --health-start-period 10s + + redis: + image: redis + options: >- + --health-cmd "redis-cli ping" + --health-interval 10s + --health-timeout 5s + --health-retries 5 + ports: + - 6379:6379 + + + steps: + - name: Update Ubuntu package lists + run: | + sudo apt-get update -y --allow-releaseinfo-change + + - name: Checkout repository + uses: actions/checkout@v4 + + - id: database-type + env: + MATRIX_DB: ${{ matrix.db }} + run: | + if [ $MATRIX_DB == 'mcr.microsoft.com/mssql/server:2019-CU27-ubuntu-20.04' ] || [ $MATRIX_DB == 'mcr.microsoft.com/mssql/server:2022-CU13-ubuntu-22.04' ] + then + db='mssql' + else + db=$(echo "${MATRIX_DB%%:*}") + fi + echo "db=$db" >> $GITHUB_OUTPUT + + - name: Setup PHP + uses: shivammathur/setup-php@v2 + with: + php-version: ${{ matrix.php }} + extensions: dom, curl, libxml, mbstring, zip, pcntl, intl, gd, exif, iconv, sqlsrv, pdo, pdo_sqlsrv + coverage: none + + - name: Get Composer Cache Directory + id: composer-cache + env: + PHP_VERSION: ${{ matrix.php }} + run: | + cd phpBB + echo "dir=$(composer config cache-files-dir)" >> $GITHUB_OUTPUT + cd .. + + - name: Cache Composer dependencies + uses: actions/cache@v4 + with: + path: ${{ steps.composer-cache.outputs.dir }} + key: composer-${{ matrix.php }}-${{ hashFiles('phpBB/composer.lock') }} + + - name: Setup environment for phpBB + env: + DB: ${{steps.database-type.outputs.db}} + PHP_VERSION: ${{ matrix.php }} + NOTESTS: '0' + run: | + .github/setup-phpbb.sh $DB $PHP_VERSION ${NOTESTS:-0} + + - name: Setup database + env: + DB: ${{steps.database-type.outputs.db}} + MYISAM: '0' + run: | + .github/setup-database.sh $DB $MYISAM + + - name: Setup node + uses: actions/setup-node@v6 + with: + node-version: 20 + - name: Setup node dependencies + run: npm ci + + - name: Run unit tests + env: + DB: ${{steps.database-type.outputs.db}} + run: | + phpBB/vendor/bin/phpunit --configuration .github/phpunit-$DB-github.xml --display-all-issues --stop-on-error + + # Test with IIS & PostgreSQL on Windows + windows-tests: + runs-on: windows-2025 + strategy: + matrix: + php: ['8.2', '8.3', '8.4', '8.5'] + db: ['postgres'] + + name: Windows - PHP ${{ matrix.php }} - ${{ matrix.db }} + + steps: + - name: Prepare git for Windows + run: | + git config --system core.autocrlf false + git config --system core.eol lf + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Setup PHP + uses: shivammathur/setup-php@v2 + with: + php-version: ${{ matrix.php }} + extensions: dom, curl, libxml, mbstring, zip, pcntl, pdo, intl, gd, exif, iconv, pgsql, pdo_pgsql, sodium, bz2, fileinfo + ini-values: upload_tmp_dir=${{ runner.temp }}, sys_temp_dir=${{ runner.temp }} + coverage: none + + - name: Get Composer Cache Directory + id: composer-cache + run: | + cd phpBB + echo "dir=$(composer config cache-files-dir)" >> $env:GITHUB_OUTPUT + cd .. + + - name: Cache Composer dependencies + uses: actions/cache@v4 + with: + path: ${{ steps.composer-cache.outputs.dir }} + key: composer-${{ matrix.php }}-${{ hashFiles('phpBB/composer.lock') }} + + - name: Setup environment for phpBB + env: + GITHUB_WORKSPACE: ${{ github.workspace }} + TEMP_DIR: ${{ runner.temp }} + run: | + # Disable Windows Defender real-time monitoring early to improve performance + Set-MpPreference -DisableRealtimeMonitoring $true + + Enable-WindowsOptionalFeature -Online -FeatureName IIS-WebServerRole, IIS-WebServer, IIS-CommonHttpFeatures, IIS-ManagementConsole, IIS-HttpErrors, IIS-HttpRedirect, IIS-WindowsAuthentication, IIS-StaticContent, IIS-DefaultDocument, IIS-HttpCompressionStatic, IIS-DirectoryBrowsing, IIS-WebServerManagementTools, IIS-CGI -All + Set-Service wuauserv -StartupType Manual + (Get-Content ${env:GITHUB_WORKSPACE}\phpBB\web.config).replace("", "`n`t`n`t`t`n`t") | Set-Content ${env:GITHUB_WORKSPACE}\phpBB\web.config + (Get-Content ${env:GITHUB_WORKSPACE}\phpBB\web.config).replace("`t", "`t`t`n`t") | Set-Content ${env:GITHUB_WORKSPACE}\phpBB\web.config + choco install urlrewrite -y + Import-Module WebAdministration + New-WebSite -Name 'phpBBTest' -PhysicalPath "${env:GITHUB_WORKSPACE}\phpBB" -Force + $session = Get-PSSession -Name WinPSCompatSession + $sb = {Set-ItemProperty 'IIS:\Sites\phpBBTest' -name Bindings -value @{protocol='http';bindingInformation='*:80:phpbb.test'}} + Invoke-Command -Scriptblock $sb -Session $session + $sb = {Set-WebConfigurationProperty -filter /system.WebServer/security/authentication/AnonymousAuthentication -name enabled -value true -location "IIS:\Sites\phpBBTest"} + Invoke-Command -Scriptblock $sb -Session $session + Add-Content -Path $env:windir\System32\drivers\etc\hosts -Value "`r`n127.0.0.1`tphpbb.test" -Force + [System.Environment]::SetEnvironmentVariable('PATH',$Env:PATH+";%windir%\system32\inetsrv") + echo Setup FAST-CGI configuration + Add-WebConfiguration -Filter /system.webServer/fastCgi -PSPath IIS:\ -Value @{fullpath="C:\tools\php\php-cgi.exe"} + echo Setup FACT-CGI handler + New-WebHandler -Name "PHP-FastCGI" -Path "*.php" -Modules FastCgiModule -ScriptProcessor "C:\tools\php\php-cgi.exe" -Verb '*' -ResourceType Either + iisreset + NET START W3SVC + + # Wait for IIS to be ready and test connectivity + Start-Sleep -Seconds 10 + try { + $response = Invoke-WebRequest -Uri "http://phpbb.test/" -UseBasicParsing -TimeoutSec 30 + Write-Host "Web server is responding: $($response.StatusCode)" + } catch { + Write-Host "Web server test failed: $_" + } + + # Create directories and set permissions more efficiently + $dirs = @("cache\test", "cache\installer") + foreach ($dir in $dirs) { + New-Item -Path "${env:GITHUB_WORKSPACE}\phpBB\$dir" -ItemType Directory -Force + } + + # Set permissions in batch for better performance + $paths = @("cache", "files", "store", "ext", "vendor-ext", "images\avatars\upload") + foreach ($path in $paths) { + if (Test-Path "${env:GITHUB_WORKSPACE}\phpBB\$path") { + icacls "${env:GITHUB_WORKSPACE}\phpBB\$path" /grant Users:F /T /Q + } + } + + # Set permissions for specific files + $files = @("composer-ext.json", "composer-ext.lock") + foreach ($file in $files) { + if (Test-Path "${env:GITHUB_WORKSPACE}\phpBB\$file") { + icacls "${env:GITHUB_WORKSPACE}\phpBB\$file" /grant Users:F /Q + } + } + + $accessRule = New-Object System.Security.AccessControl.FileSystemAccessRule("IIS_IUSRS", "FullControl", "ContainerInherit,ObjectInherit", "None", "Allow") + $acl = Get-ACL "${env:TEMP_DIR}" + $acl.AddAccessRule($accessRule) + Set-ACL -Path "${env:TEMP_DIR}" -ACLObject $acl + cd ${env:GITHUB_WORKSPACE}\phpBB + php ..\composer.phar install + cd .. + - name: Setup database + run: | + $postgreSqlSvc = Get-Service "postgresql*" + Set-Service $postgreSqlSvc.Name -StartupType manual + $runningStatus = [System.ServiceProcess.ServiceControllerStatus]::Running + $maxStartTimeout = New-TimeSpan -Seconds 120 + try { + $postgreSqlSvc.Start() + $postgreSqlSvc.WaitForStatus($runningStatus, $maxStartTimeout) + } catch { + $_ | select * + } + [System.Environment]::SetEnvironmentVariable('PATH',$Env:PATH+";${env:PGBIN}") + $env:PGPASSWORD = 'root' + + # Optimize PostgreSQL for testing performance + psql -c "ALTER SYSTEM SET fsync = off;" -U postgres + psql -c "ALTER SYSTEM SET synchronous_commit = off;" -U postgres + psql -c "ALTER SYSTEM SET checkpoint_completion_target = 0.9;" -U postgres + psql -c "ALTER SYSTEM SET wal_buffers = '16MB';" -U postgres + psql -c "ALTER SYSTEM SET shared_buffers = '128MB';" -U postgres + psql -c 'DROP DATABASE IF EXISTS phpbb_tests;' -U postgres + psql -c 'create database phpbb_tests;' -U postgres + + Set-MpPreference -ExclusionPath "${env:PGDATA}" # Exclude PGDATA directory from Windows Defender + + - name: Setup node + uses: actions/setup-node@v6 + with: + node-version: 20 + - name: Setup node dependencies + run: npm ci + + - name: Run unit tests + uses: nick-fields/retry@v3 + with: + timeout_minutes: 15 + max_attempts: 3 + command: phpBB/vendor/bin/phpunit --configuration .github/phpunit-psql-windows-github.xml --display-all-issues --stop-on-error --exclude-group functional,slow diff --git a/.gitignore b/.gitignore index 10a4e85c2ed..9d4e1bf2f9b 100644 --- a/.gitignore +++ b/.gitignore @@ -1,31 +1,60 @@ -*~ -/phpunit.xml +# Excludes cache /phpBB/cache/* !/phpBB/cache/.htaccess !/phpBB/cache/index.html -/phpBB/composer.phar + +# Excludes user data /phpBB/config*.php* /phpBB/ext/* /phpBB/files/* /phpBB/images/avatars/gallery/* /phpBB/images/avatars/upload/* /phpBB/images/ranks/* -/phpBB/install/schemas/schema.json +/phpBB/store/* + +# Excludes all custom langages /phpBB/language/* !/phpBB/language/en -/phpBB/store/* + +# Excludes all custom styles /phpBB/styles/* !/phpBB/styles/prosilver +!/phpBB/styles/prosilver/theme/en +!/phpBB/styles/prosilver/theme/images !/phpBB/styles/all -node_modules + +# Excludes all custom env +/phpBB/config/* +!/phpBB/config/default +!/phpBB/config/development +!/phpBB/config/installer +!/phpBB/config/production +!/phpBB/config/test +!/phpBB/config/.htaccess + +# Excludes vendors /phpBB/vendor /phpBB/vendor-ext/* !/phpBB/vendor-ext/.git-keep /phpBB/composer-ext.json /phpBB/composer-ext.lock + +# Excludes test / dev files +/phpunit.xml +/.phpunit.result.cache +/phpBB/composer.phar /tests/phpbb_unit_tests.sqlite* /tests/test_config*.php /tests/tmp/* /tests/vendor /vagrant/phpbb-install-config.yml .vagrant +node_modules +/build/package_signature + +# Excludes IDE / editors files +*~ +.idea +*.DS_Store* +/.vscode +/.phpunit.result.cache diff --git a/.jscsrc b/.jscsrc deleted file mode 100644 index 9dd5ab82e6c..00000000000 --- a/.jscsrc +++ /dev/null @@ -1,78 +0,0 @@ - -{ - "excludeFiles": ["node_modules/**", "**/build/**"], - "requireCurlyBraces": [ - "if", "else", "for", "while", "do", "try", "catch" - ], - "requireSpaceBeforeKeywords": [ - "else", "while", "catch" - ], - "requireSpaceAfterKeywords": [ - "do", "for", "if", "else", "switch", "case", "try", "catch", "while", "return", "typeof" - ], - "requireSpaceBeforeBlockStatements": true, - "requireParenthesesAroundIIFE": true, - "requireSpacesInConditionalExpression": { - "afterTest": true, - "beforeConsequent": true, - "afterConsequent": true, - "beforeAlternate": true - }, - "requireSpacesInAnonymousFunctionExpression": { - "beforeOpeningCurlyBrace": true - }, - "disallowSpacesInNamedFunctionExpression": { - "beforeOpeningRoundBrace": true - }, - "requireSpacesInFunction": { - "beforeOpeningCurlyBrace": true - }, - "disallowSpacesInCallExpression": true, - "requireBlocksOnNewline": true, - "requirePaddingNewlinesBeforeKeywords": ["case"], - "disallowEmptyBlocks": true, - "disallowSpacesInsideArrayBrackets": "nested", - "disallowSpacesInsideParentheses": true, - "requireSpacesInsideObjectBrackets": "all", - "disallowQuotedKeysInObjects": "allButReserved", - "disallowSpaceAfterObjectKeys": true, - "requireSpaceBeforeObjectValues": true, - "requireCommaBeforeLineBreak": true, - "requireOperatorBeforeLineBreak": [ - "?", "=", "+", "-", "/", "*", "===", "!==", ">", ">=", "<", "<=" - ], - "disallowSpaceAfterPrefixUnaryOperators": ["++", "--", "+", "-", "~", "!"], - "disallowSpaceBeforePostfixUnaryOperators": ["++", "--"], - "requireSpaceBeforeBinaryOperators": [ - "=", "+", "+=", "-", "-=", "/", "/=", "*", "*=", "===", "!==", "<", "<=", ">", ">=" - ], - "requireSpaceAfterBinaryOperators": [ - "=", "+", "+=", "-", "-=", "/", "/=", "*", "*=", "===", "!==", "<", "<=", ">", ">=" - ], - "disallowKeywords": ["with"], - "disallowMultipleLineStrings": true, - "disallowMixedSpacesAndTabs": "smart", - "disallowTrailingWhitespace": true, - "disallowTrailingComma": true, - "disallowKeywordsOnNewLine": ["else"], - "requireLineFeedAtFileEnd": true, - "maximumLineLength": { - "value": 120, - "tabSize": 4, - "allowUrlComments": true, - "allowRegex": true - }, - "requireCapitalizedConstructors": true, - "requireDotNotation": true, - "disallowYodaConditions": true, - "requireSpaceAfterLineComment": { - "allExcept": ["#", "="] - }, - "disallowNewlineBeforeBlockStatements": true, - "validateQuoteMarks": { - "mark": "'", - "escape": true - }, - "validateParameterSeparator": ", ", - "safeContextKeyword": ["that"] -} diff --git a/.jshintrc b/.jshintrc deleted file mode 100644 index c1efecd5735..00000000000 --- a/.jshintrc +++ /dev/null @@ -1,25 +0,0 @@ - -{ - "bitwise": true, - "curly": true, - "eqeqeq": true, - "es3": true, - "forin": false, - "freeze": true, - "newcap": true, - "noarg": true, - "noempty": true, - "nonbsp": true, - "undef": true, - "unused": true, - "strict": true, - - "browser": true, - "devel": true, - "jquery": true, - - "globals": { - "JSON": true, - "phpbb": true - } -} diff --git a/.postcss-sorting.json b/.postcss-sorting.json deleted file mode 100644 index 11a55f3c3d9..00000000000 --- a/.postcss-sorting.json +++ /dev/null @@ -1,243 +0,0 @@ -{ - "order": [ - "custom-properties", - "dollar-variables", - { - "type": "at-rule", - "name": "include" - }, - "declarations", - "rules", - { - "type": "at-rule", - "name": "media" - } - ], - "properties-order": [ - { - "emptyLineBefore": false, - "properties": [ - "font", - "font-family", - "font-size", - "font-weight", - "font-style", - "font-variant", - "font-size-adjust", - "font-stretch", - "font-effect", - "font-emphasize", - "font-emphasize-position", - "font-emphasize-style", - "font-smooth", - "font-smoothing", - "line-height", - "text-align", - "text-align-last", - "vertical-align", - "white-space", - "text-decoration", - "text-emphasis", - "text-emphasis-color", - "text-emphasis-style", - "text-emphasis-position", - "text-indent", - "text-justify", - "letter-spacing", - "word-spacing", - "writing-mode", - "text-outline", - "text-transform", - "text-size-adjust", - "text-wrap", - "text-overflow", - "text-overflow-ellipsis", - "text-overflow-mode", - "word-wrap", - "word-break", - "tab-size", - "hyphens" - ] - }, - { - "emptyLineBefore": false, - "properties": [ - "background", - "background-color", - "background-image", - "background-repeat", - "background-attachment", - "background-position", - "background-position-x", - "background-position-y", - "background-clip", - "background-origin", - "background-size", - "interpolation-mode", - "filter", - "border", - "border-width", - "border-style", - "border-color", - "border-top", - "border-top-width", - "border-top-style", - "border-top-color", - "border-right", - "border-right-width", - "border-right-style", - "border-right-color", - "border-bottom", - "border-bottom-width", - "border-bottom-style", - "border-bottom-color", - "border-left", - "border-left-width", - "border-left-style", - "border-left-color", - "border-radius", - "border-top-left-radius", - "border-top-right-radius", - "border-bottom-right-radius", - "border-bottom-left-radius", - "border-image", - "border-image-source", - "border-image-slice", - "border-image-width", - "border-image-outset", - "border-image-repeat", - "outline", - "outline-width", - "outline-style", - "outline-color", - "outline-offset", - "tap-highlight-color" - ] - }, - { - "emptyLineBefore": false, - "properties": [ - "box-decoration-break", - "box-shadow", - "text-shadow" - ] - }, - { - "emptyLineBefore": false, - "properties": [ - "color", - "opacity" - ] - }, - { - "emptyLineBefore": false, - "properties": [ - "position", - "z-index", - "top", - "right", - "bottom", - "left" - ] - }, - { - "emptyLineBefore": false, - "properties": [ - "display", - "visibility", - "float", - "clear", - "overflow", - "overflow-x", - "overflow-y", - "overflow-scrolling", - "clip", - "zoom", - "flex", - "flex-direction", - "flex-order", - "flex-pack", - "flex-align", - "flex-basis", - "flex-grow", - "flex-shrink", - "flex-wrap", - "justify-content", - "align-items", - "align-self" - ] - }, - { - "emptyLineBefore": false, - "properties": [ - "box-sizing", - "width", - "min-width", - "max-width", - "height", - "min-height", - "max-height", - "margin", - "margin-top", - "margin-right", - "margin-bottom", - "margin-left", - "padding", - "padding-top", - "padding-right", - "padding-bottom", - "padding-left" - ] - }, - { - "emptyLineBefore": false, - "properties": [ - "table-layout", - "empty-cells", - "caption-side", - "border-spacing", - "border-collapse", - "list-style", - "list-style-position", - "list-style-type", - "list-style-image" - ] - }, - { - "emptyLineBefore": false, - "properties": [ - "content", - "quotes", - "counter-reset", - "counter-increment", - "resize", - "cursor", - "touch-callout", - "touch-action", - "user-select", - "nav-index", - "nav-up", - "nav-right", - "nav-down", - "nav-left", - "transition", - "transition-delay", - "transition-timing-function", - "transition-duration", - "transition-property", - "transform", - "transform-origin", - "animation", - "animation-name", - "animation-duration", - "animation-play-state", - "animation-timing-function", - "animation-delay", - "animation-iteration-count", - "animation-direction", - "pointer-events" - ] - } - ], - "unspecified-properties-position": "bottomAlphabetical" -} diff --git a/.stylelintrc b/.stylelintrc index fc50e40c1ca..82c0db3515b 100644 --- a/.stylelintrc +++ b/.stylelintrc @@ -3,7 +3,7 @@ "stylelint-order" ], "ignoreFiles": [ - "./phpBB/styles/prosilver/theme/normalize.css", + "./phpBB/styles/prosilver/theme/normalize.css" ], "rules": { "at-rule-name-case": "lower", @@ -61,10 +61,10 @@ "declaration-empty-line-before": "never", - "declaration-property-unit-blacklist": { + "declaration-property-unit-disallowed-list": { "line-height": ["rem", "em", "%"] }, - "declaration-property-unit-whitelist": { + "declaration-property-unit-allowed-list": { "height": ["px", "%", "vh"], "width": ["px", "%", "vw"], "font-size": ["px", "rem", "%"], @@ -180,21 +180,27 @@ "value-list-comma-newline-before": "never-multi-line", "value-list-comma-space-after": "always-single-line", "value-list-comma-space-before": "never", - "order/declaration-block-order": [ + "order/order": [ "custom-properties", "dollar-variables", { "type": "at-rule", - "name": "include" + "name": "include", + "parameter": "type" }, "declarations", "rules", + { + "type": "at-rule", + "name": "include", + "parameter": "fluid" + }, { "type": "at-rule", "name": "media" } ], - "order/declaration-block-properties-specified-order": [ + "order/properties-order": [ [ "font", "font-family", @@ -385,7 +391,7 @@ "animation-direction", "pointer-events" ], - { unspecified: "bottomAlphabetical" } + { "unspecified": "bottomAlphabetical" } ] } } diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index 39b858801b6..00000000000 --- a/.travis.yml +++ /dev/null @@ -1,57 +0,0 @@ -language: php -sudo: required -dist: precise - -matrix: - include: - - php: 5.6 - env: DB=none;NOTESTS=1 - - php: 5.6 - env: DB=mariadb - - php: 5.6 - env: DB=postgres - - php: 5.6 - env: DB=sqlite3 - - php: 5.6 - env: DB=mysqli;SLOWTESTS=1 - - php: 5.6 - env: DB=mysqli # MyISAM - - php: 5.6 - env: DB=mysql - - php: 7.0 - env: DB=mysqli - - php: 7.1 - env: DB=mysqli - - php: 7.2 - env: DB=mysqli - - php: nightly - env: DB=mysqli - allow_failures: - - php: nightly - fast_finish: true - -addons: - apt: - sources: - - node - -services: - - redis-server - -install: - - travis/setup-phpbb.sh $DB $TRAVIS_PHP_VERSION $NOTESTS - -before_script: - - travis/setup-database.sh $DB $TRAVIS_PHP_VERSION $NOTESTS - - phantomjs --webdriver=8910 > /dev/null & - -script: - - travis/phing-sniff.sh $DB $TRAVIS_PHP_VERSION $NOTESTS - - travis/check-sami-parse-errors.sh $DB $TRAVIS_PHP_VERSION $NOTESTS - - travis/check-image-icc-profiles.sh $DB $TRAVIS_PHP_VERSION $NOTESTS - - travis/check-executable-files.sh $DB $TRAVIS_PHP_VERSION $NOTESTS ./ - - travis/check-stylesheet.sh $NOTESTS - - sh -c "if [ '$SLOWTESTS' != '1' -a '$DB' = 'mysqli' ]; then phpBB/vendor/bin/phpunit tests/lint_test.php; fi" - - sh -c "if [ '$NOTESTS' != '1' -a '$SLOWTESTS' != '1' ]; then phpBB/vendor/bin/phpunit --configuration travis/phpunit-$DB-travis.xml --verbose --stop-on-error; fi" - - sh -c "if [ '$SLOWTESTS' = '1' ]; then phpBB/vendor/bin/phpunit --configuration travis/phpunit-$DB-travis.xml --group slow; fi" - - sh -c "set -x;if [ '$NOTESTS' = '1' -a '$TRAVIS_PULL_REQUEST' != 'false' ]; then git remote set-branches --add origin $TRAVIS_BRANCH && git fetch && git-tools/commit-msg-hook-range.sh origin/$TRAVIS_BRANCH..$TRAVIS_PULL_REQUEST_SHA; fi" diff --git a/.vscode/launch.json b/.vscode/launch.json new file mode 100644 index 00000000000..46ce7fa44d1 --- /dev/null +++ b/.vscode/launch.json @@ -0,0 +1,18 @@ +{ + // Use IntelliSense to learn about possible attributes. + // Hover to view descriptions of existing attributes. + // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 + "version": "0.2.0", + "configurations": [ + { + "name": "Debug phpBB", + "type": "php", + "request": "launch", + "port": 9003, + "pathMappings": { + "/var/www/html": "${workspaceRoot}/phpBB/" + }, + "log": true + } + ] +} diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 00000000000..aec06519756 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,3 @@ +{ + "php.debug.ideKey": "VSCODE" +} diff --git a/LICENSE b/LICENSE new file mode 100644 index 00000000000..ce992b2ce7a --- /dev/null +++ b/LICENSE @@ -0,0 +1,281 @@ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc. + 675 Mass Ave, Cambridge, MA 02139, USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Library General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + diff --git a/README.md b/README.md index d1854dc74d4..228d62047f6 100644 --- a/README.md +++ b/README.md @@ -1,40 +1,50 @@ -[![phpBB](https://www.phpbb.com/theme/images/logos/blue/160x52.png)](http://www.phpbb.com) - -## ABOUT +[phpBB](https://www.phpbb.com) phpBB is a free open-source bulletin board written in PHP. -## COMMUNITY +## 🧑🏻‍🤝🏻🧑🏽 Community + +Get your copy of phpBB, find support and lots more on [phpBB.com](https://www.phpbb.com). Discuss the development on [area51](https://area51.phpbb.com/phpBB/index.php). -Get your copy of phpBB, find support and lots more on [phpBB.com](http://www.phpbb.com)! Discuss the development on [area51](http://area51.phpbb.com/phpBB/index.php). +## 👨‍💻 Contribute -## INSTALLING DEPENDENCIES +1. [Create an account on phpBB.com](https://www.phpbb.com/community/ucp.php?mode=register) +2. [Create a ticket (unless there already is one)](https://tracker.phpbb.com/secure/CreateIssue!default.jspa) +3. Read our [Coding guidelines](https://area51.phpbb.com/docs/dev/development/coding_guidelines.html) and [Git Contribution Guidelines](https://area51.phpbb.com/docs/dev/development/git.html) +4. Send us a pull request -To be able to run an installation from the repo (and not from a pre-built package) you need to run the following commands to install phpBB's dependencies. +### 🏗️ Setting up a development build of phpBB - cd phpBB - php ../composer.phar install +To run an installation from the repo (and not from a pre-built package) on a local server, run the following commands: +- Fork phpbb/phpbb to your GitHub account, then create a local clone of it: + ``` + git clone https://github.com/your_github_name/phpbb.git + ``` +- Install phpBB's dependencies (from the root of your phpbb repo): + ``` + cd phpBB + php ../composer.phar install + ``` -## CONTRIBUTE +Alternatively, you can read: -1. [Create an account on phpBB.com](http://www.phpbb.com/community/ucp.php?mode=register) -2. [Create a ticket (unless there already is one)](http://tracker.phpbb.com/secure/CreateIssue!default.jspa) -3. Read our [Coding guidelines](https://area51.phpbb.com/docs/dev/development/coding_guidelines.html) and [Git Contribution Guidelines](https://area51.phpbb.com/docs/dev/development/git.html) -4. Send us a pull request +* Our [Vagrant documentation](phpBB/docs/vagrant.md) to find out how to use Vagrant to develop and contribute to phpBB. +* Our [GitHub Codespaces documentation](phpBB/docs/codespaces.md) to learn about phpBB's cloud-based development environment. -## VAGRANT +## 📓 Documentation -Read our [Vagrant documentation](phpBB/docs/vagrant.md) to find out how to use Vagrant to develop and contribute to phpBB. +phpBB's [Development Documentation](https://area51.phpbb.com/docs/dev/index.html) contains all the information you'll need to learn about developing for phpBB's core, extensions and automated testing. -## AUTOMATED TESTING +## 🔬 Automated Testing -We have unit and functional tests in order to prevent regressions. You can view the bamboo continuous integration [here](https://bamboo.phpbb.com) or check our travis builds below: +We have unit and functional tests in order to prevent regressions. You can view the bamboo continuous integration [here](https://bamboo.phpbb.com) or check our GitHub Actions below: -* [![Build Status](https://travis-ci.org/phpbb/phpbb.svg?branch=master)](http://travis-ci.org/phpbb/phpbb)[![Build status](https://ci.appveyor.com/api/projects/status/8g98ybngd2f3axy1/branch/master?svg=true)](https://ci.appveyor.com/project/phpBB/phpbb/branch/master) **master** - Latest development version -* [![Build Status](https://travis-ci.org/phpbb/phpbb.svg?branch=3.2.x)](http://travis-ci.org/phpbb/phpbb)[![Build status](https://ci.appveyor.com/api/projects/status/8g98ybngd2f3axy1/branch/3.2.x?svg=true)](https://ci.appveyor.com/project/phpBB/phpbb/branch/3.2.x) **3.2.x** - Development of version 3.2.x -* [![Build Status](https://travis-ci.org/phpbb/phpbb.svg?branch=3.1.x)](http://travis-ci.org/phpbb/phpbb) **3.1.x** - Development of version 3.1.x +Branch | Description | GitHub Actions | +------- | ----------- | -------------- | +**master** | Latest development version | ![Tests](https://github.com/phpbb/phpbb/actions/workflows/tests.yml/badge.svg?branch=master) | +**3.3.x** | Development of version 3.3.x | ![Tests](https://github.com/phpbb/phpbb/actions/workflows/tests.yml/badge.svg?branch=3.3.x) | -## LICENSE +## 📜 License [GNU General Public License v2](http://opensource.org/licenses/gpl-2.0.php) diff --git a/SECURITY.md b/SECURITY.md new file mode 100644 index 00000000000..b62f160225e --- /dev/null +++ b/SECURITY.md @@ -0,0 +1,13 @@ +# Security Policy + +## Reporting a Vulnerability + +Please do not post potential security vulnerabilities publicly. Instead, report them to the phpBB team. +We take security very seriously and will respond to reports about potential security vulnerabilities as quickly as possible. +There are multiple ways a potential security vulnerability can be reported: + +- HackerOne: [phpBB | Vulnerability Disclosure Program | HackerOne](https://hackerone.com/phpbb) +- Create a report in the security tracker: [Security Tracker](https://www.phpbb.com/security/) +- Send an email: [security@phpbb.com](mailto:security@phpbb.com) + +Please provide as much detail as possible when reporting a vulnerability. You can expect to receive an update on your report within a few days. If the vulnerability is accepted, we will work on a fix and keep you informed of the progress. If the vulnerability is declined, we will provide an explanation. diff --git a/Vagrantfile b/Vagrantfile index ab225c9ad91..c80dfd98f86 100644 --- a/Vagrantfile +++ b/Vagrantfile @@ -11,15 +11,15 @@ aliasesPath = "vagrant/aliases" require File.expand_path(confDir + '/scripts/homestead.rb') Vagrant.configure(VAGRANTFILE_API_VERSION) do |config| - if File.exists? aliasesPath then + if File.exist? aliasesPath then config.vm.provision "file", source: aliasesPath, destination: "~/.bash_aliases" end - if File.exists? homesteadYamlPath then + if File.exist? homesteadYamlPath then Homestead.configure(config, YAML::load(File.read(homesteadYamlPath))) end - if File.exists? afterScriptPath then + if File.exist? afterScriptPath then config.vm.provision "shell", path: afterScriptPath end end diff --git a/build/build.xml b/build/build.xml index 8bf6fb750f5..a1c5511457d 100644 --- a/build/build.xml +++ b/build/build.xml @@ -2,9 +2,9 @@ - - - + + + @@ -81,31 +81,47 @@ --ignore=${project.basedir}/phpBB/phpbb/db/migration/data/v30x/* phpBB/phpbb" dir="." returnProperty="retval-php-strict" passthru="true" /> + + + + + - + + + + + + + + + + @@ -121,13 +137,13 @@ @@ -159,31 +175,32 @@ - + - + - + - + + save/phpbb-${prevversion}_to_${newversion}_language.patch" /> save/phpbb-${prevversion}_to_${newversion}_prosilver.patch" /> + + + + + + @@ -212,6 +235,31 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/build/build_changelog.php b/build/build_changelog.php index 2d38480f9fa..e95ed0e7b93 100755 --- a/build/build_changelog.php +++ b/build/build_changelog.php @@ -1,16 +1,16 @@ #!/usr/bin/env php -* @license GNU General Public License, version 2 (GPL-2.0) -* -* For full copyright and license information, please see -* the docs/CREDITS.txt file. -* -*/ + * + * This file is part of the phpBB Forum Software package. + * + * @copyright (c) phpBB Limited + * @license GNU General Public License, version 2 (GPL-2.0) + * + * For full copyright and license information, please see + * the docs/CREDITS.txt file. + * + */ if ($_SERVER['argc'] != 2) { @@ -18,40 +18,54 @@ exit(1); } -$fixVersion = $_SERVER['argv'][1]; +if ($_SERVER['argv'][1] == '--stdin') +{ + $stdIn = file_get_contents('php://stdin'); + // XML output from tracker can be directly piped to this script using: + // cat tracker_output.xml | php build/build_changelog.php --stdin + $xml = simplexml_load_string($stdIn); +} +else +{ + $fixVersion = $_SERVER['argv'][1]; -$query = 'project IN (PHPBB3, SECURITY) - AND resolution = Fixed - AND fixVersion = "' . $fixVersion . '" - AND status IN ("Unverified Fix", Closed)'; + $query = 'project IN (PHPBB, PHPBB3, SECURITY) + AND resolution = Fixed + AND fixVersion = "' . $fixVersion . '" + AND status IN ("Unverified Fix", Closed)'; -$url = 'http://tracker.phpbb.com/sr/jira.issueviews:searchrequest-xml/temp/SearchRequest.xml?jqlQuery=' . urlencode($query) . '&tempMax=1000'; -$xml = simplexml_load_string(file_get_contents($url)); + $url = 'https://tracker.phpbb.com/sr/jira.issueviews:searchrequest-xml/temp/SearchRequest.xml?jqlQuery=' . urlencode($query) . '&tempMax=1000'; + $xml = simplexml_load_string(file_get_contents($url)); +} +$types = []; foreach ($xml->xpath('//item') as $item) { $key = (string) $item->key; - $keyUrl = 'http://tracker.phpbb.com/browse/' . $key; + $keyUrl = 'https://tracker.phpbb.com/browse/' . $key; $keyLink = '' . $key . ''; - $value = str_replace($key, $keyLink, htmlspecialchars($item->title)); + $value = str_replace($key, $keyLink, htmlspecialchars($item->title, ENT_COMPAT)); $value = str_replace(']', '] -', $value); $types[(string) $item->type][$key] = $value; } -ksort($types); -foreach ($types as $type => $tickets) +if (count($types)) { - echo "

$type

\n"; - echo "
    \n"; + ksort($types); + foreach ($types as $type => $tickets) + { + echo "

    $type

    \n"; + echo "
      \n"; - uksort($tickets, 'strnatcasecmp'); + uksort($tickets, 'strnatcasecmp'); - foreach ($tickets as $ticket) - { - echo "
    • $ticket
    • \n"; + foreach ($tickets as $ticket) + { + echo "
    • $ticket
    • \n"; + } + echo "
    \n"; } - echo "
\n"; } diff --git a/build/build_helper.php b/build/build_helper.php index ff93c22a12c..63d0c3c7702 100644 --- a/build/build_helper.php +++ b/build/build_helper.php @@ -33,7 +33,7 @@ class build_package var $status_begun = false; var $num_dots = 0; - function build_package($versions, $verbose = false) + function __construct($versions, $verbose = false) { $this->versions = $versions; $this->verbose = $verbose; @@ -43,14 +43,14 @@ function build_package($versions, $verbose = false) $_before = $this->versions[count($this->versions) - 2]; $this->locations = array( - 'new_version' => dirname(dirname(__FILE__)) . '/phpBB/', - 'old_versions' => dirname(__FILE__) . '/old_versions/', - 'root' => dirname(__FILE__) . '/', - 'package_dir' => dirname(__FILE__) . '/new_version/' + 'new_version' => dirname(__DIR__) . '/phpBB/', + 'old_versions' => __DIR__ . '/old_versions/', + 'root' => __DIR__ . '/', + 'package_dir' => __DIR__ . '/new_version/' ); $this->package_infos = array( - 'package_name' => 'phpBB3', + 'package_name' => 'phpBB', 'name_prefix' => 'phpbb', 'simple_name' => 'release-' . $_latest, 'new_version_number' => $_latest, diff --git a/build/code_sniffer/phpbb/Sniffs/CodeLayout/UnionTypesCheckSniff.php b/build/code_sniffer/phpbb/Sniffs/CodeLayout/UnionTypesCheckSniff.php new file mode 100644 index 00000000000..64b30a859e3 --- /dev/null +++ b/build/code_sniffer/phpbb/Sniffs/CodeLayout/UnionTypesCheckSniff.php @@ -0,0 +1,116 @@ + + * @license GNU General Public License, version 2 (GPL-2.0) + * + * For full copyright and license information, please see + * the docs/CREDITS.txt file. + * + */ + +namespace phpbb\Sniffs\CodeLayout; + +use PHP_CodeSniffer\Files\File; +use PHP_CodeSniffer\Sniffs\Sniff; + +/** + * Checks that union type declarations follows the coding guidelines. + */ +class UnionTypesCheckSniff implements Sniff +{ + /** + * {@inheritdoc} + */ + public function register() + { + return [ + T_FUNCTION, + T_CLASS, + ]; + } + + /** + * {@inheritdoc} + */ + public function process(File $phpcsFile, $stackPtr) + { + $tokens = $phpcsFile->getTokens(); + if ($tokens[$stackPtr]['type'] === 'T_FUNCTION') + { + $method_params = $phpcsFile->getMethodParameters($stackPtr); + $method_params_array = array_column($method_params, 'type_hint', 'token'); + foreach ($method_params_array as $stack_pointer => $type_hint) + { + $this->check_union_type($phpcsFile, $stack_pointer, $type_hint); + } + + $method_properties = $phpcsFile->getMethodProperties($stackPtr); + $this->check_union_type($phpcsFile, $stackPtr, $method_properties['return_type']); + } + else if ($tokens[$stackPtr]['type'] === 'T_CLASS') + { + $class_token = $tokens[$stackPtr]; + $class_closer_pointer = $class_token['scope_closer']; + $first_method_pointer = $phpcsFile->findNext(T_FUNCTION, $stackPtr); + $class_members_declarations_end_pointer = $first_method_pointer ?: $class_closer_pointer; + + $stack_pointer = $stackPtr; + while(($class_member_pointer = $phpcsFile->findNext(T_VARIABLE, $stack_pointer)) !== false && ($class_member_pointer < $class_members_declarations_end_pointer)) + { + $properties = $phpcsFile->getMemberProperties($class_member_pointer); + $this->check_union_type($phpcsFile, $class_member_pointer, $properties['type']); + $stack_pointer = $class_member_pointer + 1; + } + } + } + + public function check_union_type(File $phpcsFile, $stack_pointer, $type_hint) + { + if (empty($type_hint)) + { + return; + } + + if (!strpos($type_hint, '|') && $type_hint[0] == '?') // Check nullable shortcut syntax + { + $type = substr($type_hint, 1); + $error = 'Nullable shortcut syntax must not be used. Use union type instead: %1$s|null; found %2$s'; + $data = [$type, $type_hint]; + $phpcsFile->addError($error, $stack_pointer, 'ShortNullableSyntax', $data); + } + else if ((count($types_array = explode('|', $type_hint))) > 1) // Check union type layout + { + $types_array_null_less = $types_array; + + // Check 'null' to be the last element + $null_position = array_search('null', $types_array); + if ($null_position !== false && $null_position != array_key_last($types_array)) + { + $error = 'The "null" type hint must be the last of the union type elements; found %s'; + $data = [implode('|', $types_array)]; + $phpcsFile->addError($error, $stack_pointer, 'NullAlwaysLast', $data); + } + + // Check types excepting 'null' to follow alphabetical order + if ($null_position !== false) + { + array_splice($types_array_null_less, $null_position, 1); + } + + if (count($types_array_null_less) > 1) + { + $types_array_null_less_sorted = $types_array_null_less; + sort($types_array_null_less_sorted); + if (!empty(array_diff_assoc($types_array_null_less, $types_array_null_less_sorted))) + { + $error = 'Union type elements must be sorted alphabetically excepting the "null" type hint must be the last if any; found %s'; + $data = [implode('|', $types_array)]; + $phpcsFile->addError($error, $stack_pointer, 'AlphabeticalSort', $data); + } + } + } + } +} diff --git a/build/code_sniffer/phpbb/Sniffs/Commenting/FileCommentSniff.php b/build/code_sniffer/phpbb/Sniffs/Commenting/FileCommentSniff.php index 8c0ec853ff3..d79657af12c 100644 --- a/build/code_sniffer/phpbb/Sniffs/Commenting/FileCommentSniff.php +++ b/build/code_sniffer/phpbb/Sniffs/Commenting/FileCommentSniff.php @@ -11,6 +11,11 @@ * */ +namespace phpbb\Sniffs\Commenting; + +use PHP_CodeSniffer\Files\File; +use PHP_CodeSniffer\Sniffs\Sniff; + /** * Checks that each PHP source file contains a valid header as defined by the * phpBB Coding Guidelines. @@ -18,7 +23,7 @@ * @package code_sniffer * @author Manuel Pichler */ -class phpbb_Sniffs_Commenting_FileCommentSniff implements PHP_CodeSniffer_Sniff +class FileCommentSniff implements Sniff { /** * Returns an array of tokens this test wants to listen for. @@ -33,13 +38,13 @@ public function register() /** * Processes this test, when one of its tokens is encountered. * - * @param PHP_CodeSniffer_File $phpcsFile The file being scanned. + * @param File $phpcsFile The file being scanned. * @param int $stackPtr The position of the current token * in the stack passed in $tokens. * - * @return null + * @return void */ - public function process(PHP_CodeSniffer_File $phpcsFile, $stackPtr) + public function process(File $phpcsFile, $stackPtr): void { // We are only interested in the first file comment. if ($stackPtr !== 0) @@ -62,7 +67,7 @@ public function process(PHP_CodeSniffer_File $phpcsFile, $stackPtr) // Mark as error if this is not a doc comment else if ($start === false || $tokens[$start]['code'] !== T_DOC_COMMENT_OPEN_TAG) { - $phpcsFile->addError('Missing required file doc comment.', $stackPtr); + $phpcsFile->addError('Missing required file doc comment.', $stackPtr, 'MissingComment'); return; } @@ -82,7 +87,7 @@ public function process(PHP_CodeSniffer_File $phpcsFile, $stackPtr) if ($tokens[$token]['column'] === 1 && (($tokens[$token]['content'] !== '*' && $tokens[$token]['content'] !== ' ') || ($tokens[$token]['content'] === ' ' && $tokens[$token + 1]['content'] !== '*'))) { $message = 'The file doc comment should not be indented.'; - $phpcsFile->addWarning($message, $token); + $phpcsFile->addWarning($message, $token, 'CommentIndented'); } } @@ -95,13 +100,13 @@ public function process(PHP_CodeSniffer_File $phpcsFile, $stackPtr) if (!(($tokens[$start + 2]['content'] !== '*' && $tokens[$start + 4]['content'] !== '*') || ($tokens[$start + 3]['content'] !== '*' && $tokens[$start + 6]['content'] !== '*'))) { $message = 'The first file comment line should be empty.'; - $phpcsFile->addWarning($message, ($start + 1)); + $phpcsFile->addWarning($message, ($start + 1), 'CommentFirstNotEmpty'); } if ($tokens[$end - 3]['content'] !== '*' && $tokens[$end - 6]['content'] !== '*') { $message = 'The last file comment line should be empty.'; - $phpcsFile->addWarning($message, $end - 1); + $phpcsFile->addWarning($message, $end - 1, 'CommentLastNotEmpty'); } //$this->processPackage($phpcsFile, $start, $tags); @@ -113,59 +118,59 @@ public function process(PHP_CodeSniffer_File $phpcsFile, $stackPtr) /** * Checks that the tags array contains a valid package tag * - * @param PHP_CodeSniffer_File $phpcsFile The context source file instance. + * @param File $phpcsFile The context source file instance. * @param integer The stack pointer for the first comment token. * @param array(string=>array) $tags The found file doc comment tags. * - * @return null + * @return void */ - protected function processPackage(PHP_CodeSniffer_File $phpcsFile, $ptr, $tags) + protected function processPackage(File $phpcsFile, $ptr, $tags): void { if (!isset($tags['package'])) { $message = 'Missing require @package tag in file doc comment.'; - $phpcsFile->addError($message, $ptr); + $phpcsFile->addError($message, $ptr, 'MissingTagPackage'); } else if (preg_match('/^([\w]+)$/', $tags['package'][0]) === 0) { $message = 'Invalid content found for @package tag.'; - $phpcsFile->addWarning($message, $tags['package'][1]); + $phpcsFile->addWarning($message, $tags['package'][1], 'InvalidTagPackage'); } } /** * Checks that the tags array contains a valid version tag * - * @param PHP_CodeSniffer_File $phpcsFile The context source file instance. + * @param File $phpcsFile The context source file instance. * @param integer The stack pointer for the first comment token. * @param array(string=>array) $tags The found file doc comment tags. * - * @return null + * @return void */ - protected function processVersion(PHP_CodeSniffer_File $phpcsFile, $ptr, $tags) + protected function processVersion(File $phpcsFile, $ptr, $tags): void { if (!isset($tags['version'])) { $message = 'Missing require @version tag in file doc comment.'; - $phpcsFile->addError($message, $ptr); + $phpcsFile->addError($message, $ptr, 'MissingTagVersion'); } else if (preg_match('/^\$Id:[^\$]+\$$/', $tags['version'][0]) === 0) { $message = 'Invalid content found for @version tag, use "$Id: $".'; - $phpcsFile->addError($message, $tags['version'][1]); + $phpcsFile->addError($message, $tags['version'][1], 'InvalidTagVersion'); } } /** * Checks that the tags array contains a valid copyright tag * - * @param PHP_CodeSniffer_File $phpcsFile The context source file instance. + * @param File $phpcsFile The context source file instance. * @param integer The stack pointer for the first comment token. * @param array(string=>array) $tags The found file doc comment tags. * - * @return null + * @return void */ - protected function processCopyright(PHP_CodeSniffer_File $phpcsFile, $ptr, $tags) + protected function processCopyright(File $phpcsFile, $ptr, $tags): void { $copyright = '(c) phpBB Limited '; $tokens = $phpcsFile->getTokens(); @@ -177,7 +182,7 @@ protected function processCopyright(PHP_CodeSniffer_File $phpcsFile, $ptr, $tags if ($tokens[$tag + 2]['content'] !== $copyright) { $message = 'Invalid content found for the first @copyright tag, use "' . $copyright . '".'; - $phpcsFile->addError($message, $tags['copyright'][0][1]); + $phpcsFile->addError($message, $tags['copyright'][0][1], 'InvalidTagCopyright'); } return; @@ -185,19 +190,19 @@ protected function processCopyright(PHP_CodeSniffer_File $phpcsFile, $ptr, $tags } $message = 'Missing require @copyright tag in file doc comment.'; - $phpcsFile->addError($message, $ptr); + $phpcsFile->addError($message, $ptr, 'MissingTagCopyright'); } /** * Checks that the tags array contains a valid license tag * - * @param PHP_CodeSniffer_File $phpcsFile The context source file instance. + * @param File $phpcsFile The context source file instance. * @param integer The stack pointer for the first comment token. * @param array(string=>array) $tags The found file doc comment tags. * - * @return null + * @return void */ - protected function processLicense(PHP_CodeSniffer_File $phpcsFile, $ptr, $tags) + protected function processLicense(File $phpcsFile, $ptr, $tags): void { $license = 'GNU General Public License, version 2 (GPL-2.0)'; $tokens = $phpcsFile->getTokens(); @@ -210,7 +215,7 @@ protected function processLicense(PHP_CodeSniffer_File $phpcsFile, $ptr, $tags) if ($found) { $message = 'It must be only one @license tag in file doc comment.'; - $phpcsFile->addError($message, $ptr); + $phpcsFile->addError($message, $ptr, 'MultiTagVersion'); } $found = true; @@ -218,7 +223,7 @@ protected function processLicense(PHP_CodeSniffer_File $phpcsFile, $ptr, $tags) if ($tokens[$tag + 2]['content'] !== $license) { $message = 'Invalid content found for @license tag, use "' . $license . '".'; - $phpcsFile->addError($message, $tags['license'][0][1]); + $phpcsFile->addError($message, $tags['license'][0][1], 'InvalidTagLicense'); } } } @@ -226,7 +231,7 @@ protected function processLicense(PHP_CodeSniffer_File $phpcsFile, $ptr, $tags) if (!$found) { $message = 'Missing require @license tag in file doc comment.'; - $phpcsFile->addError($message, $ptr); + $phpcsFile->addError($message, $ptr, 'MissingTagLicense'); } } } diff --git a/build/code_sniffer/phpbb/Sniffs/ControlStructures/OpeningBraceBsdAllmanSniff.php b/build/code_sniffer/phpbb/Sniffs/ControlStructures/OpeningBraceBsdAllmanSniff.php index 885c38c5b45..9e74f25839d 100644 --- a/build/code_sniffer/phpbb/Sniffs/ControlStructures/OpeningBraceBsdAllmanSniff.php +++ b/build/code_sniffer/phpbb/Sniffs/ControlStructures/OpeningBraceBsdAllmanSniff.php @@ -11,11 +11,16 @@ * */ +namespace phpbb\Sniffs\ControlStructures; + +use PHP_CodeSniffer\Files\File; +use PHP_CodeSniffer\Sniffs\Sniff; + /** * Checks that the opening brace of a control structures is on the line after. * From Generic_Sniffs_Functions_OpeningFunctionBraceBsdAllmanSniff */ -class phpbb_Sniffs_ControlStructures_OpeningBraceBsdAllmanSniff implements PHP_CodeSniffer_Sniff +class OpeningBraceBsdAllmanSniff implements Sniff { /** * Registers the tokens that this sniff wants to listen for. @@ -36,13 +41,13 @@ public function register() /** * Processes this test, when one of its tokens is encountered. * - * @param PHP_CodeSniffer_File $phpcsFile The file being scanned. + * @param File $phpcsFile The file being scanned. * @param int $stackPtr The position of the current token in the * stack passed in $tokens. * * @return void */ - public function process(PHP_CodeSniffer_File $phpcsFile, $stackPtr) + public function process(File $phpcsFile, $stackPtr) { $tokens = $phpcsFile->getTokens(); diff --git a/build/code_sniffer/phpbb/Sniffs/ControlStructures/OpeningParenthesisSniff.php b/build/code_sniffer/phpbb/Sniffs/ControlStructures/OpeningParenthesisSniff.php index 349bccbb020..daad603a6cb 100644 --- a/build/code_sniffer/phpbb/Sniffs/ControlStructures/OpeningParenthesisSniff.php +++ b/build/code_sniffer/phpbb/Sniffs/ControlStructures/OpeningParenthesisSniff.php @@ -10,12 +10,16 @@ * the docs/CREDITS.txt file. * */ +namespace phpbb\Sniffs\ControlStructures; + +use PHP_CodeSniffer\Files\File; +use PHP_CodeSniffer\Sniffs\Sniff; /** * Checks that there is exactly one space between the keyword and the opening * parenthesis of a control structures. */ -class phpbb_Sniffs_ControlStructures_OpeningParenthesisSniff implements PHP_CodeSniffer_Sniff +class OpeningParenthesisSniff implements Sniff { /** * Registers the tokens that this sniff wants to listen for. @@ -36,13 +40,13 @@ public function register() /** * Processes this test, when one of its tokens is encountered. * - * @param PHP_CodeSniffer_File $phpcsFile The file being scanned. + * @param File $phpcsFile The file being scanned. * @param int $stackPtr The position of the current token in the * stack passed in $tokens. * * @return void */ - public function process(PHP_CodeSniffer_File $phpcsFile, $stackPtr) + public function process(File $phpcsFile, $stackPtr) { $tokens = $phpcsFile->getTokens(); diff --git a/build/code_sniffer/phpbb/Sniffs/ControlStructures/StaticKeywordSniff.php b/build/code_sniffer/phpbb/Sniffs/ControlStructures/StaticKeywordSniff.php new file mode 100644 index 00000000000..948987cd376 --- /dev/null +++ b/build/code_sniffer/phpbb/Sniffs/ControlStructures/StaticKeywordSniff.php @@ -0,0 +1,59 @@ + + * @license GNU General Public License, version 2 (GPL-2.0) + * + * For full copyright and license information, please see + * the docs/CREDITS.txt file. + * + */ + +namespace phpbb\Sniffs\ControlStructures; + +use PHP_CodeSniffer\Files\File; +use PHP_CodeSniffer\Sniffs\Sniff; + +/** + * Checks that the visibility qualifiers are placed after the static keyword + * according to the coding guidelines + */ +class StaticKeywordSniff implements Sniff +{ + /** + * Registers the tokens that this sniff wants to listen for. + */ + public function register() + { + return [ + T_STATIC, + ]; + } + + /** + * Processes this test, when one of its tokens is encountered. + * + * @param File $phpcsFile The file being scanned. + * @param int $stackPtr The position of the current token in the stack passed in $tokens. + * + * @return void + */ + public function process(File $phpcsFile, $stackPtr) + { + $tokens = $phpcsFile->getTokens(); + + $disallowed_after_tokens = [ + T_PUBLIC, + T_PROTECTED, + T_PRIVATE, + ]; + + if (in_array($tokens[$stackPtr + 2]['code'], $disallowed_after_tokens)) + { + $error = 'Access specifier (e.g. public) should not follow static scope attribute. Encountered "' . $tokens[$stackPtr + 2]['content'] . '" after static'; + $phpcsFile->addError($error, $stackPtr, 'InvalidStaticFunctionDeclaration'); + } + } +} diff --git a/build/code_sniffer/phpbb/Sniffs/Namespaces/UnusedUseSniff.php b/build/code_sniffer/phpbb/Sniffs/Namespaces/UnusedUseSniff.php index b3cdbf74961..42a0fc5288b 100644 --- a/build/code_sniffer/phpbb/Sniffs/Namespaces/UnusedUseSniff.php +++ b/build/code_sniffer/phpbb/Sniffs/Namespaces/UnusedUseSniff.php @@ -11,31 +11,78 @@ * */ +namespace phpbb\Sniffs\Namespaces; + +use PHP_CodeSniffer\Files\File; +use PHP_CodeSniffer\Sniffs\Sniff; + /** * Checks that each use statement is used. */ -class phpbb_Sniffs_Namespaces_UnusedUseSniff implements PHP_CodeSniffer_Sniff +class UnusedUseSniff implements Sniff { + const FIND = [ + T_NS_SEPARATOR, + T_STRING, + T_WHITESPACE, + ]; + + private function getNameTokens() + { + $tokens = [T_NS_SEPARATOR, T_STRING]; + if (defined('T_NAME_QUALIFIED')) + { + $tokens[] = T_NAME_QUALIFIED; + } + if (defined('T_NAME_FULLY_QUALIFIED')) + { + $tokens[] = T_NAME_FULLY_QUALIFIED; + } + if (defined('T_NAME_RELATIVE')) + { + $tokens[] = T_NAME_RELATIVE; + } + return $tokens; + } + /** * {@inheritdoc} */ public function register() { - return array(T_USE); + return [T_USE]; } - protected function check($phpcsFile, $found_name, $full_name, $short_name, $line) + protected function check(File $phpcsFile, $found_name, $full_name, $short_name, $stack_pointer) { + $found_name_normalized = ltrim($found_name, '\\'); + $full_name = ltrim($full_name, '\\'); + + $is_global = ($full_name === $short_name); + $unnecessarily_fully_qualified = ($is_global) + ? ($found_name_normalized !== $found_name && $found_name_normalized === $short_name) + : ($found_name_normalized === $full_name); - if ($found_name === $full_name) + if ($unnecessarily_fully_qualified) { $error = 'Either use statement or full name must be used.'; - $phpcsFile->addError($error, $line, 'FullName'); + $phpcsFile->addError($error, $stack_pointer, 'FullName'); } - if ($found_name === $short_name) + /* + * Check for possible union types (like string|MyType|null) + * and question mark nullable type syntax (like ?MyType) + */ + $types = explode('|', $found_name); + foreach ($types as $type) { - return true; + // Nullable type syntax + $type = (strpos($type, '?') === 0) ? substr($type, 1) : $type; + + if ($short_name === $type) + { + return true; + } } return false; @@ -44,7 +91,7 @@ protected function check($phpcsFile, $found_name, $full_name, $short_name, $line /** * {@inheritdoc} */ - public function process(PHP_CodeSniffer_File $phpcsFile, $stackPtr) + public function process(File $phpcsFile, $stackPtr) { if ($this->should_ignore_use($phpcsFile, $stackPtr) === true) { @@ -53,29 +100,76 @@ public function process(PHP_CodeSniffer_File $phpcsFile, $stackPtr) $tokens = $phpcsFile->getTokens(); - $class_name_start = $phpcsFile->findNext(array(T_NS_SEPARATOR, T_STRING), ($stackPtr + 1)); - - $find = array( - T_NS_SEPARATOR, - T_STRING, - T_WHITESPACE, - ); + $class_name_start = $phpcsFile->findNext($this->getNameTokens(), ($stackPtr + 1)); - $class_name_end = $phpcsFile->findNext($find, ($stackPtr + 1), null, true); + // Handle PHPCS v4 T_NAME_QUALIFIED tokens + if (isset($tokens[$class_name_start]) && + (defined('T_NAME_QUALIFIED') && $tokens[$class_name_start]['code'] === T_NAME_QUALIFIED || + defined('T_NAME_FULLY_QUALIFIED') && $tokens[$class_name_start]['code'] === T_NAME_FULLY_QUALIFIED || + defined('T_NAME_RELATIVE') && $tokens[$class_name_start]['code'] === T_NAME_RELATIVE)) + { + $name_full = $tokens[$class_name_start]['content']; + $class_name_end = $class_name_start + 1; + $parts = explode('\\', $name_full); + $name_short = end($parts); + } + else + { + $class_name_end = $phpcsFile->findNext(self::FIND, ($stackPtr + 1), null, true); + $name_full = $phpcsFile->getTokensAsString($class_name_start, ($class_name_end - $class_name_start)); + $name_short = $tokens[$class_name_end - 1]['content']; + } $aliasing_as_position = $phpcsFile->findNext(T_AS, $class_name_end, null, false, null, true); if ($aliasing_as_position !== false) { $alias_position = $phpcsFile->findNext(T_STRING, $aliasing_as_position, null, false, null, true); - $class_name_short = $tokens[$alias_position]['content']; - $class_name_full = $phpcsFile->getTokensAsString($class_name_start, ($class_name_end - $class_name_start - 1)); + $name_short = $tokens[$alias_position]['content']; + + // Only recalculate name_full if it wasn't a single token (T_NAME_QUALIFIED) + // to avoid calculating it as 0 length string. Prevents incorrectly calculating the + // "full name" of the aliased class (resolving it to an empty string in some cases). + if (!isset($tokens[$class_name_start]) || + ( + (!defined('T_NAME_QUALIFIED') || $tokens[$class_name_start]['code'] !== T_NAME_QUALIFIED) && + (!defined('T_NAME_FULLY_QUALIFIED') || $tokens[$class_name_start]['code'] !== T_NAME_FULLY_QUALIFIED) && + (!defined('T_NAME_RELATIVE') || $tokens[$class_name_start]['code'] !== T_NAME_RELATIVE) + ) + ) + { + $name_full = $phpcsFile->getTokensAsString($class_name_start, ($class_name_end - $class_name_start - 1)); + } + } + + if ($tokens[$class_name_start]['content'] === 'function' + && $tokens[$class_name_start + 1]['code'] === T_WHITESPACE) + { + $class_name_start += 2; + $name_full = $phpcsFile->getTokensAsString( + $class_name_start, + ($class_name_end - $class_name_start - (int) ($aliasing_as_position !== false)) + ); + $ok = $this->findFunctionUsage($phpcsFile, $stackPtr, $tokens, $name_full, $name_short); } else { - $class_name_full = $phpcsFile->getTokensAsString($class_name_start, ($class_name_end - $class_name_start)); - $class_name_short = $tokens[$class_name_end - 1]['content']; + $ok = $this->findClassUsage($phpcsFile, $stackPtr, $tokens, $name_full, $name_short); } + if (!empty($name_full) && $name_full[0] === '\\') + { + $phpcsFile->addError("There must not be a leading '\\' in use statements.", $stackPtr, 'Malformed'); + } + + if (!$ok) + { + $error = 'There must not be unused USE statements.'; + $phpcsFile->addError($error, $stackPtr, 'Unused'); + } + } + + private function findClassUsage(File $phpcsFile, $stackPtr, $tokens, $class_name_full, $class_name_short) + { $ok = false; // Checks in simple statements (new, instanceof and extends) @@ -86,17 +180,21 @@ public function process(PHP_CodeSniffer_File $phpcsFile, $stackPtr) { $old_simple_statement = $simple_statement; - $simple_class_name_start = $phpcsFile->findNext(array(T_NS_SEPARATOR, T_STRING), ($simple_statement + 1)); + $simple_class_name_start = $phpcsFile->findNext($this->getNameTokens(), ($simple_statement + 1)); - if ($simple_class_name_start === false) { + if ($simple_class_name_start === false) + { continue; } - $simple_class_name_end = $phpcsFile->findNext($find, ($simple_statement + 1), null, true); + $simple_class_name_end = $phpcsFile->findNext(self::FIND, ($simple_statement + 1), null, true); $simple_class_name = trim($phpcsFile->getTokensAsString($simple_class_name_start, ($simple_class_name_end - $simple_class_name_start))); - $ok = $this->check($phpcsFile, $simple_class_name, $class_name_full, $class_name_short, $simple_statement) ? true : $ok; + if (!empty($simple_class_name)) + { + $ok = $this->check($phpcsFile, $simple_class_name, $class_name_full, $class_name_short, $simple_statement) || $ok; + } } } @@ -106,12 +204,15 @@ public function process(PHP_CodeSniffer_File $phpcsFile, $stackPtr) { $old_paamayim_nekudotayim = $paamayim_nekudotayim; - $paamayim_nekudotayim_class_name_start = $phpcsFile->findPrevious($find, $paamayim_nekudotayim - 1, null, true); + $paamayim_nekudotayim_class_name_start = $phpcsFile->findPrevious(self::FIND, $paamayim_nekudotayim - 1, null, true); $paamayim_nekudotayim_class_name_end = $paamayim_nekudotayim - 1; $paamayim_nekudotayim_class_name = trim($phpcsFile->getTokensAsString($paamayim_nekudotayim_class_name_start + 1, ($paamayim_nekudotayim_class_name_end - $paamayim_nekudotayim_class_name_start))); - $ok = $this->check($phpcsFile, $paamayim_nekudotayim_class_name, $class_name_full, $class_name_short, $paamayim_nekudotayim) ? true : $ok; + if (!empty($paamayim_nekudotayim_class_name)) + { + $ok = $this->check($phpcsFile, $paamayim_nekudotayim_class_name, $class_name_full, $class_name_short, $paamayim_nekudotayim) || $ok; + } } // Checks in implements @@ -125,12 +226,15 @@ public function process(PHP_CodeSniffer_File $phpcsFile, $stackPtr) { $old_implemented_class = $implemented_class; - $implements_class_name_start = $phpcsFile->findNext(array(T_NS_SEPARATOR, T_STRING), ($implemented_class - 1)); - $implements_class_name_end = $phpcsFile->findNext($find, ($implemented_class - 1), null, true); + $implements_class_name_start = $phpcsFile->findNext($this->getNameTokens(), ($implemented_class - 1)); + $implements_class_name_end = $phpcsFile->findNext(self::FIND, ($implemented_class - 1), null, true); $implements_class_name = trim($phpcsFile->getTokensAsString($implements_class_name_start, ($implements_class_name_end - $implements_class_name_start))); - $ok = $this->check($phpcsFile, $implements_class_name, $class_name_full, $class_name_short, $implements) ? true : $ok; + if (!empty($implements_class_name)) + { + $ok = $this->check($phpcsFile, $implements_class_name, $class_name_full, $class_name_short, $implements) || $ok; + } } } @@ -138,12 +242,12 @@ public function process(PHP_CodeSniffer_File $phpcsFile, $stackPtr) while (($docblock = $phpcsFile->findNext(T_DOC_COMMENT_CLOSE_TAG, ($old_docblock + 1))) !== false) { $old_docblock = $docblock; - $ok = $this->checkDocblock($phpcsFile, $docblock, $tokens, $class_name_full, $class_name_short) ? true : $ok; + $ok = $this->checkDocblock($phpcsFile, $docblock, $tokens, $class_name_full, $class_name_short) || $ok; } // Checks in type hinting $old_function_declaration = $stackPtr; - while (($function_declaration = $phpcsFile->findNext(T_FUNCTION, ($old_function_declaration + 1))) !== false) + while (($function_declaration = $phpcsFile->findNext([T_FUNCTION, T_CLOSURE], ($old_function_declaration + 1))) !== false) { $old_function_declaration = $function_declaration; @@ -151,7 +255,16 @@ public function process(PHP_CodeSniffer_File $phpcsFile, $stackPtr) $params = $phpcsFile->getMethodParameters($function_declaration); foreach ($params as $param) { - $ok = $this->check($phpcsFile, $param['type_hint'], $class_name_full, $class_name_short, $function_declaration) ? true : $ok; + if (!empty($param['type_hint'])) + { + $ok = $this->check($phpcsFile, $param['type_hint'], $class_name_full, $class_name_short, $function_declaration) || $ok; + } + } + + $method_properties = $phpcsFile->getMethodProperties($function_declaration); + if (!empty($method_properties['return_type'])) + { + $ok = $this->check($phpcsFile, $method_properties['return_type'], $class_name_full, $class_name_short, $function_declaration) || $ok; } } @@ -161,31 +274,125 @@ public function process(PHP_CodeSniffer_File $phpcsFile, $stackPtr) { $old_catch = $catch; - $caught_class_name_start = $phpcsFile->findNext(array(T_NS_SEPARATOR, T_STRING), $catch + 1); - $caught_class_name_end = $phpcsFile->findNext($find, $caught_class_name_start + 1, null, true); + $caught_class_name_start = $phpcsFile->findNext($this->getNameTokens(), $catch + 1); + $caught_class_name_end = $phpcsFile->findNext(self::FIND, $caught_class_name_start + 1, null, true); $caught_class_name = trim($phpcsFile->getTokensAsString($caught_class_name_start, ($caught_class_name_end - $caught_class_name_start))); - $ok = $this->check($phpcsFile, $caught_class_name, $class_name_full, $class_name_short, $catch) ? true : $ok; + if (!empty($caught_class_name)) + { + $ok = $this->check($phpcsFile, $caught_class_name, $class_name_full, $class_name_short, $catch) || $ok; + } } - if (!$ok) + $old_use = $stackPtr; + while (($use = $phpcsFile->findNext(T_USE, ($old_use + 1))) !== false) { - $error = 'There must not be unused USE statements.'; - $phpcsFile->addError($error, $stackPtr, 'Unused'); + $old_use = $use; + + // Needs to be inside a class and must not be inside a function scope. + if (!$phpcsFile->hasCondition($use, [T_CLASS, T_TRAIT]) || $phpcsFile->hasCondition($use, T_FUNCTION)) + { + continue; + } + + $next = $phpcsFile->findNext(T_WHITESPACE, ($use + 1), null, true, null, true); + if ($tokens[$next]['code'] === T_OPEN_PARENTHESIS) + { + continue; + } + + $class_name_start = $phpcsFile->findNext($this->getNameTokens(), $use + 1, null, false, null, true); + $class_name_end = $phpcsFile->findNext(self::FIND, $class_name_start + 1, null, true, null, true); + $found_name = trim($phpcsFile->getTokensAsString($class_name_start, ($class_name_end - $class_name_start))); + + if (!empty($found_name)) + { + $ok = $this->check($phpcsFile, $found_name, $class_name_full, $class_name_short, $use) || $ok; + } } + + return $ok; + } + + private function findFunctionUsage(File $phpcsFile, $stackPtr, $tokens, $name_full, $name_short) + { + $ok = false; + $position = $phpcsFile->findNext(T_OPEN_PARENTHESIS, $stackPtr + 1); + while ($position !== false) + { + $function_name_end = $position; + $found_start = 1 + $phpcsFile->findPrevious( + [T_NS_SEPARATOR, T_STRING, T_WHITESPACE], + $function_name_end - 1, + null, + true + ); + + $position = $phpcsFile->findNext(T_OPEN_PARENTHESIS, $position + 1); + if ($found_start === null || $found_start === false) + { + continue; + } + + $function_name_start = $found_start; + + // Trim the output. + while ($tokens[$function_name_start]['code'] === T_WHITESPACE && $function_name_start < $function_name_end) + { + ++$function_name_start; + } + + while ($tokens[$function_name_end]['code'] === T_WHITESPACE && $function_name_end > $function_name_start) + { + --$function_name_end; + } + + $function_name_length = $function_name_end - $function_name_start; + + // Filter out control structures, built in type constructors, etc. + if ($function_name_length <= 0) + { + continue; + } + + // This doesn't seem to be valid PHP, where is the opening tag? + if ($found_start === 0) + { + continue; + } + + $previous_token = $found_start - 1; + $filter = [ + T_FUNCTION, // Function declaration + T_OBJECT_OPERATOR, // Method call + T_DOUBLE_COLON, // Static method call + T_NEW, // Constructors + ]; + + // Filter out calls to methods and function declarations. + if (in_array($tokens[$previous_token]['code'], $filter)) + { + continue; + } + + $function_name = $phpcsFile->getTokensAsString($function_name_start, $function_name_length); + $ok = $this->check($phpcsFile, $function_name, $name_full, $name_short, $function_name_start) || $ok; + } + + return $ok; } /** * Check if this use statement is part of the namespace block. * - * @param PHP_CodeSniffer_File $phpcsFile The file being scanned. + * @param File $phpcsFile The file being scanned. * @param int $stackPtr The position of the current token in * the stack passed in $tokens. * * @return bool */ - private function should_ignore_use(PHP_CodeSniffer_File $phpcsFile, $stackPtr) + private function should_ignore_use(File $phpcsFile, $stackPtr) { $tokens = $phpcsFile->getTokens(); @@ -207,7 +414,7 @@ private function should_ignore_use(PHP_CodeSniffer_File $phpcsFile, $stackPtr) } /** - * @param PHP_CodeSniffer_File $phpcsFile + * @param File $phpcsFile * @param int $field * @param array $tokens * @param string $class_name_full @@ -216,7 +423,7 @@ private function should_ignore_use(PHP_CodeSniffer_File $phpcsFile, $stackPtr) * * @return bool */ - private function checkDocblock(PHP_CodeSniffer_File $phpcsFile, $comment_end, $tokens, $class_name_full, $class_name_short) + private function checkDocblock(File $phpcsFile, $comment_end, $tokens, $class_name_full, $class_name_short) { $ok = false; @@ -244,7 +451,7 @@ private function checkDocblock(PHP_CodeSniffer_File $phpcsFile, $comment_end, $t $classes = explode('|', str_replace('[]', '', $classes)); foreach ($classes as $class) { - $ok = $this->check($phpcsFile, $class, $class_name_full, $class_name_short, $tokens[$tag + 2]['line']) ? true : $ok; + $ok = $this->check($phpcsFile, $class, $class_name_full, $class_name_short, $tag + 2) || $ok; } } diff --git a/build/code_sniffer/ruleset-php-legacy.xml b/build/code_sniffer/ruleset-php-legacy.xml index c740c6080fa..8252cab03b1 100644 --- a/build/code_sniffer/ruleset-php-legacy.xml +++ b/build/code_sniffer/ruleset-php-legacy.xml @@ -17,9 +17,6 @@ - - - @@ -89,4 +86,7 @@ + + + diff --git a/build/code_sniffer/ruleset-php-strict.xml b/build/code_sniffer/ruleset-php-strict.xml index 9e2f0664d8f..8a06b72ba60 100644 --- a/build/code_sniffer/ruleset-php-strict.xml +++ b/build/code_sniffer/ruleset-php-strict.xml @@ -32,7 +32,9 @@ - + + */tests/* + + + + diff --git a/build/compare.sh b/build/compare.sh index df442fd4c79..9d01028aa96 100755 --- a/build/compare.sh +++ b/build/compare.sh @@ -19,9 +19,9 @@ do $command "$1.$ext" - for file in `find phpBB3 -name '.svn' -prune -o -type f -print` + for file in `find phpBB -name '.svn' -prune -o -type f -print` do - orig_file="${file/#phpBB3/$orig_dir}" + orig_file="${file/#phpBB/$orig_dir}" diff_result=`diff $orig_file $file` if [ -n "$diff_result" ] @@ -31,7 +31,7 @@ do fi done - rm -rf phpBB3 + rm -rf phpBB done cd .. diff --git a/build/doctum-all.conf.php b/build/doctum-all.conf.php new file mode 100644 index 00000000000..a6e5663e122 --- /dev/null +++ b/build/doctum-all.conf.php @@ -0,0 +1,21 @@ + +* @license GNU General Public License, version 2 (GPL-2.0) +* +* For full copyright and license information, please see +* the docs/CREDITS.txt file. +* +*/ + +require __DIR__ . '/doctum-checkout.conf.php'; + +$config['versions'] = Doctum\Version\GitVersionCollection::create(__DIR__ . '/../') + ->add('3.3.x') + ->add('master') +; + +return new Doctum\Doctum($iterator, $config); diff --git a/build/doctum-checkout.conf.php b/build/doctum-checkout.conf.php new file mode 100644 index 00000000000..bbcf8f26ba2 --- /dev/null +++ b/build/doctum-checkout.conf.php @@ -0,0 +1,31 @@ + +* @license GNU General Public License, version 2 (GPL-2.0) +* +* For full copyright and license information, please see +* the docs/CREDITS.txt file. +* +*/ + +$iterator = Symfony\Component\Finder\Finder::create() + ->files() + ->name('*.php') + ->in(__DIR__ . '/../phpBB/') + ->notPath('#^cache/#') + ->notPath('#^develop/#') + ->notPath('#^ext/#') + ->notPath('#^vendor/#') + ->notPath('data'); + +// This variable will be used and changed in doctum-all.conf.php +$config = [ + 'title' => 'phpBB API Documentation', + 'build_dir' => __DIR__ . '/api/output/%version%', + 'cache_dir' => __DIR__ . '/api/cache/%version%', +]; + +return new Doctum\Doctum($iterator, $config); diff --git a/build/generate_package_json.php b/build/generate_package_json.php new file mode 100644 index 00000000000..29ad4fd64f8 --- /dev/null +++ b/build/generate_package_json.php @@ -0,0 +1,133 @@ +#!/usr/bin/env php + + * @license GNU General Public License, version 2 (GPL-2.0) + * + * For full copyright and license information, please see + * the docs/CREDITS.txt file. + * + */ + +if (version_compare(PHP_VERSION, '7.0-dev', '<')) +{ + die('generate_package_json.php requires at least PHP 7.0.'); +} + +define('IN_PHPBB', true); +include_once('../phpBB/includes/functions.php'); + +$json_data = new \stdClass(); +$json_data->metadata = new stdClass(); + +$json_data->metadata->current_version_date = ''; +$json_data->metadata->current_version = ''; +$json_data->metadata->download_path = ''; +$json_data->metadata->show_update_package = true; +$json_data->metadata->historic = false; + +$json_data->package = []; + +// Open build.xml +$build_xml = simplexml_load_file('build.xml'); +$current_version = (string) $build_xml->xpath('/project/property[@name=\'newversion\']/@value')[0]->value; +$previous_version = (string) $build_xml->xpath('/project/property[@name=\'prevversion\']/@value')[0]->value; +$older_verions = explode(', ', (string) $build_xml->xpath('/project/property[@name=\'olderversions\']/@value')[0]->value); + +// Clean and sort version info +$older_verions[] = $previous_version; +$older_verions = array_filter($older_verions, function($version) { + preg_match(get_preg_expression('semantic_version'), $version, $matches); + return empty($matches['prerelease']) || strpos($matches['prerelease'], 'pl') !== false; +}); +usort($older_verions, function($version_a, $version_b) +{ + return phpbb_version_compare($version_b, $version_a); +}); + +// Set metadata +$json_data->metadata->current_version = $current_version; +$json_data->metadata->current_version_date = date('Y-m-d'); +$json_data->metadata->download_path = 'https://download.phpbb.com/pub/release/' . preg_replace('#([0-9]+\.[0-9]+)(\..+)#', '$1', $current_version) . '/' . $current_version . '/'; + +// Add package, patch files, and changed files +phpbb_add_package_file( + $json_data->package, + 'phpBB ' . $current_version, + 'phpBB-' . $current_version, + 'full', + '' +); +phpbb_add_package_file( + $json_data->package, + 'phpBB ' . $current_version . ' Patch Files', + 'phpBB-' . $current_version . '-patch', + 'update', + 'patch' +); +phpbb_add_package_file( + $json_data->package, + 'phpBB ' . $current_version . ' Changed Files', + 'phpBB-' . $current_version . '-files', + 'update', + 'files' +); + +// Loop through packages and assign to packages array +foreach ($older_verions as $version) +{ + phpbb_add_package_file( + $json_data->package, + 'phpBB ' . $version . ' to ' . $current_version . ' Update Package', + 'phpBB-' . $version . '_to_' . $current_version, + 'update', + 'advanced_update', + $version + ); +} + +echo(json_encode($json_data, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES) . "\n"); + +function phpbb_add_package_file(array &$package_list, $name, $file_name, $type, $subtype, $from = '') +{ + if (!file_exists(__DIR__ . '/new_version/release_files/' . $file_name . '.zip')) + { + trigger_error('File does not exist: ' . __DIR__ . '/new_version/release_files/' . $file_name . '.zip'); + return; + } + + $package_file = new stdClass(); + $package_file->name = $name; + $package_file->filename = $file_name; + $package_file->type = $type; + if (!empty($subtype)) + { + $package_file->subtype = $subtype; + } + if (!empty($from)) + { + $package_file->from = $from; + } + $package_file->files = []; + + foreach (['zip', 'tar.bz2'] as $extension) + { + $file_path = 'new_version/release_files/' . $file_name . '.' . $extension; + $filedata = new stdClass(); + $filedata->filesize = filesize($file_path); + $filedata->checksum = trim(preg_replace('/(^\w+)(.+)/', '$1', file_get_contents($file_path . '.sha256'))); + $filedata->filetype = $extension; + + if (file_exists($file_path . '.sig')) + { + $filedata->signature = trim(file_get_contents($file_path . '.sig')); + } + + $package_file->files[] = $filedata; + } + + $package_list[] = $package_file; +} diff --git a/build/generate_signature.php b/build/generate_signature.php new file mode 100644 index 00000000000..d1b56751199 --- /dev/null +++ b/build/generate_signature.php @@ -0,0 +1,52 @@ +#!/usr/bin/env php + + * @license GNU General Public License, version 2 (GPL-2.0) + * + * For full copyright and license information, please see + * the docs/CREDITS.txt file. + * + */ + +if ($_SERVER['argc'] != 3) +{ + echo "Please specify the secret key and filename for which the signature should be created, e.g. generate_signature.php mySecretSecret path/to/file\n"; + exit(1); +} + +$secret_key = base64_decode($_SERVER['argv'][1]); +$file_path = $_SERVER['argv'][2]; + +if (!extension_loaded('sodium')) +{ + die('Required sodium extension not loaded'); +} + +if (!file_exists($file_path)) +{ + die('File does not exist'); +} + +$hash = hash_file('sha384', $file_path, true); +try +{ + $signature = sodium_crypto_sign_detached($hash, $secret_key); +} +catch (SodiumException $e) +{ + $keypair = sodium_crypto_sign_keypair(); + + $secret_key = base64_encode(sodium_crypto_sign_secretkey($keypair)); + $public_key = base64_encode(sodium_crypto_sign_publickey($keypair)); + echo 'Unable to create the signature: ' . $e->getMessage() . "\n"; + echo "Maybe use these keys:\nPublic key: {$public_key}\nSecret key: {$secret_key}\n"; + die(); +} + +$signature = base64_encode($signature); + +file_put_contents($file_path . '.sig', $signature); diff --git a/build/psalm/stubs/apcu.php b/build/psalm/stubs/apcu.php new file mode 100644 index 00000000000..7fee581ff74 --- /dev/null +++ b/build/psalm/stubs/apcu.php @@ -0,0 +1,35 @@ + + * @license GNU General Public License, version 2 (GPL-2.0) + * + * For full copyright and license information, please see + * the docs/CREDITS.txt file. + * + */ + +class APCUIterator implements Iterator +{ + public function current() + { + } + + public function next() + { + } + + public function key() + { + } + + public function valid() + { + } + + public function rewind() + { + } +} diff --git a/build/psalm/stubs/gd.php b/build/psalm/stubs/gd.php new file mode 100644 index 00000000000..2b5b5a2bf78 --- /dev/null +++ b/build/psalm/stubs/gd.php @@ -0,0 +1,15 @@ + + * @license GNU General Public License, version 2 (GPL-2.0) + * + * For full copyright and license information, please see + * the docs/CREDITS.txt file. + * + */ + +/** @link https://www.php.net/manual/en/image.constants.php */ +define('IMG_COLOR_STYLED', -2); diff --git a/build/psalm/stubs/ldap.php b/build/psalm/stubs/ldap.php new file mode 100644 index 00000000000..44ed90fdb9f --- /dev/null +++ b/build/psalm/stubs/ldap.php @@ -0,0 +1,16 @@ + + * @license GNU General Public License, version 2 (GPL-2.0) + * + * For full copyright and license information, please see + * the docs/CREDITS.txt file. + * + */ + +/** @link https://www.php.net/manual/en/ldap.constants.php */ +define('LDAP_OPT_PROTOCOL_VERSION', 17); +define('LDAP_OPT_REFERRALS', 8); diff --git a/build/psalm/stubs/memcached.php b/build/psalm/stubs/memcached.php new file mode 100644 index 00000000000..9283d877f83 --- /dev/null +++ b/build/psalm/stubs/memcached.php @@ -0,0 +1,20 @@ + + * @license GNU General Public License, version 2 (GPL-2.0) + * + * For full copyright and license information, please see + * the docs/CREDITS.txt file. + * + */ + +/** @link https://www.php.net/manual/en/memcached.constants.php */ +class Memcached +{ + public const OPT_COMPRESSION = -1001; + + public const OPT_BINARY_PROTOCOL = 18; +} diff --git a/build/psalm/stubs/oci8.php b/build/psalm/stubs/oci8.php new file mode 100644 index 00000000000..5d05a36fce7 --- /dev/null +++ b/build/psalm/stubs/oci8.php @@ -0,0 +1,19 @@ + + * @license GNU General Public License, version 2 (GPL-2.0) + * + * For full copyright and license information, please see + * the docs/CREDITS.txt file. + * + */ + +/** @link https://php.net/manual/en/oci8.constants.php */ +define('OCI_DEFAULT', 0); + +define('OCI_ASSOC', 1); + +define('OCI_RETURN_NULLS', 4); diff --git a/build/psalm/stubs/pgsql.php b/build/psalm/stubs/pgsql.php new file mode 100644 index 00000000000..a00b21e46e5 --- /dev/null +++ b/build/psalm/stubs/pgsql.php @@ -0,0 +1,15 @@ + + * @license GNU General Public License, version 2 (GPL-2.0) + * + * For full copyright and license information, please see + * the docs/CREDITS.txt file. + * + */ + +/** @link https://www.php.net/manual/en/pgsql.constants.php */ +define('PGSQL_CONNECT_FORCE_NEW', 2); diff --git a/build/psalm/stubs/redis.php b/build/psalm/stubs/redis.php new file mode 100644 index 00000000000..96e912f707a --- /dev/null +++ b/build/psalm/stubs/redis.php @@ -0,0 +1,19 @@ + + * @license GNU General Public License, version 2 (GPL-2.0) + * + * For full copyright and license information, please see + * the docs/CREDITS.txt file. + * + */ + +/** @link https://phpredis.github.io/phpredis/Redis.html */ +class Redis +{ + public const OPT_PREFIX = 2; + public const SERIALIZER_PHP = 1; +} diff --git a/build/psalm/stubs/sqlite3.php b/build/psalm/stubs/sqlite3.php new file mode 100644 index 00000000000..5646c6623ea --- /dev/null +++ b/build/psalm/stubs/sqlite3.php @@ -0,0 +1,33 @@ + + * @license GNU General Public License, version 2 (GPL-2.0) + * + * For full copyright and license information, please see + * the docs/CREDITS.txt file. + * + */ + +class SQLite3 +{ + public function query(string $query) {} +} + +class SQLite3Result +{ + public function fetchArray(int $mode = SQLITE3_BOTH) {} +} + +/** + * @link https://www.php.net/manual/en/sqlite3.constants.php + */ +define('SQLITE3_ASSOC', 1); +define('SQLITE3_NUM', 2); +define('SQLITE3_BOTH', 3); + +define('SQLITE3_OPEN_READONLY', 1); +define('SQLITE3_OPEN_READWRITE', 2); +define('SQLITE3_OPEN_CREATE', 4); diff --git a/build/psalm/stubs/sqlsrv.php b/build/psalm/stubs/sqlsrv.php new file mode 100644 index 00000000000..8e2aaf74265 --- /dev/null +++ b/build/psalm/stubs/sqlsrv.php @@ -0,0 +1,17 @@ + + * @license GNU General Public License, version 2 (GPL-2.0) + * + * For full copyright and license information, please see + * the docs/CREDITS.txt file. + * + */ + +/** @link https://www.php.net/manual/en/sqlsrv.constants.php */ +define('SQLSRV_ERR_ERRORS', 0); +define('SQLSRV_FETCH_ASSOC', 2); +define('SQLSRV_CURSOR_STATIC', 'static'); diff --git a/build/psalm_bootstrap.php b/build/psalm_bootstrap.php new file mode 100644 index 00000000000..92099c77f50 --- /dev/null +++ b/build/psalm_bootstrap.php @@ -0,0 +1,55 @@ + +* @license GNU General Public License, version 2 (GPL-2.0) +* +* For full copyright and license information, please see +* the docs/CREDITS.txt file. +* +*/ + +define('IN_PHPBB', true); +define('PHPBB_ENVIRONMENT', 'test'); + +$phpbb_root_path = 'phpBB/'; +$phpEx = 'php'; + +global $table_prefix; +require_once $phpbb_root_path . 'includes/startup.php'; + +$table_prefix = 'phpbb_'; +require_once $phpbb_root_path . 'includes/constants.php'; +require_once $phpbb_root_path . 'phpbb/class_loader.' . $phpEx; +require_once $phpbb_root_path . 'includes/acp/acp_database.' . $phpEx; +require_once $phpbb_root_path . 'includes/utf/utf_tools.' . $phpEx; +require_once $phpbb_root_path . 'includes/functions.' . $phpEx; +require_once $phpbb_root_path . 'includes/functions_acp.' . $phpEx; +require_once $phpbb_root_path . 'includes/functions_admin.' . $phpEx; +require_once $phpbb_root_path . 'includes/functions_compatibility.' . $phpEx; +require_once $phpbb_root_path . 'includes/functions_compress.' . $phpEx; +require_once $phpbb_root_path . 'includes/functions_content.' . $phpEx; +require_once $phpbb_root_path . 'includes/functions_display.' . $phpEx; +require_once $phpbb_root_path . 'includes/functions_mcp.' . $phpEx; +require_once $phpbb_root_path . 'includes/functions_module.' . $phpEx; +require_once $phpbb_root_path . 'includes/functions_posting.' . $phpEx; +require_once $phpbb_root_path . 'includes/functions_privmsgs.' . $phpEx; +require_once $phpbb_root_path . 'includes/functions_transfer.' . $phpEx; +require_once $phpbb_root_path . 'includes/functions_user.' . $phpEx; +require_once $phpbb_root_path . 'includes/sphinxapi.' . $phpEx; +require_once $phpbb_root_path . 'includes/diff/diff.' . $phpEx; +require_once $phpbb_root_path . 'includes/diff/engine.' . $phpEx; +require_once $phpbb_root_path . 'includes/compatibility_globals.' . $phpEx; + +$phpbb_class_loader = new \phpbb\class_loader('phpbb\\', $phpbb_root_path . 'phpbb/', "php"); +$phpbb_class_loader->register(); + +// Include files that require class loader to be initialized +require_once $phpbb_root_path . 'includes/acp/auth.' . $phpEx; +require_once $phpbb_root_path . 'includes/acp/acp_captcha.' . $phpEx; + +class phpbb_cache_container extends \Symfony\Component\DependencyInjection\Container +{ +} diff --git a/build/sami-all.conf.php b/build/sami-all.conf.php deleted file mode 100644 index 4bf812eb02c..00000000000 --- a/build/sami-all.conf.php +++ /dev/null @@ -1,32 +0,0 @@ - -* @license GNU General Public License, version 2 (GPL-2.0) -* -* For full copyright and license information, please see -* the docs/CREDITS.txt file. -* -*/ - -require __DIR__ . '/sami-checkout.conf.php'; - -$config['versions'] = Sami\Version\GitVersionCollection::create(__DIR__ . '/../') - /* - This would be nice, but currently causes various problems that need - debugging. - ->addFromTags('release-3.0.*') - ->add('3.0.x', '3.0-next (olympus)') - ->addFromTags('release-3.1.*') - ->add('3.1.x', '3.1-next (ascraeus)') - ->add('master') - */ - ->add('3.0.x') - ->add('3.1.x') - ->add('3.2.x') - ->add('master') -; - -return new Sami\Sami($iterator, $config); diff --git a/build/sami-checkout.conf.php b/build/sami-checkout.conf.php deleted file mode 100644 index abbf1d257e3..00000000000 --- a/build/sami-checkout.conf.php +++ /dev/null @@ -1,44 +0,0 @@ - -* @license GNU General Public License, version 2 (GPL-2.0) -* -* For full copyright and license information, please see -* the docs/CREDITS.txt file. -* -*/ - -// Prevent 'Class "acm" does not exist.' exception on removeClass(). -class PhpbbArrayStore extends Sami\Store\ArrayStore -{ - public function removeClass(Sami\Project $project, $name) - { - unset($this->classes[$name]); - } -} - -$iterator = Symfony\Component\Finder\Finder::create() - ->files() - ->name('*.php') - ->in(__DIR__ . '/../phpBB/') - ->notPath('#^cache/#') - ->notPath('#^develop/#') - ->notPath('#^ext/#') - ->notPath('#^vendor/#') - ->notPath('data') -; - -$config = array( - 'theme' => 'enhanced', - 'title' => 'phpBB API Documentation', - 'build_dir' => __DIR__.'/api/output/%version%', - 'cache_dir' => __DIR__.'/api/cache/%version%', - 'default_opened_level' => 2, - // Do not use JsonStore. See https://github.com/fabpot/Sami/issues/79 - 'store' => new PhpbbArrayStore, -); - -return new Sami\Sami($iterator, $config); diff --git a/build/update_stylesheet_querystrings.php b/build/update_stylesheet_querystrings.php new file mode 100644 index 00000000000..e3a3f8de15e --- /dev/null +++ b/build/update_stylesheet_querystrings.php @@ -0,0 +1,54 @@ + +* @license GNU General Public License, version 2 (GPL-2.0) +* +* For full copyright and license information, please see +* the docs/CREDITS.txt file. +* +*/ + +if (php_sapi_name() !== 'cli') +{ + die("This program must be run from the command line.\n"); +} + +if (version_compare(PHP_VERSION, '7.1.3', '<')) +{ + die('update_stylesheet_querystrings.php requires at least PHP 7.1.3'); +} + +// Usage: "$ php build/update_stylesheet_querystrings.php" +$targets = [dirname(dirname(__FILE__)) . '/phpBB/styles/prosilver/theme/stylesheet.css']; + +array_map('patch_glob', $targets); + +function patch_glob($glob): void +{ + array_map('patch_file', glob($glob)); +} + +function patch_file(string $filepath): void +{ + $file = file_get_contents($filepath); + $old = $file; + $new = preg_replace_callback( + '(^@import\\s+url\\([\'"](?\\w++\\.css)\\?\\K(?:hash|v)=[^\'"]++)m', + function ($match) use ($filepath) + { + $path = dirname($filepath) . DIRECTORY_SEPARATOR . $match['basename']; + $hash = sprintf('%08x', crc32(file_get_contents($path))); + + return 'hash=' . $hash; + }, + $old + ); + + if ($new !== $old) + { + file_put_contents($filepath, $new); + } +} diff --git a/build/verify_signature.php b/build/verify_signature.php new file mode 100644 index 00000000000..fd432ed638c --- /dev/null +++ b/build/verify_signature.php @@ -0,0 +1,56 @@ +#!/usr/bin/env php + + * @license GNU General Public License, version 2 (GPL-2.0) + * + * For full copyright and license information, please see + * the docs/CREDITS.txt file. + * + */ + +if ($_SERVER['argc'] != 4) +{ + echo "Please specify the public key, filename for which the signature should be check, and the signature file, e.g. verify_signature.php superPublicKey path/to/file path/to/signature\n"; + exit(1); +} + +$public_key = base64_decode($_SERVER['argv'][1]); +$file_path = $_SERVER['argv'][2]; +$signature_path = $_SERVER['argv'][3]; + +if (!extension_loaded('sodium')) +{ + die('Required sodium extension not loaded'); +} + +if (!file_exists($file_path)) +{ + die('File does not exist'); +} + +if (!file_exists($signature_path)) +{ + die('Signature file does not exist'); +} + +$hash = hash_file('sha384', $file_path, true); +$signature = base64_decode(file_get_contents($signature_path)); + +try +{ + if (sodium_crypto_sign_verify_detached($signature, $hash, $public_key)) + { + echo 'Signature is valid!'; + } + else + { + echo 'Signature is not valid!'; + } +} catch (SodiumException $e) +{ + die('Unable to verify the signature: ' . $e->getMessage() . "\n"); +} diff --git a/composer.phar b/composer.phar index 508f9cf274b..5a80d7434b5 100755 Binary files a/composer.phar and b/composer.phar differ diff --git a/doctum.phar b/doctum.phar new file mode 100755 index 00000000000..b20e8de4d51 Binary files /dev/null and b/doctum.phar differ diff --git a/eslint.config.mjs b/eslint.config.mjs new file mode 100644 index 00000000000..0f2f72bf69a --- /dev/null +++ b/eslint.config.mjs @@ -0,0 +1,67 @@ +import globals from 'globals'; + +// File patterns to ignore +const IGNORED_FILES = [ + 'phpBB/assets/javascript/cropper.js', + 'phpBB/assets/javascript/hermite.js', + 'phpBB/assets/javascript/jquery-cropper.js', + 'phpBB/**/*.min.js', + 'phpBB/vendor/**/*.js', + 'phpBB/vendor-ext/**/*.js', + 'phpBB/phpbb/**/*.js', + 'phpBB/tests/**/*.js', +]; + +// ESLint rule configurations +const FORMATTING_RULES = { + 'quotes': ['error', 'single'], + 'comma-dangle': ['error', 'always-multiline'], + 'block-spacing': 'error', + 'array-bracket-spacing': ['error', 'always'], + 'object-curly-spacing': ['error', 'always'], + 'space-before-function-paren': ['error', 'never'], + 'space-in-parens': 'off', +}; + +const CODE_QUALITY_RULES = { + 'semi': ['error', 'always'], + 'eqeqeq': ['error', 'always'], + 'curly': ['error', 'multi-line'], + 'no-var': 'error', + 'prefer-const': 'error', + 'no-console': 'off', + 'no-unused-vars': ['error', { argsIgnorePattern: '^_', varsIgnorePattern: '^_' }], +}; + +const DISABLED_STYLE_RULES = { + 'multiline-comment-style': 'off', + 'computed-property-spacing': 'off', + 'capitalized-comments': 'off', + 'no-lonely-if': 'off', +}; + +const mainConfig = { + files: ['**/*.js', '**/*.js.twig'], + linterOptions: { + reportUnusedDisableDirectives: false, + }, + languageOptions: { + ecmaVersion: 'latest', + sourceType: 'module', + globals: { + ...globals.browser, + ...globals.node, + ...globals.jquery, + }, + }, + rules: { + ...FORMATTING_RULES, + ...CODE_QUALITY_RULES, + ...DISABLED_STYLE_RULES, + }, +}; + +export default [ + { ignores: IGNORED_FILES }, + mainConfig, +]; diff --git a/git-tools/commit-msg-hook-range.sh b/git-tools/commit-msg-hook-range.sh index 91f7577eb53..84f291b2212 100755 --- a/git-tools/commit-msg-hook-range.sh +++ b/git-tools/commit-msg-hook-range.sh @@ -24,7 +24,17 @@ COMMIT_MSG_HOOK_FATAL=$(git config --bool phpbb.hooks.commit-msg.fatal 2> /dev/n git config phpbb.hooks.commit-msg.fatal true EXIT_STATUS=0 -for COMMIT_HASH in $(git rev-list --no-merges "$COMMIT_RANGE") + +COMMIT_HASHES=$(git rev-list --no-merges "$COMMIT_RANGE") + +# If any message have been returned instead of commit hashes list +# send a non-zero exit status upstream. +if ! [[ "$COMMIT_HASHES" =~ ^[0-9a-f]{5,40} ]] +then + EXIT_STATUS=1 +fi + +for COMMIT_HASH in $COMMIT_HASHES do echo "Inspecting commit message of commit $COMMIT_HASH" diff --git a/git-tools/hooks/commit-msg b/git-tools/hooks/commit-msg index 136606252c5..b35d1c89c71 100755 --- a/git-tools/hooks/commit-msg +++ b/git-tools/hooks/commit-msg @@ -1,7 +1,7 @@ #!/bin/sh # -# A hook to check syntax of a phpBB3 commit message, per: -# * +# A hook to check syntax of a phpBB commit message, per: +# * # * # # This is a commit-msg hook. @@ -147,6 +147,15 @@ then quit $ERR_LENGTH; fi +# Check for CR/LF line breaks +if grep -q $'\r$' "$1" +then + complain "The commit message uses CR/LF line breaks, which are not permitted." >&2 + complain >&2 + + quit $ERR_EOF; +fi + lines=$(wc -l "$1" | awk '{ print $1; }'); expecting=header; in_description=0; @@ -215,7 +224,7 @@ do "footer") err=$ERR_FOOTER; # Each ticket is on its own line - echo "$line" | grep -Eq "^PHPBB3-[0-9]+$"; + echo "$line" | grep -Eq "^PHPBB3?-[0-9]+$"; ;; "eof") err=$ERR_EOF; @@ -328,7 +337,7 @@ done # If EOF is expected exit cleanly echo "$expecting" | grep -q "eof" || ( # Unexpected EOF, error - complain "Unexpected EOF encountered" >&2; + complain "Expected to see footer (e.g. PHPBB-12345) or description line, but reached end of file." >&2; quit $ERR_EOF; ) && ( # Do post scan checks @@ -347,7 +356,7 @@ echo "$expecting" | grep -q "eof" || ( # Check the branch ticket is mentioned, doesn't make sense otherwise if [ $ticket -gt 0 ] then - echo "$tickets" | grep -Eq "\bPHPBB3-$ticket\b" || ( + echo "$tickets" | grep -Eq "\bPHPBB3?-$ticket\b" || ( complain "Ticket ID [$ticket] of branch missing from list of tickets:" >&2; complain "$tickets" | sed 's/ /\n/g;s/^/* /g' >&2; quit $ERR_FOOTER; diff --git a/git-tools/hooks/pre-commit b/git-tools/hooks/pre-commit index 06ba15c7fa3..d7071f2c474 100755 --- a/git-tools/hooks/pre-commit +++ b/git-tools/hooks/pre-commit @@ -75,7 +75,7 @@ do if [ $? -ne 0 ] then # Swap back in correct filenames - errors=$(echo "$errors"; echo "$result" | grep ':' | sed -e "s@in - on@in $filename on@g") + errors=$(echo "$errors"; echo "$result" | grep ':' | sed -E "s@in (.+) on line@in $filename on@g") fi done unset IFS diff --git a/git-tools/hooks/prepare-commit-msg b/git-tools/hooks/prepare-commit-msg index 11d2b6b2f2a..6e5b701fdea 100755 --- a/git-tools/hooks/prepare-commit-msg +++ b/git-tools/hooks/prepare-commit-msg @@ -1,4 +1,4 @@ -#!/bin/sh +#!/bin/bash # # A hook to add [$branch] to the beginning of a commit message # if certain conditions are met. @@ -31,12 +31,25 @@ branch="$(echo "$branch" | sed "s/refs\/heads\///g")" if [ "$2" = "" ] then tail=""; + ticket_id=$(sed -E 's/(ticket\/)(security\/)?([0-9]+)(.+$)?/\3/gm;t;d' <<< "$branch"); + branch_title=$(sed -E 's/(ticket\/)(security\/)?([0-9]+)(.+$)?/\1\2\3/gm;t;d' <<< "$branch"); - # Branch is prefixed with 'ticket/', append ticket ID to message - if [ "$branch" != "${branch##ticket/}" ]; + # Fall back to branch name if no ticket ID + if [ -z "$branch_title" ]; then - tail="$(printf "\n\nPHPBB3-${branch##ticket/}")"; + branch_title="$branch"; fi - echo "[$branch] $tail$(cat "$1")" > "$1" + if [ "security/" = "$(sed -E 's/(ticket\/)(security\/)?([0-9]+)(.+$)?/\2/gm;t;d' <<< "$branch")" ]; + then + tail="$(printf '\n\nSECURITY-%s' "$ticket_id")"; + else + # Branch is prefixed with 'ticket/', append ticket ID to message + if [ "$branch" != "${branch##ticket/}" ]; + then + tail="$(printf '\n\nPHPBB-%s' "$ticket_id")"; + fi + fi + + echo "[$branch_title] $tail$(cat "$1")" > "$1" fi diff --git a/git-tools/merge.php b/git-tools/merge.php index a9bb0514013..7feda889333 100755 --- a/git-tools/merge.php +++ b/git-tools/merge.php @@ -56,7 +56,7 @@ function show_usage() function work($pull_id, $remote) { // Get some basic data - $pull = get_pull('phpbb', 'phpbb3', $pull_id); + $pull = get_pull('phpbb', 'phpbb', $pull_id); if (!$pull_id) { @@ -79,7 +79,7 @@ function work($pull_id, $remote) run("git checkout develop-olympus"); run("git pull $remote develop-olympus"); - add_remote($pull_user, 'phpbb3'); + add_remote($pull_user, 'phpbb'); run("git fetch $pull_user"); run("git merge --no-ff $pull_user/$pull_branch"); run("phpBB/vendor/bin/phpunit"); @@ -94,7 +94,7 @@ function work($pull_id, $remote) run("git checkout develop"); run("git pull $remote develop"); - add_remote($pull_user, 'phpbb3'); + add_remote($pull_user, 'phpbb'); run("git fetch $pull_user"); run("git merge --no-ff $pull_user/$pull_branch"); run("phpBB/vendor/bin/phpunit"); diff --git a/gulpfile.js b/gulpfile.js deleted file mode 100644 index c2a18225452..00000000000 --- a/gulpfile.js +++ /dev/null @@ -1,71 +0,0 @@ -'use strict'; - -const del = require('del'); -const gulp = require('gulp'); -const autoprefixer = require('gulp-autoprefixer'); -const sass = require('gulp-sass'); -const rename = require('gulp-rename'); -const sourcemaps = require('gulp-sourcemaps'); -const cssnano = require('gulp-cssnano'); -const postcss = require('gulp-postcss'); -const stylefmt = require('gulp-stylefmt'); -const sorting = require('postcss-sorting'); -const atimport = require('postcss-import'); -const torem = require('postcss-pxtorem'); -const sortOrder = require('./.postcss-sorting.json'); -const pkg = require('./package.json'); - -// Config -const build = { - css: './phpBB/styles/prosilver/theme/', -}; - -const AUTOPREFIXER_BROWSERS = [ - '> 1%', - 'last 2 versions' -]; - -gulp.task('css', () => { - const css = gulp - .src(build.css + '*.css') - .pipe(autoprefixer(AUTOPREFIXER_BROWSERS)) - .pipe( - postcss([ - sorting(sortOrder) - ]) - ) - .pipe(stylefmt()) - .pipe(gulp.dest(build.css)); - - return css; -}); - -gulp.task('clean', () => { - del(['dist']); -}); - -gulp.task('minify', () => { - const css = gulp - .src(build.css + '/bidi.css') - .pipe(sourcemaps.init()) - .pipe( - postcss([ - atimport() - ]) - ) - .pipe(cssnano()) - .pipe(rename({ - suffix: '.min', - extname: '.css' - })) - .pipe(sourcemaps.write('./')) - .pipe(gulp.dest(build.css)); - - return css; -}); - -gulp.task('watch', () => { - gulp.watch('phpBB/styles/prosilver/theme/*.css', ['css']); -}); - -gulp.task('default', ['css', 'watch']); diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 00000000000..add3d4534d4 --- /dev/null +++ b/package-lock.json @@ -0,0 +1,4049 @@ +{ + "name": "phpbb", + "version": "4.0.0-dev", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "phpbb", + "version": "4.0.0-dev", + "license": "GPL-2.0", + "devDependencies": { + "eslint": "^9.28.0", + "globals": "^17.0.0", + "stylelint": "^14.7.0", + "stylelint-order": "^5.0.0", + "web-push-testing": "^1.1.1" + } + }, + "node_modules/@babel/code-frame": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.27.1.tgz", + "integrity": "sha512-cjQ7ZlQ0Mv3b47hABuTevyTuYN4i+loJKGeV9flcCgIK37cCXRh+L1bd3iBHlynerhQ7BhCkn2BPbQUL+rGqFg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-validator-identifier": "^7.27.1", + "js-tokens": "^4.0.0", + "picocolors": "^1.1.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-identifier": { + "version": "7.28.5", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.28.5.tgz", + "integrity": "sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@csstools/selector-specificity": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@csstools/selector-specificity/-/selector-specificity-2.2.0.tgz", + "integrity": "sha512-+OJ9konv95ClSTOJCmMZqpd5+YGsB2S+x6w3E1oaM8UuR5j8nTNHYSz8c9BEPGDOCMQYIEEGlVPj/VY64iTbGw==", + "dev": true, + "license": "CC0-1.0", + "engines": { + "node": "^14 || ^16 || >=18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + }, + "peerDependencies": { + "postcss-selector-parser": "^6.0.10" + } + }, + "node_modules/@eslint-community/eslint-utils": { + "version": "4.9.1", + "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.9.1.tgz", + "integrity": "sha512-phrYmNiYppR7znFEdqgfWHXR6NCkZEK7hwWDHZUjit/2/U0r6XvkDl0SYnoM51Hq7FhCGdLDT6zxCCOY1hexsQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "eslint-visitor-keys": "^3.4.3" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + }, + "peerDependencies": { + "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" + } + }, + "node_modules/@eslint-community/eslint-utils/node_modules/eslint-visitor-keys": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", + "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/@eslint-community/regexpp": { + "version": "4.12.2", + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.12.2.tgz", + "integrity": "sha512-EriSTlt5OC9/7SXkRSCAhfSxxoSUgBm33OH+IkwbdpgoqsSsUg7y3uh+IICI/Qg4BBWr3U2i39RpmycbxMq4ew==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^12.0.0 || ^14.0.0 || >=16.0.0" + } + }, + "node_modules/@eslint/config-array": { + "version": "0.21.1", + "resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.21.1.tgz", + "integrity": "sha512-aw1gNayWpdI/jSYVgzN5pL0cfzU02GT3NBpeT/DXbx1/1x7ZKxFPd9bwrzygx/qiwIQiJ1sw/zD8qY/kRvlGHA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@eslint/object-schema": "^2.1.7", + "debug": "^4.3.1", + "minimatch": "^3.1.2" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/config-helpers": { + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/@eslint/config-helpers/-/config-helpers-0.4.2.tgz", + "integrity": "sha512-gBrxN88gOIf3R7ja5K9slwNayVcZgK6SOUORm2uBzTeIEfeVaIhOpCtTox3P6R7o2jLFwLFTLnC7kU/RGcYEgw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@eslint/core": "^0.17.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/core": { + "version": "0.17.0", + "resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.17.0.tgz", + "integrity": "sha512-yL/sLrpmtDaFEiUj1osRP4TI2MDz1AddJL+jZ7KSqvBuliN4xqYY54IfdN8qD8Toa6g1iloph1fxQNkjOxrrpQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@types/json-schema": "^7.0.15" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/eslintrc": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-3.3.3.tgz", + "integrity": "sha512-Kr+LPIUVKz2qkx1HAMH8q1q6azbqBAsXJUxBl/ODDuVPX45Z9DfwB8tPjTi6nNZ8BuM3nbJxC5zCAg5elnBUTQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ajv": "^6.12.4", + "debug": "^4.3.2", + "espree": "^10.0.1", + "globals": "^14.0.0", + "ignore": "^5.2.0", + "import-fresh": "^3.2.1", + "js-yaml": "^4.1.1", + "minimatch": "^3.1.2", + "strip-json-comments": "^3.1.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/@eslint/eslintrc/node_modules/globals": { + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-14.0.0.tgz", + "integrity": "sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@eslint/js": { + "version": "9.39.2", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.39.2.tgz", + "integrity": "sha512-q1mjIoW1VX4IvSocvM/vbTiveKC4k9eLrajNEuSsmjymSDEbpGddtpfOoN7YGAqBK3NG+uqo8ia4PDTt8buCYA==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://eslint.org/donate" + } + }, + "node_modules/@eslint/object-schema": { + "version": "2.1.7", + "resolved": "https://registry.npmjs.org/@eslint/object-schema/-/object-schema-2.1.7.tgz", + "integrity": "sha512-VtAOaymWVfZcmZbp6E2mympDIHvyjXs/12LqWYjVw6qjrfF+VK+fyG33kChz3nnK+SU5/NeHOqrTEHS8sXO3OA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/plugin-kit": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.4.1.tgz", + "integrity": "sha512-43/qtrDUokr7LJqoF2c3+RInu/t4zfrpYdoSDfYyhg52rwLV6TnOvdG4fXm7IkSB3wErkcmJS9iEhjVtOSEjjA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@eslint/core": "^0.17.0", + "levn": "^0.4.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@humanfs/core": { + "version": "0.19.1", + "resolved": "https://registry.npmjs.org/@humanfs/core/-/core-0.19.1.tgz", + "integrity": "sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=18.18.0" + } + }, + "node_modules/@humanfs/node": { + "version": "0.16.7", + "resolved": "https://registry.npmjs.org/@humanfs/node/-/node-0.16.7.tgz", + "integrity": "sha512-/zUx+yOsIrG4Y43Eh2peDeKCxlRt/gET6aHfaKpuq267qXdYDFViVHfMaLyygZOnl0kGWxFIgsBy8QFuTLUXEQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@humanfs/core": "^0.19.1", + "@humanwhocodes/retry": "^0.4.0" + }, + "engines": { + "node": ">=18.18.0" + } + }, + "node_modules/@humanwhocodes/module-importer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", + "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=12.22" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, + "node_modules/@humanwhocodes/retry": { + "version": "0.4.3", + "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.4.3.tgz", + "integrity": "sha512-bV0Tgo9K4hfPCek+aMAn81RppFKv2ySDQeMoSZuvTASywNTnVJCArCZE2FWqpvIatKu7VMRLWlR1EazvVhDyhQ==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=18.18" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, + "node_modules/@nodelib/fs.scandir": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.stat": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.walk": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", + "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@types/estree": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.8.tgz", + "integrity": "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/json-schema": { + "version": "7.0.15", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", + "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/minimist": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/@types/minimist/-/minimist-1.2.5.tgz", + "integrity": "sha512-hov8bUuiLiyFPGyFPE1lwWhmzYbirOXQNNo40+y3zow8aFVTeyn3VWL0VFFfdNddA8S4Vf0Tc062rzyNr7Paag==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/normalize-package-data": { + "version": "2.4.4", + "resolved": "https://registry.npmjs.org/@types/normalize-package-data/-/normalize-package-data-2.4.4.tgz", + "integrity": "sha512-37i+OaWTh9qeK4LSHPsyRC7NahnGotNuZvjLSgcPzblpHB3rrCJxAOgI5gCdKm7coonsaX1Of0ILiTcnZjbfxA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/parse-json": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.2.tgz", + "integrity": "sha512-dISoDXWWQwUquiKsyZ4Ng+HX2KsPL7LyHKHQwgGFEA3IaKac4Obd+h2a/a6waisAoepJlBcx9paWqjA8/HVjCw==", + "dev": true, + "license": "MIT" + }, + "node_modules/accepts": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", + "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==", + "dev": true, + "license": "MIT", + "dependencies": { + "mime-types": "~2.1.34", + "negotiator": "0.6.3" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/acorn": { + "version": "8.15.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.15.0.tgz", + "integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==", + "dev": true, + "license": "MIT", + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/acorn-jsx": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", + "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" + } + }, + "node_modules/ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true, + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/arg": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/arg/-/arg-5.0.2.tgz", + "integrity": "sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==", + "dev": true, + "license": "MIT" + }, + "node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true, + "license": "Python-2.0" + }, + "node_modules/array-flatten": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", + "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==", + "dev": true, + "license": "MIT" + }, + "node_modules/array-union": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", + "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/arrify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", + "integrity": "sha512-3CYzex9M9FGQjCGMGyi6/31c8GJbgb0qGyrx5HWxPd0aCwh4cB2YjMb2Xf9UuoogrMrlO9cTqnB5rI5GHZTcUA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/astral-regex": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz", + "integrity": "sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true, + "license": "MIT" + }, + "node_modules/body-parser": { + "version": "1.20.4", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.4.tgz", + "integrity": "sha512-ZTgYYLMOXY9qKU/57FAo8F+HA2dGX7bqGc71txDRC1rS4frdFI5R7NhluHxH6M0YItAP0sHB4uqAOcYKxO6uGA==", + "dev": true, + "license": "MIT", + "dependencies": { + "bytes": "~3.1.2", + "content-type": "~1.0.5", + "debug": "2.6.9", + "depd": "2.0.0", + "destroy": "~1.2.0", + "http-errors": "~2.0.1", + "iconv-lite": "~0.4.24", + "on-finished": "~2.4.1", + "qs": "~6.14.0", + "raw-body": "~2.5.3", + "type-is": "~1.6.18", + "unpipe": "~1.0.0" + }, + "engines": { + "node": ">= 0.8", + "npm": "1.2.8000 || >= 1.4.16" + } + }, + "node_modules/body-parser/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/body-parser/node_modules/iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "dev": true, + "license": "MIT", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/body-parser/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "dev": true, + "license": "MIT" + }, + "node_modules/brace-expansion": { + "version": "1.1.12", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", + "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/braces": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", + "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", + "dev": true, + "license": "MIT", + "dependencies": { + "fill-range": "^7.1.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/buffer-equal-constant-time": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz", + "integrity": "sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA==", + "dev": true, + "license": "BSD-3-Clause" + }, + "node_modules/bytes": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", + "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/call-bind-apply-helpers": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz", + "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/call-bound": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.4.tgz", + "integrity": "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.2", + "get-intrinsic": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/callsites": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/camelcase-keys": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-6.2.2.tgz", + "integrity": "sha512-YrwaA0vEKazPBkn0ipTiMpSajYDSe+KjQfrjhcBMxJt/znbvlHd8Pw/Vamaz5EB4Wfhs3SUR3Z9mwRu/P3s3Yg==", + "dev": true, + "license": "MIT", + "dependencies": { + "camelcase": "^5.3.1", + "map-obj": "^4.0.0", + "quick-lru": "^4.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true, + "license": "MIT" + }, + "node_modules/colord": { + "version": "2.9.3", + "resolved": "https://registry.npmjs.org/colord/-/colord-2.9.3.tgz", + "integrity": "sha512-jeC1axXpnb0/2nn/Y1LPuLdgXBLH7aDcHu4KEKfqw3CUhX7ZpfBSlPKyqXE6btIgEzfWtrX3/tyBCaCvXvMkOw==", + "dev": true, + "license": "MIT" + }, + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", + "dev": true, + "license": "MIT" + }, + "node_modules/connected-domain": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/connected-domain/-/connected-domain-1.0.0.tgz", + "integrity": "sha512-lHlohUiJxlpunvDag2Y0pO20bnvarMjnrdciZeuJUqRwrf/5JHNhdpiPIr5GQ8IkqrFj5TDMQwcCjblGo1oeuA==", + "dev": true, + "license": "MIT" + }, + "node_modules/content-disposition": { + "version": "0.5.4", + "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz", + "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "safe-buffer": "5.2.1" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/content-disposition/node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/content-type": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz", + "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/cookie": { + "version": "0.7.2", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.2.tgz", + "integrity": "sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/cookie-signature": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.7.tgz", + "integrity": "sha512-NXdYc3dLr47pBkpUCHtKSwIOQXLVn8dZEuywboCOJY/osA0wFSLlSawr3KN8qXJEyX66FcONTH8EIlVuK0yyFA==", + "dev": true, + "license": "MIT" + }, + "node_modules/cosmiconfig": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-7.1.0.tgz", + "integrity": "sha512-AdmX6xUzdNASswsFtmwSt7Vj8po9IuqXm0UXz7QKPuEUmPB4XyjGfaAr2PSuELMwkRMVH1EpIkX5bTZGRB3eCA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/parse-json": "^4.0.0", + "import-fresh": "^3.2.1", + "parse-json": "^5.0.0", + "path-type": "^4.0.0", + "yaml": "^1.10.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/cross-spawn": { + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", + "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", + "dev": true, + "license": "MIT", + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/css-functions-list": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/css-functions-list/-/css-functions-list-3.2.3.tgz", + "integrity": "sha512-IQOkD3hbR5KrN93MtcYuad6YPuTSUhntLHDuLEbFWE+ff2/XSZNdZG+LcbbIW5AXKg/WFIfYItIzVoHngHXZzA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12 || >=16" + } + }, + "node_modules/cssesc": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz", + "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==", + "dev": true, + "license": "MIT", + "bin": { + "cssesc": "bin/cssesc" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/debug": { + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", + "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/decamelize": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", + "integrity": "sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/decamelize-keys": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/decamelize-keys/-/decamelize-keys-1.1.1.tgz", + "integrity": "sha512-WiPxgEirIV0/eIOMcnFBA3/IJZAZqKnwAwWyvvdi4lsr1WCN22nhdf/3db3DoZcUjTV2SqfzIwNyp6y2xs3nmg==", + "dev": true, + "license": "MIT", + "dependencies": { + "decamelize": "^1.1.0", + "map-obj": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/decamelize-keys/node_modules/map-obj": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-1.0.1.tgz", + "integrity": "sha512-7N/q3lyZ+LVCp7PzuxrJr4KMbBE2hW7BT7YNia330OFxIf4d3r5zVpicP2650l7CPN6RM9zOJRl3NGpqSiw3Eg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/deep-is": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", + "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/depd": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", + "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/destroy": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz", + "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8", + "npm": "1.2.8000 || >= 1.4.16" + } + }, + "node_modules/dir-glob": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", + "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", + "dev": true, + "license": "MIT", + "dependencies": { + "path-type": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/dunder-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz", + "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.1", + "es-errors": "^1.3.0", + "gopd": "^1.2.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/ecdsa-sig-formatter": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz", + "integrity": "sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "safe-buffer": "^5.0.1" + } + }, + "node_modules/ee-first": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", + "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==", + "dev": true, + "license": "MIT" + }, + "node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true, + "license": "MIT" + }, + "node_modules/encodeurl": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-2.0.0.tgz", + "integrity": "sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/error-ex": { + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.4.tgz", + "integrity": "sha512-sqQamAnR14VgCr1A618A3sGrygcpK+HEbenA/HiEAkkUwcZIIB/tgWqHFxWgOyDh4nB4JCRimh79dR5Ywc9MDQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-arrayish": "^0.2.1" + } + }, + "node_modules/es-define-property": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz", + "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-errors": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", + "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-object-atoms": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz", + "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/escape-html": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", + "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==", + "dev": true, + "license": "MIT" + }, + "node_modules/escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint": { + "version": "9.39.2", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.39.2.tgz", + "integrity": "sha512-LEyamqS7W5HB3ujJyvi0HQK/dtVINZvd5mAAp9eT5S/ujByGjiZLCzPcHVzuXbpJDJF/cxwHlfceVUDZ2lnSTw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@eslint-community/eslint-utils": "^4.8.0", + "@eslint-community/regexpp": "^4.12.1", + "@eslint/config-array": "^0.21.1", + "@eslint/config-helpers": "^0.4.2", + "@eslint/core": "^0.17.0", + "@eslint/eslintrc": "^3.3.1", + "@eslint/js": "9.39.2", + "@eslint/plugin-kit": "^0.4.1", + "@humanfs/node": "^0.16.6", + "@humanwhocodes/module-importer": "^1.0.1", + "@humanwhocodes/retry": "^0.4.2", + "@types/estree": "^1.0.6", + "ajv": "^6.12.4", + "chalk": "^4.0.0", + "cross-spawn": "^7.0.6", + "debug": "^4.3.2", + "escape-string-regexp": "^4.0.0", + "eslint-scope": "^8.4.0", + "eslint-visitor-keys": "^4.2.1", + "espree": "^10.4.0", + "esquery": "^1.5.0", + "esutils": "^2.0.2", + "fast-deep-equal": "^3.1.3", + "file-entry-cache": "^8.0.0", + "find-up": "^5.0.0", + "glob-parent": "^6.0.2", + "ignore": "^5.2.0", + "imurmurhash": "^0.1.4", + "is-glob": "^4.0.0", + "json-stable-stringify-without-jsonify": "^1.0.1", + "lodash.merge": "^4.6.2", + "minimatch": "^3.1.2", + "natural-compare": "^1.4.0", + "optionator": "^0.9.3" + }, + "bin": { + "eslint": "bin/eslint.js" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://eslint.org/donate" + }, + "peerDependencies": { + "jiti": "*" + }, + "peerDependenciesMeta": { + "jiti": { + "optional": true + } + } + }, + "node_modules/eslint-scope": { + "version": "8.4.0", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-8.4.0.tgz", + "integrity": "sha512-sNXOfKCn74rt8RICKMvJS7XKV/Xk9kA7DyJr8mJik3S7Cwgy3qlkkmyS2uQB3jiJg6VNdZd/pDBJu0nvG2NlTg==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^5.2.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint-visitor-keys": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.1.tgz", + "integrity": "sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/espree": { + "version": "10.4.0", + "resolved": "https://registry.npmjs.org/espree/-/espree-10.4.0.tgz", + "integrity": "sha512-j6PAQ2uUr79PZhBjP5C5fhl8e39FmRnOjsD5lGnWrFU8i2G776tBK7+nP8KuQUTTyAZUwfQqXAgrVH5MbH9CYQ==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "acorn": "^8.15.0", + "acorn-jsx": "^5.3.2", + "eslint-visitor-keys": "^4.2.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/esquery": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.7.0.tgz", + "integrity": "sha512-Ap6G0WQwcU/LHsvLwON1fAQX9Zp0A2Y6Y/cJBl9r/JbW90Zyg4/zbG6zzKa2OTALELarYHmKu0GhpM5EO+7T0g==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "estraverse": "^5.1.0" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/esrecurse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", + "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "estraverse": "^5.2.0" + }, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=4.0" + } + }, + "node_modules/esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/etag": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", + "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/express": { + "version": "4.22.1", + "resolved": "https://registry.npmjs.org/express/-/express-4.22.1.tgz", + "integrity": "sha512-F2X8g9P1X7uCPZMA3MVf9wcTqlyNp7IhH5qPCI0izhaOIYXaW9L535tGA3qmjRzpH+bZczqq7hVKxTR4NWnu+g==", + "dev": true, + "license": "MIT", + "dependencies": { + "accepts": "~1.3.8", + "array-flatten": "1.1.1", + "body-parser": "~1.20.3", + "content-disposition": "~0.5.4", + "content-type": "~1.0.4", + "cookie": "~0.7.1", + "cookie-signature": "~1.0.6", + "debug": "2.6.9", + "depd": "2.0.0", + "encodeurl": "~2.0.0", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "finalhandler": "~1.3.1", + "fresh": "~0.5.2", + "http-errors": "~2.0.0", + "merge-descriptors": "1.0.3", + "methods": "~1.1.2", + "on-finished": "~2.4.1", + "parseurl": "~1.3.3", + "path-to-regexp": "~0.1.12", + "proxy-addr": "~2.0.7", + "qs": "~6.14.0", + "range-parser": "~1.2.1", + "safe-buffer": "5.2.1", + "send": "~0.19.0", + "serve-static": "~1.16.2", + "setprototypeof": "1.2.0", + "statuses": "~2.0.1", + "type-is": "~1.6.18", + "utils-merge": "1.0.1", + "vary": "~1.1.2" + }, + "engines": { + "node": ">= 0.10.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/express/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/express/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "dev": true, + "license": "MIT" + }, + "node_modules/express/node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "dev": true, + "license": "MIT" + }, + "node_modules/fast-glob": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.3.tgz", + "integrity": "sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.2", + "merge2": "^1.3.0", + "micromatch": "^4.0.8" + }, + "engines": { + "node": ">=8.6.0" + } + }, + "node_modules/fast-glob/node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", + "dev": true, + "license": "MIT" + }, + "node_modules/fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", + "dev": true, + "license": "MIT" + }, + "node_modules/fast-uri": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.1.0.tgz", + "integrity": "sha512-iPeeDKJSWf4IEOasVVrknXpaBV0IApz/gp7S2bb7Z4Lljbl2MGJRqInZiUrQwV16cpzw/D3S5j5Julj/gT52AA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fastify" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/fastify" + } + ], + "license": "BSD-3-Clause" + }, + "node_modules/fastest-levenshtein": { + "version": "1.0.16", + "resolved": "https://registry.npmjs.org/fastest-levenshtein/-/fastest-levenshtein-1.0.16.tgz", + "integrity": "sha512-eRnCtTTtGZFpQCwhJiUOuxPQWRXVKYDn0b2PeHfXL6/Zi53SLAzAHfVhVWK2AryC/WH05kGfxhFIPvTF0SXQzg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 4.9.1" + } + }, + "node_modules/fastq": { + "version": "1.20.1", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.20.1.tgz", + "integrity": "sha512-GGToxJ/w1x32s/D2EKND7kTil4n8OVk/9mycTc4VDza13lOvpUZTGX3mFSCtV9ksdGBVzvsyAVLM6mHFThxXxw==", + "dev": true, + "license": "ISC", + "dependencies": { + "reusify": "^1.0.4" + } + }, + "node_modules/file-entry-cache": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-8.0.0.tgz", + "integrity": "sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "flat-cache": "^4.0.0" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/fill-range": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", + "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", + "dev": true, + "license": "MIT", + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/finalhandler": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.3.2.tgz", + "integrity": "sha512-aA4RyPcd3badbdABGDuTXCMTtOneUCAYH/gxoYRTZlIJdF0YPWuGqiAsIrhNnnqdXGswYk6dGujem4w80UJFhg==", + "dev": true, + "license": "MIT", + "dependencies": { + "debug": "2.6.9", + "encodeurl": "~2.0.0", + "escape-html": "~1.0.3", + "on-finished": "~2.4.1", + "parseurl": "~1.3.3", + "statuses": "~2.0.2", + "unpipe": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/finalhandler/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/finalhandler/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "dev": true, + "license": "MIT" + }, + "node_modules/find-up": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", + "dev": true, + "license": "MIT", + "dependencies": { + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/flat-cache": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-4.0.1.tgz", + "integrity": "sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==", + "dev": true, + "license": "MIT", + "dependencies": { + "flatted": "^3.2.9", + "keyv": "^4.5.4" + }, + "engines": { + "node": ">=16" + } + }, + "node_modules/flatted": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.3.tgz", + "integrity": "sha512-GX+ysw4PBCz0PzosHDepZGANEuFCMLrnRTiEy9McGjmkCQYwRq4A/X786G/fjM/+OjsWSU1ZrY5qyARZmO/uwg==", + "dev": true, + "license": "ISC" + }, + "node_modules/forwarded": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", + "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/fresh": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", + "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", + "dev": true, + "license": "ISC" + }, + "node_modules/function-bind": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-intrinsic": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz", + "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.2", + "es-define-property": "^1.0.1", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.1.1", + "function-bind": "^1.1.2", + "get-proto": "^1.0.1", + "gopd": "^1.2.0", + "has-symbols": "^1.1.0", + "hasown": "^2.0.2", + "math-intrinsics": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz", + "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==", + "dev": true, + "license": "MIT", + "dependencies": { + "dunder-proto": "^1.0.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "deprecated": "Glob versions prior to v9 are no longer supported", + "dev": true, + "license": "ISC", + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/glob-parent": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", + "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", + "dev": true, + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.3" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/globals": { + "version": "17.0.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-17.0.0.tgz", + "integrity": "sha512-gv5BeD2EssA793rlFWVPMMCqefTlpusw6/2TbAVMy0FzcG8wKJn4O+NqJ4+XWmmwrayJgw5TzrmWjFgmz1XPqw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/globby": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", + "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", + "dev": true, + "license": "MIT", + "dependencies": { + "array-union": "^2.1.0", + "dir-glob": "^3.0.1", + "fast-glob": "^3.2.9", + "ignore": "^5.2.0", + "merge2": "^1.4.1", + "slash": "^3.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/globjoin": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/globjoin/-/globjoin-0.1.4.tgz", + "integrity": "sha512-xYfnw62CKG8nLkZBfWbhWwDw02CHty86jfPcc2cr3ZfeuK9ysoVPPEUxf21bAD/rWAgk52SuBrLJlefNy8mvFg==", + "dev": true, + "license": "MIT" + }, + "node_modules/gopd": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", + "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/hard-rejection": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/hard-rejection/-/hard-rejection-2.1.0.tgz", + "integrity": "sha512-VIZB+ibDhx7ObhAe7OVtoEbuP4h/MuOTHJ+J8h/eBXotJYl0fBgR72xDFCKgIh22OJZIOVNxBMWuhAr10r8HdA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/has-symbols": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz", + "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/hasown": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", + "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/hosted-git-info": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-4.1.0.tgz", + "integrity": "sha512-kyCuEOWjJqZuDbRHzL8V93NzQhwIB71oFWSyzVo+KPZI+pnQPPxucdkrOZvkLRnrf5URsQM+IJ09Dw29cRALIA==", + "dev": true, + "license": "ISC", + "dependencies": { + "lru-cache": "^6.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/html-tags": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/html-tags/-/html-tags-3.3.1.tgz", + "integrity": "sha512-ztqyC3kLto0e9WbNp0aeP+M3kTt+nbaIveGmUxAtZa+8iFgKLUOD4YKM5j+f3QD89bra7UeumolZHKuOXnTmeQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/http_ece": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/http_ece/-/http_ece-1.2.1.tgz", + "integrity": "sha512-+tzLoMYgXvicu60sVFoswTiu6BiQ6EX3DORRJQ3W2dNpNWCyZ3tcmRFZZ3jgVyw8ziWUCeUARKCkYDY6JgFx+w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=16" + } + }, + "node_modules/http-errors": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.1.tgz", + "integrity": "sha512-4FbRdAX+bSdmo4AUFuS0WNiPz8NgFt+r8ThgNWmlrjQjt1Q7ZR9+zTlce2859x4KSXrwIsaeTqDoKQmtP8pLmQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "depd": "~2.0.0", + "inherits": "~2.0.4", + "setprototypeof": "~1.2.0", + "statuses": "~2.0.2", + "toidentifier": "~1.0.1" + }, + "engines": { + "node": ">= 0.8" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/ignore": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", + "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 4" + } + }, + "node_modules/import-fresh": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.1.tgz", + "integrity": "sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/import-lazy": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/import-lazy/-/import-lazy-4.0.0.tgz", + "integrity": "sha512-rKtvo6a868b5Hu3heneU+L4yEQ4jYKLtjpnPeUdK7h0yzXGmyBTypknlkCvHFBqfX9YlorEiMM6Dnq/5atfHkw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.8.19" + } + }, + "node_modules/indent-string": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", + "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", + "deprecated": "This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.", + "dev": true, + "license": "ISC", + "dependencies": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/ini": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", + "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", + "dev": true, + "license": "ISC" + }, + "node_modules/ipaddr.js": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", + "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/is-arrayish": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==", + "dev": true, + "license": "MIT" + }, + "node_modules/is-core-module": { + "version": "2.16.1", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.16.1.tgz", + "integrity": "sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==", + "dev": true, + "license": "MIT", + "dependencies": { + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/is-plain-obj": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-1.1.0.tgz", + "integrity": "sha512-yvkRyxmFKEOQ4pNXCmJG5AEQNlXJS5LaONXo5/cLdTZdWvsZ1ioJEonLGAosKlMWE8lwUy/bJzMjcw8az73+Fg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-plain-object": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-5.0.0.tgz", + "integrity": "sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "dev": true, + "license": "ISC" + }, + "node_modules/js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/js-yaml": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.1.tgz", + "integrity": "sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==", + "dev": true, + "license": "MIT", + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/json-buffer": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", + "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/json-parse-even-better-errors": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", + "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", + "dev": true, + "license": "MIT" + }, + "node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true, + "license": "MIT" + }, + "node_modules/json-stable-stringify-without-jsonify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", + "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", + "dev": true, + "license": "MIT" + }, + "node_modules/jsonwebtoken": { + "version": "9.0.3", + "resolved": "https://registry.npmjs.org/jsonwebtoken/-/jsonwebtoken-9.0.3.tgz", + "integrity": "sha512-MT/xP0CrubFRNLNKvxJ2BYfy53Zkm++5bX9dtuPbqAeQpTVe0MQTFhao8+Cp//EmJp244xt6Drw/GVEGCUj40g==", + "dev": true, + "license": "MIT", + "dependencies": { + "jws": "^4.0.1", + "lodash.includes": "^4.3.0", + "lodash.isboolean": "^3.0.3", + "lodash.isinteger": "^4.0.4", + "lodash.isnumber": "^3.0.3", + "lodash.isplainobject": "^4.0.6", + "lodash.isstring": "^4.0.1", + "lodash.once": "^4.0.0", + "ms": "^2.1.1", + "semver": "^7.5.4" + }, + "engines": { + "node": ">=12", + "npm": ">=6" + } + }, + "node_modules/jwa": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/jwa/-/jwa-2.0.1.tgz", + "integrity": "sha512-hRF04fqJIP8Abbkq5NKGN0Bbr3JxlQ+qhZufXVr0DvujKy93ZCbXZMHDL4EOtodSbCWxOqR8MS1tXA5hwqCXDg==", + "dev": true, + "license": "MIT", + "dependencies": { + "buffer-equal-constant-time": "^1.0.1", + "ecdsa-sig-formatter": "1.0.11", + "safe-buffer": "^5.0.1" + } + }, + "node_modules/jws": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/jws/-/jws-4.0.1.tgz", + "integrity": "sha512-EKI/M/yqPncGUUh44xz0PxSidXFr/+r0pA70+gIYhjv+et7yxM+s29Y+VGDkovRofQem0fs7Uvf4+YmAdyRduA==", + "dev": true, + "license": "MIT", + "dependencies": { + "jwa": "^2.0.1", + "safe-buffer": "^5.0.1" + } + }, + "node_modules/keyv": { + "version": "4.5.4", + "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", + "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==", + "dev": true, + "license": "MIT", + "dependencies": { + "json-buffer": "3.0.1" + } + }, + "node_modules/kind-of": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", + "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/known-css-properties": { + "version": "0.26.0", + "resolved": "https://registry.npmjs.org/known-css-properties/-/known-css-properties-0.26.0.tgz", + "integrity": "sha512-5FZRzrZzNTBruuurWpvZnvP9pum+fe0HcK8z/ooo+U+Hmp4vtbyp1/QDsqmufirXy4egGzbaH/y2uCZf+6W5Kg==", + "dev": true, + "license": "MIT" + }, + "node_modules/levn": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", + "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "prelude-ls": "^1.2.1", + "type-check": "~0.4.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/lines-and-columns": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", + "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", + "dev": true, + "license": "MIT" + }, + "node_modules/locate-path": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-locate": "^5.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/lodash.includes": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/lodash.includes/-/lodash.includes-4.3.0.tgz", + "integrity": "sha512-W3Bx6mdkRTGtlJISOvVD/lbqjTlPPUDTMnlXZFnVwi9NKJ6tiAk6LVdlhZMm17VZisqhKcgzpO5Wz91PCt5b0w==", + "dev": true, + "license": "MIT" + }, + "node_modules/lodash.isboolean": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/lodash.isboolean/-/lodash.isboolean-3.0.3.tgz", + "integrity": "sha512-Bz5mupy2SVbPHURB98VAcw+aHh4vRV5IPNhILUCsOzRmsTmSQ17jIuqopAentWoehktxGd9e/hbIXq980/1QJg==", + "dev": true, + "license": "MIT" + }, + "node_modules/lodash.isinteger": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/lodash.isinteger/-/lodash.isinteger-4.0.4.tgz", + "integrity": "sha512-DBwtEWN2caHQ9/imiNeEA5ys1JoRtRfY3d7V9wkqtbycnAmTvRRmbHKDV4a0EYc678/dia0jrte4tjYwVBaZUA==", + "dev": true, + "license": "MIT" + }, + "node_modules/lodash.isnumber": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/lodash.isnumber/-/lodash.isnumber-3.0.3.tgz", + "integrity": "sha512-QYqzpfwO3/CWf3XP+Z+tkQsfaLL/EnUlXWVkIk5FUPc4sBdTehEqZONuyRt2P67PXAk+NXmTBcc97zw9t1FQrw==", + "dev": true, + "license": "MIT" + }, + "node_modules/lodash.isplainobject": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz", + "integrity": "sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA==", + "dev": true, + "license": "MIT" + }, + "node_modules/lodash.isstring": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/lodash.isstring/-/lodash.isstring-4.0.1.tgz", + "integrity": "sha512-0wJxfxH1wgO3GrbuP+dTTk7op+6L41QCXbGINEmD+ny/G/eCqGzxyCsh7159S+mgDDcoarnBw6PC1PS5+wUGgw==", + "dev": true, + "license": "MIT" + }, + "node_modules/lodash.merge": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", + "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/lodash.once": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/lodash.once/-/lodash.once-4.1.1.tgz", + "integrity": "sha512-Sb487aTOCr9drQVL8pIxOzVhafOjZN9UU54hiN8PU3uAiSV7lx1yYNpbNmex2PK6dSJoNTSJUUswT651yww3Mg==", + "dev": true, + "license": "MIT" + }, + "node_modules/lodash.truncate": { + "version": "4.4.2", + "resolved": "https://registry.npmjs.org/lodash.truncate/-/lodash.truncate-4.4.2.tgz", + "integrity": "sha512-jttmRe7bRse52OsWIMDLaXxWqRAmtIUccAQ3garviCqJjafXOfNMO0yMfNpdD6zbGaTU0P5Nz7e7gAT6cKmJRw==", + "dev": true, + "license": "MIT" + }, + "node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "license": "ISC", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/map-obj": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-4.3.0.tgz", + "integrity": "sha512-hdN1wVrZbb29eBGiGjJbeP8JbKjq1urkHJ/LIP/NY48MZ1QVXUsQBV1G1zvYFHn1XE06cwjBsOI2K3Ulnj1YXQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/math-intrinsics": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", + "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/mathml-tag-names": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/mathml-tag-names/-/mathml-tag-names-2.1.3.tgz", + "integrity": "sha512-APMBEanjybaPzUrfqU0IMU5I0AswKMH7k8OTLs0vvV4KZpExkTkY87nR/zpbuTPj+gARop7aGUbl11pnDfW6xg==", + "dev": true, + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/media-typer": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", + "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/meow": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/meow/-/meow-9.0.0.tgz", + "integrity": "sha512-+obSblOQmRhcyBt62furQqRAQpNyWXo8BuQ5bN7dG8wmwQ+vwHKp/rCFD4CrTP8CsDQD1sjoZ94K417XEUk8IQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/minimist": "^1.2.0", + "camelcase-keys": "^6.2.2", + "decamelize": "^1.2.0", + "decamelize-keys": "^1.1.0", + "hard-rejection": "^2.1.0", + "minimist-options": "4.1.0", + "normalize-package-data": "^3.0.0", + "read-pkg-up": "^7.0.1", + "redent": "^3.0.0", + "trim-newlines": "^3.0.0", + "type-fest": "^0.18.0", + "yargs-parser": "^20.2.3" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/merge-descriptors": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.3.tgz", + "integrity": "sha512-gaNvAS7TZ897/rVaZ0nMtAyxNyi/pdbjbAwUpFQpN70GqnVfOiXpeUUMKRBmzXaSQ8DdTX4/0ms62r2K+hE6mQ==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/merge2": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 8" + } + }, + "node_modules/methods": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", + "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/micromatch": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", + "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==", + "dev": true, + "license": "MIT", + "dependencies": { + "braces": "^3.0.3", + "picomatch": "^2.3.1" + }, + "engines": { + "node": ">=8.6" + } + }, + "node_modules/mime": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", + "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", + "dev": true, + "license": "MIT", + "bin": { + "mime": "cli.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "dev": true, + "license": "MIT", + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/min-indent": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/min-indent/-/min-indent-1.0.1.tgz", + "integrity": "sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/minimist": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", + "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/minimist-options": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/minimist-options/-/minimist-options-4.1.0.tgz", + "integrity": "sha512-Q4r8ghd80yhO/0j1O3B2BjweX3fiHg9cdOwjJd2J76Q135c+NDxGCqdYKQ1SKBuFfgWbAUzBfvYjPUEeNgqN1A==", + "dev": true, + "license": "MIT", + "dependencies": { + "arrify": "^1.0.1", + "is-plain-obj": "^1.1.0", + "kind-of": "^6.0.3" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/mkdirp": { + "version": "0.5.6", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz", + "integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==", + "dev": true, + "license": "MIT", + "dependencies": { + "minimist": "^1.2.6" + }, + "bin": { + "mkdirp": "bin/cmd.js" + } + }, + "node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true, + "license": "MIT" + }, + "node_modules/nanoid": { + "version": "3.3.11", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.11.tgz", + "integrity": "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + } + }, + "node_modules/natural-compare": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", + "dev": true, + "license": "MIT" + }, + "node_modules/negotiator": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", + "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/node-persist": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/node-persist/-/node-persist-2.1.0.tgz", + "integrity": "sha512-NI30KmynAIpKtvl3XaLE/Q/hPUNfh2bFM0U9zgWyIVzBUL/fh1EMk2/rTAqWY6KXrX8jqusVA6avPJ6I2S9B4w==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-absolute": "^0.2.6", + "mkdirp": "~0.5.1", + "q": "~1.1.1" + } + }, + "node_modules/node-persist/node_modules/is-absolute": { + "version": "0.2.6", + "resolved": "https://registry.npmjs.org/is-absolute/-/is-absolute-0.2.6.tgz", + "integrity": "sha512-7Kr05z5LkcOpoMvxHN1PC11WbPabdNFmMYYo0eZvWu3BfVS0T03yoqYDczoCBx17xqk2x1XAZrcKiFVL88jxlQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-relative": "^0.2.1", + "is-windows": "^0.2.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/node-persist/node_modules/is-relative": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-relative/-/is-relative-0.2.1.tgz", + "integrity": "sha512-9AMzjRmLqcue629b4ezEVSK6kJsYJlUIhMcygmYORUgwUNJiavHcC3HkaGx0XYpyVKQSOqFbMEZmW42cY87sYw==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-unc-path": "^0.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/node-persist/node_modules/is-unc-path": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/is-unc-path/-/is-unc-path-0.1.2.tgz", + "integrity": "sha512-HhLc5VDMH4pu3oMtIuunz/DFQUIoR561kMME3U3Afhj8b7vH085vkIkemrz1kLXCEIuoMAmO3yVmafWdSbGW8w==", + "dev": true, + "license": "MIT", + "dependencies": { + "unc-path-regex": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/node-persist/node_modules/is-windows": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-0.2.0.tgz", + "integrity": "sha512-n67eJYmXbniZB7RF4I/FTjK1s6RPOCTxhYrVYLRaCt3lF0mpWZPKr3T2LSZAqyjQsxR2qMmGYXXzK0YWwcPM1Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/normalize-package-data": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-3.0.3.tgz", + "integrity": "sha512-p2W1sgqij3zMMyRC067Dg16bfzVH+w7hyegmpIvZ4JNjqtGOVAIvLmjBx3yP7YTe9vKJgkoNOPjwQGogDoMXFA==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "hosted-git-info": "^4.0.1", + "is-core-module": "^2.5.0", + "semver": "^7.3.4", + "validate-npm-package-license": "^3.0.1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object-inspect": { + "version": "1.13.4", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.4.tgz", + "integrity": "sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/on-finished": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", + "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", + "dev": true, + "license": "MIT", + "dependencies": { + "ee-first": "1.1.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "dev": true, + "license": "ISC", + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/optionator": { + "version": "0.9.4", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz", + "integrity": "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==", + "dev": true, + "license": "MIT", + "dependencies": { + "deep-is": "^0.1.3", + "fast-levenshtein": "^2.0.6", + "levn": "^0.4.1", + "prelude-ls": "^1.2.1", + "type-check": "^0.4.0", + "word-wrap": "^1.2.5" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "yocto-queue": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-locate": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-limit": "^3.0.2" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/parent-module": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", + "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", + "dev": true, + "license": "MIT", + "dependencies": { + "callsites": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/parse-json": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", + "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.0.0", + "error-ex": "^1.3.1", + "json-parse-even-better-errors": "^2.3.0", + "lines-and-columns": "^1.1.6" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/parseurl": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", + "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/path-parse": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", + "dev": true, + "license": "MIT" + }, + "node_modules/path-to-regexp": { + "version": "0.1.12", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.12.tgz", + "integrity": "sha512-RA1GjUVMnvYFxuqovrEqZoxxW5NUZqbwKtYz/Tt7nXerk0LbLblQmrsgdeOxV5SFHf0UDggjS/bSeOZwt1pmEQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/path-type": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", + "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/picocolors": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", + "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", + "dev": true, + "license": "ISC" + }, + "node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/postcss": { + "version": "8.5.6", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.6.tgz", + "integrity": "sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "nanoid": "^3.3.11", + "picocolors": "^1.1.1", + "source-map-js": "^1.2.1" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, + "node_modules/postcss-media-query-parser": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/postcss-media-query-parser/-/postcss-media-query-parser-0.2.3.tgz", + "integrity": "sha512-3sOlxmbKcSHMjlUXQZKQ06jOswE7oVkXPxmZdoB1r5l0q6gTFTQSHxNxOrCccElbW7dxNytifNEo8qidX2Vsig==", + "dev": true, + "license": "MIT" + }, + "node_modules/postcss-resolve-nested-selector": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/postcss-resolve-nested-selector/-/postcss-resolve-nested-selector-0.1.6.tgz", + "integrity": "sha512-0sglIs9Wmkzbr8lQwEyIzlDOOC9bGmfVKcJTaxv3vMmd3uo4o4DerC3En0bnmgceeql9BfC8hRkp7cg0fjdVqw==", + "dev": true, + "license": "MIT" + }, + "node_modules/postcss-safe-parser": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/postcss-safe-parser/-/postcss-safe-parser-6.0.0.tgz", + "integrity": "sha512-FARHN8pwH+WiS2OPCxJI8FuRJpTVnn6ZNFiqAM2aeW2LwTHWWmWgIyKC6cUo0L8aeKiF/14MNvnpls6R2PBeMQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + "peerDependencies": { + "postcss": "^8.3.3" + } + }, + "node_modules/postcss-selector-parser": { + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.1.2.tgz", + "integrity": "sha512-Q8qQfPiZ+THO/3ZrOrO0cJJKfpYCagtMUkXbnEfmgUjwXg6z/WBeOyS9APBBPCTSiDV+s4SwQGu8yFsiMRIudg==", + "dev": true, + "license": "MIT", + "dependencies": { + "cssesc": "^3.0.0", + "util-deprecate": "^1.0.2" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/postcss-sorting": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/postcss-sorting/-/postcss-sorting-7.0.1.tgz", + "integrity": "sha512-iLBFYz6VRYyLJEJsBJ8M3TCqNcckVzz4wFounSc5Oez35ogE/X+aoC5fFu103Ot7NyvjU3/xqIXn93Gp3kJk4g==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "postcss": "^8.3.9" + } + }, + "node_modules/postcss-value-parser": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz", + "integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/prelude-ls": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", + "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/proxy-addr": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", + "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", + "dev": true, + "license": "MIT", + "dependencies": { + "forwarded": "0.2.0", + "ipaddr.js": "1.9.1" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/ps-node": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/ps-node/-/ps-node-0.1.6.tgz", + "integrity": "sha512-w7QJhUTbu70hpDso0YXDRNKCPNuchV8UTUZsAv0m7Qj5g85oHOJfr9drA1EjvK4nQK/bG8P97W4L6PJ3IQLoOA==", + "dev": true, + "license": "MIT", + "dependencies": { + "table-parser": "^0.1.3" + } + }, + "node_modules/punycode": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", + "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/q": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/q/-/q-1.1.2.tgz", + "integrity": "sha512-ROtylwux7Vkc4C07oKE/ReigUmb33kVoLtcR4SJ1QVqwaZkBEDL3vX4/kwFzIERQ5PfCl0XafbU8u2YUhyGgVA==", + "deprecated": "You or someone you depend on is using Q, the JavaScript Promise library that gave JavaScript developers strong feelings about promises. They can almost certainly migrate to the native JavaScript promise now. Thank you literally everyone for joining me in this bet against the odds. Be excellent to each other.\n\n(For a CapTP with native promises, see @endo/eventual-send and @endo/captp)", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.6.0", + "teleport": ">=0.2.0" + } + }, + "node_modules/qs": { + "version": "6.14.1", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.14.1.tgz", + "integrity": "sha512-4EK3+xJl8Ts67nLYNwqw/dsFVnCf+qR7RgXSK9jEEm9unao3njwMDdmsdvoKBKHzxd7tCYz5e5M+SnMjdtXGQQ==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "side-channel": "^1.1.0" + }, + "engines": { + "node": ">=0.6" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/queue-microtask": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/quick-lru": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-4.0.1.tgz", + "integrity": "sha512-ARhCpm70fzdcvNQfPoy49IaanKkTlRWF2JMzqhcJbhSFRZv7nPTvZJdcY7301IPmvW+/p0RgIWnQDLJxifsQ7g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/range-parser": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", + "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/raw-body": { + "version": "2.5.3", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.3.tgz", + "integrity": "sha512-s4VSOf6yN0rvbRZGxs8Om5CWj6seneMwK3oDb4lWDH0UPhWcxwOWw5+qk24bxq87szX1ydrwylIOp2uG1ojUpA==", + "dev": true, + "license": "MIT", + "dependencies": { + "bytes": "~3.1.2", + "http-errors": "~2.0.1", + "iconv-lite": "~0.4.24", + "unpipe": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/raw-body/node_modules/iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "dev": true, + "license": "MIT", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/read-pkg": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz", + "integrity": "sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/normalize-package-data": "^2.4.0", + "normalize-package-data": "^2.5.0", + "parse-json": "^5.0.0", + "type-fest": "^0.6.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/read-pkg-up": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-7.0.1.tgz", + "integrity": "sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg==", + "dev": true, + "license": "MIT", + "dependencies": { + "find-up": "^4.1.0", + "read-pkg": "^5.2.0", + "type-fest": "^0.8.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/read-pkg-up/node_modules/find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "dev": true, + "license": "MIT", + "dependencies": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/read-pkg-up/node_modules/locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-locate": "^4.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/read-pkg-up/node_modules/p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-try": "^2.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/read-pkg-up/node_modules/p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-limit": "^2.2.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/read-pkg-up/node_modules/type-fest": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", + "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==", + "dev": true, + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=8" + } + }, + "node_modules/read-pkg/node_modules/hosted-git-info": { + "version": "2.8.9", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz", + "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==", + "dev": true, + "license": "ISC" + }, + "node_modules/read-pkg/node_modules/normalize-package-data": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", + "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "hosted-git-info": "^2.1.4", + "resolve": "^1.10.0", + "semver": "2 || 3 || 4 || 5", + "validate-npm-package-license": "^3.0.1" + } + }, + "node_modules/read-pkg/node_modules/semver": { + "version": "5.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", + "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/read-pkg/node_modules/type-fest": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.6.0.tgz", + "integrity": "sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==", + "dev": true, + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=8" + } + }, + "node_modules/redent": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/redent/-/redent-3.0.0.tgz", + "integrity": "sha512-6tDA8g98We0zd0GvVeMT9arEOnTw9qM03L9cJXaCjrip1OO764RDBLBfrB4cwzNGDj5OA5ioymC9GkizgWJDUg==", + "dev": true, + "license": "MIT", + "dependencies": { + "indent-string": "^4.0.0", + "strip-indent": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/require-from-string": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", + "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/resolve": { + "version": "1.22.11", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.11.tgz", + "integrity": "sha512-RfqAvLnMl313r7c9oclB1HhUEAezcpLjz95wFH4LVuhk9JF/r22qmVP9AMmOU4vMX7Q8pN8jwNg/CSpdFnMjTQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-core-module": "^2.16.1", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/resolve-from": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/reusify": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.1.0.tgz", + "integrity": "sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==", + "dev": true, + "license": "MIT", + "engines": { + "iojs": ">=1.0.0", + "node": ">=0.10.0" + } + }, + "node_modules/rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "deprecated": "Rimraf versions prior to v4 are no longer supported", + "dev": true, + "license": "ISC", + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/run-parallel": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", + "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT", + "dependencies": { + "queue-microtask": "^1.2.2" + } + }, + "node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true, + "license": "MIT" + }, + "node_modules/safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", + "dev": true, + "license": "MIT" + }, + "node_modules/semver": { + "version": "7.7.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.3.tgz", + "integrity": "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/send": { + "version": "0.19.2", + "resolved": "https://registry.npmjs.org/send/-/send-0.19.2.tgz", + "integrity": "sha512-VMbMxbDeehAxpOtWJXlcUS5E8iXh6QmN+BkRX1GARS3wRaXEEgzCcB10gTQazO42tpNIya8xIyNx8fll1OFPrg==", + "dev": true, + "license": "MIT", + "dependencies": { + "debug": "2.6.9", + "depd": "2.0.0", + "destroy": "1.2.0", + "encodeurl": "~2.0.0", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "fresh": "~0.5.2", + "http-errors": "~2.0.1", + "mime": "1.6.0", + "ms": "2.1.3", + "on-finished": "~2.4.1", + "range-parser": "~1.2.1", + "statuses": "~2.0.2" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/send/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/send/node_modules/debug/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "dev": true, + "license": "MIT" + }, + "node_modules/serve-static": { + "version": "1.16.3", + "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.16.3.tgz", + "integrity": "sha512-x0RTqQel6g5SY7Lg6ZreMmsOzncHFU7nhnRWkKgWuMTu5NN0DR5oruckMqRvacAN9d5w6ARnRBXl9xhDCgfMeA==", + "dev": true, + "license": "MIT", + "dependencies": { + "encodeurl": "~2.0.0", + "escape-html": "~1.0.3", + "parseurl": "~1.3.3", + "send": "~0.19.1" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/setprototypeof": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", + "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==", + "dev": true, + "license": "ISC" + }, + "node_modules/shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, + "license": "MIT", + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/side-channel": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.1.0.tgz", + "integrity": "sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "object-inspect": "^1.13.3", + "side-channel-list": "^1.0.0", + "side-channel-map": "^1.0.1", + "side-channel-weakmap": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-list": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/side-channel-list/-/side-channel-list-1.0.0.tgz", + "integrity": "sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "object-inspect": "^1.13.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-map": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/side-channel-map/-/side-channel-map-1.0.1.tgz", + "integrity": "sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.5", + "object-inspect": "^1.13.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-weakmap": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/side-channel-weakmap/-/side-channel-weakmap-1.0.2.tgz", + "integrity": "sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.5", + "object-inspect": "^1.13.3", + "side-channel-map": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/signal-exit": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/slice-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-4.0.0.tgz", + "integrity": "sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.0.0", + "astral-regex": "^2.0.0", + "is-fullwidth-code-point": "^3.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/slice-ansi?sponsor=1" + } + }, + "node_modules/source-map-js": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", + "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/spdx-correct": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.2.0.tgz", + "integrity": "sha512-kN9dJbvnySHULIluDHy32WHRUu3Og7B9sbY7tsFLctQkIqnMh3hErYgdMjTYuqmcXX+lK5T1lnUt3G7zNswmZA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "spdx-expression-parse": "^3.0.0", + "spdx-license-ids": "^3.0.0" + } + }, + "node_modules/spdx-exceptions": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.5.0.tgz", + "integrity": "sha512-PiU42r+xO4UbUS1buo3LPJkjlO7430Xn5SVAhdpzzsPHsjbYVflnnFdATgabnLude+Cqu25p6N+g2lw/PFsa4w==", + "dev": true, + "license": "CC-BY-3.0" + }, + "node_modules/spdx-expression-parse": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz", + "integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "spdx-exceptions": "^2.1.0", + "spdx-license-ids": "^3.0.0" + } + }, + "node_modules/spdx-license-ids": { + "version": "3.0.22", + "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.22.tgz", + "integrity": "sha512-4PRT4nh1EImPbt2jASOKHX7PB7I+e4IWNLvkKFDxNhJlfjbYlleYQh285Z/3mPTHSAK/AvdMmw5BNNuYH8ShgQ==", + "dev": true, + "license": "CC0-1.0" + }, + "node_modules/statuses": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.2.tgz", + "integrity": "sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-indent": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-3.0.0.tgz", + "integrity": "sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "min-indent": "^1.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-json-comments": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/style-search": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/style-search/-/style-search-0.1.0.tgz", + "integrity": "sha512-Dj1Okke1C3uKKwQcetra4jSuk0DqbzbYtXipzFlFMZtowbF1x7BKJwB9AayVMyFARvU8EDrZdcax4At/452cAg==", + "dev": true, + "license": "ISC" + }, + "node_modules/stylelint": { + "version": "14.16.1", + "resolved": "https://registry.npmjs.org/stylelint/-/stylelint-14.16.1.tgz", + "integrity": "sha512-ErlzR/T3hhbV+a925/gbfc3f3Fep9/bnspMiJPorfGEmcBbXdS+oo6LrVtoUZ/w9fqD6o6k7PtUlCOsCRdjX/A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@csstools/selector-specificity": "^2.0.2", + "balanced-match": "^2.0.0", + "colord": "^2.9.3", + "cosmiconfig": "^7.1.0", + "css-functions-list": "^3.1.0", + "debug": "^4.3.4", + "fast-glob": "^3.2.12", + "fastest-levenshtein": "^1.0.16", + "file-entry-cache": "^6.0.1", + "global-modules": "^2.0.0", + "globby": "^11.1.0", + "globjoin": "^0.1.4", + "html-tags": "^3.2.0", + "ignore": "^5.2.1", + "import-lazy": "^4.0.0", + "imurmurhash": "^0.1.4", + "is-plain-object": "^5.0.0", + "known-css-properties": "^0.26.0", + "mathml-tag-names": "^2.1.3", + "meow": "^9.0.0", + "micromatch": "^4.0.5", + "normalize-path": "^3.0.0", + "picocolors": "^1.0.0", + "postcss": "^8.4.19", + "postcss-media-query-parser": "^0.2.3", + "postcss-resolve-nested-selector": "^0.1.1", + "postcss-safe-parser": "^6.0.0", + "postcss-selector-parser": "^6.0.11", + "postcss-value-parser": "^4.2.0", + "resolve-from": "^5.0.0", + "string-width": "^4.2.3", + "strip-ansi": "^6.0.1", + "style-search": "^0.1.0", + "supports-hyperlinks": "^2.3.0", + "svg-tags": "^1.0.0", + "table": "^6.8.1", + "v8-compile-cache": "^2.3.0", + "write-file-atomic": "^4.0.2" + }, + "bin": { + "stylelint": "bin/stylelint.js" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/stylelint" + } + }, + "node_modules/stylelint-order": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/stylelint-order/-/stylelint-order-5.0.0.tgz", + "integrity": "sha512-OWQ7pmicXufDw5BlRqzdz3fkGKJPgLyDwD1rFY3AIEfIH/LQY38Vu/85v8/up0I+VPiuGRwbc2Hg3zLAsJaiyw==", + "dev": true, + "license": "MIT", + "dependencies": { + "postcss": "^8.3.11", + "postcss-sorting": "^7.0.1" + }, + "peerDependencies": { + "stylelint": "^14.0.0" + } + }, + "node_modules/stylelint/node_modules/balanced-match": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-2.0.0.tgz", + "integrity": "sha512-1ugUSr8BHXRnK23KfuYS+gVMC3LB8QGH9W1iGtDPsNWoQbgtXSExkBu2aDR4epiGWZOjZsj6lDl/N/AqqTC3UA==", + "dev": true, + "license": "MIT" + }, + "node_modules/stylelint/node_modules/file-entry-cache": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", + "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", + "dev": true, + "license": "MIT", + "dependencies": { + "flat-cache": "^3.0.4" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + } + }, + "node_modules/stylelint/node_modules/flat-cache": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.2.0.tgz", + "integrity": "sha512-CYcENa+FtcUKLmhhqyctpclsq7QF38pKjZHsGNiSQF5r4FtoKDWabFDl3hzaEQMvT1LHEysw5twgLvpYYb4vbw==", + "dev": true, + "license": "MIT", + "dependencies": { + "flatted": "^3.2.9", + "keyv": "^4.5.3", + "rimraf": "^3.0.2" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + } + }, + "node_modules/stylelint/node_modules/global-modules": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/global-modules/-/global-modules-2.0.0.tgz", + "integrity": "sha512-NGbfmJBp9x8IxyJSd1P+otYK8vonoJactOogrVfFRIAEY1ukil8RSKDz2Yo7wh1oihl51l/r6W4epkeKJHqL8A==", + "dev": true, + "license": "MIT", + "dependencies": { + "global-prefix": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/stylelint/node_modules/global-prefix": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/global-prefix/-/global-prefix-3.0.0.tgz", + "integrity": "sha512-awConJSVCHVGND6x3tmMaKcQvwXLhjdkmomy2W+Goaui8YPgYgXJZewhg3fWC+DlfqqQuWg8AwqjGTD2nAPVWg==", + "dev": true, + "license": "MIT", + "dependencies": { + "ini": "^1.3.5", + "kind-of": "^6.0.2", + "which": "^1.3.1" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/stylelint/node_modules/resolve-from": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", + "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/stylelint/node_modules/which": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", + "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "which": "bin/which" + } + }, + "node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/supports-hyperlinks": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/supports-hyperlinks/-/supports-hyperlinks-2.3.0.tgz", + "integrity": "sha512-RpsAZlpWcDwOPQA22aCH4J0t7L8JmAvsCxfOSEwm7cQs3LshN36QaTkwd70DnBOXDWGssw2eUoc8CaRWT0XunA==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0", + "supports-color": "^7.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/supports-preserve-symlinks-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", + "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/svg-tags": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/svg-tags/-/svg-tags-1.0.0.tgz", + "integrity": "sha512-ovssysQTa+luh7A5Weu3Rta6FJlFBBbInjOh722LIt6klpU2/HtdUbszju/G4devcvk8PGt7FCLv5wftu3THUA==", + "dev": true + }, + "node_modules/table": { + "version": "6.9.0", + "resolved": "https://registry.npmjs.org/table/-/table-6.9.0.tgz", + "integrity": "sha512-9kY+CygyYM6j02t5YFHbNz2FN5QmYGv9zAjVp4lCDjlCw7amdckXlEt/bjMhUIfj4ThGRE4gCUH5+yGnNuPo5A==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "ajv": "^8.0.1", + "lodash.truncate": "^4.4.2", + "slice-ansi": "^4.0.0", + "string-width": "^4.2.3", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/table-parser": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/table-parser/-/table-parser-0.1.3.tgz", + "integrity": "sha512-LCYeuvqqoPII3lzzYaXKbC3Forb+d2u4bNwhk/9FlivuGRxPE28YEWAYcujeSlLLDlMfvy29+WPybFJZFiKMYg==", + "dev": true, + "license": "MIT", + "dependencies": { + "connected-domain": "^1.0.0" + } + }, + "node_modules/table/node_modules/ajv": { + "version": "8.17.1", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz", + "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==", + "dev": true, + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.3", + "fast-uri": "^3.0.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/table/node_modules/json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", + "dev": true, + "license": "MIT" + }, + "node_modules/to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/toidentifier": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", + "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.6" + } + }, + "node_modules/trim-newlines": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-3.0.1.tgz", + "integrity": "sha512-c1PTsA3tYrIsLGkJkzHF+w9F2EyxfXGo4UyJc4pFL++FMjnq0HJS69T3M7d//gKrFKwy429bouPescbjecU+Zw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/type-check": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", + "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", + "dev": true, + "license": "MIT", + "dependencies": { + "prelude-ls": "^1.2.1" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/type-fest": { + "version": "0.18.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.18.1.tgz", + "integrity": "sha512-OIAYXk8+ISY+qTOwkHtKqzAuxchoMiD9Udx+FSGQDuiRR+PJKJHc2NJAXlbhkGwTt/4/nKZxELY1w3ReWOL8mw==", + "dev": true, + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/type-is": { + "version": "1.6.18", + "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", + "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", + "dev": true, + "license": "MIT", + "dependencies": { + "media-typer": "0.3.0", + "mime-types": "~2.1.24" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/unc-path-regex": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/unc-path-regex/-/unc-path-regex-0.1.2.tgz", + "integrity": "sha512-eXL4nmJT7oCpkZsHZUOJo8hcX3GbsiDOa0Qu9F646fi8dT3XuSVopVqAcEiVzSKKH7UoDti23wNX3qGFxcW5Qg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/unpipe": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", + "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/uri-js": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "punycode": "^2.1.0" + } + }, + "node_modules/urlsafe-base64": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/urlsafe-base64/-/urlsafe-base64-1.0.0.tgz", + "integrity": "sha512-RtuPeMy7c1UrHwproMZN9gN6kiZ0SvJwRaEzwZY0j9MypEkFqyBaKv176jvlPtg58Zh36bOkS0NFABXMHvvGCA==", + "dev": true + }, + "node_modules/util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", + "dev": true, + "license": "MIT" + }, + "node_modules/utils-merge": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", + "integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/v8-compile-cache": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.4.0.tgz", + "integrity": "sha512-ocyWc3bAHBB/guyqJQVI5o4BZkPhznPYUG2ea80Gond/BgNWpap8TOmLSeeQG7bnh2KMISxskdADG59j7zruhw==", + "dev": true, + "license": "MIT" + }, + "node_modules/validate-npm-package-license": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", + "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "spdx-correct": "^3.0.0", + "spdx-expression-parse": "^3.0.0" + } + }, + "node_modules/vary": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", + "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/web-push-testing": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/web-push-testing/-/web-push-testing-1.2.2.tgz", + "integrity": "sha512-UnrbIfg3Vjounhlqo4Ko30ZKXEdytK9r1a2l0Drrj4CjxqLE7v3nzfTX6aTKhtqwrO3i7uFTgvwY6l0Lr4aXMw==", + "dev": true, + "license": "MIT", + "dependencies": { + "arg": "^5.0.1", + "express": "^4.17.2", + "http_ece": "^1.1.0", + "jsonwebtoken": "^9.0.0", + "node-persist": "^2.1.0", + "ps-node": "^0.1.6", + "urlsafe-base64": "^1.0.0" + }, + "bin": { + "web-push-testing": "src/bin/cli.js" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "license": "ISC", + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/word-wrap": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", + "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/write-file-atomic": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-4.0.2.tgz", + "integrity": "sha512-7KxauUdBmSdWnmpaGFg+ppNjKF8uNLry8LyzjauQDOVONfFLNKrKvQOxZ/VuTIcS/gge/YNahf5RIIQWTSarlg==", + "dev": true, + "license": "ISC", + "dependencies": { + "imurmurhash": "^0.1.4", + "signal-exit": "^3.0.7" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + } + }, + "node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true, + "license": "ISC" + }, + "node_modules/yaml": { + "version": "1.10.2", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz", + "integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">= 6" + } + }, + "node_modules/yargs-parser": { + "version": "20.2.9", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz", + "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=10" + } + }, + "node_modules/yocto-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + } + } +} diff --git a/package.json b/package.json index 1053083ed87..7947d041537 100644 --- a/package.json +++ b/package.json @@ -1,52 +1,49 @@ { - "name": "phpbb", - "version": "3.3.0-dev", - "description": "phpBB Forum Software application", - "main": " ", - "directories": { - "doc": "docs" - }, - "scripts": { - "test": "echo \"Error: no test specified\" && exit 1" - }, - "repository": { - "type": "git", - "url": "git+https://github.com/phpbb/phpbb.git" - }, - "browserslist": [ - "> 1%", - "last 2 versions" - ], - "keywords": [ - "phpBB", - "phpbb", - "forum", - "php", - "software", - "community" - ], - "author": "", - "license": "GPL-2.0", - "bugs": { - "url": "https://tracker.phpbb.com" - }, - "homepage": "https://www.phpbb.com", - "devDependencies": { - "stylelint": "8.0.0", - "stylelint-order": "0.3.0" - }, - "dependencies": { - "del": "^3.0.0", - "gulp": "^3.9.1", - "gulp-autoprefixer": "^4.0.0", - "gulp-cssnano": "^2.1.2", - "gulp-postcss": "^7.0.0", - "gulp-rename": "^1.2.2", - "gulp-sass": "^3.1.0", - "gulp-sourcemaps": "^2.6.1", - "gulp-stylefmt": "^1.1.0", - "postcss-import": "^11.0.0", - "postcss-pxtorem": "^4.0.1", - "postcss-sorting": "^3.0.2" - } + "name": "phpbb", + "version": "4.0.0-dev", + "description": "phpBB Forum Software application", + "main": " ", + "directories": { + "doc": "docs" + }, + "browserslist": [ + "> 1%", + "not ie 11", + "not samsung 10.1", + "not and_uc 12.12", + "not op_mini all", + "edge >= 18", + "ff >= 72", + "chrome >= 79", + "safari >= 13", + "ios >= 12.4" + ], + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1" + }, + "repository": { + "type": "git", + "url": "git+https://github.com/phpbb/phpbb.git" + }, + "keywords": [ + "phpBB", + "phpbb", + "forum", + "php", + "software", + "community" + ], + "author": "", + "license": "GPL-2.0", + "bugs": { + "url": "https://tracker.phpbb.com" + }, + "homepage": "https://www.phpbb.com", + "devDependencies": { + "eslint": "^9.28.0", + "globals": "^17.0.0", + "stylelint": "^14.7.0", + "stylelint-order": "^5.0.0", + "web-push-testing": "^1.1.1" + } } diff --git a/phpBB/.htaccess b/phpBB/.htaccess index 53bce762ea8..e55375e58be 100644 --- a/phpBB/.htaccess +++ b/phpBB/.htaccess @@ -36,6 +36,13 @@ RewriteRule ^(.*)$ app.php [QSA,L] #Options +FollowSymLinks +# Apache content negotation tries to interpret non-existent paths as files if +# MultiViews is enabled. This will however cause issues with paths containg +# dots, e.g. for the cron tasks + + Options -MultiViews + + # With Apache 2.4 the "Order, Deny" syntax has been deprecated and moved from # module mod_authz_host to a new module called mod_access_compat (which may be # disabled) and a new "Require" syntax has been introduced to mod_authz_host. @@ -53,6 +60,14 @@ RewriteRule ^(.*)$ app.php [QSA,L] Order Allow,Deny Deny from All + + Order Allow,Deny + Deny from All + + + Order Allow,Deny + Deny from All + = 2.4> @@ -61,6 +76,12 @@ RewriteRule ^(.*)$ app.php [QSA,L] Require all denied + + Require all denied + + + Require all denied + @@ -73,6 +94,14 @@ RewriteRule ^(.*)$ app.php [QSA,L] Order Allow,Deny Deny from All + + Order Allow,Deny + Deny from All + + + Order Allow,Deny + Deny from All + @@ -81,5 +110,11 @@ RewriteRule ^(.*)$ app.php [QSA,L] Require all denied + + Require all denied + + + Require all denied + diff --git a/phpBB/adm/images/alert_close.png b/phpBB/adm/images/alert_close.png deleted file mode 100644 index 79750a013c5..00000000000 Binary files a/phpBB/adm/images/alert_close.png and /dev/null differ diff --git a/phpBB/adm/images/arrow_down.gif b/phpBB/adm/images/arrow_down.gif deleted file mode 100644 index b7fbf7e2764..00000000000 Binary files a/phpBB/adm/images/arrow_down.gif and /dev/null differ diff --git a/phpBB/adm/images/arrow_left.gif b/phpBB/adm/images/arrow_left.gif deleted file mode 100644 index ac92cb49719..00000000000 Binary files a/phpBB/adm/images/arrow_left.gif and /dev/null differ diff --git a/phpBB/adm/images/arrow_right.gif b/phpBB/adm/images/arrow_right.gif deleted file mode 100644 index 3a080ffdfe2..00000000000 Binary files a/phpBB/adm/images/arrow_right.gif and /dev/null differ diff --git a/phpBB/adm/images/arrow_up.gif b/phpBB/adm/images/arrow_up.gif deleted file mode 100644 index 0ff58721820..00000000000 Binary files a/phpBB/adm/images/arrow_up.gif and /dev/null differ diff --git a/phpBB/adm/images/bg_button.gif b/phpBB/adm/images/bg_button.gif deleted file mode 100644 index 03172ff5c67..00000000000 Binary files a/phpBB/adm/images/bg_button.gif and /dev/null differ diff --git a/phpBB/adm/images/bg_hash1.gif b/phpBB/adm/images/bg_hash1.gif deleted file mode 100644 index 61163679a80..00000000000 Binary files a/phpBB/adm/images/bg_hash1.gif and /dev/null differ diff --git a/phpBB/adm/images/bg_hash2.gif b/phpBB/adm/images/bg_hash2.gif deleted file mode 100644 index d31840361c1..00000000000 Binary files a/phpBB/adm/images/bg_hash2.gif and /dev/null differ diff --git a/phpBB/adm/images/bg_hash3.gif b/phpBB/adm/images/bg_hash3.gif deleted file mode 100644 index 40bc7e1b5c6..00000000000 Binary files a/phpBB/adm/images/bg_hash3.gif and /dev/null differ diff --git a/phpBB/adm/images/bg_hash4.gif b/phpBB/adm/images/bg_hash4.gif deleted file mode 100644 index 54e7f0019f7..00000000000 Binary files a/phpBB/adm/images/bg_hash4.gif and /dev/null differ diff --git a/phpBB/adm/images/bg_header.gif b/phpBB/adm/images/bg_header.gif deleted file mode 100644 index b95bf3ba959..00000000000 Binary files a/phpBB/adm/images/bg_header.gif and /dev/null differ diff --git a/phpBB/adm/images/bg_header.jpg b/phpBB/adm/images/bg_header.jpg deleted file mode 100644 index 5ecec5360b1..00000000000 Binary files a/phpBB/adm/images/bg_header.jpg and /dev/null differ diff --git a/phpBB/adm/images/bg_tabs_alt1.gif b/phpBB/adm/images/bg_tabs_alt1.gif deleted file mode 100644 index 335a72c7116..00000000000 Binary files a/phpBB/adm/images/bg_tabs_alt1.gif and /dev/null differ diff --git a/phpBB/adm/images/bg_tabs_alt2.gif b/phpBB/adm/images/bg_tabs_alt2.gif deleted file mode 100644 index a2142d5432b..00000000000 Binary files a/phpBB/adm/images/bg_tabs_alt2.gif and /dev/null differ diff --git a/phpBB/adm/images/cellpic3.gif b/phpBB/adm/images/cellpic3.gif deleted file mode 100644 index be46fc6fcc2..00000000000 Binary files a/phpBB/adm/images/cellpic3.gif and /dev/null differ diff --git a/phpBB/adm/images/file_conflict.gif b/phpBB/adm/images/file_conflict.gif deleted file mode 100644 index 4458c4ff230..00000000000 Binary files a/phpBB/adm/images/file_conflict.gif and /dev/null differ diff --git a/phpBB/adm/images/file_modified.gif b/phpBB/adm/images/file_modified.gif deleted file mode 100644 index 17e8f976c37..00000000000 Binary files a/phpBB/adm/images/file_modified.gif and /dev/null differ diff --git a/phpBB/adm/images/file_new.gif b/phpBB/adm/images/file_new.gif deleted file mode 100644 index d0ec75876d8..00000000000 Binary files a/phpBB/adm/images/file_new.gif and /dev/null differ diff --git a/phpBB/adm/images/file_new_conflict.gif b/phpBB/adm/images/file_new_conflict.gif deleted file mode 100644 index 84efde4faa9..00000000000 Binary files a/phpBB/adm/images/file_new_conflict.gif and /dev/null differ diff --git a/phpBB/adm/images/file_not_modified.gif b/phpBB/adm/images/file_not_modified.gif deleted file mode 100644 index 8f9b3d38391..00000000000 Binary files a/phpBB/adm/images/file_not_modified.gif and /dev/null differ diff --git a/phpBB/adm/images/file_up_to_date.gif b/phpBB/adm/images/file_up_to_date.gif deleted file mode 100644 index c3723426462..00000000000 Binary files a/phpBB/adm/images/file_up_to_date.gif and /dev/null differ diff --git a/phpBB/adm/images/gradient2b.gif b/phpBB/adm/images/gradient2b.gif deleted file mode 100644 index a8107659e29..00000000000 Binary files a/phpBB/adm/images/gradient2b.gif and /dev/null differ diff --git a/phpBB/adm/images/icon_delete.gif b/phpBB/adm/images/icon_delete.gif deleted file mode 100644 index 57962d51728..00000000000 Binary files a/phpBB/adm/images/icon_delete.gif and /dev/null differ diff --git a/phpBB/adm/images/icon_delete_disabled.gif b/phpBB/adm/images/icon_delete_disabled.gif deleted file mode 100644 index da55bbbe445..00000000000 Binary files a/phpBB/adm/images/icon_delete_disabled.gif and /dev/null differ diff --git a/phpBB/adm/images/icon_down.gif b/phpBB/adm/images/icon_down.gif deleted file mode 100644 index 793db26cde2..00000000000 Binary files a/phpBB/adm/images/icon_down.gif and /dev/null differ diff --git a/phpBB/adm/images/icon_down_disabled.gif b/phpBB/adm/images/icon_down_disabled.gif deleted file mode 100644 index 3ba36975b46..00000000000 Binary files a/phpBB/adm/images/icon_down_disabled.gif and /dev/null differ diff --git a/phpBB/adm/images/icon_edit.gif b/phpBB/adm/images/icon_edit.gif deleted file mode 100644 index c95cf98eb9d..00000000000 Binary files a/phpBB/adm/images/icon_edit.gif and /dev/null differ diff --git a/phpBB/adm/images/icon_edit_disabled.gif b/phpBB/adm/images/icon_edit_disabled.gif deleted file mode 100644 index ac96b0e6dca..00000000000 Binary files a/phpBB/adm/images/icon_edit_disabled.gif and /dev/null differ diff --git a/phpBB/adm/images/icon_folder.gif b/phpBB/adm/images/icon_folder.gif deleted file mode 100644 index 845618c1a26..00000000000 Binary files a/phpBB/adm/images/icon_folder.gif and /dev/null differ diff --git a/phpBB/adm/images/icon_folder_link.gif b/phpBB/adm/images/icon_folder_link.gif deleted file mode 100644 index efeaf0a11f3..00000000000 Binary files a/phpBB/adm/images/icon_folder_link.gif and /dev/null differ diff --git a/phpBB/adm/images/icon_folder_lock.gif b/phpBB/adm/images/icon_folder_lock.gif deleted file mode 100644 index 7afb092a8f1..00000000000 Binary files a/phpBB/adm/images/icon_folder_lock.gif and /dev/null differ diff --git a/phpBB/adm/images/icon_subfolder.gif b/phpBB/adm/images/icon_subfolder.gif deleted file mode 100644 index 71194865391..00000000000 Binary files a/phpBB/adm/images/icon_subfolder.gif and /dev/null differ diff --git a/phpBB/adm/images/icon_sync.gif b/phpBB/adm/images/icon_sync.gif deleted file mode 100644 index 16223dfd9a4..00000000000 Binary files a/phpBB/adm/images/icon_sync.gif and /dev/null differ diff --git a/phpBB/adm/images/icon_sync_disabled.gif b/phpBB/adm/images/icon_sync_disabled.gif deleted file mode 100644 index 39985045c8b..00000000000 Binary files a/phpBB/adm/images/icon_sync_disabled.gif and /dev/null differ diff --git a/phpBB/adm/images/icon_trace.gif b/phpBB/adm/images/icon_trace.gif deleted file mode 100644 index 5c622e9a9dc..00000000000 Binary files a/phpBB/adm/images/icon_trace.gif and /dev/null differ diff --git a/phpBB/adm/images/icon_up.gif b/phpBB/adm/images/icon_up.gif deleted file mode 100644 index 7daa95c07ee..00000000000 Binary files a/phpBB/adm/images/icon_up.gif and /dev/null differ diff --git a/phpBB/adm/images/icon_up_disabled.gif b/phpBB/adm/images/icon_up_disabled.gif deleted file mode 100644 index 2797192574a..00000000000 Binary files a/phpBB/adm/images/icon_up_disabled.gif and /dev/null differ diff --git a/phpBB/adm/images/innerbox_bg.gif b/phpBB/adm/images/innerbox_bg.gif deleted file mode 100644 index 460526f0ba7..00000000000 Binary files a/phpBB/adm/images/innerbox_bg.gif and /dev/null differ diff --git a/phpBB/adm/images/loading.gif b/phpBB/adm/images/loading.gif deleted file mode 100644 index e1ed0883e07..00000000000 Binary files a/phpBB/adm/images/loading.gif and /dev/null differ diff --git a/phpBB/adm/images/phpbb_logo.png b/phpBB/adm/images/phpbb_logo.png deleted file mode 100644 index 2d76ef18cbf..00000000000 Binary files a/phpBB/adm/images/phpbb_logo.png and /dev/null differ diff --git a/phpBB/adm/images/phpbb_logo.svg b/phpBB/adm/images/phpbb_logo.svg new file mode 100644 index 00000000000..2a241067f9a --- /dev/null +++ b/phpBB/adm/images/phpbb_logo.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/phpBB/adm/index.php b/phpBB/adm/index.php index d27f56f28bf..25975e04666 100644 --- a/phpBB/adm/index.php +++ b/phpBB/adm/index.php @@ -15,7 +15,6 @@ */ define('IN_PHPBB', true); define('ADMIN_START', true); -define('NEED_SID', true); // Include files $phpbb_root_path = (defined('PHPBB_ROOT_PATH')) ? PHPBB_ROOT_PATH : './../'; @@ -49,21 +48,28 @@ define('IN_ADMIN', true); // Some oft used variables -$safe_mode = (@ini_get('safe_mode') == '1' || strtolower(@ini_get('safe_mode')) === 'on') ? true : false; $file_uploads = (@ini_get('file_uploads') == '1' || strtolower(@ini_get('file_uploads')) === 'on') ? true : false; $module_id = $request->variable('i', ''); $mode = $request->variable('mode', ''); // Set custom style for admin area -$template->set_custom_style(array( - array( - 'name' => 'adm', - 'ext_path' => 'adm/style/', - ), -), $phpbb_admin_path . 'style'); - -$template->assign_var('T_ASSETS_PATH', $phpbb_root_path . 'assets'); -$template->assign_var('T_TEMPLATE_PATH', $phpbb_admin_path . 'style'); +/** @var \phpbb\template\base $template */ +$template->set_custom_style( + [ + [ + 'name' => 'adm', + 'ext_path' => 'adm/style/', + ] + ], + [ + $phpbb_admin_path . 'style', + $phpbb_root_path . 'styles/all/imgs/', + $phpbb_root_path . 'styles/all/template/', + ], +); + +$template->assign_var('T_ASSETS_PATH', $phpbb_path_helper->update_web_root_path($phpbb_root_path . 'assets')); +$template->assign_var('T_TEMPLATE_PATH', $phpbb_path_helper->update_web_root_path($phpbb_root_path . 'style')); // Instantiate new module $module = new p_master(); diff --git a/phpBB/adm/style/acp_attachments.html b/phpBB/adm/style/acp_attachments.html index 2baca09f5e0..c33d30b1c11 100644 --- a/phpBB/adm/style/acp_attachments.html +++ b/phpBB/adm/style/acp_attachments.html @@ -29,7 +29,7 @@

{L_UPLOADING_FILES}

:: {upload.FILE_INFO}
- {upload.DENIED}{upload.ERROR_MSG}{L_SUCCESSFULLY_UPLOADED} + {upload.L_DENIED}{upload.ERROR_MSG}{L_SUCCESSFULLY_UPLOADED}

@@ -37,12 +37,6 @@

{L_UPLOADING_FILES}

- -
-

{L_NO_THUMBNAIL_SUPPORT}

-
- -
@@ -55,17 +49,28 @@

{L_UPLOADING_FILES}


{options.TITLE_EXPLAIN}
-
{options.CONTENT}
+
+ {% if options.CONTENT is iterable %} + {{ FormsBuildTemplate(options.CONTENT)}} + {% else %} + {options.CONTENT} + {% endif %} +
+ {% if (options.KEY == 'allow_attachments' and S_EMPTY_POST_GROUPS) or (options.KEY == 'allow_pm_attach' and S_EMPTY_PM_GROUPS) %} +
{{ lang(options.KEY == 'allow_attachments' ? 'NO_EXT_GROUP_ALLOWED_POST' : 'NO_EXT_GROUP_ALLOWED_PM', U_EXTENSION_GROUPS) }}
+ {% endif %}
-
- {L_SUBMIT} -   - +
+ {{ lang('ACP_SUBMIT_CHANGES') }} +

+   + +

@@ -116,7 +121,7 @@

{L_UPLOADING_FILES}

- @@ -60,11 +73,6 @@

{L_TITLE}

-
-

{L_BAN_EXCLUDE_EXPLAIN}
-
-
-
@@ -73,12 +81,14 @@

{L_TITLE}

- -

-   - -

-{S_FORM_TOKEN} +
+
+ {L_ACP_SUBMIT_CHANGES} +

+   + +

+ {S_FORM_TOKEN}
@@ -88,44 +98,41 @@

{L_UNBAN_TITLE}

{L_UNBAN_EXPLAIN}

-
+
- {L_UNBAN_TITLE} + {{ lang('UNBAN_TITLE') }} - +{% if BANNED_SELECT %}
-
-
+
+
+ {{ FormsSelect(BANNED_SELECT) }} +
-
+
-
+
-
+

-   - +   +

- {S_FORM_TOKEN} -
- - - -

{L_NO_BAN_CELL}

- {S_FORM_TOKEN} +{% else %} +

{{ lang('NO_BAN_CELL') }}

+{% endif %} + {{ S_FORM_TOKEN }} - -
diff --git a/phpBB/adm/style/acp_bbcodes.html b/phpBB/adm/style/acp_bbcodes.html index 8c8b8059753..aade2f8aac7 100644 --- a/phpBB/adm/style/acp_bbcodes.html +++ b/phpBB/adm/style/acp_bbcodes.html @@ -14,7 +14,7 @@

{L_ACP_BBCODES}

{L_BBCODE_USAGE} -

{L_BBCODE_USAGE_EXPLAIN}

+

{{ lang('BBCODE_USAGE_EXPLAIN', '', '') }}



{L_BBCODE_USAGE_EXAMPLE}
@@ -31,11 +31,11 @@

{L_ACP_BBCODES}

- {L_BBCODE_HELPLINE} -

{L_BBCODE_HELPLINE_EXPLAIN}

+ {{ lang('BBCODE_HELPLINE') }} +

{{ lang('BBCODE_HELPLINE_EXPLAIN') }}

-
-
+
+
@@ -47,6 +47,17 @@

{L_ACP_BBCODES}

+
+ {{ lang('APPEARANCE') }} +
+

{{ lang('BBCODE_FONT_ICON_EXPLAIN', '', '') }}
+
+ + {{ Icon('font', ' ', '', false, '', {'id':'bbcode_icon_preview'}) }} +
+
+
+
diff --git a/phpBB/adm/style/acp_board.html b/phpBB/adm/style/acp_board.html index fe3e2500992..ae1525d5862 100644 --- a/phpBB/adm/style/acp_board.html +++ b/phpBB/adm/style/acp_board.html @@ -27,7 +27,13 @@

{L_WARNING}


{options.TITLE_EXPLAIN}
-
{options.CONTENT}
+
+ {% if options.CONTENT is iterable %} + {{ FormsBuildTemplate(options.CONTENT)}} + {% else %} + {{ options.CONTENT }} + {% endif %} +
diff --git a/phpBB/adm/style/acp_bots.html b/phpBB/adm/style/acp_bots.html index b0e61015b6c..8332df7e2b5 100644 --- a/phpBB/adm/style/acp_bots.html +++ b/phpBB/adm/style/acp_bots.html @@ -27,15 +27,21 @@

{L_WARNING}


{L_BOT_STYLE_EXPLAIN}
-
+
+ {{ FormsSelect(S_STYLE_OPTIONS) }} +
-

{L_BOT_LANG_EXPLAIN}
-
+

{L_BOT_LANG_EXPLAIN}
+
+ {{ FormsSelect(LANG_OPTIONS) }} +
-
+
+ {{ FormsSelect(S_ACTIVE_OPTIONS) }} +

{L_BOT_AGENT_EXPLAIN}
diff --git a/phpBB/adm/style/acp_captcha.html b/phpBB/adm/style/acp_captcha.html index 4353becd2f4..0c9d3bf0afb 100644 --- a/phpBB/adm/style/acp_captcha.html +++ b/phpBB/adm/style/acp_captcha.html @@ -1,79 +1,85 @@ - +{% include 'overall_header.html' %} -

{L_ACP_VC_SETTINGS}

+

{{ lang('ACP_VC_SETTINGS') }}

-

{L_ACP_VC_SETTINGS_EXPLAIN}

+

{{ lang('ACP_VC_SETTINGS_EXPLAIN') }}

-

{L_ACP_VC_EXT_GET_MORE}

+

{{ lang('ACP_VC_EXT_GET_MORE') }}

- +{% if ERRORS %}
-

{L_WARNING}

-

{ERROR_MSG}

+

{{ lang('WARNING') }}

+

{{ ERRORS|join('
') }}

- +{% endif %} -
+
-{L_GENERAL_OPTIONS} +{{ lang('GENERAL_OPTIONS') }}
-

{L_VISUAL_CONFIRM_REG_EXPLAIN}
-
-
+

{{ lang('VISUAL_CONFIRM_REG_EXPLAIN') }}
+
+ + +
-

{L_REG_LIMIT_EXPLAIN}
-
+

{{ lang('REG_LIMIT_EXPLAIN') }}
+
-

{L_MAX_LOGIN_ATTEMPTS_EXPLAIN}
-
+

{{ lang('MAX_LOGIN_ATTEMPTS_EXPLAIN') }}
+
-

{L_VISUAL_CONFIRM_POST_EXPLAIN}
-
-
+

{{ lang('VISUAL_CONFIRM_POST_EXPLAIN') }}
+
+ + +
-

{L_VISUAL_CONFIRM_REFRESH_EXPLAIN}
-
-
+

{{ lang('VISUAL_CONFIRM_REFRESH_EXPLAIN') }}
+
+ + +
-{L_AVAILABLE_CAPTCHAS} -
-

{L_CAPTCHA_SELECT_EXPLAIN}
-
-
- -
-

{L_CAPTCHA_CONFIGURE_EXPLAIN}
-
-
- +{{ lang('AVAILABLE_CAPTCHAS') }} +
+

{{ lang('CAPTCHA_SELECT_EXPLAIN') }}
+
{{ FormsSelect(CAPTCHA_SELECT | merge({id: 'captcha_select', onchange: "(document.getElementById('acp_captcha')).submit()"})) }}
+
+ {% if S_CAPTCHA_HAS_CONFIG %} +
+

{{ lang('CAPTCHA_CONFIGURE_EXPLAIN') }}
+
+
+ {% endif %}
- +{% if CAPTCHA_PREVIEW_TPL %}
- {L_PREVIEW} - + {{ lang('PREVIEW') }} + {% include CAPTCHA_PREVIEW_TPL %}
- +{% endif %}
- {L_ACP_SUBMIT_CHANGES} + {{ lang('ACP_SUBMIT_CHANGES') }}

-   -   +   +  

- {S_FORM_TOKEN} + {{ S_FORM_TOKEN }}
- +{% include 'overall_footer.html' %} diff --git a/phpBB/adm/style/acp_contact.html b/phpBB/adm/style/acp_contact.html index 828fd4b6594..7aa9d8d6a68 100644 --- a/phpBB/adm/style/acp_contact.html +++ b/phpBB/adm/style/acp_contact.html @@ -1,6 +1,6 @@ -
+ {L_ACP_SUBMIT_CHANGES}

-

@@ -51,8 +54,13 @@

{L_SEND_STATISTICS}

+ {L_ACP_SUBMIT_CHANGES}

- + {% for providers in providers %} + {% for values in providers.values %} + + {% endfor %} + {% endfor %}

diff --git a/phpBB/adm/style/acp_icons.html b/phpBB/adm/style/acp_icons.html index 5493cbde0a4..9a5179419e1 100644 --- a/phpBB/adm/style/acp_icons.html +++ b/phpBB/adm/style/acp_icons.html @@ -4,7 +4,7 @@ - - + « {L_BACK} diff --git a/phpBB/adm/style/acp_permissions.html b/phpBB/adm/style/acp_permissions.html index 7766052c596..80420530285 100644 --- a/phpBB/adm/style/acp_permissions.html +++ b/phpBB/adm/style/acp_permissions.html @@ -340,9 +340,12 @@

{L_ACL_SET}



- - - {S_FORM_TOKEN} + {L_ACP_SUBMIT_CHANGES} +

+   + + {S_FORM_TOKEN} +



diff --git a/phpBB/adm/style/acp_posting_buttons.html b/phpBB/adm/style/acp_posting_buttons.html index c3c42f8e827..c0c5aacd747 100644 --- a/phpBB/adm/style/acp_posting_buttons.html +++ b/phpBB/adm/style/acp_posting_buttons.html @@ -1,30 +1,9 @@ - @@ -49,10 +28,7 @@ - - - - @@ -65,7 +41,7 @@ - + diff --git a/phpBB/adm/style/acp_profile.html b/phpBB/adm/style/acp_profile.html index bd3935b464f..7a0ecce14ea 100644 --- a/phpBB/adm/style/acp_profile.html +++ b/phpBB/adm/style/acp_profile.html @@ -21,8 +21,11 @@

{L_WARNING}

+ {% EVENT acp_profile_options_before %} +
{L_TITLE} + {% EVENT acp_profile_basic_options_before %}

{L_FIELD_TYPE_EXPLAIN}
{FIELD_TYPE}
@@ -43,8 +46,11 @@

{L_WARNING}

+ {% EVENT acp_profile_basic_options_after %}
+ {% EVENT acp_profile_visibility_options_before %} +
{L_VISIBILITY_OPTION}
@@ -87,8 +93,11 @@

{L_WARNING}

+ {% EVENT acp_profile_contact_after %}
+ {% EVENT acp_profile_visibility_options_after %} +
@@ -238,7 +247,7 @@

{L_WARNING}

- + {S_FORM_TOKEN} diff --git a/phpBB/adm/style/acp_prune_users.html b/phpBB/adm/style/acp_prune_users.html index 6e8b2e42149..ecd18392500 100644 --- a/phpBB/adm/style/acp_prune_users.html +++ b/phpBB/adm/style/acp_prune_users.html @@ -7,7 +7,7 @@

{L_ACP_PRUNE_USERS}

{L_ACP_PRUNE_USERS_EXPLAIN}

- +
{L_CRITERIA}
@@ -66,15 +66,19 @@

{L_ACP_PRUNE_USERS}

+
-

- +

+ {L_ACP_SUBMIT_CHANGES} +

+ -   - - {S_FORM_TOKEN} -

+   + + {S_FORM_TOKEN} +

+ diff --git a/phpBB/adm/style/acp_ranks.html b/phpBB/adm/style/acp_ranks.html index e67c9acd800..aa31db497aa 100644 --- a/phpBB/adm/style/acp_ranks.html +++ b/phpBB/adm/style/acp_ranks.html @@ -6,7 +6,7 @@ « {L_BACK} - - -

{L_ACP_SEARCH_INDEX}

- - -

{L_CONTINUE_EXPLAIN}

- -
-
- {L_SUBMIT} -   - - {S_FORM_TOKEN} -
-
- - -

{L_ACP_SEARCH_INDEX_EXPLAIN}

- - - - - -
- -
- - {backend.S_HIDDEN_FIELDS} - - {L_INDEX_STATS}{L_COLON} {backend.L_NAME} ({L_ACTIVE}) - - - - - - - - - - - - - - - - - - - - - - -
{backend.L_NAME} ({L_ACTIVE})
{L_STATISTIC}{L_VALUE}{L_STATISTIC}{L_VALUE}
{backend.data.STATISTIC_1}{L_COLON}{backend.data.VALUE_1}{backend.data.STATISTIC_2}{L_COLON}{backend.data.VALUE_2}
- - - -

- - - - - - - -

- {S_FORM_TOKEN} -
- -
- - - - - - - diff --git a/phpBB/adm/style/acp_search_index.html b/phpBB/adm/style/acp_search_index.html new file mode 100644 index 00000000000..9c2fda674a0 --- /dev/null +++ b/phpBB/adm/style/acp_search_index.html @@ -0,0 +1,66 @@ +{% include 'overall_header.html' %} + + + +

{{ lang('ACP_SEARCH_INDEX') }}

+ +

{{ lang('ACP_SEARCH_INDEX_EXPLAIN') }}

+ +{% for backend in backends %} + + {% if backend.S_STATS is not empty %} + +
+ +
+ + {{ backend.S_HIDDEN_FIELDS }} + + {{ lang('INDEX_STATS') ~ lang('COLON') }} {{ backend.NAME }} {% if backend.S_ACTIVE %}({{ lang('ACTIVE') }}) {% endif %} + + + + + + + + + + + + + + {% for stat in backend.S_STATS | batch(2, '') %} + + {% for key, value in stat %} + {% if value is not empty %} + + + {% else %} + + + {% endif %} + {% endfor %} + + {% endfor %} + +
{{ backend.NAME }} {% if backend.S_ACTIVE %}({{ lang('ACTIVE') }}) {% endif %}
{{ lang('STATISTIC') }}{{ lang('VALUE') }}{{ lang('STATISTIC') }}{{ lang('VALUE') }}
{{ key ~ lang('COLON') }}{{ value }}
+ + {% endif %} + +

+ {% if backend.S_INDEXED %} + + + {% else %} + + + {% endif %} +

+ {{ S_FORM_TOKEN }} +
+ +
+{% endfor %} + +{% include 'overall_footer.html' %} diff --git a/phpBB/adm/style/acp_search_index_inprogress.html b/phpBB/adm/style/acp_search_index_inprogress.html new file mode 100644 index 00000000000..3f8f51f378d --- /dev/null +++ b/phpBB/adm/style/acp_search_index_inprogress.html @@ -0,0 +1,43 @@ +{% include 'overall_header.html' %} + + + +

+ {% if S_ACTION == 'create' %} + {{ lang('CONTINUE_INDEXING') }} + {% else %} + {{ lang('CONTINUE_DELETING_INDEX') }} + {% endif %} +

+ +

+ {% if S_ACTION == 'create' %} + {{ lang('CONTINUE_INDEXING_EXPLAIN') }} + {% else %} + {{ lang('CONTINUE_DELETING_INDEX_EXPLAIN') }} + {% endif %} +

+ +
+
+ {{ lang('CONTINUE_INDEXING') }} + {% if CONTINUE_PROGRESS %} +
+
+
+ {{ CONTINUE_PROGRESS.PERCENTAGE|number_format(2) ~ ' %' }}
+ {{ lang('SEARCH_INDEX_PROGRESS', CONTINUE_PROGRESS.VALUE, CONTINUE_PROGRESS.REMAINING, CONTINUE_PROGRESS.TOTAL) }} +
+ {% endif %} +

+   + +

+ {{ S_FORM_TOKEN }} +
+
+ +{% include 'overall_footer.html' %} diff --git a/phpBB/adm/style/acp_search_index_progress.html b/phpBB/adm/style/acp_search_index_progress.html new file mode 100644 index 00000000000..6c41105bab7 --- /dev/null +++ b/phpBB/adm/style/acp_search_index_progress.html @@ -0,0 +1,23 @@ +{% include 'overall_header.html' %} + + + +
+

{{ INDEXING_TITLE }}

+

+ {{ INDEXING_EXPLAIN }} + {% if INDEXING_PROGRESS %}
{{ INDEXING_PROGRESS }}{% endif %} + {% if INDEXING_RATE %}
{{ INDEXING_RATE }}{% endif %} + {% if INDEXING_PROGRESS_BAR %} +
+
+ {{ INDEXING_PROGRESS_BAR.PERCENTAGE|number_format(2) ~ ' %' }}
+ {{ lang('SEARCH_INDEX_PROGRESS', INDEXING_PROGRESS_BAR.VALUE, INDEXING_PROGRESS_BAR.REMAINING, INDEXING_PROGRESS_BAR.TOTAL) }} + {% endif %} +

+
+ +{% include 'overall_footer.html' %} diff --git a/phpBB/adm/style/acp_search_settings.html b/phpBB/adm/style/acp_search_settings.html new file mode 100644 index 00000000000..fe899ec2076 --- /dev/null +++ b/phpBB/adm/style/acp_search_settings.html @@ -0,0 +1,78 @@ +{% include 'overall_header.html' %} + + + +

{{ lang('ACP_SEARCH_SETTINGS') }}

+ +

{{ lang('ACP_SEARCH_SETTINGS_EXPLAIN') }}

+ + + +{% include 'overall_footer.html' %} diff --git a/phpBB/adm/style/acp_storage.html b/phpBB/adm/style/acp_storage.html index 4689a7546dd..f3b93020f8b 100644 --- a/phpBB/adm/style/acp_storage.html +++ b/phpBB/adm/style/acp_storage.html @@ -6,65 +6,115 @@

{{ lang('STORAGE_TITLE') }}

{{ lang('STORAGE_TITLE_EXPLAIN') }}

-
+ + + + + + + + + + + {% for storage in STORAGE_STATS %} + + + + + + + {% endfor %} + +
{{ lang('STORAGE_NAME') }}{{ lang('STORAGE_NUM_FILES') }}{{ lang('STORAGE_SIZE') }}{{ lang('STORAGE_FREE') }}
{{ storage.name }}{{ storage.files }}{{ storage.size }}{{ storage.free_space }}
+ +{% if ERROR_MESSAGES is not empty %} +
+

{{ lang('WARNING') }}

+ {% for ERROR_MESSAGE in ERROR_MESSAGES %} +

{{ ERROR_MESSAGE }}

+ {% endfor %} +
+{% endif %} + {% for storage in STORAGES %}
{{ lang('STORAGE_' ~ storage.get_name | upper ~ '_TITLE') }}
-

{{ lang('STORAGE_SELECT_DESC') }}
+

{{ lang('STORAGE_SELECT_DESC') }}
- {% for provider in PROVIDERS if provider.is_available %} -
- {{ lang('STORAGE_' ~ storage.get_name | upper ~ '_TITLE') }} - {{ lang('STORAGE_ADAPTER_' ~ provider.get_name | upper ~ '_NAME') }} - {% for name, options in provider.get_options %} - {% set title = 'STORAGE_ADAPTER_' ~ provider.get_name | upper ~ '_OPTION_' ~ name | upper %} - {% set description = 'STORAGE_ADAPTER_' ~ provider.get_name | upper ~ '_OPTION_' ~ name | upper ~ '_EXPLAIN' %} - {% set input_id = storage.get_name ~ '_' ~ provider.get_name ~ '_' ~ name %} - {% set input_type = options['type'] %} - {% set input_name = storage.get_name ~ '[' ~ name ~ ']' %} - {% set input_value = attribute(config, 'storage\\' ~ storage.get_name ~ '\\config\\' ~ name) %} -
-
- - {% if lang_defined(description) %} -
{{ lang(description) }} - {% endif %} -
-
- {% if input_type in ['text', 'password', 'email'] %} - - {% elseif input_type == 'textarea' %} - - {% elseif input_type == 'radio' %} - {% for option_name, option_value in options['options'] %} - {{ lang(option_name) }} - {% endfor %} - {% elseif input_type == 'select' %} - - {% endif %} -
-
- {% endfor %} -
+ + {{ FormsRadioButtons(form_macro | merge({"buttons": buttons})) }} + {% elseif form_macro.tag == 'select' %} + {% set select_options = [] %} + + {% for option in form_macro.options %} + {% set new_option = option | merge({"selected": option.value == input_value}) %} + {% set select_options = select_options | merge([new_option]) %} + {% endfor %} + + {{ FormsSelect(form_macro | merge({"name": input_name, "options": select_options})) }} + {% endif %} + +
+ {% endfor %} +
+ {% endif %} {% endfor %} {% endfor %} +
+
+
+
+ + + +
+
+
+
{{ lang('SUBMIT') }}   diff --git a/phpBB/adm/style/acp_storage_update_inprogress.html b/phpBB/adm/style/acp_storage_update_inprogress.html new file mode 100644 index 00000000000..5f7614cb2c7 --- /dev/null +++ b/phpBB/adm/style/acp_storage_update_inprogress.html @@ -0,0 +1,32 @@ +{% include 'overall_header.html' %} + + + +

{{ lang('STORAGE_TITLE') }}

+ +

{{ lang('STORAGE_TITLE_EXPLAIN') }}

+ + +
+ {{ lang('SUBMIT') }} + + {% if CONTINUE_PROGRESS %} +
+
+
+ {{ CONTINUE_PROGRESS.PERCENTAGE|number_format(2) ~ ' %' }} +
+ {% endif %} + +

+   + +

+ {{ S_FORM_TOKEN }} +
+ + +{% include 'overall_footer.html' %} diff --git a/phpBB/adm/style/acp_storage_update_progress.html b/phpBB/adm/style/acp_storage_update_progress.html new file mode 100644 index 00000000000..17ba67a037f --- /dev/null +++ b/phpBB/adm/style/acp_storage_update_progress.html @@ -0,0 +1,20 @@ +{% include 'overall_header.html' %} + + + +
+

{{ INDEXING_TITLE }}

+

+ {{ INDEXING_EXPLAIN }} + {% if INDEXING_PROGRESS_BAR %} +
+
+ {{ INDEXING_PROGRESS_BAR.PERCENTAGE|number_format(2) ~ ' %' }} + {% endif %} +

+
+ +{% include 'overall_footer.html' %} diff --git a/phpBB/adm/style/acp_styles.html b/phpBB/adm/style/acp_styles.html index 38bec5a1e4d..b0c16612c62 100644 --- a/phpBB/adm/style/acp_styles.html +++ b/phpBB/adm/style/acp_styles.html @@ -33,7 +33,7 @@

{MESSAGE_TITLE}

{L_EXPLAIN}

- {L_BROWSE_STYLES_DATABASE} + {L_BROWSE_STYLES_DATABASE}
@@ -96,9 +96,10 @@

{MESSAGE_TITLE}

{L_STYLE_NAME} - {L_STYLE_PHPBB_VERSION} - {L_STYLE_USED_BY} - {L_ACTIONS} + {{ lang('STYLE_VERSION') }} + {L_STYLE_PHPBB_VERSION} + {L_STYLE_USED_BY} + {L_ACTIONS} {STYLES_LIST_EXTRA}   @@ -126,10 +127,11 @@

{MESSAGE_TITLE}


{styles_list.COMMENT}
- +
{L_STYLE_PATH}{L_COLON} {styles_list.STYLE_PATH_FULL}
+ {{ styles_list.STYLE_VERSION }} {styles_list.STYLE_PHPBB_VERSION} {styles_list.USERS} @@ -144,9 +146,11 @@

{MESSAGE_TITLE}

{styles_list.EXTRA} - + - + {% if styles_list.STYLE_NAME !== 'prosilver' %} + + {% endif %}   diff --git a/phpBB/adm/style/acp_users.html b/phpBB/adm/style/acp_users.html index 50b6ec9bc93..c500541e63a 100644 --- a/phpBB/adm/style/acp_users.html +++ b/phpBB/adm/style/acp_users.html @@ -137,9 +137,13 @@

{L_WARNING}

{group.GROUP_NAME} {L_GROUP_DEFAULT}{L_GROUP_DEFAULT}{L_GROUP_APPROVE}  {group.L_DEMOTE_PROMOTE}  - {L_GROUP_DELETE} + {% if group.U_DELETE %}{{ lang('GROUP_DELETE') }}{% endif %} + + + {{ lang('NO_GROUP') }} + diff --git a/phpBB/adm/style/acp_users_avatar.html b/phpBB/adm/style/acp_users_avatar.html index 8466985fb3c..3c2556905db 100644 --- a/phpBB/adm/style/acp_users_avatar.html +++ b/phpBB/adm/style/acp_users_avatar.html @@ -5,7 +5,7 @@

{ERROR}


{L_AVATAR_EXPLAIN}
-
{AVATAR}
+
{% include 'avatar.html' with {avatar_data: AVATAR} only %}
diff --git a/phpBB/adm/style/acp_users_overview.html b/phpBB/adm/style/acp_users_overview.html index 506101c3f75..2af669a41fe 100644 --- a/phpBB/adm/style/acp_users_overview.html +++ b/phpBB/adm/style/acp_users_overview.html @@ -79,7 +79,7 @@ - -
+
- -{L_RECAPTCHA_NOT_AVAILABLE} - diff --git a/phpBB/adm/style/captcha_recaptcha_acp.html b/phpBB/adm/style/captcha_recaptcha_acp.html index 67176ebd072..c31cfa7a1b3 100644 --- a/phpBB/adm/style/captcha_recaptcha_acp.html +++ b/phpBB/adm/style/captcha_recaptcha_acp.html @@ -21,6 +21,20 @@

{L_ACP_VC_SETTINGS}

+
+
+ +
{{ lang('RECAPTCHA_V3_DOMAIN_EXPLAIN') }} +
+
+ {% for domain in RECAPTCHA_V2_DOMAINS %} + + {% endfor %} +
+
diff --git a/phpBB/adm/style/captcha_recaptcha_v3.html b/phpBB/adm/style/captcha_recaptcha_v3.html new file mode 100644 index 00000000000..0f2d279fe9c --- /dev/null +++ b/phpBB/adm/style/captcha_recaptcha_v3.html @@ -0,0 +1,15 @@ +{% if S_RECAPTCHA_AVAILABLE %} +
+
 
+
+ + + {{ lang('RECAPTCHA_INVISIBLE') }} + +
+
+{% else %} + {{ lang('RECAPTCHA_NOT_AVAILABLE') }} +{% endif %} diff --git a/phpBB/adm/style/captcha_recaptcha_v3_acp.html b/phpBB/adm/style/captcha_recaptcha_v3_acp.html new file mode 100644 index 00000000000..ef9896a742c --- /dev/null +++ b/phpBB/adm/style/captcha_recaptcha_v3_acp.html @@ -0,0 +1,108 @@ +{% include 'overall_header.html' %} + + + +

{{ lang('ACP_VC_SETTINGS') }}

+

{{ lang('ACP_VC_SETTINGS_EXPLAIN') }}

+ + +
+ {{ lang('GENERAL_OPTIONS') }} + +
+
+ +
{{ lang('RECAPTCHA_V3_PUBLIC_EXPLAIN') }} +
+
+ +
+
+
+
+ +
{{ lang('RECAPTCHA_V3_PRIVATE_EXPLAIN') }} +
+
+ +
+
+ +
+
+ +
{{ lang('RECAPTCHA_V3_DOMAIN_EXPLAIN') }} +
+
+ {% for domain in RECAPTCHA_V3_DOMAINS %} + + {% endfor %} +
+
+
+
+ +
{{ lang('RECAPTCHA_V3_METHOD_EXPLAIN') }} +
+
+ {% for method, available in RECAPTCHA_V3_METHODS %} + + {% endfor %} +
+
+
+ +
+ {{ lang('RECAPTCHA_V3_THRESHOLDS') }} +

{{ lang('RECAPTCHA_V3_THRESHOLDS_EXPLAIN') }}

+ + {% for threshold in thresholds %} +
+
+ + {% if lang_defined(threshold.key|upper ~ '_EXPLAIN') %} +
{{ lang(threshold.key|upper ~ '_EXPLAIN') }} + {% endif %} +
+
+
+ {% endfor %} +
+ +
+ {{ lang('PREVIEW') }} + + {% if PREVIEW %} +
+

{{ lang('WARNING') }}

+

{{ lang('CAPTCHA_PREVIEW_MSG') }}

+
+ {% endif %} + + {% include CAPTCHA_PREVIEW %} +
+ +
+ {{ lang('ACP_SUBMIT_CHANGES') }} + +

+ + + + + + {{ S_FORM_TOKEN }} +

+
+ + +{% include 'overall_footer.html' %} diff --git a/phpBB/adm/style/captcha_turnstile_acp.html b/phpBB/adm/style/captcha_turnstile_acp.html new file mode 100644 index 00000000000..a187e1e41b1 --- /dev/null +++ b/phpBB/adm/style/captcha_turnstile_acp.html @@ -0,0 +1,64 @@ +{% include('overall_header.html') %} + + + +

{{ lang('ACP_VC_SETTINGS') }}

+ +

{{ lang('ACP_VC_SETTINGS_EXPLAIN') }}

+ +
+
+ {{ lang('GENERAL_OPTIONS') }} +
+
+
+ {{ lang('CAPTCHA_TURNSTILE_SITEKEY_EXPLAIN') }} +
+
+
+
+
+
+ {{ lang('CAPTCHA_TURNSTILE_SECRET_EXPLAIN') }} +
+
+
+
+
+ +
{{ lang('CAPTCHA_TURNSTILE_THEME_EXPLAIN') }} +
+
+ {% for theme in CAPTCHA_TURNSTILE_THEMES %} + + {% endfor %} +
+
+
+
+ {{ lang('PREVIEW') }} + {% if PREVIEW %} +
+

{{ lang('WARNING') }}

+

{{ lang('CAPTCHA_PREVIEW_MSG') }}

+
+ {% endif %} + {% include(CAPTCHA_PREVIEW) %} +
+ +
+ {{ lang('ACP_SUBMIT_CHANGES') }} +

+   +   +

+ + + {{ S_FORM_TOKEN }} +
+
+ +{% include('overall_footer.html') %} diff --git a/phpBB/adm/style/captcha_turnstile_acp_demo.html b/phpBB/adm/style/captcha_turnstile_acp_demo.html new file mode 100644 index 00000000000..757d0a4bcb9 --- /dev/null +++ b/phpBB/adm/style/captcha_turnstile_acp_demo.html @@ -0,0 +1,23 @@ +
+
+
+{% INCLUDEJS U_TURNSTILE_SCRIPT %} + diff --git a/phpBB/adm/style/installer_footer.html b/phpBB/adm/style/installer_footer.html index fefa8f6d3fd..4aa47cbf8ac 100644 --- a/phpBB/adm/style/installer_footer.html +++ b/phpBB/adm/style/installer_footer.html @@ -6,12 +6,14 @@ - - - - + + + + {$SCRIPTS} diff --git a/phpBB/adm/style/installer_header.html b/phpBB/adm/style/installer_header.html index 704db9e1742..39d86da1797 100644 --- a/phpBB/adm/style/installer_header.html +++ b/phpBB/adm/style/installer_header.html @@ -7,6 +7,7 @@ {META} {PAGE_TITLE} + @@ -19,7 +20,7 @@

{L_INSTALL_PANEL}

- diff --git a/phpBB/adm/style/installer_install.html b/phpBB/adm/style/installer_install.html index 53a91f27002..ae77f6b55ec 100644 --- a/phpBB/adm/style/installer_install.html +++ b/phpBB/adm/style/installer_install.html @@ -6,6 +6,9 @@

{TITLE}

{L_SUBMIT} + {% if SHOW_RESTART_BUTTON %} + + {% endif %}
diff --git a/phpBB/adm/style/installer_update_file_status.html b/phpBB/adm/style/installer_update_file_status.html index a27bfa6a44b..b49faf0f414 100644 --- a/phpBB/adm/style/installer_update_file_status.html +++ b/phpBB/adm/style/installer_update_file_status.html @@ -4,7 +4,7 @@

{L_FILES_DELETED}

{L_FILES_DELETED_EXPLAIN}

- {L_STATUS_DELETED} + {{ Icon('font', 'circle-xmark', lang('STATUS_DELETED'), true, '', {'style' : 'color:red;'}) }}
{deleted.DIR_PART}{deleted.FILE_PART}
@@ -20,7 +20,7 @@

{L_FILES_CONFLICT}

{L_FILES_CONFLICT_EXPLAIN}

- {L_STATUS_CONFLICT} + {{ Icon('font', 'circle-exclamation', lang('STATUS_CONFLICT'), true, '', {'style' : 'color:red;'}) }}
{conflict.DIR_PART}{conflict.FILE_PART}
@@ -36,7 +36,7 @@

{L_FILES_MODIFIED}

{L_FILES_MODIFIED_EXPLAIN}

- {L_STATUS_MODIFIED} + {{ Icon('font', 'circle-arrow-left', lang('STATUS_MODIFIED'), true, '', {'style' : 'color:#ffd43b;'}) }}
{modified.DIR_PART}{modified.FILE_PART}
@@ -52,7 +52,7 @@

{L_FILES_NEW}

{L_FILES_NEW_EXPLAIN}

@@ -85,7 +74,7 @@

{L_TITLE}

- {S_HIDDEN_FIELDS}  + {S_HIDDEN_FIELDS} {S_FORM_TOKEN}
@@ -122,7 +111,7 @@

{L_UNBAN_TITLE}

- {S_HIDDEN_FIELDS}  + {S_HIDDEN_FIELDS}
diff --git a/phpBB/styles/prosilver/template/mcp_forum.html b/phpBB/styles/prosilver/template/mcp_forum.html index a41fea82949..786c09c5317 100644 --- a/phpBB/styles/prosilver/template/mcp_forum.html +++ b/phpBB/styles/prosilver/template/mcp_forum.html @@ -36,9 +36,25 @@

{L_FORUM}{L_COLON} {FORUM_NAME}

  • -
    -
    style="background-image: url({T_ICONS_PATH}{topicrow.TOPIC_ICON_IMG}); background-repeat: no-repeat;"> - +
    +
    + + {{ Icon('svg', { + 'globe' : topicrow.S_POST_GLOBAL, + 'bullhorn' : topicrow.S_POST_ANNOUNCE, + 'thumbtack' : topicrow.S_POST_STICKY, + 'lock' : topicrow.S_TOPIC_LOCKED, + 'arrow-right-bold' : topicrow.S_TOPIC_MOVED, + 'fire' : topicrow.S_TOPIC_HOT, + 'file-document-outline' : true, + }, '', true, 'c-forum-row-icon') }} + + {% if lang(topicrow.TOPIC_AUTHOR) == S_USERNAME %} + + {% endif%} + {% if topicrow.TOPIC_ICON_IMG and S_TOPIC_ICONS %} + + {% endif %}
    [ {L_SELECT_MERGE} ]   @@ -47,52 +63,57 @@

    {L_FORUM}{L_COLON} {FORUM_NAME}

    - {L_TOPIC_UNAPPROVED} + {{ Icon('font', 'circle-question', lang('TOPIC_UNAPPROVED'), true, 'fas c-unapproved-icon o-icon-baseline') }} - {L_TOPIC_DELETED} + {{ Icon('font', 'recycle', lang('TOPIC_DELETED'), true, 'fas c-topic-deleted-icon o-icon-baseline') }} - {L_TOPIC_REPORTED} + {{ Icon('font', 'triangle-exclamation', lang('TOPIC_REPORTED'), true, 'fas c-topic-reported-icon o-icon-baseline') }}  [ {L_DELETE_SHADOW_TOPIC} ]
    - - {L_POST_BY_AUTHOR} {topicrow.TOPIC_AUTHOR_FULL} » {topicrow.FIRST_POST_TIME} + {% if topicrow.ATTACH_ICON_IMG %}{{ Icon('font', 'paperclip', '', true) }} {% endif %} + {% EVENT topiclist_row_topic_by_author_before %} + {L_POST_BY_AUTHOR} {% EVENT mcp_forum_topic_author_username_prepend %}{topicrow.TOPIC_AUTHOR_FULL}{% EVENT mcp_forum_topic_author_username_append %} » {topicrow.FIRST_POST_TIME} + {% EVENT topiclist_row_topic_by_author_after %}
    {topicrow.REPLIES} {L_REPLIES}
    -
    {L_LAST_POST} {L_POST_BY_AUTHOR} {topicrow.LAST_POST_AUTHOR_FULL}
    {topicrow.LAST_POST_TIME}
    +
    {L_LAST_POST} {L_POST_BY_AUTHOR} {% EVENT mcp_forum_last_post_author_username_prepend %}{topicrow.LAST_POST_AUTHOR_FULL}{% EVENT mcp_forum_last_post_author_username_append %}
    {topicrow.LAST_POST_TIME}
    checked="checked" />  diff --git a/phpBB/styles/prosilver/template/mcp_front.html b/phpBB/styles/prosilver/template/mcp_front.html index f84faeee656..b594fc7bcb1 100644 --- a/phpBB/styles/prosilver/template/mcp_front.html +++ b/phpBB/styles/prosilver/template/mcp_front.html @@ -20,6 +20,7 @@

    {L_LATEST_UNAPPROVED}

    {L_VIEW_DETAILS}
    {L_TOPIC} & {L_FORUM}
    +
    {{ lang('MARK') }}
  • @@ -30,7 +31,7 @@

    {L_LATEST_UNAPPROVED}

    - {unapproved.SUBJECT}
    + {unapproved.SUBJECT} {{ Icon('font', 'paperclip', '', true) }}
    {L_POSTED} {L_POST_BY_AUTHOR} {unapproved.AUTHOR_FULL} » {unapproved.POST_TIME}
    @@ -86,12 +87,12 @@

    {L_LATEST_REPORTED}

    - {report.SUBJECT}
    + {report.SUBJECT} {{ Icon('font', 'paperclip', '', true) }}
    {L_POSTED} {L_POST_BY_AUTHOR} {report.AUTHOR_FULL} » {report.POST_TIME}
    - {L_REPORTED} {L_POST_BY_AUTHOR} {report.REPORTER_FULL} {L_REPORTED_ON_DATE}
    + {L_REPORTED} {L_POST_BY_AUTHOR} {report.REPORTER_FULL} {L_REPORTED_ON_DATE} {{ report.REPORT_TIME }}
    {L_FORUM}{L_COLON} {report.FORUM_NAME}
    @@ -129,7 +130,7 @@

    {L_LATEST_REPORTED_PMS}

    - {pm_report.PM_SUBJECT}
    + {pm_report.PM_SUBJECT} {{ Icon('font', 'paperclip', '', true) }}
    {L_MESSAGE_BY_AUTHOR} {pm_report.PM_AUTHOR_FULL} » {pm_report.PM_TIME}
    {L_MESSAGE_TO} {pm_report.RECIPIENTS}
    diff --git a/phpBB/styles/prosilver/template/mcp_move.html b/phpBB/styles/prosilver/template/mcp_move.html index d8e39f5b995..ee3e2146ac6 100644 --- a/phpBB/styles/prosilver/template/mcp_move.html +++ b/phpBB/styles/prosilver/template/mcp_move.html @@ -43,12 +43,14 @@

    {MESSAGE_TITLE}

    {ADDITIONAL_MSG}

    + {% EVENT mcp_move_destination_forum_before %}
    + {% EVENT mcp_move_destination_forum_after %}
     
    {MESSAGE_TEXT}
    diff --git a/phpBB/styles/prosilver/template/mcp_notes_front.html b/phpBB/styles/prosilver/template/mcp_notes_front.html index ee985a53da3..73634eadefa 100644 --- a/phpBB/styles/prosilver/template/mcp_notes_front.html +++ b/phpBB/styles/prosilver/template/mcp_notes_front.html @@ -19,7 +19,6 @@

    {L_TITLE}

    -   {S_FORM_TOKEN}
    diff --git a/phpBB/styles/prosilver/template/mcp_notes_user.html b/phpBB/styles/prosilver/template/mcp_notes_user.html index 6d318dda977..c4682e09754 100644 --- a/phpBB/styles/prosilver/template/mcp_notes_user.html +++ b/phpBB/styles/prosilver/template/mcp_notes_user.html @@ -11,13 +11,13 @@

    {USERNAME_FULL}

    -
    {AVATAR_IMG}
    + {% include 'avatar.html' with {'avatar_data': USER_AVATAR} only %}
    {L_RANK}{L_COLON}
    {RANK_TITLE}
    -
     {L_RANK}{L_COLON}
    {RANK_IMG}
    + {% if RANK_IMG %}
    {% if RANK_TITLE %} {% else %}{{ lang('RANK') ~ lang('COLON') }}{% endif %}
    {{ RANK_IMG }}
    {% endif %}
    {L_JOINED}{L_COLON}
    {JOINED}
    {L_TOTAL_POSTS}{L_COLON}
    {POSTS}
    {L_WARNINGS}{L_COLON}
    {WARNINGS}
    @@ -42,7 +42,7 @@

    {L_ADD_FEEDBACK}

    - {S_HIDDEN_FIELDS}  + {S_HIDDEN_FIELDS} {S_FORM_TOKEN}
    diff --git a/phpBB/styles/prosilver/template/mcp_post.html b/phpBB/styles/prosilver/template/mcp_post.html index 7fa48caf117..45c6088f768 100644 --- a/phpBB/styles/prosilver/template/mcp_post.html +++ b/phpBB/styles/prosilver/template/mcp_post.html @@ -14,7 +14,7 @@

    {L_REPORT_DETAILS}

    {L_REPORT_REASON}{L_COLON} {REPORT_REASON_TITLE}

    {L_REPORTED} {L_POST_BY_AUTHOR} {REPORTER_FULL} « {REPORT_DATE}

    -

    {L_REPORT_CLOSED}

    +

    {{ Icon('font', 'exclamation', '', true, 'fas c-topic-reported-icon') }}{L_REPORT_CLOSED}

    @@ -31,10 +31,12 @@

    {L_REPORT_REASON}{L_COLON} {REPORT_REASON_TITLE}

    + {% EVENT mcp_post_report_buttons_top_before %}   + {% EVENT mcp_post_report_buttons_top_after %} {S_FORM_TOKEN}
    @@ -59,7 +61,7 @@

    {POST_SUBJECT}

  • - {L_EDIT_POST} + {{ Icon('font', 'pencil', lang('EDIT_POST'), true, 'fas c-button-icon') }}
  • @@ -69,13 +71,14 @@

    {POST_SUBJECT}

    {L_SENT_AT}{L_COLON} {POST_DATE}
    {L_PM_FROM}{L_COLON} {POST_AUTHOR_FULL} -
    {L_TO}{L_COLON} {to_recipient.NAME_FULL}{to_recipient.NAME}  -
    {L_BCC}{L_COLON} {bcc_recipient.NAME_FULL}{bcc_recipient.NAME}  +
    {L_TO}{L_COLON} {to_recipient.NAME_FULL} style="color:{to_recipient.COLOUR};">{to_recipient.NAME}  +
    {L_BCC}{L_COLON} {bcc_recipient.NAME_FULL} style="color:{bcc_recipient.COLOUR};">{bcc_recipient.NAME} 

    -

    {MINI_POST_IMG} {L_POSTED} {L_POST_BY_AUTHOR} {POST_AUTHOR_FULL} » {POST_DATE}

    +

    {{ Icon('font', 'file', MINI_POST, true, 'fas c-topic-icon') }} {L_POSTED} {L_POST_BY_AUTHOR} {POST_AUTHOR_FULL} » {POST_DATE}

    + {% if S_CAN_APPROVE %} @@ -99,17 +102,23 @@

    {POST_SUBJECT}

    + {% endif %} - + {% if S_POST_REPORTED and not S_MCP_REPORT %}

    - {L_TOPIC_REPORTED} {L_MESSAGE_REPORTED} + {{ Icon('font', 'exclamation', lang('TOPIC_REPORTED'), true, 'fas c-topic-reported-icon') }} + {{ lang('POST_REPORTED') }}

    - + {% endif %} + + {% EVENT mcp_post_text_before %}
    {POST_PREVIEW}
    + {% EVENT mcp_post_text_after %} +
    {L_ATTACHMENTS}
    @@ -323,21 +332,23 @@

    {L_MCP_POST_REPORTS}

    - + {% if U_LOOKUP_ALL %} + + {% endif %}
    diff --git a/phpBB/styles/prosilver/template/overall_footer.html b/phpBB/styles/prosilver/template/overall_footer.html index 3db3087dc0f..237620bd612 100644 --- a/phpBB/styles/prosilver/template/overall_footer.html +++ b/phpBB/styles/prosilver/template/overall_footer.html @@ -8,11 +8,34 @@
    @@ -29,13 +52,13 @@ @@ -45,27 +68,27 @@

     

    - {RUN_CRON_TASK} + {% if not S_IS_BOT %}{{ RUN_CRON_TASK }}{% endif %}
    - - - + + + - - - +{% if S_ALLOW_CDN %} + +{% endif %} @@ -86,7 +109,7 @@

     

    "message": "{LA_COOKIE_CONSENT_MSG}", "dismiss": "{LA_COOKIE_CONSENT_OK}", "link": "{LA_COOKIE_CONSENT_INFO}", - "href": "{LA_COOKIE_CONSENT_HREF}" + "href": "{UA_PRIVACY}" } }); }); diff --git a/phpBB/styles/prosilver/template/overall_header.html b/phpBB/styles/prosilver/template/overall_header.html index cb1283cab44..cb94e8b11d3 100644 --- a/phpBB/styles/prosilver/template/overall_header.html +++ b/phpBB/styles/prosilver/template/overall_header.html @@ -4,6 +4,9 @@ + + + {META} <!-- IF UNREAD_NOTIFICATIONS_COUNT -->({UNREAD_NOTIFICATIONS_COUNT}) <!-- ENDIF --><!-- IF not S_VIEWTOPIC and not S_VIEWFORUM -->{SITENAME} - <!-- ENDIF --><!-- IF S_IN_MCP -->{L_MCP} - <!-- ELSEIF S_IN_UCP -->{L_UCP} - <!-- ENDIF -->{PAGE_TITLE}<!-- IF S_VIEWTOPIC or S_VIEWFORUM --> - {SITENAME}<!-- ENDIF --> @@ -24,7 +27,7 @@ @@ -39,7 +42,7 @@ (function(d) { var wf = d.createElement('script'), s = d.scripts[0]; - wf.src = 'https://ajax.googleapis.com/ajax/libs/webfont/1.5.18/webfont.js'; + wf.src = 'https://cdn.jsdelivr.net/npm/webfontloader@1.6.28/webfontloader.min.js'; wf.async = true; s.parentNode.insertBefore(wf, s); })(document); @@ -49,10 +52,6 @@ - - - - @@ -61,12 +60,18 @@ + + {$STYLESHEETS} +{% if NOTIFICATIONS_WEBPUSH_ENABLE %} + {% include 'ucp_notifications_webpush.html' %} +{% endif %} + @@ -75,16 +80,25 @@
    + {% include 'breadcrumbs.html' %} + diff --git a/phpBB/styles/prosilver/template/pagination.html b/phpBB/styles/prosilver/template/pagination.html index 4e7297dafc2..db1251caa37 100644 --- a/phpBB/styles/prosilver/template/pagination.html +++ b/phpBB/styles/prosilver/template/pagination.html @@ -1,7 +1,7 @@
    diff --git a/phpBB/styles/prosilver/template/posting_buttons.html b/phpBB/styles/prosilver/template/posting_buttons.html index 14185ed66be..4712cc34a62 100644 --- a/phpBB/styles/prosilver/template/posting_buttons.html +++ b/phpBB/styles/prosilver/template/posting_buttons.html @@ -1,6 +1,5 @@ - + +{% include 'mentions_templates.html' %} + + + -
    +
    data-mention-url="{U_MENTION_URL}" data-mention-names-limit="{S_MENTION_NAMES_LIMIT}" data-topic-id="{S_TOPIC_ID}" data-user-id="{S_USER_ID}"> - - - - @@ -120,8 +98,12 @@ -
    diff --git a/phpBB/styles/prosilver/template/posting_editor.html b/phpBB/styles/prosilver/template/posting_editor.html index 49fff3fb082..eebc96623eb 100644 --- a/phpBB/styles/prosilver/template/posting_editor.html +++ b/phpBB/styles/prosilver/template/posting_editor.html @@ -1,16 +1,24 @@

    {ERROR}

    + {% EVENT posting_editor_topic_icons_before %} +
    + {% EVENT posting_editor_topic_icons_prepend %} + + + {% EVENT posting_editor_topic_icons_append %}
    + {% EVENT posting_editor_topic_icons_after %} +
    @@ -57,7 +65,6 @@ {BBCODE_STATUS}
    {IMG_STATUS}
    - {FLASH_STATUS}
    {URL_STATUS}
    {SMILIES_STATUS} @@ -109,7 +116,7 @@
    - -
    + {% if S_SOFTDELETE_ALLOWED || S_DELETE_ALLOWED %} +
    -
    -
    - -
    - +
    + {% if S_SOFTDELETE_ALLOWED %} +
    + {% endif %} + {% if S_DELETE_ALLOWED %} +
    + {% endif %}
    - + {% endif %}
    diff --git a/phpBB/styles/prosilver/template/posting_layout.html b/phpBB/styles/prosilver/template/posting_layout.html index 985f92b23d4..3bb57593f4a 100644 --- a/phpBB/styles/prosilver/template/posting_layout.html +++ b/phpBB/styles/prosilver/template/posting_layout.html @@ -38,27 +38,6 @@

    {L_INFORMATION}

    - -
    -
    -
    -

    {L_SELECT_DESTINATION_FORUM}

    -

    {L_UNGLOBALISE_EXPLAIN}

    -
    -
    -
    -
    - -
    -
     
    -
    -
    -
    - -
    -
    - -
    @@ -73,7 +52,7 @@

    {L_POST_A}

    - + diff --git a/phpBB/styles/prosilver/template/posting_pm_header.html b/phpBB/styles/prosilver/template/posting_pm_header.html index 02c7d805582..2569e1583a6 100644 --- a/phpBB/styles/prosilver/template/posting_pm_header.html +++ b/phpBB/styles/prosilver/template/posting_pm_header.html @@ -1,83 +1,116 @@
    - + {% if not S_SHOW_DRAFTS %} - + {% if S_GROUP_OPTIONS %}
    -
    -
    +
    +
    - - -
    -
    -
    - -
    -
    + {% endif %} + {% if S_ALLOW_MASS_PM %} +
    + {% if not S_EDIT_POST %} +
    +
    - + + + {% EVENT posting_pm_header_find_username_before %} + {{ lang('FIND_USERNAME') }} + {% EVENT posting_pm_header_find_username_after %}
    - -
    - -
    + {% endif %} +
    + {% if to_recipient or bcc_recipient %} +
    + {% endif %} +
    + {% if to_recipient %} +
    +
    +
    +
      + {% for recipient in to_recipient %} +
    • + {% if not S_EDIT_POST %} + + {% endif %} + {% if recipient.IS_GROUP %} + {{ recipient.NAME }} + {% else %} + {{ recipient.NAME_FULL }} + {% endif %} +
    • + {% endfor %} +
    +
    +
    + {% endif %} +
    + {% if bcc_recipient %} +
    +
    +
    +
    +
      + {% for recipient in bcc_recipient %} +
    • + {% if not S_EDIT_POST %} + + {% endif %} + {% if recipient.IS_GROUP %} + {{ recipient.NAME }} + {% else %} + {{ recipient.NAME_FULL }} + {% endif %} +
    • + {% endfor %} +
    +
    +
    +
    + {% endif %} + {% else %} +
    -
    -
    - -
    +
    + + {% if not S_EDIT_POST %} +
    {{ lang('FIND_USERNAME') }} + {% endif %} +
    + {% if not S_EDIT_POST %} +
    + +
    + {% endif %} + {% if to_recipient %} +
    +
      + {% for recipient in to_recipient %} +
    • + {% if not S_EDIT_POST %} + + {% endif %} + {% if recipient.IS_GROUP %} + {{ recipient.NAME }} + {% else %} + {{ recipient.NAME_FULL }} + {% endif %} +
    • + {% endfor %} +
    +
    + {% endif %}
    - - -
    -
    -

    {L_FIND_USERNAME}
    - -
    - - -
    -
    - -
    -
    - - - -
    + {% endif %} + {% endif %} +
    diff --git a/phpBB/styles/prosilver/template/posting_pm_layout.html b/phpBB/styles/prosilver/template/posting_pm_layout.html index 316fa791e45..9c9b3272015 100644 --- a/phpBB/styles/prosilver/template/posting_pm_layout.html +++ b/phpBB/styles/prosilver/template/posting_pm_layout.html @@ -34,7 +34,7 @@

    {L_TITLE}

    - + diff --git a/phpBB/styles/prosilver/template/posting_poll_body.html b/phpBB/styles/prosilver/template/posting_poll_body.html index ee7100aded5..795649650dd 100644 --- a/phpBB/styles/prosilver/template/posting_poll_body.html +++ b/phpBB/styles/prosilver/template/posting_poll_body.html @@ -15,8 +15,8 @@
    -
    -
    +
    +

    {L_POLL_OPTIONS_EXPLAIN}
    diff --git a/phpBB/styles/prosilver/template/posting_preview.html b/phpBB/styles/prosilver/template/posting_preview.html index aac117c090f..781d0de06b9 100644 --- a/phpBB/styles/prosilver/template/posting_preview.html +++ b/phpBB/styles/prosilver/template/posting_preview.html @@ -31,6 +31,8 @@

    {L_PREVIEW}{L_COLON} {PREVIEW_SUBJECT}

    {PREVIEW_MESSAGE}
    + +
    {L_ATTACHMENTS}
    diff --git a/phpBB/styles/prosilver/template/posting_review.html b/phpBB/styles/prosilver/template/posting_review.html index 1304046b23b..86151430709 100644 --- a/phpBB/styles/prosilver/template/posting_review.html +++ b/phpBB/styles/prosilver/template/posting_review.html @@ -6,23 +6,24 @@

    {L_POST_REVIEW}

    - {post_review_row.L_IGNORE_POST} + {post_review_row.L_IGNORE_POST}
    + {{ lang('POST_DISPLAY') }}
    -

    {post_review_row.POST_SUBJECT}

    +

    {post_review_row.POST_SUBJECT}

    - {post_review_row.MINI_POST} + {{ Icon('font', 'file', post_review_row.MINI_POST, true, 'fas c-topic-icon') }} - {post_review_row.MINI_POST} + {{ Icon('font', 'file', post_review_row.MINI_POST, true, 'fas c-topic-icon') }} - {L_POST_BY_AUTHOR} {post_review_row.POST_AUTHOR_FULL} » {post_review_row.POST_DATE} + {L_POST_BY_AUTHOR} {post_review_row.POST_AUTHOR_FULL} » {post_review_row.POST_DATE}

    {post_review_row.MESSAGE}
    diff --git a/phpBB/styles/prosilver/template/posting_smilies.html b/phpBB/styles/prosilver/template/posting_smilies.html index 54e82a58bc9..b5794d5afff 100644 --- a/phpBB/styles/prosilver/template/posting_smilies.html +++ b/phpBB/styles/prosilver/template/posting_smilies.html @@ -1,10 +1,8 @@ - diff --git a/phpBB/styles/prosilver/template/posting_topic_review.html b/phpBB/styles/prosilver/template/posting_topic_review.html index 857c6867748..7d602b2ccc9 100644 --- a/phpBB/styles/prosilver/template/posting_topic_review.html +++ b/phpBB/styles/prosilver/template/posting_topic_review.html @@ -5,42 +5,42 @@

    -
    - {topic_review_row.L_IGNORE_POST} + {topic_review_row.L_IGNORE_POST}
    + {{ lang('POST_DISPLAY') }}
    - {topic_review_row.L_DELETE_POST} + {topic_review_row.L_DELETE_POST}
    + {{ lang('POST_DISPLAY') }}
    -

    {topic_review_row.POST_SUBJECT}

    +

    {topic_review_row.POST_SUBJECT}

    @@ -93,7 +96,7 @@

    {L_SEARCH_OPTIONS}

    - {S_HIDDEN_FIELDS}  + {S_HIDDEN_FIELDS}
    diff --git a/phpBB/styles/prosilver/template/search_results.html b/phpBB/styles/prosilver/template/search_results.html index 6bc5c72a879..9e8a3c3e9bd 100644 --- a/phpBB/styles/prosilver/template/search_results.html +++ b/phpBB/styles/prosilver/template/search_results.html @@ -10,13 +10,13 @@

    {SEARCH_TITLE} @@ -32,10 +32,10 @@

    {SEARCH_TITLE}{SEARCH_TITLE}{SEARCH_TITLE}
  • -
    - style="background-image: url({T_ICONS_PATH}{searchresults.TOPIC_ICON_IMG}); background-repeat: no-repeat;" title="{searchresults.TOPIC_FOLDER_IMG_ALT}"> - +
    +
    + {% if searchresults.U_NEWEST_POST and searchresults.S_UNREAD_TOPIC and not S_IS_BOT %} + {% set U_ITEM_LINK = searchresults.U_NEWEST_POST %} + {% elseif searchresults.U_VIEW_TOPIC %} + {% set U_ITEM_LINK = searchresults.U_VIEW_TOPIC %} + {% endif %} + {% if U_ITEM_LINK is defined %} + + {{ Icon('svg', { + 'globe' : searchresults.S_POST_GLOBAL, + 'bullhorn' : searchresults.S_POST_ANNOUNCE, + 'thumbtack' : searchresults.S_POST_STICKY, + 'lock' : searchresults.S_TOPIC_LOCKED, + 'arrow-right-bold' : searchresults.S_TOPIC_MOVED, + 'fire' : searchresults.S_TOPIC_HOT, + 'file-document-outline' : true, + }, '', true, 'c-forum-row-icon') }} + + {% else %} + + {{ Icon('svg', { + 'globe' : searchresults.S_POST_GLOBAL, + 'bullhorn' : searchresults.S_POST_ANNOUNCE, + 'thumbtack' : searchresults.S_POST_STICKY, + 'lock' : searchresults.S_TOPIC_LOCKED, + 'arrow-right-bold' : searchresults.S_TOPIC_MOVED, + 'fire' : searchresults.S_TOPIC_HOT, + 'file-document-outline' : true, + }, '', true, 'c-forum-row-icon') }} + + {% endif %} + {% if lang(searchresults.TOPIC_AUTHOR) == S_USERNAME %} + + {% endif%} + {% if searchresults.TOPIC_ICON_IMG and S_TOPIC_ICONS %} + + {% endif %}
    - - - {L_NEW_POST} - - - {searchresults.TOPIC_TITLE} + {% if searchresults.U_NEWEST_POST and searchresults.S_UNREAD_TOPIC and not S_IS_BOT %} + {{ searchresults.TOPIC_TITLE }} + {% elseif searchresults.U_VIEW_TOPIC %} + {{ searchresults.TOPIC_TITLE }} + {% else %} + {{ searchresults.TOPIC_TITLE }} + {% endif %} - {L_TOPIC_UNAPPROVED} + {{ Icon('font', 'circle-question', lang('TOPIC_UNAPPROVED'), true, 'fas c-unapproved-icon') }} - {L_TOPIC_DELETED} + {{ Icon('font', 'recycle', lang('TOPIC_DELETED'), true, 'fas c-topic-deleted-icon') }} - {L_TOPIC_REPORTED} + {{ Icon('font', 'triangle-exclamation', lang('TOPIC_REPORTED'), true, 'fas c-topic-reported-icon') }}
    @@ -108,21 +145,23 @@

    {SEARCH_TITLE}
    - - - {L_POST_BY_AUTHOR} {searchresults.TOPIC_AUTHOR_FULL} » {searchresults.FIRST_POST_TIME} » {L_IN} {searchresults.FORUM_TITLE} + {{ Icon('font', 'chart-bar', '', true) }} + {{ Icon('font', 'paperclip', '', true) }} + {% EVENT topiclist_row_topic_by_author_before %} + {L_POST_BY_AUTHOR} {searchresults.TOPIC_AUTHOR_FULL} » » {L_IN} {searchresults.FORUM_TITLE} + {% EVENT topiclist_row_topic_by_author_after %}

  • @@ -181,7 +221,7 @@

    {SEARCH_TITLE}
    -
    {L_POST_BY_AUTHOR} {searchresults.POST_AUTHOR_FULL}
    +
    {L_POST_BY_AUTHOR} {searchresults.POST_AUTHOR_FULL}
    {searchresults.POST_DATE}
    {L_FORUM}{L_COLON} {searchresults.FORUM_TITLE}
    {L_TOPIC}{L_COLON} {searchresults.TOPIC_TITLE}
    @@ -192,8 +232,10 @@

    {SEARCH_TITLE}

    @@ -201,7 +243,7 @@

    {searchresults.POST_SUBJECT}

    @@ -220,7 +262,7 @@

    {searchresults.POST_SUBJECT}

    - + @@ -235,7 +277,7 @@

    {searchresults.POST_SUBJECT}

    - +{% EVENT search_results_jumpbox_before %} diff --git a/phpBB/styles/prosilver/template/simple_footer.html b/phpBB/styles/prosilver/template/simple_footer.html index a3b7439c4f8..b5f7894581c 100644 --- a/phpBB/styles/prosilver/template/simple_footer.html +++ b/phpBB/styles/prosilver/template/simple_footer.html @@ -1,8 +1,19 @@ - - - - + + + +{% if S_ALLOW_CDN %} + +{% endif %} - {$SCRIPTS} +{% EVENT simple_footer_body_after %} + diff --git a/phpBB/styles/prosilver/template/simple_header.html b/phpBB/styles/prosilver/template/simple_header.html index d7a6e050e96..d0ab4e77b16 100644 --- a/phpBB/styles/prosilver/template/simple_header.html +++ b/phpBB/styles/prosilver/template/simple_header.html @@ -17,7 +17,7 @@ (function(d) { var wf = d.createElement('script'), s = d.scripts[0]; - wf.src = 'https://ajax.googleapis.com/ajax/libs/webfont/1.5.18/webfont.js'; + wf.src = 'https://cdn.jsdelivr.net/npm/webfontloader@1.6.28/webfontloader.min.js'; wf.async = true; s.parentNode.insertBefore(wf, s); })(document); @@ -27,10 +27,6 @@ - - - - diff --git a/phpBB/styles/prosilver/template/timezone.js b/phpBB/styles/prosilver/template/timezone.js index 44ec1b0979c..5e6c0942cd9 100644 --- a/phpBB/styles/prosilver/template/timezone.js +++ b/phpBB/styles/prosilver/template/timezone.js @@ -1,20 +1,18 @@ /* global phpbb */ (function($) { // Avoid conflicts with other libraries + 'use strict'; -'use strict'; + $('#tz_date').change(() => { + phpbb.timezoneSwitchDate(false); + }); -$('#tz_date').change(function() { - phpbb.timezoneSwitchDate(false); -}); - -$('#tz_select_date_suggest').click(function(){ - phpbb.timezonePreselectSelect(true); -}); - -$(function () { - phpbb.timezoneEnableDateSelection(); - phpbb.timezonePreselectSelect($('#tz_select_date_suggest').attr('timezone-preselect') === 'true'); -}); + $('#tz_select_date_suggest').click(() => { + phpbb.timezonePreselectSelect(true); + }); + $(() => { + phpbb.timezoneEnableDateSelection(); + phpbb.timezonePreselectSelect($('#tz_select_date_suggest').attr('timezone-preselect') === 'true'); + }); })(jQuery); // Avoid conflicts with other libraries diff --git a/phpBB/styles/prosilver/template/timezone_option.html b/phpBB/styles/prosilver/template/timezone_option.html index 01786d5ef43..0c7be8de74c 100644 --- a/phpBB/styles/prosilver/template/timezone_option.html +++ b/phpBB/styles/prosilver/template/timezone_option.html @@ -1,28 +1,16 @@
    -
    - -
    + {% if TIMEZONE_OPTIONS %} +
    + {% set tz_date_data = TIMEZONE_OPTIONS | merge({ options: [{ value: "", label: lang('SELECT_CURRENT_TIME') }] | merge(TIMEZONE_OPTIONS.options) }) %} + {{ FormsSelect(tz_date_data | merge({class: 'autowidth tz_select', id: 'tz_date', name: 'tz_date', group_only: true})) }}
    - + {% endif %}
    - + {% set tz_select_data = TIMEZONE_OPTIONS | merge({ options: [{ value: "", label: lang('SELECT_TIMEZONE') }] | merge(TIMEZONE_OPTIONS.options) }) %} + {{ FormsSelect(tz_select_data | merge({class: 'autowidth tz_select', id: 'timezone'})) }} - + {% INCLUDEJS('timezone.js') %}
    diff --git a/phpBB/styles/prosilver/template/ucp_agreement.html b/phpBB/styles/prosilver/template/ucp_agreement.html index 57f902df622..94d280a31ad 100644 --- a/phpBB/styles/prosilver/template/ucp_agreement.html +++ b/phpBB/styles/prosilver/template/ucp_agreement.html @@ -2,41 +2,38 @@ - - - +{% if LANG_OPTIONS %}

    - + + {{ FormsSelect(LANG_OPTIONS) }} {S_HIDDEN_FIELDS}

    - + +{% endif %}
    -

    {SITENAME} - {L_REGISTRATION}

    +

    {{ SITENAME }} - {{ lang('REGISTRATION') }}

    -

    {L_COPPA_BIRTHDAY}{L_TERMS_OF_USE}

    +
    {% if S_SHOW_COPPA %}

    {{ lang('COPPA_BIRTHDAY') }}

    {% else %}{{ lang('TERMS_OF_USE') }}{% endif %}
    @@ -46,7 +43,8 @@

    {SITENAME} - {L_REGISTRATION}

    - {L_COPPA_NO}  {L_COPPA_YES} + +   @@ -63,10 +61,8 @@

    {SITENAME} - {L_REGISTRATION}

    -

    {SITENAME} - {AGREEMENT_TITLE}

    -

    {AGREEMENT_TEXT}

    -
    -

    {L_BACK}

    +

    {{ SITENAME }} - {{ AGREEMENT_TITLE }}

    +
    {{ AGREEMENT_TEXT }}
    diff --git a/phpBB/styles/prosilver/template/ucp_attachments.html b/phpBB/styles/prosilver/template/ucp_attachments.html index c13ef0713a7..2e588da8923 100644 --- a/phpBB/styles/prosilver/template/ucp_attachments.html +++ b/phpBB/styles/prosilver/template/ucp_attachments.html @@ -10,7 +10,7 @@

    {L_TITLE}

    {L_ATTACHMENTS_EXPLAIN}

    -
    +
    -
    +
    {S_FORM_TOKEN}
    -  
    diff --git a/phpBB/styles/prosilver/template/ucp_avatar_options_remote.html b/phpBB/styles/prosilver/template/ucp_avatar_options_remote.html deleted file mode 100644 index 8e175623ac9..00000000000 --- a/phpBB/styles/prosilver/template/ucp_avatar_options_remote.html +++ /dev/null @@ -1,11 +0,0 @@ -
    -

    {L_LINK_REMOTE_AVATAR_EXPLAIN}
    -
    -
    -
    -

    {L_LINK_REMOTE_SIZE_EXPLAIN}
    -
    - ×  - -
    -
    diff --git a/phpBB/styles/prosilver/template/ucp_avatar_options_upload.html b/phpBB/styles/prosilver/template/ucp_avatar_options_upload.html index 63a734ea7dd..38bb016de26 100644 --- a/phpBB/styles/prosilver/template/ucp_avatar_options_upload.html +++ b/phpBB/styles/prosilver/template/ucp_avatar_options_upload.html @@ -1,11 +1,69 @@
    -
    +
    - -
    -

    {L_UPLOAD_AVATAR_URL_EXPLAIN}
    -
    -
    - +{% INCLUDECSS T_ASSETS_PATH ~ '/css/cropper.min.css' %} +{% INCLUDEJS T_ASSETS_PATH ~ '/javascript/cropper.min.js' %} +{% INCLUDEJS T_ASSETS_PATH ~ '/javascript/jquery-cropper.js' %} +{% INCLUDEJS T_ASSETS_PATH ~ '/javascript/hermite.js' %} +{% INCLUDEJS T_ASSETS_PATH ~ '/javascript/phpbb-avatars.js' %} + + + +{% apply spaceless %} +
    +
    + + +
    + +
    + + + + +
    + +
    + + +
    + +
    + + +
    + +
    + + +
    +
    +{% endapply %} diff --git a/phpBB/styles/prosilver/template/ucp_footer.html b/phpBB/styles/prosilver/template/ucp_footer.html index eb07f52e059..e64dd0a4e9e 100644 --- a/phpBB/styles/prosilver/template/ucp_footer.html +++ b/phpBB/styles/prosilver/template/ucp_footer.html @@ -1,6 +1,6 @@
    - + {% EVENT ucp_footer_content_after %}
    diff --git a/phpBB/styles/prosilver/template/ucp_groups_manage.html b/phpBB/styles/prosilver/template/ucp_groups_manage.html index 514f12562a8..c593ea94dc2 100644 --- a/phpBB/styles/prosilver/template/ucp_groups_manage.html +++ b/phpBB/styles/prosilver/template/ucp_groups_manage.html @@ -1,6 +1,6 @@ - style="color:#{GROUP_COLOR};">{L_USERGROUPS} :: {GROUP_NAME} + style="color:#{GROUP_COLOUR};">{L_USERGROUPS} :: {GROUP_NAME} @@ -52,19 +52,21 @@

    {L_GROUP_DETAILS}

    {L_GROUP_SETTINGS_SAVE}

    +

    {L_GROUP_COLOR_EXPLAIN}
        [ {L_COLOUR_SWATCH} ] - +
    +
    @@ -74,7 +76,6 @@

    {L_GROUP_SETTINGS_SAVE}

    {S_HIDDEN_FIELDS} -   {S_FORM_TOKEN}
    diff --git a/phpBB/styles/prosilver/template/ucp_header.html b/phpBB/styles/prosilver/template/ucp_header.html index 9ebb404dd9d..95352e68583 100644 --- a/phpBB/styles/prosilver/template/ucp_header.html +++ b/phpBB/styles/prosilver/template/ucp_header.html @@ -69,11 +69,11 @@

    {L_UCP}

    {L_FRIENDS}
    -
    {friends_online.USERNAME_FULL}
    +
    {% EVENT ucp_header_friends_online_username_full_prepend %}{friends_online.USERNAME_FULL}{% EVENT ucp_header_friends_online_username_full_append %}
    -
    {friends_offline.USERNAME_FULL}
    +
    {% EVENT ucp_header_friends_offline_username_full_prepend %}{friends_offline.USERNAME_FULL}{% EVENT ucp_header_friends_offline_username_full_append %}
    @@ -98,4 +98,6 @@

    {L_UCP}

    + {% EVENT ucp_header_content_before %} +
    diff --git a/phpBB/styles/prosilver/template/ucp_login_link.html b/phpBB/styles/prosilver/template/ucp_login_link.html index 10d2d377ec1..fe2d667b4c5 100644 --- a/phpBB/styles/prosilver/template/ucp_login_link.html +++ b/phpBB/styles/prosilver/template/ucp_login_link.html @@ -32,11 +32,11 @@

    {L_LOGIN}

    {LOGIN_ERROR}
    -
    +
    -
    +
    diff --git a/phpBB/styles/prosilver/template/ucp_main_bookmarks.html b/phpBB/styles/prosilver/template/ucp_main_bookmarks.html index d14ae234257..6d0fd6933c7 100644 --- a/phpBB/styles/prosilver/template/ucp_main_bookmarks.html +++ b/phpBB/styles/prosilver/template/ucp_main_bookmarks.html @@ -34,46 +34,66 @@

    {L_TITLE}

    -
    - style="background-image: url({T_ICONS_PATH}{topicrow.TOPIC_ICON_IMG}); background-repeat: no-repeat;" title="{topicrow.TOPIC_FOLDER_IMG_ALT}"> - +
    +
    + + {{ Icon('svg', { + 'globe' : topicrow.S_POST_GLOBAL, + 'bullhorn' : topicrow.S_POST_ANNOUNCE, + 'thumbtack' : topicrow.S_POST_STICKY, + 'lock' : topicrow.S_TOPIC_LOCKED, + 'arrow-right-bold' : topicrow.S_TOPIC_MOVED, + 'fire' : topicrow.S_TOPIC_HOT, + 'file-document-outline' : true, + }, '', true, 'c-forum-row-icon') }} + + {% if lang(topicrow.TOPIC_AUTHOR) == S_USERNAME %} + + {% endif%} + {% if topicrow.TOPIC_ICON_IMG and S_TOPIC_ICONS %} + + {% endif %}
    - - - {NEW_POST} - - {topicrow.TOPIC_TITLE} + {% if topicrow.S_UNREAD_TOPIC %} + {{ topicrow.TOPIC_TITLE }} + {% else %} + {{ topicrow.TOPIC_TITLE }} + {% endif %} - {L_TOPIC_UNAPPROVED} + {{ Icon('font', 'circle-question', lang('TOPIC_UNAPPROVED'), true, 'fas c-unapproved-icon') }} - {L_TOPIC_REPORTED} + {{ Icon('font', 'triangle-exclamation', lang('TOPIC_REPORTED'), true, 'fas c-topic-reported-icon') }}
    + {% EVENT ucp_main_bookmarks_topic_title_after %}
    - + {{ Icon('font', 'paperclip', '', true) }} {L_POST_BY_AUTHOR} {topicrow.TOPIC_AUTHOR_FULL} » {topicrow.FIRST_POST_TIME}
    @@ -81,7 +101,7 @@

    {L_TITLE}

    {L_LAST_POST} {L_POST_BY_AUTHOR} {topicrow.LAST_POST_AUTHOR_FULL} - {VIEW_LATEST_POST} + {{ Icon('font', 'arrow-up-right-from-square', VIEW_LATEST_POST, true, 'fas c-last-post-icon') }}
    {topicrow.LAST_POST_TIME}
    diff --git a/phpBB/styles/prosilver/template/ucp_main_drafts.html b/phpBB/styles/prosilver/template/ucp_main_drafts.html index 25eb5ce2d1a..2cf99b963c5 100644 --- a/phpBB/styles/prosilver/template/ucp_main_drafts.html +++ b/phpBB/styles/prosilver/template/ucp_main_drafts.html @@ -16,7 +16,7 @@

    {L_TITLE}

    - {S_HIDDEN_FIELDS}  + {S_HIDDEN_FIELDS} {S_FORM_TOKEN}
    diff --git a/phpBB/styles/prosilver/template/ucp_main_front.html b/phpBB/styles/prosilver/template/ucp_main_front.html index 04b568f6237..1276b387385 100644 --- a/phpBB/styles/prosilver/template/ucp_main_front.html +++ b/phpBB/styles/prosilver/template/ucp_main_front.html @@ -13,36 +13,56 @@

    {L_IMPORTANT_NEWS}

    diff --git a/phpBB/styles/prosilver/template/ucp_profile_reg_details.html b/phpBB/styles/prosilver/template/ucp_profile_reg_details.html index 8d7c6728a77..9600f2fa8eb 100644 --- a/phpBB/styles/prosilver/template/ucp_profile_reg_details.html +++ b/phpBB/styles/prosilver/template/ucp_profile_reg_details.html @@ -50,7 +50,7 @@

    {L_TITLE}

    - {S_HIDDEN_FIELDS}  + {S_HIDDEN_FIELDS} {S_FORM_TOKEN}
    diff --git a/phpBB/styles/prosilver/template/ucp_profile_signature.html b/phpBB/styles/prosilver/template/ucp_profile_signature.html index 41bd3ee2c67..6825598a6f4 100644 --- a/phpBB/styles/prosilver/template/ucp_profile_signature.html +++ b/phpBB/styles/prosilver/template/ucp_profile_signature.html @@ -24,6 +24,7 @@

    {L_SIGNATURE_PREVIEW}

    {L_OPTIONS}

    + {% EVENT ucp_profile_signature_posting_editor_options_prepend %}
    @@ -41,7 +42,6 @@

    {L_OPTIONS}

    {S_HIDDEN_FIELDS} -     {S_FORM_TOKEN} diff --git a/phpBB/styles/prosilver/template/ucp_register.html b/phpBB/styles/prosilver/template/ucp_register.html index 0b9897abf6b..73cfa836dfa 100644 --- a/phpBB/styles/prosilver/template/ucp_register.html +++ b/phpBB/styles/prosilver/template/ucp_register.html @@ -1,7 +1,6 @@ - +{% if PROVIDER_TEMPLATE_FILE %} +
    +
    + +

    {{ SITENAME }} - {{ lang('OAUTH_REGISTRATION') }}

    + + {% include PROVIDER_TEMPLATE_FILE %} +
    +
    +{% endif %} +
    @@ -29,35 +38,47 @@

    {SITENAME} - {L_REGISTRATION}


    {L_USERNAME_EXPLAIN}
    -
    -
    -
    -
    -
    +

    {L_PASSWORD_EXPLAIN}
    -
    +
    -
    +
    +
    +
    +
    +

    + {% if LANG_OPTIONS %}
    -
    -
    +
    +
    + {{ FormsSelect(LANG_OPTIONS) }} +
    + + {% endif %} - -
    {L_ITEMS_REQUIRED}
    + {% if PROFILE_FIELDS_REQUIRED %}
    {L_ITEMS_REQUIRED}
    {% endif %}
    @@ -67,7 +88,6 @@

    {SITENAME} - {L_REGISTRATION}

    {profile_fields.FIELD}
    -
    @@ -96,7 +116,6 @@

    {L_COPPA_COMPLIANCE}

    {S_HIDDEN_FIELDS} -   {S_FORM_TOKEN}
    diff --git a/phpBB/styles/prosilver/template/ucp_remind.html b/phpBB/styles/prosilver/template/ucp_remind.html deleted file mode 100644 index 57d5d5a2604..00000000000 --- a/phpBB/styles/prosilver/template/ucp_remind.html +++ /dev/null @@ -1,32 +0,0 @@ - - - - -
    -
    - -
    -

    {L_SEND_PASSWORD}

    - -
    -
    -
    -
    -
    -
    -

    {L_EMAIL_REMIND}
    -
    -
    -
    -
     
    -
    {S_HIDDEN_FIELDS} 
    -
    - {S_FORM_TOKEN} -
    -
    - -
    -
    - - - diff --git a/phpBB/styles/prosilver/template/ucp_resend.html b/phpBB/styles/prosilver/template/ucp_resend.html index 48827d811bb..5909e0b8505 100644 --- a/phpBB/styles/prosilver/template/ucp_resend.html +++ b/phpBB/styles/prosilver/template/ucp_resend.html @@ -20,7 +20,7 @@

    {L_UCP_RESEND}

     
    -
    {S_HIDDEN_FIELDS}{S_FORM_TOKEN} 
    +
    {S_HIDDEN_FIELDS}{S_FORM_TOKEN}
    diff --git a/phpBB/styles/prosilver/template/ucp_reset_password.html b/phpBB/styles/prosilver/template/ucp_reset_password.html new file mode 100644 index 00000000000..5a9a0a3ab89 --- /dev/null +++ b/phpBB/styles/prosilver/template/ucp_reset_password.html @@ -0,0 +1,49 @@ + + +
    + +
    +
    + +
    +

    {{ lang('RESET_PASSWORD') }}

    + +
    + {% if S_IS_PASSWORD_RESET %} + {% if PASSWORD_RESET_ERRORS %}

    {{ PASSWORD_RESET_ERRORS | join('
    ') }}

    {% endif %} +
    +

    {{ lang('CHANGE_PASSWORD_EXPLAIN') }}
    +
    +
    +
    +
    +
    +
    + {% else %} + {% if USERNAME_REQUIRED %} +

    {{ lang('EMAIL_NOT_UNIQUE') }}

    + {% endif %} +
    +

    {{ lang('EMAIL_REMIND') }}
    +
    +
    + {% if USERNAME_REQUIRED %} +
    +
    +
    +
    + {% endif %} + {% endif %} +
    +
     
    +
    {{ S_HIDDEN_FIELDS }}
    +
    + {{ S_FORM_TOKEN }} +
    +
    + +
    +
    +
    + + diff --git a/phpBB/styles/prosilver/template/ucp_zebra_foes.html b/phpBB/styles/prosilver/template/ucp_zebra_foes.html index efd7a0613d8..0c726ec887e 100644 --- a/phpBB/styles/prosilver/template/ucp_zebra_foes.html +++ b/phpBB/styles/prosilver/template/ucp_zebra_foes.html @@ -32,7 +32,7 @@

    {L_TITLE}

    - {S_HIDDEN_FIELDS}  + {S_HIDDEN_FIELDS} {S_FORM_TOKEN}
    diff --git a/phpBB/styles/prosilver/template/ucp_zebra_friends.html b/phpBB/styles/prosilver/template/ucp_zebra_friends.html index 1478fb9546f..14fb46cbcc3 100644 --- a/phpBB/styles/prosilver/template/ucp_zebra_friends.html +++ b/phpBB/styles/prosilver/template/ucp_zebra_friends.html @@ -34,7 +34,7 @@

    {L_TITLE}

    - {S_HIDDEN_FIELDS}  + {S_HIDDEN_FIELDS} {S_FORM_TOKEN}
    diff --git a/phpBB/styles/prosilver/template/viewforum_body.html b/phpBB/styles/prosilver/template/viewforum_body.html index 2113c6d7c5f..63750e32186 100644 --- a/phpBB/styles/prosilver/template/viewforum_body.html +++ b/phpBB/styles/prosilver/template/viewforum_body.html @@ -42,9 +42,9 @@

    - {L_BUTTON_FORUM_LOCKED} + {L_BUTTON_FORUM_LOCKED} {{ Icon('font', 'lock', '', true, 'fas c-button-icon') }} - {L_BUTTON_NEW_TOPIC} + {L_BUTTON_NEW_TOPIC} {{ Icon('font', 'pencil', '', true, 'fas c-button-icon') }} @@ -56,10 +56,10 @@

    - - {L_SEARCH_ADV} + + {{ Icon('font', 'gear', lang('SEARCH_ADV'), true, 'fas c-button-icon') }} {S_SEARCH_LOCAL_HIDDEN_FIELDS}

    @@ -101,12 +101,12 @@

    {L_LOGIN_LOGOUT}
    +
    +
    @@ -114,6 +114,7 @@

    {L_LOGIN_LOGOUT}
  • -
    - style="background-image: url({T_ICONS_PATH}{topicrow.TOPIC_ICON_IMG}); background-repeat: no-repeat;" title="{topicrow.TOPIC_FOLDER_IMG_ALT}"> - +
    +
    + {% if topicrow.U_NEWEST_POST and topicrow.S_UNREAD_TOPIC and not S_IS_BOT %} + {% set U_ITEM_LINK = topicrow.U_NEWEST_POST %} + {% elseif topicrow.U_VIEW_TOPIC %} + {% set U_ITEM_LINK = topicrow.U_VIEW_TOPIC %} + {% endif %} + {% if U_ITEM_LINK is defined %} + + {{ Icon('svg', { + 'globe' : topicrow.S_POST_GLOBAL, + 'bullhorn' : topicrow.S_POST_ANNOUNCE, + 'thumbtack' : topicrow.S_POST_STICKY, + 'lock' : topicrow.S_TOPIC_LOCKED, + 'arrow-right-bold' : topicrow.S_TOPIC_MOVED, + 'fire' : topicrow.S_TOPIC_HOT, + 'file-document-outline' : true, + }, '', true, 'c-forum-row-icon') }} + + {% else %} + + {{ Icon('svg', { + 'globe' : topicrow.S_POST_GLOBAL, + 'bullhorn' : topicrow.S_POST_ANNOUNCE, + 'thumbtack' : topicrow.S_POST_STICKY, + 'lock' : topicrow.S_TOPIC_LOCKED, + 'arrow-right-bold' : topicrow.S_TOPIC_MOVED, + 'fire' : topicrow.S_TOPIC_HOT, + 'file-document-outline' : true, + }, '', true, 'c-forum-row-icon') }} + + {% endif %} + {% if lang(topicrow.TOPIC_AUTHOR) == S_USERNAME %} + + {% endif%} + {% if topicrow.TOPIC_ICON_IMG and S_TOPIC_ICONS %} + + {% endif %}
    - - - {NEW_POST} - - - {topicrow.TOPIC_TITLE}{topicrow.TOPIC_TITLE} + {% if topicrow.U_NEWEST_POST and topicrow.S_UNREAD_TOPIC and not S_IS_BOT %} + {{ topicrow.TOPIC_TITLE }} + {% elseif topicrow.U_VIEW_TOPIC %} + {{ topicrow.TOPIC_TITLE }} + {% else %} + {{ topicrow.TOPIC_TITLE }} + {% endif %} - {L_TOPIC_UNAPPROVED}{L_POSTS_UNAPPROVED} + {{ Icon('font', 'circle-question', '', true, 'fas c-unapproved-icon o-icon-baseline') }}{L_TOPIC_UNAPPROVED}{L_POSTS_UNAPPROVED} - {L_TOPIC_DELETED} + {{ Icon('font', 'recycle', lang('TOPIC_DELETED'), true, 'fas c-topic-deleted-icon o-icon-baseline') }} - {L_TOPIC_REPORTED} + {{ Icon('font', 'triangle-exclamation', lang('TOPIC_REPORTED'), true, 'fas c-topic-reported-icon o-icon-baseline') }}
    @@ -186,7 +223,7 @@

    {L_LOGIN_LOGOUT} @@ -195,24 +232,29 @@

    {L_LOGIN_LOGOUT}
    - - - {L_POST_BY_AUTHOR} {topicrow.TOPIC_AUTHOR_FULL} » {topicrow.FIRST_POST_TIME} + {{ Icon('font', 'chart-bar', '', true) }} + {{ Icon('font', 'paperclip', '', true) }} + {% EVENT topiclist_row_topic_by_author_before %} + {L_POST_BY_AUTHOR} {topicrow.TOPIC_AUTHOR_FULL} » + {% EVENT topiclist_row_topic_by_author_after %} » {L_IN} {topicrow.FORUM_NAME}
    @@ -223,13 +265,13 @@

    {L_LOGIN_LOGOUT}{topicrow.LAST_POST_AUTHOR_FULL} - {VIEW_LATEST_POST} + {{ Icon('font', 'arrow-up-right-from-square', VIEW_LATEST_POST, true, 'fas c-last-post-icon') }} -
    {topicrow.LAST_POST_TIME} +

    @@ -247,7 +289,7 @@

    {L_LOGIN_LOGOUT}
    - {L_NO_TOPICS} + {{ lang(S_SORT_DAYS ? 'NO_TOPICS_TIME_FRAME' : 'NO_TOPICS') }}
    @@ -266,9 +308,9 @@

    {L_LOGIN_LOGOUT}{L_FORUM_LOCKED}{L_POST_TOPIC}"> - {L_BUTTON_FORUM_LOCKED} + {L_BUTTON_FORUM_LOCKED} {{ Icon('font', 'lock', '', true, 'fas c-button-icon') }} - {L_BUTTON_NEW_TOPIC} + {L_BUTTON_NEW_TOPIC} {{ Icon('font', 'pencil', '', true, 'fas c-button-icon') }} @@ -295,6 +337,8 @@

    {L_LOGIN_LOGOUT} +{% EVENT viewforum_body_online_list_before %} +

    {L_WHO_IS_ONLINE}

    @@ -302,7 +346,7 @@

    {L_WHO_IS_ONLINE}

    - +

    {L_FORUM_PERMISSIONS}

    {rules.RULE}

    diff --git a/phpBB/styles/prosilver/template/viewonline_body.html b/phpBB/styles/prosilver/template/viewonline_body.html index dd0ca72502a..acbfb71ba55 100644 --- a/phpBB/styles/prosilver/template/viewonline_body.html +++ b/phpBB/styles/prosilver/template/viewonline_body.html @@ -29,7 +29,7 @@

    {TOTAL_REGISTERED_USERS_ONLINE}

    - {user_row.USERNAME_FULL} {L_IP}{L_COLON} {user_row.USER_IP} » {L_WHOIS} + {user_row.USERNAME_FULL} {L_IP}{L_COLON} {user_row.USER_IP} » {L_WHOIS}
    {user_row.USER_BROWSER} {user_row.FORUM_LOCATION} {user_row.LASTUPDATE} @@ -47,7 +47,22 @@

    {TOTAL_REGISTERED_USERS_ONLINE}

    -

    {L_LEGEND}{L_COLON} {LEGEND}

    +{% if LEGEND|length > 0 %} + {% apply spaceless %} +

    + + {{ lang('LEGEND') ~ lang('COLON') }} + {% for group in LEGEND %} + {% if group.GROUP_URL %} + {{ group.GROUP_NAME }}{% if not loop.last %}, {% endif %} + {% else %} + {{ group.GROUP_NAME }}{% if not loop.last %}, {% endif %} + {% endif %} + {% endfor %} + +

    + {% endapply %} +{% endif %}

  • @@ -77,7 +77,7 @@

    +
    @@ -140,21 +140,22 @@

    {POLL_
    style="display: none;"> -
    +
    - {postrow.POST_AUTHOR_FULL}{postrow.POST_AUTHOR_FULL} {L_ONLINE} + {postrow.POST_AUTHOR_FULL}{postrow.POST_AUTHOR_FULL} {{ Icon('font', 'circle', lang('ONLINE'), true, 'fas c-online-icon') }}
    -
    {postrow.RANK_TITLE}
    {postrow.RANK_IMG}
    + {% if postrow.RANK_IMG or postrow.RANK_TITLE %}
    {{ postrow.RANK_TITLE }}{% if postrow.RANK_IMG and postrow.RANK_TITLE %}
    {% endif %}{{ postrow.RANK_IMG }}
    {% endif %}
    {L_POSTS}{L_COLON} {postrow.POSTER_POSTS}
    @@ -180,7 +181,7 @@

    {POLL_ {L_CONTACT}{L_COLON}