diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index f16a793ece5b..e39d50b0b187 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -5,8 +5,9 @@ Each pull request should address a single issue and have a meaningful title. - PR title must include the type (feat, fix, chore, docs, perf, refactor, style, test) of the commit per Conventional Commits specification. See https://www.conventionalcommits.org/en/v1.0.0/ for the discussion. - Pull requests must be in English. - If a pull request fixes an issue, reference the issue with a suitable keyword (e.g., Fixes ). +- Your branch name and the target name should be different. - All bug fixes should be sent to the __"develop"__ branch, this is where the next bug fix version will be developed. -- PRs with any enhancement should be sent to the next minor version branch, e.g. __"4.5"__ +- PRs with any enhancement should be sent to the next minor version branch, e.g. __"4.7"__ --> **Description** @@ -14,7 +15,7 @@ Explain what you have changed, and why. **Checklist:** - [ ] Securely signed commits -- [ ] Component(s) with PHPDoc blocks, only if necessary or adds value +- [ ] Component(s) with PHPDoc blocks, only if necessary or adds value (without duplication) - [ ] Unit testing, with >80% coverage - [ ] User guide updated - [ ] Conforms to style guide diff --git a/.github/mergeable.yml b/.github/mergeable.yml index d20aa796f5d0..2e58526188aa 100644 --- a/.github/mergeable.yml +++ b/.github/mergeable.yml @@ -16,7 +16,7 @@ mergeable: regex: '### CodeIgniter4 Version' - do: author must_include: - regex: ^kenjis|lonnieezell|MGatner|michalsn|paulbalandan|samsonasik$ + regex: ^kenjis|lonnieezell|MGatner|michalsn|paulbalandan|samsonasik|ddevsr$ fail: - do: comment payload: diff --git a/.github/workflows/deploy-apidocs.yml b/.github/workflows/deploy-apidocs.yml index ca77c6a08c26..a660e33eb03c 100644 --- a/.github/workflows/deploy-apidocs.yml +++ b/.github/workflows/deploy-apidocs.yml @@ -29,12 +29,12 @@ jobs: git config --global user.name "${GITHUB_ACTOR}" - name: Checkout source - uses: actions/checkout@v4 + uses: actions/checkout@v6 with: path: source - name: Checkout target - uses: actions/checkout@v4 + uses: actions/checkout@v6 with: repository: codeigniter4/api token: ${{ secrets.ACCESS_TOKEN }} diff --git a/.github/workflows/deploy-distributables.yml b/.github/workflows/deploy-distributables.yml index 7c0b4e4dd1ce..e1a63e792ffa 100644 --- a/.github/workflows/deploy-distributables.yml +++ b/.github/workflows/deploy-distributables.yml @@ -16,7 +16,7 @@ jobs: steps: - name: Checkout - uses: actions/checkout@v4 + uses: actions/checkout@v6 with: fetch-depth: 0 # fetch all tags @@ -48,12 +48,12 @@ jobs: git config --global user.name "${GITHUB_ACTOR}" - name: Checkout source - uses: actions/checkout@v4 + uses: actions/checkout@v6 with: path: source - name: Checkout target - uses: actions/checkout@v4 + uses: actions/checkout@v6 with: repository: codeigniter4/framework token: ${{ secrets.ACCESS_TOKEN }} @@ -66,7 +66,7 @@ jobs: run: ./source/.github/scripts/deploy-framework ${GITHUB_WORKSPACE}/source ${GITHUB_WORKSPACE}/framework ${GITHUB_REF##*/} - name: Release - uses: actions/github-script@v7 + uses: actions/github-script@v8 with: github-token: ${{secrets.ACCESS_TOKEN}} script: | @@ -98,12 +98,12 @@ jobs: git config --global user.name "${GITHUB_ACTOR}" - name: Checkout source - uses: actions/checkout@v4 + uses: actions/checkout@v6 with: path: source - name: Checkout target - uses: actions/checkout@v4 + uses: actions/checkout@v6 with: repository: codeigniter4/appstarter token: ${{ secrets.ACCESS_TOKEN }} @@ -116,7 +116,7 @@ jobs: run: ./source/.github/scripts/deploy-appstarter ${GITHUB_WORKSPACE}/source ${GITHUB_WORKSPACE}/appstarter ${GITHUB_REF##*/} - name: Release - uses: actions/github-script@v7 + uses: actions/github-script@v8 with: github-token: ${{secrets.ACCESS_TOKEN}} script: | @@ -148,19 +148,19 @@ jobs: git config --global user.name "${GITHUB_ACTOR}" - name: Checkout source - uses: actions/checkout@v4 + uses: actions/checkout@v6 with: path: source - name: Checkout target - uses: actions/checkout@v4 + uses: actions/checkout@v6 with: repository: codeigniter4/userguide token: ${{ secrets.ACCESS_TOKEN }} path: userguide - name: Setup Python - uses: actions/setup-python@v5 + uses: actions/setup-python@v6 with: python-version: '3.12' @@ -176,7 +176,7 @@ jobs: run: ./source/.github/scripts/deploy-userguide ${GITHUB_WORKSPACE}/source ${GITHUB_WORKSPACE}/userguide ${GITHUB_REF##*/} - name: Release - uses: actions/github-script@v7 + uses: actions/github-script@v8 with: github-token: ${{secrets.ACCESS_TOKEN}} script: | diff --git a/.github/workflows/deploy-userguide-latest.yml b/.github/workflows/deploy-userguide-latest.yml index 9188672f907a..5365d4e94d78 100644 --- a/.github/workflows/deploy-userguide-latest.yml +++ b/.github/workflows/deploy-userguide-latest.yml @@ -25,7 +25,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout - uses: actions/checkout@v4 + uses: actions/checkout@v6 - name: Setup PHP uses: shivammathur/setup-php@v2 @@ -34,7 +34,7 @@ jobs: coverage: none - name: Setup Python - uses: actions/setup-python@v5 + uses: actions/setup-python@v6 with: python-version: '3.12' @@ -57,7 +57,7 @@ jobs: # Create an artifact of the html output - name: Upload artifact - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@v5 with: name: HTML Documentation path: user_guide_src/build/html/ @@ -75,7 +75,7 @@ jobs: git commit -m "Update User Guide" -a || true - name: Push changes - uses: ad-m/github-push-action@v0.6.0 + uses: ad-m/github-push-action@v1.0.0 with: branch: gh-pages directory: gh-pages diff --git a/.github/workflows/label-add-conflict-all-pr.yml b/.github/workflows/label-add-conflict-all-pr.yml index e83e4daf0b99..16467abd161c 100644 --- a/.github/workflows/label-add-conflict-all-pr.yml +++ b/.github/workflows/label-add-conflict-all-pr.yml @@ -17,7 +17,7 @@ jobs: runs-on: ubuntu-22.04 steps: - name: Checkout - uses: actions/checkout@v4 + uses: actions/checkout@v6 - name: Get PR List id: PR-list diff --git a/.github/workflows/label-signing.yml b/.github/workflows/label-signing.yml index 389ad8844411..5f6b99290e89 100644 --- a/.github/workflows/label-signing.yml +++ b/.github/workflows/label-signing.yml @@ -19,7 +19,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout - uses: actions/checkout@v4 + uses: actions/checkout@v6 - name: Check signed commits in PR uses: 1Password/check-signed-commits-action@v1 diff --git a/.github/workflows/reusable-coveralls.yml b/.github/workflows/reusable-coveralls.yml index b3fcd09484fc..0625e042bad8 100644 --- a/.github/workflows/reusable-coveralls.yml +++ b/.github/workflows/reusable-coveralls.yml @@ -15,12 +15,12 @@ jobs: steps: - name: Checkout base branch for PR if: github.event_name == 'pull_request' - uses: actions/checkout@v4 + uses: actions/checkout@v6 with: ref: ${{ github.base_ref }} - name: Checkout - uses: actions/checkout@v4 + uses: actions/checkout@v6 - name: Setup PHP uses: shivammathur/setup-php@v2 @@ -30,7 +30,7 @@ jobs: coverage: xdebug - name: Download coverage files - uses: actions/download-artifact@v4 + uses: actions/download-artifact@v6 with: path: build/cov diff --git a/.github/workflows/reusable-phpunit-test.yml b/.github/workflows/reusable-phpunit-test.yml index cf23be58f2bc..3ce33ecb7000 100644 --- a/.github/workflows/reusable-phpunit-test.yml +++ b/.github/workflows/reusable-phpunit-test.yml @@ -150,12 +150,12 @@ jobs: - name: Checkout base branch for PR if: github.event_name == 'pull_request' - uses: actions/checkout@v4 + uses: actions/checkout@v6 with: ref: ${{ github.base_ref }} - name: Checkout - uses: actions/checkout@v4 + uses: actions/checkout@v6 - name: Setup PHP uses: shivammathur/setup-php@v2 @@ -212,7 +212,7 @@ jobs: - name: Upload coverage results as artifact if: ${{ inputs.enable-artifact-upload }} - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@v5 with: name: ${{ env.ARTIFACT_NAME }} path: build/cov/coverage-${{ env.ARTIFACT_NAME }}.cov diff --git a/.github/workflows/reusable-serviceless-phpunit-test.yml b/.github/workflows/reusable-serviceless-phpunit-test.yml index 25080164320b..209430eb5b00 100644 --- a/.github/workflows/reusable-serviceless-phpunit-test.yml +++ b/.github/workflows/reusable-serviceless-phpunit-test.yml @@ -62,12 +62,12 @@ jobs: - name: Checkout base branch for PR if: github.event_name == 'pull_request' - uses: actions/checkout@v4 + uses: actions/checkout@v6 with: ref: ${{ github.base_ref }} - name: Checkout - uses: actions/checkout@v4 + uses: actions/checkout@v6 - name: Setup PHP uses: shivammathur/setup-php@v2 @@ -122,7 +122,7 @@ jobs: - name: Upload coverage results as artifact if: ${{ inputs.enable-artifact-upload }} - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@v5 with: name: ${{ env.ARTIFACT_NAME }} path: build/cov/coverage-${{ env.ARTIFACT_NAME }}.cov diff --git a/.github/workflows/test-autoreview.yml b/.github/workflows/test-autoreview.yml index 10424ff0d4c5..55300ae5eff5 100644 --- a/.github/workflows/test-autoreview.yml +++ b/.github/workflows/test-autoreview.yml @@ -37,12 +37,12 @@ jobs: steps: - name: Checkout base branch for PR if: github.event_name == 'pull_request' - uses: actions/checkout@v4 + uses: actions/checkout@v6 with: ref: ${{ github.base_ref }} - name: Checkout - uses: actions/checkout@v4 + uses: actions/checkout@v6 - name: Setup PHP uses: shivammathur/setup-php@v2 diff --git a/.github/workflows/test-coding-standards.yml b/.github/workflows/test-coding-standards.yml index c49fd416ea8e..804c587e7f77 100644 --- a/.github/workflows/test-coding-standards.yml +++ b/.github/workflows/test-coding-standards.yml @@ -34,12 +34,12 @@ jobs: steps: - name: Checkout base branch for PR if: github.event_name == 'pull_request' - uses: actions/checkout@v4 + uses: actions/checkout@v6 with: ref: ${{ github.base_ref }} - name: Checkout - uses: actions/checkout@v4 + uses: actions/checkout@v6 - name: Setup PHP uses: shivammathur/setup-php@v2 diff --git a/.github/workflows/test-deptrac.yml b/.github/workflows/test-deptrac.yml index d96f8f27ef00..f66e1057b8d4 100644 --- a/.github/workflows/test-deptrac.yml +++ b/.github/workflows/test-deptrac.yml @@ -38,12 +38,12 @@ jobs: steps: - name: Checkout base branch for PR if: github.event_name == 'pull_request' - uses: actions/checkout@v4 + uses: actions/checkout@v6 with: ref: ${{ github.base_ref }} - name: Checkout - uses: actions/checkout@v4 + uses: actions/checkout@v6 - name: Setup PHP uses: shivammathur/setup-php@v2 @@ -80,7 +80,7 @@ jobs: - name: Run architectural inspection run: | - composer require --dev qossmic/deptrac-shim + composer require --dev deptrac/deptrac vendor/bin/deptrac analyze --cache-file=build/deptrac.cache env: GITHUB_AUTH_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/test-file-permissions.yml b/.github/workflows/test-file-permissions.yml index e6ad5949d8b4..c6fed8f71d1b 100644 --- a/.github/workflows/test-file-permissions.yml +++ b/.github/workflows/test-file-permissions.yml @@ -18,7 +18,7 @@ jobs: steps: - name: Checkout - uses: actions/checkout@v4 + uses: actions/checkout@v6 - name: Detect unnecessary execution permissions run: php utils/check_permission_x.php diff --git a/.github/workflows/test-phpstan.yml b/.github/workflows/test-phpstan.yml index b5e93d699063..d4657396da6c 100644 --- a/.github/workflows/test-phpstan.yml +++ b/.github/workflows/test-phpstan.yml @@ -47,12 +47,12 @@ jobs: steps: - name: Checkout base branch for PR if: github.event_name == 'pull_request' - uses: actions/checkout@v4 + uses: actions/checkout@v6 with: ref: ${{ github.base_ref }} - name: Checkout - uses: actions/checkout@v4 + uses: actions/checkout@v6 - name: Setup PHP uses: shivammathur/setup-php@v2 diff --git a/.github/workflows/test-psalm.yml b/.github/workflows/test-psalm.yml index d24c2916df5e..0e0a865843ba 100644 --- a/.github/workflows/test-psalm.yml +++ b/.github/workflows/test-psalm.yml @@ -29,12 +29,12 @@ jobs: steps: - name: Checkout base branch for PR if: github.event_name == 'pull_request' - uses: actions/checkout@v4 + uses: actions/checkout@v6 with: ref: ${{ github.base_ref }} - name: Checkout - uses: actions/checkout@v4 + uses: actions/checkout@v6 - name: Setup PHP uses: shivammathur/setup-php@v2 diff --git a/.github/workflows/test-rector.yml b/.github/workflows/test-rector.yml index f1a81bd170bf..74a46590b80a 100644 --- a/.github/workflows/test-rector.yml +++ b/.github/workflows/test-rector.yml @@ -49,12 +49,12 @@ jobs: steps: - name: Checkout base branch for PR if: github.event_name == 'pull_request' - uses: actions/checkout@v4 + uses: actions/checkout@v6 with: ref: ${{ github.base_ref }} - name: Checkout - uses: actions/checkout@v4 + uses: actions/checkout@v6 - name: Setup PHP uses: shivammathur/setup-php@v2 diff --git a/.github/workflows/test-scss.yml b/.github/workflows/test-scss.yml index e93455d3a050..71ca99253872 100644 --- a/.github/workflows/test-scss.yml +++ b/.github/workflows/test-scss.yml @@ -33,10 +33,10 @@ jobs: steps: - name: Checkout - uses: actions/checkout@v4 + uses: actions/checkout@v6 - name: Setup Node - uses: actions/setup-node@v4.0.0 + uses: actions/setup-node@v6.0.0 with: # node version based on dart-sass test workflow node-version: 16 diff --git a/.github/workflows/test-userguide.yml b/.github/workflows/test-userguide.yml index f1e0d0bd60e6..0405af7cd6d7 100644 --- a/.github/workflows/test-userguide.yml +++ b/.github/workflows/test-userguide.yml @@ -24,10 +24,10 @@ jobs: steps: - name: Checkout - uses: actions/checkout@v4 + uses: actions/checkout@v6 - name: Setup Python - uses: actions/setup-python@v5 + uses: actions/setup-python@v6 with: python-version: '3.12' diff --git a/CHANGELOG.md b/CHANGELOG.md index 76e89d04e4ee..f1e51255081e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,38 @@ # Changelog +## [v4.6.4](https://github.com/codeigniter4/CodeIgniter4/tree/v4.6.4) (2025-12-12) +[Full Changelog](https://github.com/codeigniter4/CodeIgniter4/compare/v4.6.3...v4.6.4) + +### Fixed Bugs + +* fix: prevent non-shared DB instances from polluting shared cache by @michalsn in https://github.com/codeigniter4/CodeIgniter4/pull/9679 +* fix: `Connection::getFieldData()` default value convention for `SQLSRV` and `OCI8` by @michalsn in https://github.com/codeigniter4/CodeIgniter4/pull/9680 +* fix: `Forge::modifyColumn()` for Postgre handler by @michalsn in https://github.com/codeigniter4/CodeIgniter4/pull/9676 +* fix: setting `created_at` field in `Model::replace()` method by @michalsn in https://github.com/codeigniter4/CodeIgniter4/pull/9693 +* fix: Casting in insertBatch and updateBatch methods. by @patel-vansh in https://github.com/codeigniter4/CodeIgniter4/pull/9698 +* fix: `compileOrderBy()` method by @michalsn in https://github.com/codeigniter4/CodeIgniter4/pull/9697 +* fix: SQLite3 password handling for empty string by @michalsn in https://github.com/codeigniter4/CodeIgniter4/pull/9729 +* fix: TypeError in `valid_base64` rule when checking invalid base64 strings by @michalsn in https://github.com/codeigniter4/CodeIgniter4/pull/9733 +* fix: debug toolbar logs collector behavior on `isEmpty()` by @mjomble in https://github.com/codeigniter4/CodeIgniter4/pull/9724 +* fix: crash in `toggleViewsHints` - `debugDiv.appendChild` (`toolbar.js`) by @mjomble in https://github.com/codeigniter4/CodeIgniter4/pull/9735 +* fix: cannot read properties of null in `toggleViewsHints` (`toolbar.js`) by @michalsn in https://github.com/codeigniter4/CodeIgniter4/pull/9736 +* fix: type error in controlled cell by @michalsn in https://github.com/codeigniter4/CodeIgniter4/pull/9784 +* fix: handle resources and closures in JSON exception responses by @michalsn in https://github.com/codeigniter4/CodeIgniter4/pull/9788 +* fix: quote reserved keyword `timestamp` used as a field name for session table by @michalsn in https://github.com/codeigniter4/CodeIgniter4/pull/9805 +* fix: Add an IDs for toolbar form fields by @neznaika0 in https://github.com/codeigniter4/CodeIgniter4/pull/9823 +* fix: disable echo in the preload file by @michalsn in https://github.com/codeigniter4/CodeIgniter4/pull/9825 +* fix(cache): prevent Redis error when `deleteMatching()` finds no keys by @michalsn in https://github.com/codeigniter4/CodeIgniter4/pull/9829 + +### Refactoring + +* refactor: change `$request` to `CLIRequest|IncomingRequest` in `ResponseTrait` by @paulbalandan in https://github.com/codeigniter4/CodeIgniter4/pull/9658 +* refactor: fix phpdoc and improve code in `Language` by @paulbalandan in https://github.com/codeigniter4/CodeIgniter4/pull/9656 +* refactor: remove redundant property declarations in `BaseController` by @paulbalandan in https://github.com/codeigniter4/CodeIgniter4/pull/9659 +* refactor: update `CheckPhpIni` code by @paulbalandan in https://github.com/codeigniter4/CodeIgniter4/pull/9672 +* refactor: Improve types for phpstan by @neznaika0 in https://github.com/codeigniter4/CodeIgniter4/pull/9685 +* refactor: fix phpstan issues on magic properties by @paulbalandan in https://github.com/codeigniter4/CodeIgniter4/pull/9728 +* refactor: use `superglobals` service in the `UserAgent` class by @michalsn in https://github.com/codeigniter4/CodeIgniter4/pull/9783 + ## [v4.6.3](https://github.com/codeigniter4/CodeIgniter4/tree/v4.6.3) (2025-08-02) [Full Changelog](https://github.com/codeigniter4/CodeIgniter4/compare/v4.6.2...v4.6.3) diff --git a/admin/framework/composer.json b/admin/framework/composer.json index 499a97eae337..7a6e1c58a1e1 100644 --- a/admin/framework/composer.json +++ b/admin/framework/composer.json @@ -20,7 +20,7 @@ "codeigniter/coding-standard": "^1.7", "fakerphp/faker": "^1.24", "friendsofphp/php-cs-fixer": "^3.47.1", - "kint-php/kint": "^6.0", + "kint-php/kint": "^6.1", "mikey179/vfsstream": "^1.6.12", "nexusphp/cs-config": "^3.6", "phpunit/phpunit": "^10.5.16 || ^11.2", diff --git a/admin/starter/app/Config/Paths.php b/admin/starter/app/Config/Paths.php index d0035fbcfb9b..39a902029882 100644 --- a/admin/starter/app/Config/Paths.php +++ b/admin/starter/app/Config/Paths.php @@ -12,6 +12,9 @@ * share a system folder between multiple applications, and more. * * All paths are relative to the project's root folder. + * + * NOTE: This class is required prior to Autoloader instantiation, + * and does not extend BaseConfig. */ class Paths { diff --git a/app/Config/Database.php b/app/Config/Database.php index 29f6f4a14f42..d7939bc26f9e 100644 --- a/app/Config/Database.php +++ b/app/Config/Database.php @@ -182,6 +182,7 @@ class Database extends Config 'port' => 3306, 'foreignKeys' => true, 'busyTimeout' => 1000, + 'synchronous' => null, 'dateFormat' => [ 'date' => 'Y-m-d', 'datetime' => 'Y-m-d H:i:s', diff --git a/app/Controllers/BaseController.php b/app/Controllers/BaseController.php index 689405bdf314..ab45a7710be9 100644 --- a/app/Controllers/BaseController.php +++ b/app/Controllers/BaseController.php @@ -3,44 +3,28 @@ namespace App\Controllers; use CodeIgniter\Controller; -use CodeIgniter\HTTP\CLIRequest; -use CodeIgniter\HTTP\IncomingRequest; use CodeIgniter\HTTP\RequestInterface; use CodeIgniter\HTTP\ResponseInterface; use Psr\Log\LoggerInterface; /** - * Class BaseController - * * BaseController provides a convenient place for loading components * and performing functions that are needed by all your controllers. + * * Extend this class in any new controllers: + * ``` * class Home extends BaseController + * ``` * - * For security be sure to declare any new methods as protected or private. + * For security, be sure to declare any new methods as protected or private. */ abstract class BaseController extends Controller { - /** - * Instance of the main Request object. - * - * @var CLIRequest|IncomingRequest - */ - protected $request; - - /** - * An array of helpers to be loaded automatically upon - * class instantiation. These helpers will be available - * to all other controllers that extend BaseController. - * - * @var list - */ - protected $helpers = []; - /** * Be sure to declare properties for any property fetch you initialized. * The creation of dynamic property is deprecated in PHP 8.2. */ + // protected $session; /** @@ -48,11 +32,14 @@ abstract class BaseController extends Controller */ public function initController(RequestInterface $request, ResponseInterface $response, LoggerInterface $logger) { - // Do Not Edit This Line + // Load here all helpers you want to be available in your controllers that extend BaseController. + // Caution: Do not put the this below the parent::initController() call below. + // $this->helpers = ['form', 'url']; + + // Caution: Do not edit this line. parent::initController($request, $response, $logger); // Preload any models, libraries, etc, here. - - // E.g.: $this->session = service('session'); + // $this->session = service('session'); } } diff --git a/composer.json b/composer.json index 64253d857046..48007df18b3d 100644 --- a/composer.json +++ b/composer.json @@ -19,7 +19,7 @@ "require-dev": { "codeigniter/phpstan-codeigniter": "1.x-dev", "fakerphp/faker": "^1.24", - "kint-php/kint": "^6.0", + "kint-php/kint": "^6.1", "mikey179/vfsstream": "^1.6.12", "nexusphp/tachycardia": "^2.0", "phpstan/extension-installer": "^1.4", @@ -28,7 +28,7 @@ "phpunit/phpcov": "^9.0.2 || ^10.0", "phpunit/phpunit": "^10.5.16 || ^11.2", "predis/predis": "^3.0", - "rector/rector": "2.1.2", + "rector/rector": "2.2.14", "shipmonk/phpstan-baseline-per-identifier": "^2.0" }, "replace": { diff --git a/contributing/pull_request.md b/contributing/pull_request.md index 8e3b5ed9f419..b5db40417873 100644 --- a/contributing/pull_request.md +++ b/contributing/pull_request.md @@ -96,7 +96,7 @@ implementation comments to explain potentially confusing sections of code, and documentation comments before each public or protected class/interface/trait, method, and variable. -Do not add PHPDoc comments that are superficial, duplicated, or stating the obvious. +Do not add PHPDoc comments that are superficial, duplicated, or stating the obvious. It is not recommended to reuse comments if the parent class or interface already contains a description of the child element. See the following for more information. diff --git a/contributing/styleguide.md b/contributing/styleguide.md index 95e68bb37ddb..1d57aa698358 100644 --- a/contributing/styleguide.md +++ b/contributing/styleguide.md @@ -241,6 +241,7 @@ of the classes they declare. - */ public function analyse(string $data): void {}; ``` +- SHOULD NOT duplicate comments from the parent class or interface. ### PHPUnit Assertions diff --git a/deptrac.yaml b/deptrac.yaml index 178de9a74fd7..7f5687af4bca 100644 --- a/deptrac.yaml +++ b/deptrac.yaml @@ -8,7 +8,7 @@ # - Exception # - Service # - Validation\FormatRules -parameters: +deptrac: paths: - ./app - ./system @@ -17,148 +17,149 @@ parameters: layers: - name: API collectors: - - type: className - regex: ^Codeigniter\\API\\.* + - type: classNameRegex + value: '/^CodeIgniter\\API\\.*$/' - name: Cache collectors: - - type: className - regex: ^Codeigniter\\Cache\\.* + - type: classNameRegex + value: '/^CodeIgniter\\Cache\\.*$/' - name: Controller collectors: - - type: className - regex: ^CodeIgniter\\Controller$ + - type: classNameRegex + value: '/^CodeIgniter\\Controller$/' - name: Cookie collectors: - - type: className - regex: ^Codeigniter\\Cookie\\.* + - type: classNameRegex + value: '/^CodeIgniter\\Cookie\\.*$/' - name: Database collectors: - - type: className - regex: ^Codeigniter\\Database\\.* + - type: classNameRegex + value: '/^CodeIgniter\\Database\\.*$/' - name: DataCaster collectors: - - type: className - regex: ^Codeigniter\\DataCaster\\.* + - type: classNameRegex + value: '/^CodeIgniter\\DataCaster\\.*$/' - name: DataConverter collectors: - - type: className - regex: ^Codeigniter\\DataConverter\\.* + - type: classNameRegex + value: '/^CodeIgniter\\DataConverter\\.*$/' - name: Email collectors: - - type: className - regex: ^Codeigniter\\Email\\.* + - type: classNameRegex + value: '/^CodeIgniter\\Email\\.*$/' - name: Encryption collectors: - - type: className - regex: ^Codeigniter\\Encryption\\.* + - type: classNameRegex + value: '/^CodeIgniter\\Encryption\\.*$/' - name: Entity collectors: - - type: className - regex: ^Codeigniter\\Entity\\.* + - type: classNameRegex + value: '/^CodeIgniter\\Entity\\.*$/' - name: Events collectors: - - type: className - regex: ^Codeigniter\\Events\\.* + - type: classNameRegex + value: '/^CodeIgniter\\Events\\.*$/' - name: Files collectors: - - type: className - regex: ^Codeigniter\\Files\\.* + - type: classNameRegex + value: '/^CodeIgniter\\Files\\.*$/' - name: Filters collectors: - type: bool must: - - type: className - regex: ^Codeigniter\\Filters\\Filter.* + - type: classNameRegex + value: '/^CodeIgniter\\Filters\\Filter.*$/' - name: Format collectors: - - type: className - regex: ^Codeigniter\\Format\\.* + - type: classNameRegex + value: '/^CodeIgniter\\Format\\.*$/' - name: Honeypot collectors: - - type: className - regex: ^Codeigniter\\.*Honeypot.* # includes the Filter + - type: classNameRegex + # includes the Filter + value: '/^CodeIgniter\\.*Honeypot.*$/' - name: HTTP collectors: - type: bool must: - - type: className - regex: ^Codeigniter\\HTTP\\.* + - type: classNameRegex + value: '/^CodeIgniter\\HTTP\\.*$/' must_not: - - type: className - regex: (Exception|URI) + - type: classNameRegex + value: '(Exception|URI)' - name: I18n collectors: - - type: className - regex: ^Codeigniter\\I18n\\.* + - type: classNameRegex + value: '/^CodeIgniter\\I18n\\.*$/' - name: Images collectors: - - type: className - regex: ^Codeigniter\\Images\\.* + - type: classNameRegex + value: '/^CodeIgniter\\Images\\.*$/' - name: Language collectors: - - type: className - regex: ^Codeigniter\\Language\\.* + - type: classNameRegex + value: '/^CodeIgniter\\Language\\.*$/' - name: Log collectors: - - type: className - regex: ^Codeigniter\\Log\\.* + - type: classNameRegex + value: '/^CodeIgniter\\Log\\.*$/' - name: Model collectors: - - type: className - regex: ^Codeigniter\\.*Model$ + - type: classNameRegex + value: '/^CodeIgniter\\.*Model$/' - name: Modules collectors: - - type: className - regex: ^Codeigniter\\Modules\\.* + - type: classNameRegex + value: '/^CodeIgniter\\Modules\\.*$/' - name: Pager collectors: - - type: className - regex: ^Codeigniter\\Pager\\.* + - type: classNameRegex + value: '/^CodeIgniter\\Pager\\.*$/' - name: Publisher collectors: - - type: className - regex: ^Codeigniter\\Publisher\\.* + - type: classNameRegex + value: '/^CodeIgniter\\Publisher\\.*$/' - name: RESTful collectors: - - type: className - regex: ^Codeigniter\\RESTful\\.* + - type: classNameRegex + value: '/^CodeIgniter\\RESTful\\.*$/' - name: Router collectors: - - type: className - regex: ^Codeigniter\\Router\\.* + - type: classNameRegex + value: '/^CodeIgniter\\Router\\.*$/' - name: Security collectors: - - type: className - regex: ^Codeigniter\\Security\\.* + - type: classNameRegex + value: '/^CodeIgniter\\Security\\.*$/' - name: Session collectors: - - type: className - regex: ^Codeigniter\\Session\\.* + - type: classNameRegex + value: '/^CodeIgniter\\Session\\.*$/' - name: Throttle collectors: - - type: className - regex: ^Codeigniter\\Throttle\\.* + - type: classNameRegex + value: '/^CodeIgniter\\Throttle\\.*$/' - name: Typography collectors: - - type: className - regex: ^Codeigniter\\Typography\\.* + - type: classNameRegex + value: '/^CodeIgniter\\Typography\\.*$/' - name: URI collectors: - - type: className - regex: ^CodeIgniter\\HTTP\\URI$ + - type: classNameRegex + value: '/^CodeIgniter\\HTTP\\URI$/' - name: Validation collectors: - type: bool must: - - type: className - regex: ^Codeigniter\\Validation\\.* + - type: classNameRegex + value: '/^CodeIgniter\\Validation\\.*$/' must_not: - - type: className - regex: ^Codeigniter\\Validation\\FormatRules$ + - type: classNameRegex + value: '/^CodeIgniter\\Validation\\FormatRules$/' - name: View collectors: - - type: className - regex: ^Codeigniter\\View\\.* + - type: classNameRegex + value: '/^CodeIgniter\\View\\.*$/' ruleset: API: - Format diff --git a/phpdoc.dist.xml b/phpdoc.dist.xml index 0238aec5f019..2c811d13b74b 100644 --- a/phpdoc.dist.xml +++ b/phpdoc.dist.xml @@ -10,7 +10,7 @@ api/build/ api/cache/ - + system diff --git a/preload.php b/preload.php index 9d16bb31554f..288b30b4ef48 100644 --- a/preload.php +++ b/preload.php @@ -101,7 +101,9 @@ public function load(): void } require_once $file[0]; - echo 'Loaded: ' . $file[0] . "\n"; + // Uncomment only for debugging (to inspect which files are included). + // Never use this in production - preload scripts must not generate output. + // echo 'Loaded: ' . $file[0] . "\n"; } } } diff --git a/psalm-baseline.xml b/psalm-baseline.xml index 778bdd654739..160ba4d97cd8 100644 --- a/psalm-baseline.xml +++ b/psalm-baseline.xml @@ -1,5 +1,5 @@ - + |parser_callable_string|parser_callable>]]> @@ -68,6 +68,12 @@ + + + + + + |parser_callable_string|parser_callable>]]> diff --git a/rector.php b/rector.php index c814a7402c4d..23d5de95427f 100644 --- a/rector.php +++ b/rector.php @@ -13,11 +13,9 @@ use Rector\Caching\ValueObject\Storage\FileCacheStorage; use Rector\CodeQuality\Rector\Empty_\SimplifyEmptyCheckOnEmptyArrayRector; -use Rector\CodeQuality\Rector\Expression\InlineIfToExplicitIfRector; -use Rector\CodeQuality\Rector\Foreach_\UnusedForeachValueToArrayKeysRector; -use Rector\CodeQuality\Rector\FuncCall\ChangeArrayPushToArrayAssignRector; use Rector\CodeQuality\Rector\FuncCall\CompactToVariablesRector; use Rector\CodeQuality\Rector\FunctionLike\SimplifyUselessVariableRector; +use Rector\CodeQuality\Rector\Isset_\IssetOnPropertyObjectToPropertyExistsRector; use Rector\CodeQuality\Rector\Ternary\TernaryEmptyArrayArrayDimFetchToCoalesceRector; use Rector\CodingStyle\Rector\ClassMethod\FuncGetArgsToVariadicParamRector; use Rector\CodingStyle\Rector\ClassMethod\MakeInheritedMethodVisibilitySameAsParentRector; @@ -27,19 +25,20 @@ use Rector\DeadCode\Rector\ClassMethod\RemoveUnusedConstructorParamRector; use Rector\DeadCode\Rector\ClassMethod\RemoveUnusedPrivateMethodRector; use Rector\DeadCode\Rector\If_\UnwrapFutureCompatibleIfPhpVersionRector; +use Rector\DeadCode\Rector\MethodCall\RemoveNullArgOnNullDefaultParamRector; use Rector\EarlyReturn\Rector\Foreach_\ChangeNestedForeachIfsToEarlyContinueRector; use Rector\EarlyReturn\Rector\If_\ChangeIfElseValueAssignToEarlyReturnRector; use Rector\EarlyReturn\Rector\If_\RemoveAlwaysElseRector; use Rector\EarlyReturn\Rector\Return_\PreparedValueToEarlyReturnRector; -use Rector\Php55\Rector\String_\StringClassNameToClassConstantRector; use Rector\Php70\Rector\FuncCall\RandomFunctionRector; use Rector\Php80\Rector\Class_\ClassPropertyAssignToConstructorPromotionRector; use Rector\Php81\Rector\FuncCall\NullToStrictStringFuncCallArgRector; -use Rector\PHPUnit\CodeQuality\Rector\Class_\RemoveDataProviderParamKeysRector; use Rector\PHPUnit\CodeQuality\Rector\Class_\YieldDataProviderRector; +use Rector\PHPUnit\CodeQuality\Rector\FuncCall\AssertFuncCallToPHPUnitAssertRector; +use Rector\PHPUnit\CodeQuality\Rector\StmtsAwareInterface\DeclareStrictTypesTestsRector; +use Rector\Privatization\Rector\Class_\FinalizeTestCaseClassRector; use Rector\Privatization\Rector\Property\PrivatizeFinalClassPropertyRector; use Rector\Strict\Rector\Empty_\DisallowedEmptyRuleFixerRector; -use Rector\Strict\Rector\If_\BooleanInIfConditionRuleFixerRector; use Rector\TypeDeclaration\Rector\ArrowFunction\AddArrowFunctionReturnTypeRector; use Rector\TypeDeclaration\Rector\ClassMethod\AddMethodCallBasedStrictParamTypeRector; use Rector\TypeDeclaration\Rector\ClassMethod\ReturnNeverTypeRector; @@ -54,7 +53,7 @@ return RectorConfig::configure() ->withPhpSets(php81: true) - ->withPreparedSets(deadCode: true, instanceOf: true, strictBooleans: true, phpunitCodeQuality: true) + ->withPreparedSets(deadCode: true, instanceOf: true, phpunitCodeQuality: true) ->withComposerBased(phpunit: true) ->withParallel(120, 8, 10) ->withCache( @@ -128,7 +127,6 @@ __DIR__ . '/system/Validation/Views', __DIR__ . '/system/View/Parser.php', __DIR__ . '/tests/system/Debug/ExceptionsTest.php', - __DIR__ . '/tests/system/View/Views', ], // use mt_rand instead of random_int on purpose on non-cryptographically random @@ -168,7 +166,27 @@ CompactToVariablesRector::class, - RemoveDataProviderParamKeysRector::class, + // possibly isset() on purpose, on updated Config classes property accross versions + IssetOnPropertyObjectToPropertyExistsRector::class, + + AssertFuncCallToPHPUnitAssertRector::class => [ + // use $this inside static closure + __DIR__ . '/tests/system/AutoReview/FrameworkCodeTest.php', + ], + + // some tests extended by other tests + FinalizeTestCaseClassRector::class, + + DeclareStrictTypesTestsRector::class => [ + __DIR__ . '/tests/system/Debug/ExceptionsTest.php', + ], + + RemoveNullArgOnNullDefaultParamRector::class => [ + // skip form query usage, easier to read + __DIR__ . '/system/Model.php', + __DIR__ . '/tests/system/Database', + __DIR__ . '/tests/system/Models', + ], ]) // auto import fully qualified class names ->withImportNames(removeUnusedImports: true) @@ -181,10 +199,7 @@ CountArrayToEmptyArrayComparisonRector::class, ChangeNestedForeachIfsToEarlyContinueRector::class, ChangeIfElseValueAssignToEarlyReturnRector::class, - InlineIfToExplicitIfRector::class, PreparedValueToEarlyReturnRector::class, - UnusedForeachValueToArrayKeysRector::class, - ChangeArrayPushToArrayAssignRector::class, RemoveErrorSuppressInTryCatchStmtsRector::class, FuncGetArgsToVariadicParamRector::class, MakeInheritedMethodVisibilitySameAsParentRector::class, @@ -192,7 +207,6 @@ TernaryEmptyArrayArrayDimFetchToCoalesceRector::class, DisallowedEmptyRuleFixerRector::class, PrivatizeFinalClassPropertyRector::class, - BooleanInIfConditionRuleFixerRector::class, VersionCompareFuncCallToConstantRector::class, AddClosureVoidReturnTypeWhereNoReturnRector::class, AddFunctionVoidReturnTypeWhereNoReturnRector::class, @@ -201,8 +215,4 @@ ClosureReturnTypeRector::class, AddArrowFunctionReturnTypeRector::class, ]) - ->withConfiguredRule(StringClassNameToClassConstantRector::class, [ - // keep '\\' prefix string on string '\Foo\Bar' - StringClassNameToClassConstantRector::SHOULD_KEEP_PRE_SLASH => true, - ]) - ->withCodeQualityLevel(34); + ->withCodeQualityLevel(61); diff --git a/system/API/ResponseTrait.php b/system/API/ResponseTrait.php index 318af4b28bea..f64cc671a514 100644 --- a/system/API/ResponseTrait.php +++ b/system/API/ResponseTrait.php @@ -15,8 +15,8 @@ use CodeIgniter\Format\Format; use CodeIgniter\Format\FormatterInterface; +use CodeIgniter\HTTP\CLIRequest; use CodeIgniter\HTTP\IncomingRequest; -use CodeIgniter\HTTP\RequestInterface; use CodeIgniter\HTTP\ResponseInterface; /** @@ -24,10 +24,10 @@ * consistent HTTP responses under a variety of common * situations when working as an API. * - * @property RequestInterface $request - * @property ResponseInterface $response - * @property bool $stringAsHtml Whether to treat string data as HTML in JSON response. - * Setting `true` is only for backward compatibility. + * @property CLIRequest|IncomingRequest $request + * @property ResponseInterface $response + * @property bool $stringAsHtml Whether to treat string data as HTML in JSON response. + * Setting `true` is only for backward compatibility. */ trait ResponseTrait { @@ -122,9 +122,9 @@ protected function respond($data = null, ?int $status = null, string $message = /** * Used for generic failures that no custom methods exist for. * - * @param list|string $messages - * @param int $status HTTP status code - * @param string|null $code Custom, API-specific, error code + * @param array|string $messages + * @param int $status HTTP status code + * @param string|null $code Custom, API-specific, error code * * @return ResponseInterface */ @@ -230,7 +230,7 @@ protected function failNotFound(string $description = 'Not Found', ?string $code /** * Used when the data provided by the client cannot be validated on one or more fields. * - * @param list|string $errors + * @param array|string $errors * * @return ResponseInterface */ diff --git a/system/BaseModel.php b/system/BaseModel.php index 4f1cf3dca18f..fdc07ba2330d 100644 --- a/system/BaseModel.php +++ b/system/BaseModel.php @@ -769,7 +769,7 @@ protected function shouldUpdate($row): bool { $id = $this->getIdValue($row); - return ! ($id === null || $id === [] || $id === ''); + return ! in_array($id, [null, [], ''], true); } /** @@ -909,22 +909,7 @@ public function insertBatch(?array $set = null, ?bool $escape = null, int $batch if (is_array($set)) { foreach ($set as &$row) { - // If $row is using a custom class with public or protected - // properties representing the collection elements, we need to grab - // them as an array. - if (is_object($row) && ! $row instanceof stdClass) { - $row = $this->objectToArray($row, false, true); - } - - // If it's still a stdClass, go ahead and convert to - // an array so doProtectFields and other model methods - // don't have to do special checks. - if (is_object($row)) { - $row = (array) $row; - } - - // Convert any Time instances to appropriate $dateFormat - $row = $this->timeToString($row); + $row = $this->transformDataRowToArray($row); // Validate every row. if (! $this->skipValidation && ! $this->validate($row)) { @@ -1051,21 +1036,7 @@ public function updateBatch(?array $set = null, ?string $index = null, int $batc { if (is_array($set)) { foreach ($set as &$row) { - // If $row is using a custom class with public or protected - // properties representing the collection elements, we need to grab - // them as an array. - if (is_object($row) && ! $row instanceof stdClass) { - // For updates the index field is needed even if it is not changed. - // So set $onlyChanged to false. - $row = $this->objectToArray($row, false, true); - } - - // If it's still a stdClass, go ahead and convert to - // an array so doProtectFields and other model methods - // don't have to do special checks. - if (is_object($row)) { - $row = (array) $row; - } + $row = $this->transformDataRowToArray($row); // Validate data before saving. if (! $this->skipValidation && ! $this->validate($row)) { @@ -1220,7 +1191,9 @@ public function replace(?array $row = null, bool $returnSQL = false) return false; } - $row = $this->setUpdatedField((array) $row, $this->setDate()); + $row = (array) $row; + $row = $this->setCreatedField($row, $this->setDate()); + $row = $this->setUpdatedField($row, $this->setDate()); return $this->doReplace($row, $returnSQL); } @@ -1694,6 +1667,52 @@ protected function trigger(string $event, array $eventData) return $eventData; } + /** + * If the model is using casts, this will convert the data + * in $row according to the rules defined in `$casts`. + * + * @param object|row_array|null $row Row data + * + * @return object|row_array|null Converted row data + * + * @used-by insertBatch() + * @used-by updateBatch() + * + * @throws ReflectionException + * @deprecated Since 4.6.4, temporary solution - will be removed in 4.7 + */ + protected function transformDataRowToArray(array|object|null $row): array|object|null + { + // If casts are used, convert the data first + if ($this->useCasts()) { + if (is_array($row)) { + $row = $this->converter->toDataSource($row); + } elseif ($row instanceof stdClass) { + $row = (array) $row; + $row = $this->converter->toDataSource($row); + } elseif ($row instanceof Entity) { + $row = $this->converter->extract($row); + } elseif (is_object($row)) { + $row = $this->converter->extract($row); + } + } elseif (is_object($row) && ! $row instanceof stdClass) { + // If $row is using a custom class with public or protected + // properties representing the collection elements, we need to grab + // them as an array. + $row = $this->objectToArray($row, false, true); + } + + // If it's still a stdClass, go ahead and convert to + // an array so doProtectFields and other model methods + // don't have to do special checks. + if (is_object($row)) { + $row = (array) $row; + } + + // Convert any Time instances to appropriate $dateFormat + return $this->timeToString($row); + } + /** * Sets the return type of the results to be as an associative array. * diff --git a/system/CLI/BaseCommand.php b/system/CLI/BaseCommand.php index afeb80eb5267..57df52d47f55 100644 --- a/system/CLI/BaseCommand.php +++ b/system/CLI/BaseCommand.php @@ -142,7 +142,7 @@ public function showHelp() { CLI::write(lang('CLI.helpUsage'), 'yellow'); - if (isset($this->usage)) { + if ($this->usage !== null) { $usage = $this->usage; } else { $usage = $this->name; @@ -154,7 +154,7 @@ public function showHelp() CLI::write($this->setPad($usage, 0, 0, 2)); - if (isset($this->description)) { + if ($this->description !== null) { CLI::newLine(); CLI::write(lang('CLI.helpDescription'), 'yellow'); CLI::write($this->setPad($this->description, 0, 0, 2)); diff --git a/system/CLI/CLI.php b/system/CLI/CLI.php index b8ea4714f39b..b7c9ed64e2de 100644 --- a/system/CLI/CLI.php +++ b/system/CLI/CLI.php @@ -318,11 +318,7 @@ public static function promptByMultipleKeys(string $text, array $options): array if ($opts === []) { $extraOutput = $extraOutputDefault; } else { - $optsKey = []; - - foreach (array_keys($opts) as $key) { - $optsKey[] = $key; - } + $optsKey = array_keys($opts); $extraOutput = '[' . $extraOutputDefault . ', ' . implode(', ', $optsKey) . ']'; $extraOutput = 'You can specify multiple values separated by commas.' . PHP_EOL . $extraOutput; } diff --git a/system/CLI/Commands.php b/system/CLI/Commands.php index aecd22c3f348..5630ee0f7b69 100644 --- a/system/CLI/Commands.php +++ b/system/CLI/Commands.php @@ -129,7 +129,7 @@ public function discoverCommands() $class = new $className($this->logger, $this); - if (isset($class->group) && ! isset($this->commands[$class->name])) { + if ($class->group !== null && ! isset($this->commands[$class->name])) { $this->commands[$class->name] = [ 'class' => $className, 'file' => $file, diff --git a/system/Cache/Handlers/PredisHandler.php b/system/Cache/Handlers/PredisHandler.php index 250ea74a88e0..8d0ce9998807 100644 --- a/system/Cache/Handlers/PredisHandler.php +++ b/system/Cache/Handlers/PredisHandler.php @@ -162,6 +162,10 @@ public function deleteMatching(string $pattern) $matchedKeys[] = $key; } + if ($matchedKeys === []) { + return 0; + } + return $this->redis->del($matchedKeys); } diff --git a/system/Cache/Handlers/RedisHandler.php b/system/Cache/Handlers/RedisHandler.php index 3a13ee07f8e4..06a089e2660b 100644 --- a/system/Cache/Handlers/RedisHandler.php +++ b/system/Cache/Handlers/RedisHandler.php @@ -195,7 +195,7 @@ public function deleteMatching(string $pattern) } } while ($iterator > 0); - return $this->redis->del($matchedKeys); + return (int) $this->redis->del($matchedKeys); } /** diff --git a/system/CodeIgniter.php b/system/CodeIgniter.php index c87ff78e8348..4156c99453a5 100644 --- a/system/CodeIgniter.php +++ b/system/CodeIgniter.php @@ -55,7 +55,7 @@ class CodeIgniter /** * The current version of CodeIgniter Framework */ - public const CI_VERSION = '4.6.3'; + public const CI_VERSION = '4.6.4'; /** * App startup time. diff --git a/system/Commands/Database/CreateDatabase.php b/system/Commands/Database/CreateDatabase.php index 0c8d2016dc93..facd060abf6e 100644 --- a/system/Commands/Database/CreateDatabase.php +++ b/system/Commands/Database/CreateDatabase.php @@ -109,7 +109,7 @@ public function run(array $params) $config->{$group}['database'] = $name; if ($name !== ':memory:') { - $dbName = ! str_contains($name, DIRECTORY_SEPARATOR) ? WRITEPATH . $name : $name; + $dbName = str_contains($name, DIRECTORY_SEPARATOR) ? $name : WRITEPATH . $name; if (is_file($dbName)) { CLI::error("Database \"{$dbName}\" already exists.", 'light_gray', 'red'); diff --git a/system/Commands/Generators/Views/migration.tpl.php b/system/Commands/Generators/Views/migration.tpl.php index 321895e670c2..124b1b83c4c7 100644 --- a/system/Commands/Generators/Views/migration.tpl.php +++ b/system/Commands/Generators/Views/migration.tpl.php @@ -15,7 +15,7 @@ public function up() 'id' => ['type' => 'VARCHAR', 'constraint' => 128, 'null' => false], 'ip_address' => ['type' => 'VARCHAR', 'constraint' => 45, 'null' => false], - 'timestamp timestamp DEFAULT CURRENT_TIMESTAMP NOT NULL', + '`timestamp` timestamp DEFAULT CURRENT_TIMESTAMP NOT NULL', 'data' => ['type' => 'BLOB', 'null' => false], 'ip_address inet NOT NULL', diff --git a/system/Commands/Utilities/Routes/AutoRouterImproved/AutoRouteCollector.php b/system/Commands/Utilities/Routes/AutoRouterImproved/AutoRouteCollector.php index f4a5204fb49b..d29f6a9b7049 100644 --- a/system/Commands/Utilities/Routes/AutoRouterImproved/AutoRouteCollector.php +++ b/system/Commands/Utilities/Routes/AutoRouterImproved/AutoRouteCollector.php @@ -99,7 +99,7 @@ public function get(): array * * @return list> */ - private function addFilters($routes) + private function addFilters(array $routes): array { $filterCollector = new FilterCollector(true); diff --git a/system/Common.php b/system/Common.php index 3f69838e0b80..41b16100c295 100644 --- a/system/Common.php +++ b/system/Common.php @@ -216,9 +216,19 @@ function config(string $name, bool $getShared = true) /** * Simpler way to create a new Cookie instance. * - * @param string $name Name of the cookie - * @param string $value Value of the cookie - * @param array $options Array of options to be passed to the cookie + * @param string $name Name of the cookie + * @param string $value Value of the cookie + * @param array{ + * prefix?: string, + * max-age?: int|numeric-string, + * expires?: DateTimeInterface|int|string, + * path?: string, + * domain?: string, + * secure?: bool, + * httponly?: bool, + * samesite?: string, + * raw?: bool + * } $options Cookie configuration options * * @throws CookieException */ @@ -352,7 +362,27 @@ function csp_script_nonce(): string * If $getShared === false then a new connection instance will be provided, * otherwise it will all calls will return the same instance. * - * @param array|ConnectionInterface|string|null $db + * @param array{ + * DSN?: string, + * hostname?: string, + * username?: string, + * password?: string, + * database?: string, + * DBDriver?: 'MySQLi'|'OCI8'|'Postgre'|'SQLite3'|'SQLSRV', + * DBPrefix?: string, + * pConnect?: bool, + * DBDebug?: bool, + * charset?: string, + * DBCollat?: string, + * swapPre?: string, + * encrypt?: bool, + * compress?: bool, + * strictOn?: bool, + * failover?: array, + * port?: int, + * dateFormat?: array, + * foreignKeys?: bool + * }|ConnectionInterface|string|null $db * * @return BaseConnection */ @@ -402,13 +432,13 @@ function env(string $key, $default = null) * If $data is an array, then it loops over it, escaping each * 'value' of the key/value pairs. * - * @param array|string $data - * @param 'attr'|'css'|'html'|'js'|'raw'|'url' $context - * @param string|null $encoding Current encoding for escaping. - * If not UTF-8, we convert strings from this encoding - * pre-escaping and back to this encoding post-escaping. + * @param array|string>|string $data + * @param 'attr'|'css'|'html'|'js'|'raw'|'url' $context + * @param string|null $encoding Current encoding for escaping. + * If not UTF-8, we convert strings from this encoding + * pre-escaping and back to this encoding post-escaping. * - * @return array|string + * @return ($data is string ? string : array|string>) * * @throws InvalidArgumentException */ @@ -560,7 +590,7 @@ function function_usable(string $functionName): bool * 2. {namespace}/Helpers * 3. system/Helpers * - * @param array|string $filenames + * @param list|string $filenames * * @throws FileNotFoundException */ @@ -729,6 +759,8 @@ function is_windows(?bool $mock = null): bool * A convenience method to translate a string or array of them and format * the result with the intl extension's MessageFormatter. * + * @param array $args + * * @return list|string */ function lang(string $line, array $args = [], ?string $locale = null) @@ -1089,7 +1121,7 @@ function stringify_attributes($attributes, bool $js = false): string { $atts = ''; - if ($attributes === '' || $attributes === [] || $attributes === null) { + if (in_array($attributes, ['', [], null], true)) { return $atts; } @@ -1194,7 +1226,7 @@ function view_cell(string $library, $params = null, int $ttl = 0, ?string $cache /** * Get the class "basename" of the given object / class. * - * @param object|string $class + * @param class-string|object $class * * @return string * @@ -1212,9 +1244,9 @@ function class_basename($class) /** * Returns all traits used by a class, its parent classes and trait of their traits. * - * @param object|string $class + * @param class-string|object $class * - * @return array + * @return array * * @codeCoverageIgnore */ @@ -1238,9 +1270,9 @@ function class_uses_recursive($class) /** * Returns all traits used by a trait and its traits. * - * @param string $trait + * @param class-string $trait * - * @return array + * @return array * * @codeCoverageIgnore */ diff --git a/system/Config/Services.php b/system/Config/Services.php index c9266a892e38..c2a73f839f28 100644 --- a/system/Config/Services.php +++ b/system/Config/Services.php @@ -345,7 +345,7 @@ public static function image(?string $handler = null, ?Images $config = null, bo $config ??= config(Images::class); assert($config instanceof Images); - $handler = $handler !== null && $handler !== '' && $handler !== '0' ? $handler : $config->defaultHandler; + $handler = in_array($handler, [null, '', '0'], true) ? $config->defaultHandler : $handler; $class = $config->handlers[$handler]; return new $class($config); @@ -385,7 +385,7 @@ public static function language(?string $locale = null, bool $getShared = true) } // Use '?:' for empty string check - $locale = $locale !== null && $locale !== '' && $locale !== '0' ? $locale : $requestLocale; + $locale = in_array($locale, [null, '', '0'], true) ? $requestLocale : $locale; return new Language($locale); } @@ -484,7 +484,7 @@ public static function parser(?string $viewPath = null, ?ViewConfig $config = nu return static::getSharedInstance('parser', $viewPath, $config); } - $viewPath = $viewPath !== null && $viewPath !== '' && $viewPath !== '0' ? $viewPath : (new Paths())->viewDirectory; + $viewPath = in_array($viewPath, [null, '', '0'], true) ? (new Paths())->viewDirectory : $viewPath; $config ??= config(ViewConfig::class); return new Parser($config, $viewPath, AppServices::get('locator'), CI_DEBUG, AppServices::get('logger')); @@ -503,7 +503,7 @@ public static function renderer(?string $viewPath = null, ?ViewConfig $config = return static::getSharedInstance('renderer', $viewPath, $config); } - $viewPath = $viewPath !== null && $viewPath !== '' && $viewPath !== '0' ? $viewPath : (new Paths())->viewDirectory; + $viewPath = in_array($viewPath, [null, '', '0'], true) ? (new Paths())->viewDirectory : $viewPath; $config ??= config(ViewConfig::class); return new View($config, $viewPath, AppServices::get('locator'), CI_DEBUG, AppServices::get('logger')); diff --git a/system/Controller.php b/system/Controller.php index 9c6e7ee36a63..af74f3a3af10 100644 --- a/system/Controller.php +++ b/system/Controller.php @@ -25,8 +25,6 @@ use Psr\Log\LoggerInterface; /** - * Class Controller - * * @see \CodeIgniter\ControllerTest */ class Controller diff --git a/system/Cookie/Cookie.php b/system/Cookie/Cookie.php index ad461c721112..e3d2488e6a10 100644 --- a/system/Cookie/Cookie.php +++ b/system/Cookie/Cookie.php @@ -225,9 +225,19 @@ public static function fromHeaderString(string $cookie, bool $raw = false) /** * Construct a new Cookie instance. * - * @param string $name The cookie's name - * @param string $value The cookie's value - * @param array{prefix?: string, max-age?: int|numeric-string, expires?: DateTimeInterface|int|string, path?: string, domain?: string, secure?: bool, httponly?: bool, samesite?: string, raw?: bool} $options The cookie's options + * @param string $name The cookie's name + * @param string $value The cookie's value + * @param array{ + * prefix?: string, + * max-age?: int|numeric-string, + * expires?: DateTimeInterface|int|string, + * path?: string, + * domain?: string, + * secure?: bool, + * httponly?: bool, + * samesite?: string, + * raw?: bool, + * } $options The cookie's options * * @throws CookieException */ @@ -497,7 +507,7 @@ public function withExpired() */ public function withPath(?string $path) { - $path = $path !== null && $path !== '' && $path !== '0' ? $path : self::$defaults['path']; + $path = in_array($path, [null, '', '0'], true) ? self::$defaults['path'] : $path; $this->validatePrefix($this->prefix, $this->secure, $path, $this->domain); $cookie = clone $this; diff --git a/system/DataCaster/DataCaster.php b/system/DataCaster/DataCaster.php index 81ebe233c125..5ef4579619ba 100644 --- a/system/DataCaster/DataCaster.php +++ b/system/DataCaster/DataCaster.php @@ -28,6 +28,12 @@ use CodeIgniter\Entity\Exceptions\CastException; use CodeIgniter\Exceptions\InvalidArgumentException; +/** + * @phpstan-type cast_handlers array> + * + * @see CodeIgniter\DataCaster\DataCasterTest + * @see CodeIgniter\Entity\EntityTest + */ final class DataCaster { /** @@ -38,9 +44,9 @@ final class DataCaster private array $types = []; /** - * Convert handlers + * Convert handlers. * - * @var array [type => classname] + * @var cast_handlers [type => classname] */ private array $castHandlers = [ 'array' => ArrayCast::class, @@ -59,10 +65,10 @@ final class DataCaster ]; /** - * @param array|null $castHandlers Custom convert handlers - * @param array|null $types [field => type] - * @param object|null $helper Helper object. - * @param bool $strict Strict mode? Set to false for casts for Entity. + * @param cast_handlers|null $castHandlers Custom convert handlers + * @param array|null $types [field => type] + * @param object|null $helper Helper object. + * @param bool $strict Strict mode? Set to `false` for casts for Entity. */ public function __construct( ?array $castHandlers = null, @@ -70,7 +76,7 @@ public function __construct( private readonly ?object $helper = null, private readonly bool $strict = true, ) { - $this->castHandlers = array_merge($this->castHandlers, $castHandlers); + $this->castHandlers = array_merge($this->castHandlers, $castHandlers ?? []); if ($types !== null) { $this->setTypes($types); @@ -113,12 +119,16 @@ public function setTypes(array $types): static * Add ? at the beginning of the type (i.e. ?string) to get `null` * instead of casting $value when $value is null. * - * @param mixed $value The value to convert - * @param string $field The field name - * @param 'get'|'set' $method Allowed to "get" and "set" + * @param mixed $value The value to convert + * @param string $field The field name + * @param string $method Allowed to "get" and "set" */ public function castAs(mixed $value, string $field, string $method = 'get'): mixed { + if ($method !== 'get' && $method !== 'set') { + throw CastException::forInvalidMethod($method); + } + // If the type is not defined, return as it is. if (! isset($this->types[$field])) { return $value; diff --git a/system/Database/BaseBuilder.php b/system/Database/BaseBuilder.php index 82442fbca2b1..fd33bf40a566 100644 --- a/system/Database/BaseBuilder.php +++ b/system/Database/BaseBuilder.php @@ -41,7 +41,7 @@ class BaseBuilder /** * QB SELECT data * - * @var array + * @var list */ protected $QBSelect = []; @@ -1152,7 +1152,7 @@ protected function _like($field, string $match = '', string $type = 'AND ', stri return $this; } - $keyValue = ! is_array($field) ? [$field => $match] : $field; + $keyValue = is_array($field) ? $field : [$field => $match]; foreach ($keyValue as $k => $v) { if ($insensitiveSearch) { @@ -2113,7 +2113,7 @@ public function onConstraint($set) if (is_string($set)) { $set = explode(',', $set); - $set = array_map(static fn ($key): string => trim($key), $set); + $set = array_map(trim(...), $set); } if ($set instanceof RawSql) { @@ -2157,7 +2157,7 @@ public function setQueryAsData($query, ?string $alias = null, $columns = null): if (is_string($query)) { if ($columns !== null && is_string($columns)) { $columns = explode(',', $columns); - $columns = array_map(static fn ($key): string => trim($key), $columns); + $columns = array_map(trim(...), $columns); } $columns = (array) $columns; @@ -3065,7 +3065,7 @@ protected function compileSelect($selectOverride = false): string if ($selectOverride !== false) { $sql = $selectOverride; } else { - $sql = (! $this->QBDistinct) ? 'SELECT ' : 'SELECT DISTINCT '; + $sql = $this->QBDistinct ? 'SELECT DISTINCT ' : 'SELECT '; if (empty($this->QBSelect)) { $sql .= '*'; @@ -3257,6 +3257,9 @@ protected function compileOrderBy(): string { if (is_array($this->QBOrderBy) && $this->QBOrderBy !== []) { foreach ($this->QBOrderBy as &$orderBy) { + if (is_string($orderBy)) { + continue; + } if ($orderBy['escape'] !== false && ! $this->isLiteral($orderBy['field'])) { $orderBy['field'] = $this->db->protectIdentifiers($orderBy['field']); } @@ -3264,11 +3267,7 @@ protected function compileOrderBy(): string $orderBy = $orderBy['field'] . $orderBy['direction']; } - return $this->QBOrderBy = "\nORDER BY " . implode(', ', $this->QBOrderBy); - } - - if (is_string($this->QBOrderBy)) { - return $this->QBOrderBy; + return "\nORDER BY " . implode(', ', $this->QBOrderBy); } return ''; diff --git a/system/Database/BaseUtils.php b/system/Database/BaseUtils.php index 26957ffe01f1..a9310e1d4e32 100644 --- a/system/Database/BaseUtils.php +++ b/system/Database/BaseUtils.php @@ -250,7 +250,7 @@ public function getXMLFromResult(ResultInterface $query, array $params = []): st $xml .= $tab . '<' . $element . '>' . $newline; foreach ($row as $key => $val) { - $val = (! empty($val)) ? xml_convert((string) $val) : ''; + $val = empty($val) ? '' : xml_convert((string) $val); $xml .= $tab . $tab . '<' . $key . '>' . $val . '' . $newline; } diff --git a/system/Database/Config.php b/system/Database/Config.php index 6f25ad3c0059..fcf700ee3bcb 100644 --- a/system/Database/Config.php +++ b/system/Database/Config.php @@ -81,7 +81,9 @@ public static function connect($group = null, bool $getShared = true) $connection = static::$factory->load($config, $group); - static::$instances[$group] = $connection; + if ($getShared) { + static::$instances[$group] = $connection; + } return $connection; } diff --git a/system/Database/Database.php b/system/Database/Database.php index 80e902d5ab58..5582e4022db5 100644 --- a/system/Database/Database.php +++ b/system/Database/Database.php @@ -96,7 +96,7 @@ protected function parseDSN(array $params): array { $dsn = parse_url($params['DSN']); - if ($dsn === 0 || $dsn === '' || $dsn === '0' || $dsn === [] || $dsn === false || $dsn === null) { + if (in_array($dsn, [0, '', '0', [], false, null], true)) { throw new InvalidArgumentException('Your DSN connection string is invalid.'); } @@ -136,9 +136,9 @@ protected function parseDSN(array $params): array */ protected function initDriver(string $driver, string $class, $argument): object { - $classname = (! str_contains($driver, '\\')) - ? "CodeIgniter\\Database\\{$driver}\\{$class}" - : $driver . '\\' . $class; + $classname = str_contains($driver, '\\') + ? $driver . '\\' . $class + : "CodeIgniter\\Database\\{$driver}\\{$class}"; return new $classname($argument); } diff --git a/system/Database/MigrationRunner.php b/system/Database/MigrationRunner.php index fdff86589132..01c4e5ff64ad 100644 --- a/system/Database/MigrationRunner.php +++ b/system/Database/MigrationRunner.php @@ -47,7 +47,7 @@ class MigrationRunner * * @var string|null */ - protected $namespace; + protected $namespace = APP_NAMESPACE; /** * The database Group to migrate. @@ -136,8 +136,6 @@ public function __construct(MigrationsConfig $config, $db = null) $this->enabled = $config->enabled ?? false; $this->table = $config->table ?? 'migrations'; - $this->namespace = APP_NAMESPACE; - // Even if a DB connection is passed, since it is a test, // it is assumed to use the default group name $this->group = is_string($db) ? $db : config(Database::class)->defaultGroup; @@ -659,7 +657,7 @@ public function getHistory(string $group = 'default'): array $query = $builder->orderBy('id', 'ASC')->get(); - return ! empty($query) ? $query->getResultObject() : []; + return empty($query) ? [] : $query->getResultObject(); } /** @@ -676,7 +674,7 @@ public function getBatchHistory(int $batch, $order = 'asc'): array ->orderBy('id', $order) ->get(); - return ! empty($query) ? $query->getResultObject() : []; + return empty($query) ? [] : $query->getResultObject(); } /** diff --git a/system/Database/MySQLi/Connection.php b/system/Database/MySQLi/Connection.php index 2a9f9d3401c8..a1c0dcce8479 100644 --- a/system/Database/MySQLi/Connection.php +++ b/system/Database/MySQLi/Connection.php @@ -123,7 +123,7 @@ public function connect(bool $persistent = false) $this->mysqli->options(MYSQLI_OPT_INT_AND_FLOAT_NATIVE, 1); } - if (isset($this->strictOn)) { + if ($this->strictOn !== null) { if ($this->strictOn) { $this->mysqli->options( MYSQLI_INIT_COMMAND, diff --git a/system/Database/OCI8/Connection.php b/system/Database/OCI8/Connection.php index 67921d2c13f8..796b412982a9 100644 --- a/system/Database/OCI8/Connection.php +++ b/system/Database/OCI8/Connection.php @@ -349,12 +349,25 @@ protected function _fieldData(string $table): array $retval[$i]->max_length = $length; $retval[$i]->nullable = $query[$i]->NULLABLE === 'Y'; - $retval[$i]->default = $query[$i]->DATA_DEFAULT; + $retval[$i]->default = $this->normalizeDefault($query[$i]->DATA_DEFAULT); } return $retval; } + /** + * Removes trailing whitespace from default values + * returned in database column metadata queries. + */ + private function normalizeDefault(?string $default): ?string + { + if ($default === null) { + return $default; + } + + return rtrim($default); + } + /** * Returns an array of objects with index data * diff --git a/system/Database/Postgre/Connection.php b/system/Database/Postgre/Connection.php index 9b480975de2e..71549ad0b08f 100644 --- a/system/Database/Postgre/Connection.php +++ b/system/Database/Postgre/Connection.php @@ -382,7 +382,7 @@ protected function _indexData(string $table): array $obj = new stdClass(); $obj->name = $row->indexname; $_fields = explode(',', preg_replace('/^.*\((.+?)\)$/', '$1', trim($row->indexdef))); - $obj->fields = array_map(static fn ($v): string => trim($v), $_fields); + $obj->fields = array_map(trim(...), $_fields); if (str_starts_with($row->indexdef, 'CREATE UNIQUE INDEX pk')) { $obj->type = 'PRIMARY'; diff --git a/system/Database/Postgre/Forge.php b/system/Database/Postgre/Forge.php index 8b18d7d48ca7..d8e7d5886604 100644 --- a/system/Database/Postgre/Forge.php +++ b/system/Database/Postgre/Forge.php @@ -109,7 +109,7 @@ protected function _alterTable(string $alterType, string $table, $processedField if (! empty($field['default'])) { $sqls[] = $sql . ' ALTER COLUMN ' . $this->db->escapeIdentifiers($field['name']) - . " SET DEFAULT {$field['default']}"; + . " SET {$field['default']}"; } $nullable = true; // Nullable by default. diff --git a/system/Database/SQLSRV/Builder.php b/system/Database/SQLSRV/Builder.php index ec4d41195626..0b17a52ff344 100644 --- a/system/Database/SQLSRV/Builder.php +++ b/system/Database/SQLSRV/Builder.php @@ -584,7 +584,7 @@ protected function compileSelect($selectOverride = false): string if ($selectOverride !== false) { $sql = $selectOverride; } else { - $sql = (! $this->QBDistinct) ? 'SELECT ' : 'SELECT DISTINCT '; + $sql = $this->QBDistinct ? 'SELECT DISTINCT ' : 'SELECT '; // SQL Server can't work with select * if group by is specified if (empty($this->QBSelect) && $this->QBGroupBy !== [] && is_array($this->QBGroupBy)) { diff --git a/system/Database/SQLSRV/Connection.php b/system/Database/SQLSRV/Connection.php index 7ef4f31901d1..1ebd73908ebd 100644 --- a/system/Database/SQLSRV/Connection.php +++ b/system/Database/SQLSRV/Connection.php @@ -266,7 +266,7 @@ protected function _indexData(string $table): array $obj->name = $row->index_name; $_fields = explode(',', trim($row->index_keys)); - $obj->fields = array_map(static fn ($v): string => trim($v), $_fields); + $obj->fields = array_map(trim(...), $_fields); if (str_contains($row->index_description, 'primary key located on')) { $obj->type = 'PRIMARY'; @@ -384,12 +384,42 @@ protected function _fieldData(string $table): array ); $retVal[$i]->nullable = $query[$i]->IS_NULLABLE !== 'NO'; - $retVal[$i]->default = $query[$i]->COLUMN_DEFAULT; + $retVal[$i]->default = $this->normalizeDefault($query[$i]->COLUMN_DEFAULT); } return $retVal; } + /** + * Normalizes SQL Server COLUMN_DEFAULT values. + * Removes wrapping parentheses and handles basic conversions. + */ + private function normalizeDefault(?string $default): ?string + { + if ($default === null) { + return null; + } + + $default = trim($default); + + // Remove outer parentheses (handles both single and double wrapping) + while (preg_match('/^\((.*)\)$/', $default, $matches)) { + $default = trim($matches[1]); + } + + // Handle NULL literal + if (strcasecmp($default, 'NULL') === 0) { + return null; + } + + // Handle string literals - remove quotes and unescape + if (preg_match("/^'(.*)'$/s", $default, $matches)) { + return str_replace("''", "'", $matches[1]); + } + + return $default; + } + /** * Begin Transaction */ diff --git a/system/Database/SQLSRV/Forge.php b/system/Database/SQLSRV/Forge.php index f35d8e7bbca2..b64c25a05100 100644 --- a/system/Database/SQLSRV/Forge.php +++ b/system/Database/SQLSRV/Forge.php @@ -253,8 +253,27 @@ protected function _alterTable(string $alterType, string $table, $processedField } if (! empty($field['default'])) { - $sqls[] = $sql . ' ALTER COLUMN ADD CONSTRAINT ' . $this->db->escapeIdentifiers($field['name']) . '_def' - . " DEFAULT {$field['default']} FOR " . $this->db->escapeIdentifiers($field['name']); + $fullTable = $this->db->escapeIdentifiers($this->db->schema) . '.' . $this->db->escapeIdentifiers($table); + $colName = $field['name']; // bare, for sys.columns lookup + + // find the existing default constraint name for this column + $findSql = <<db->query($findSql)->getRowArray(); + if (isset($toDrop['constraint_name']) && $toDrop['constraint_name'] !== '') { + $sqls[] = $sql . ' DROP CONSTRAINT ' . $this->db->escapeIdentifiers($toDrop['constraint_name']); + } + + $sqls[] = $sql . ' ADD CONSTRAINT ' . $this->db->escapeIdentifiers($field['name'] . '_def') + . "{$field['default']} FOR " . $this->db->escapeIdentifiers($field['name']); } $nullable = true; // Nullable by default. @@ -379,7 +398,7 @@ protected function _attributeType(array &$attributes) // https://learn.microsoft.com/en-us/sql/t-sql/data-types/char-and-varchar-transact-sql?view=sql-server-ver16#remarks $maxLength = max( array_map( - static fn ($value): int => strlen($value), + strlen(...), $attributes['CONSTRAINT'], ), ); diff --git a/system/Database/SQLite3/Connection.php b/system/Database/SQLite3/Connection.php index 0d3290b38d9d..ec73a75b18bd 100644 --- a/system/Database/SQLite3/Connection.php +++ b/system/Database/SQLite3/Connection.php @@ -107,7 +107,7 @@ public function connect(bool $persistent = false) $this->database = WRITEPATH . $this->database; } - $sqlite = (! isset($this->password) || $this->password !== '') + $sqlite = ($this->password === null || $this->password === '') ? new SQLite3($this->database) : new SQLite3($this->database, SQLITE3_OPEN_READWRITE | SQLITE3_OPEN_CREATE, $this->password); diff --git a/system/Debug/BaseExceptionHandler.php b/system/Debug/BaseExceptionHandler.php index 3966b2ee1bae..b9180a98bd59 100644 --- a/system/Debug/BaseExceptionHandler.php +++ b/system/Debug/BaseExceptionHandler.php @@ -13,6 +13,8 @@ namespace CodeIgniter\Debug; +use CodeIgniter\HTTP\CLIRequest; +use CodeIgniter\HTTP\IncomingRequest; use CodeIgniter\HTTP\RequestInterface; use CodeIgniter\HTTP\ResponseInterface; use Config\Exceptions as ExceptionsConfig; @@ -54,6 +56,8 @@ public function __construct(ExceptionsConfig $config) /** * The main entry point into the handler. * + * @param CLIRequest|IncomingRequest $request + * * @return void */ abstract public function handle( diff --git a/system/Debug/ExceptionHandler.php b/system/Debug/ExceptionHandler.php index 68ab5feb768e..805b5691c079 100644 --- a/system/Debug/ExceptionHandler.php +++ b/system/Debug/ExceptionHandler.php @@ -13,8 +13,10 @@ namespace CodeIgniter\Debug; +use Closure; use CodeIgniter\API\ResponseTrait; use CodeIgniter\Exceptions\PageNotFoundException; +use CodeIgniter\HTTP\CLIRequest; use CodeIgniter\HTTP\Exceptions\HTTPException; use CodeIgniter\HTTP\IncomingRequest; use CodeIgniter\HTTP\RequestInterface; @@ -41,6 +43,8 @@ final class ExceptionHandler extends BaseExceptionHandler implements ExceptionHa /** * Determines the correct way to display the error. + * + * @param CLIRequest|IncomingRequest $request */ public function handle( Throwable $exception, @@ -82,6 +86,12 @@ public function handle( ? $this->collectVars($exception, $statusCode) : ''; + // Sanitize data to remove non-JSON-serializable values (resources, closures) + // before formatting for API responses (JSON, XML, etc.) + if ($data !== '') { + $data = $this->sanitizeData($data); + } + $this->respond($data, $statusCode)->send(); if (ENVIRONMENT !== 'testing') { @@ -164,4 +174,53 @@ private function isDisplayErrorsEnabled(): bool true, ); } + + /** + * Sanitizes data to remove non-JSON-serializable values like resources and closures. + * This is necessary for API responses that need to be JSON/XML encoded. + * + * @param array $seen Used internally to prevent infinite recursion + */ + private function sanitizeData(mixed $data, array &$seen = []): mixed + { + $type = gettype($data); + + switch ($type) { + case 'resource': + case 'resource (closed)': + return '[Resource #' . (int) $data . ']'; + + case 'array': + $result = []; + + foreach ($data as $key => $value) { + $result[$key] = $this->sanitizeData($value, $seen); + } + + return $result; + + case 'object': + $oid = spl_object_id($data); + if (isset($seen[$oid])) { + return '[' . $data::class . ' Object *RECURSION*]'; + } + $seen[$oid] = true; + + if ($data instanceof Closure) { + return '[Closure]'; + } + + $result = []; + + foreach ((array) $data as $key => $value) { + $cleanKey = preg_replace('/^\x00.*\x00/', '', (string) $key); + $result[$cleanKey] = $this->sanitizeData($value, $seen); + } + + return $result; + + default: + return $data; + } + } } diff --git a/system/Debug/ExceptionHandlerInterface.php b/system/Debug/ExceptionHandlerInterface.php index 05915c638f36..7f91b3c5152d 100644 --- a/system/Debug/ExceptionHandlerInterface.php +++ b/system/Debug/ExceptionHandlerInterface.php @@ -13,6 +13,8 @@ namespace CodeIgniter\Debug; +use CodeIgniter\HTTP\CLIRequest; +use CodeIgniter\HTTP\IncomingRequest; use CodeIgniter\HTTP\RequestInterface; use CodeIgniter\HTTP\ResponseInterface; use Throwable; @@ -21,6 +23,8 @@ interface ExceptionHandlerInterface { /** * Determines the correct way to display the error. + * + * @param CLIRequest|IncomingRequest $request */ public function handle( Throwable $exception, diff --git a/system/Debug/Timer.php b/system/Debug/Timer.php index 37e9901977e7..98b1299a89f7 100644 --- a/system/Debug/Timer.php +++ b/system/Debug/Timer.php @@ -46,7 +46,7 @@ class Timer public function start(string $name, ?float $time = null) { $this->timers[strtolower($name)] = [ - 'start' => ! empty($time) ? $time : microtime(true), + 'start' => empty($time) ? microtime(true) : $time, 'end' => null, ]; diff --git a/system/Debug/Toolbar/Collectors/Database.php b/system/Debug/Toolbar/Collectors/Database.php index df876422aaf1..be57931b30f9 100644 --- a/system/Debug/Toolbar/Collectors/Database.php +++ b/system/Debug/Toolbar/Collectors/Database.php @@ -104,7 +104,7 @@ public static function collect(Query $query) static::$queries[] = [ 'query' => $query, 'string' => $queryString, - 'duplicate' => in_array($queryString, array_column(static::$queries, 'string', null), true), + 'duplicate' => in_array($queryString, array_column(static::$queries, 'string'), true), 'trace' => $backtrace, ]; } @@ -147,8 +147,7 @@ protected function formatTimelineData(): array */ public function display(): array { - $data = []; - $data['queries'] = array_map(static function (array $query): array { + return ['queries' => array_map(static function (array $query): array { $isDuplicate = $query['duplicate'] === true; $firstNonSystemLine = ''; @@ -195,9 +194,7 @@ public function display(): array 'trace-file' => $firstNonSystemLine, 'qid' => md5($query['query'] . Time::now()->format('0.u00 U')), ]; - }, static::$queries); - - return $data; + }, static::$queries)]; } /** diff --git a/system/Debug/Toolbar/Collectors/Logs.php b/system/Debug/Toolbar/Collectors/Logs.php index c6e22fc0bbd2..f9fdabecbff1 100644 --- a/system/Debug/Toolbar/Collectors/Logs.php +++ b/system/Debug/Toolbar/Collectors/Logs.php @@ -47,7 +47,7 @@ class Logs extends BaseCollector * * @var list */ - protected $data; + protected $data = []; /** * Returns the data of this collector to be formatted in the toolbar. @@ -68,7 +68,7 @@ public function isEmpty(): bool { $this->collectLogs(); - return $this->data !== []; + return $this->data === []; } /** diff --git a/system/Debug/Toolbar/Views/toolbar.js b/system/Debug/Toolbar/Views/toolbar.js index ddaa2386f260..9e4547b6cb35 100644 --- a/system/Debug/Toolbar/Views/toolbar.js +++ b/system/Debug/Toolbar/Views/toolbar.js @@ -337,6 +337,11 @@ var ciDebugBar = { const OUTER_ELEMENTS = ["HTML", "BODY", "HEAD"]; var getValidElementInner = function (node, reverse) { + // handle null node + if (node === null) { + return null; + } + // handle invalid tags if (OUTER_ELEMENTS.indexOf(node.nodeName) !== -1) { for (var i = 0; i < document.body.children.length; ++i) { @@ -440,7 +445,7 @@ var ciDebugBar = { var debugPath = document.createElement("div"); // path var childArray = startElement[0].parentNode.childNodes; // target child array var parent = startElement[0].parentNode; - var start, end; + let start, end; // setup container debugDiv.classList.add("debug-view"); @@ -785,7 +790,7 @@ var ciDebugBar = { '">' + row.innerText.replace( patt, - '' + '' ) + '' + ""; diff --git a/system/Email/Email.php b/system/Email/Email.php index 9ed8465daa66..19282e7e5cce 100644 --- a/system/Email/Email.php +++ b/system/Email/Email.php @@ -839,7 +839,7 @@ public function setNewline($newline = "\n") */ public function setCRLF($CRLF = "\n") { - $this->CRLF = ! in_array($CRLF, ["\n", "\r\n", "\r"], true) ? "\n" : $CRLF; + $this->CRLF = in_array($CRLF, ["\n", "\r\n", "\r"], true) ? $CRLF : "\n"; return $this; } @@ -2222,7 +2222,7 @@ protected function mimeTypes($ext = '') { $mime = Mimes::guessTypeFromExtension(strtolower($ext)); - return ! empty($mime) ? $mime : 'application/x-unknown-content-type'; + return empty($mime) ? 'application/x-unknown-content-type' : $mime; } public function __destruct() diff --git a/system/Entity/Cast/ArrayCast.php b/system/Entity/Cast/ArrayCast.php index 1c810645dec6..6860b41416b6 100644 --- a/system/Entity/Cast/ArrayCast.php +++ b/system/Entity/Cast/ArrayCast.php @@ -13,14 +13,8 @@ namespace CodeIgniter\Entity\Cast; -/** - * Class ArrayCast - */ class ArrayCast extends BaseCast { - /** - * {@inheritDoc} - */ public static function get($value, array $params = []): array { if (is_string($value) && (str_starts_with($value, 'a:') || str_starts_with($value, 's:'))) { @@ -30,9 +24,6 @@ public static function get($value, array $params = []): array return (array) $value; } - /** - * {@inheritDoc} - */ public static function set($value, array $params = []): string { return serialize($value); diff --git a/system/Entity/Cast/BaseCast.php b/system/Entity/Cast/BaseCast.php index 34cb28e787c5..c93e32c0537c 100644 --- a/system/Entity/Cast/BaseCast.php +++ b/system/Entity/Cast/BaseCast.php @@ -13,32 +13,13 @@ namespace CodeIgniter\Entity\Cast; -/** - * Class BaseCast - */ abstract class BaseCast implements CastInterface { - /** - * Get - * - * @param array|bool|float|int|object|string|null $value Data - * @param array $params Additional param - * - * @return array|bool|float|int|object|string|null - */ public static function get($value, array $params = []) { return $value; } - /** - * Set - * - * @param array|bool|float|int|object|string|null $value Data - * @param array $params Additional param - * - * @return array|bool|float|int|object|string|null - */ public static function set($value, array $params = []) { return $value; diff --git a/system/Entity/Cast/BooleanCast.php b/system/Entity/Cast/BooleanCast.php index 8d95ba24b1de..7ac9f0ba37ee 100644 --- a/system/Entity/Cast/BooleanCast.php +++ b/system/Entity/Cast/BooleanCast.php @@ -13,14 +13,8 @@ namespace CodeIgniter\Entity\Cast; -/** - * Class BooleanCast - */ class BooleanCast extends BaseCast { - /** - * {@inheritDoc} - */ public static function get($value, array $params = []): bool { return (bool) $value; diff --git a/system/Entity/Cast/CSVCast.php b/system/Entity/Cast/CSVCast.php index 7b8be55d523c..c78a1315111a 100644 --- a/system/Entity/Cast/CSVCast.php +++ b/system/Entity/Cast/CSVCast.php @@ -13,22 +13,13 @@ namespace CodeIgniter\Entity\Cast; -/** - * Class CSVCast - */ class CSVCast extends BaseCast { - /** - * {@inheritDoc} - */ public static function get($value, array $params = []): array { return explode(',', $value); } - /** - * {@inheritDoc} - */ public static function set($value, array $params = []): string { return implode(',', $value); diff --git a/system/Entity/Cast/CastInterface.php b/system/Entity/Cast/CastInterface.php index 9d790e8edbb9..8f837fe8014c 100644 --- a/system/Entity/Cast/CastInterface.php +++ b/system/Entity/Cast/CastInterface.php @@ -14,8 +14,6 @@ namespace CodeIgniter\Entity\Cast; /** - * Interface CastInterface - * * The methods work at (1)(4) only. * [App Code] --- (1) --> [Entity] --- (2) --> [Database] * [App Code] <-- (4) --- [Entity] <-- (3) --- [Database] diff --git a/system/Entity/Cast/DatetimeCast.php b/system/Entity/Cast/DatetimeCast.php index 88b7b29267e0..72206ca883f7 100644 --- a/system/Entity/Cast/DatetimeCast.php +++ b/system/Entity/Cast/DatetimeCast.php @@ -17,9 +17,6 @@ use DateTime; use Exception; -/** - * Class DatetimeCast - */ class DatetimeCast extends BaseCast { /** diff --git a/system/Entity/Cast/FloatCast.php b/system/Entity/Cast/FloatCast.php index 642e849e747e..1a767c0953f0 100644 --- a/system/Entity/Cast/FloatCast.php +++ b/system/Entity/Cast/FloatCast.php @@ -13,14 +13,8 @@ namespace CodeIgniter\Entity\Cast; -/** - * Class FloatCast - */ class FloatCast extends BaseCast { - /** - * {@inheritDoc} - */ public static function get($value, array $params = []): float { return (float) $value; diff --git a/system/Entity/Cast/IntBoolCast.php b/system/Entity/Cast/IntBoolCast.php index fb1c470e892e..94e65df8dde0 100644 --- a/system/Entity/Cast/IntBoolCast.php +++ b/system/Entity/Cast/IntBoolCast.php @@ -14,8 +14,6 @@ namespace CodeIgniter\Entity\Cast; /** - * Int Bool Cast - * * DB column: int (0/1) <--> Class property: bool */ final class IntBoolCast extends BaseCast diff --git a/system/Entity/Cast/IntegerCast.php b/system/Entity/Cast/IntegerCast.php index c0ecec732436..84bf09211c0f 100644 --- a/system/Entity/Cast/IntegerCast.php +++ b/system/Entity/Cast/IntegerCast.php @@ -13,14 +13,8 @@ namespace CodeIgniter\Entity\Cast; -/** - * Class IntegerCast - */ class IntegerCast extends BaseCast { - /** - * {@inheritDoc} - */ public static function get($value, array $params = []): int { return (int) $value; diff --git a/system/Entity/Cast/JsonCast.php b/system/Entity/Cast/JsonCast.php index ef389269ede4..245de29f3956 100644 --- a/system/Entity/Cast/JsonCast.php +++ b/system/Entity/Cast/JsonCast.php @@ -17,14 +17,8 @@ use JsonException; use stdClass; -/** - * Class JsonCast - */ class JsonCast extends BaseCast { - /** - * {@inheritDoc} - */ public static function get($value, array $params = []) { $associative = in_array('array', $params, true); diff --git a/system/Entity/Cast/ObjectCast.php b/system/Entity/Cast/ObjectCast.php index 1bee213d50a7..10affad4c80c 100644 --- a/system/Entity/Cast/ObjectCast.php +++ b/system/Entity/Cast/ObjectCast.php @@ -13,14 +13,8 @@ namespace CodeIgniter\Entity\Cast; -/** - * Class ObjectCast - */ class ObjectCast extends BaseCast { - /** - * {@inheritDoc} - */ public static function get($value, array $params = []): object { return (object) $value; diff --git a/system/Entity/Cast/StringCast.php b/system/Entity/Cast/StringCast.php index e4ed04b94d95..d538f4332dca 100644 --- a/system/Entity/Cast/StringCast.php +++ b/system/Entity/Cast/StringCast.php @@ -13,14 +13,8 @@ namespace CodeIgniter\Entity\Cast; -/** - * Class StringCast - */ class StringCast extends BaseCast { - /** - * {@inheritDoc} - */ public static function get($value, array $params = []): string { return (string) $value; diff --git a/system/Entity/Cast/TimestampCast.php b/system/Entity/Cast/TimestampCast.php index a445badec1f9..44bdf78864d1 100644 --- a/system/Entity/Cast/TimestampCast.php +++ b/system/Entity/Cast/TimestampCast.php @@ -15,14 +15,8 @@ use CodeIgniter\Entity\Exceptions\CastException; -/** - * Class TimestampCast - */ class TimestampCast extends BaseCast { - /** - * {@inheritDoc} - */ public static function get($value, array $params = []) { $value = strtotime($value); diff --git a/system/Entity/Cast/URICast.php b/system/Entity/Cast/URICast.php index d0d510b10919..a66bfba3ef45 100644 --- a/system/Entity/Cast/URICast.php +++ b/system/Entity/Cast/URICast.php @@ -15,14 +15,8 @@ use CodeIgniter\HTTP\URI; -/** - * Class URICast - */ class URICast extends BaseCast { - /** - * {@inheritDoc} - */ public static function get($value, array $params = []): URI { return $value instanceof URI ? $value : new URI($value); diff --git a/system/Events/Events.php b/system/Events/Events.php index ae68e20573ed..4c255f02df05 100644 --- a/system/Events/Events.php +++ b/system/Events/Events.php @@ -85,7 +85,7 @@ public static function initialize() } $files = array_filter(array_map( - static fn (string $file): false|string => realpath($file), + realpath(...), $files, )); diff --git a/system/Filters/PageCache.php b/system/Filters/PageCache.php index b0013c81ce37..7a2949802723 100644 --- a/system/Filters/PageCache.php +++ b/system/Filters/PageCache.php @@ -46,13 +46,7 @@ public function before(RequestInterface $request, $arguments = null) $response = service('response'); - $cachedResponse = $this->pageCache->get($request, $response); - - if ($cachedResponse instanceof ResponseInterface) { - return $cachedResponse; - } - - return null; + return $this->pageCache->get($request, $response); } /** diff --git a/system/HTTP/Exceptions/RedirectException.php b/system/HTTP/Exceptions/RedirectException.php index abb9be1e9e35..a16dfc1a8a2d 100644 --- a/system/HTTP/Exceptions/RedirectException.php +++ b/system/HTTP/Exceptions/RedirectException.php @@ -80,7 +80,7 @@ public function getResponse(): ResponseInterface $location = $this->response->getHeaderLine('Location'); - service(('logger'))->info(sprintf( + service('logger')->info(sprintf( 'REDIRECTED ROUTE at %s', $location !== '' ? $location : substr($this->response->getHeaderLine('Refresh'), 6), )); diff --git a/system/HTTP/Response.php b/system/HTTP/Response.php index 9de285b85d08..3c59f2e9800d 100644 --- a/system/HTTP/Response.php +++ b/system/HTTP/Response.php @@ -221,7 +221,7 @@ public function getStatusCode(): int public function getReasonPhrase() { if ($this->reason === '') { - return ! empty($this->statusCode) ? static::$statusCodes[$this->statusCode] : ''; + return empty($this->statusCode) ? '' : static::$statusCodes[$this->statusCode]; } return $this->reason; diff --git a/system/HTTP/URI.php b/system/HTTP/URI.php index 5bcf11de655a..6045f0fd3e64 100644 --- a/system/HTTP/URI.php +++ b/system/HTTP/URI.php @@ -181,9 +181,9 @@ public static function createURIString( } if ((string) $path !== '') { - $uri .= ! str_ends_with($uri, '/') - ? '/' . ltrim($path, '/') - : ltrim($path, '/'); + $uri .= str_ends_with($uri, '/') + ? ltrim($path, '/') + : '/' . ltrim($path, '/'); } if ((string) $query !== '') { diff --git a/system/HTTP/UserAgent.php b/system/HTTP/UserAgent.php index 5e8eece63659..ba9e544ae2f8 100644 --- a/system/HTTP/UserAgent.php +++ b/system/HTTP/UserAgent.php @@ -109,8 +109,10 @@ public function __construct(?UserAgents $config = null) { $this->config = $config ?? config(UserAgents::class); - if (isset($_SERVER['HTTP_USER_AGENT'])) { - $this->agent = trim($_SERVER['HTTP_USER_AGENT']); + $userAgent = service('superglobals')->server('HTTP_USER_AGENT'); + + if ($userAgent !== null) { + $this->agent = trim($userAgent); $this->compileData(); } } @@ -175,10 +177,11 @@ public function isMobile(?string $key = null): bool public function isReferral(): bool { if (! isset($this->referrer)) { - if (empty($_SERVER['HTTP_REFERER'])) { + $referer = service('superglobals')->server('HTTP_REFERER'); + if ($referer === null || $referer === '') { $this->referrer = false; } else { - $refererHost = @parse_url($_SERVER['HTTP_REFERER'], PHP_URL_HOST); + $refererHost = @parse_url($referer, PHP_URL_HOST); $ownHost = parse_url(\base_url(), PHP_URL_HOST); $this->referrer = ($refererHost && $refererHost !== $ownHost); @@ -241,7 +244,9 @@ public function getMobile(): string */ public function getReferrer(): string { - return empty($_SERVER['HTTP_REFERER']) ? '' : trim($_SERVER['HTTP_REFERER']); + $referrer = service('superglobals')->server('HTTP_REFERER'); + + return $referrer === null ? '' : trim($referrer); } /** diff --git a/system/Helpers/cookie_helper.php b/system/Helpers/cookie_helper.php index 18239fe2ebff..fb1c1f366fed 100644 --- a/system/Helpers/cookie_helper.php +++ b/system/Helpers/cookie_helper.php @@ -24,16 +24,29 @@ * * Accepts seven parameters, or you can submit an associative * array in the first parameter containing all the values. + * ['', 'value', 'expire', '', '', '', '', '', 'name'] * - * @param array|Cookie|string $name Cookie name / array containing binds / Cookie object - * @param string $value The value of the cookie - * @param int $expire The number of seconds until expiration - * @param string $domain For site-wide cookie. Usually: .yourdomain.com - * @param string $path The cookie path - * @param string $prefix The cookie prefix ('': the default prefix) - * @param bool|null $secure True makes the cookie secure - * @param bool|null $httpOnly True makes the cookie accessible via http(s) only (no javascript) - * @param string|null $sameSite The cookie SameSite value + * @param array{ + * name?: string, + * value?: string, + * prefix?: string, + * max-age?: int|numeric-string, + * expire?: DateTimeInterface|int|string, + * path?: string, + * domain?: string, + * secure?: bool, + * httponly?: bool, + * samesite?: string, + * raw?: bool + * }|Cookie|string $name Cookie name / array containing binds / Cookie object + * @param string $value The value of the cookie + * @param int $expire The number of seconds until expiration + * @param string $domain For site-wide cookie. Usually: .yourdomain.com + * @param string $path The cookie path + * @param string $prefix The cookie prefix ('': the default prefix) + * @param bool|null $secure True makes the cookie secure + * @param bool|null $httpOnly True makes the cookie accessible via http(s) only (no javascript) + * @param string|null $sameSite The cookie SameSite value * * @see \CodeIgniter\HTTP\Response::setCookie() */ @@ -62,7 +75,7 @@ function set_cookie( * '': the prefix in Config\Cookie * null: no prefix * - * @return array|string|null + * @return array|string|null * * @see \CodeIgniter\HTTP\IncomingRequest::getCookie() */ diff --git a/system/Helpers/form_helper.php b/system/Helpers/form_helper.php index 7b89bb9ec173..a9415821f970 100644 --- a/system/Helpers/form_helper.php +++ b/system/Helpers/form_helper.php @@ -350,7 +350,7 @@ function form_checkbox($data = '', string $value = '', bool $checked = false, $e { $defaults = [ 'type' => 'checkbox', - 'name' => (! is_array($data) ? $data : ''), + 'name' => is_array($data) ? '' : $data, 'value' => $value, ]; diff --git a/system/Honeypot/Exceptions/HoneypotException.php b/system/Honeypot/Exceptions/HoneypotException.php index 7ff493e4edf8..5185f6d3c843 100644 --- a/system/Honeypot/Exceptions/HoneypotException.php +++ b/system/Honeypot/Exceptions/HoneypotException.php @@ -41,6 +41,8 @@ public static function forNoNameField() * Thrown when the hidden value of config is false. * * @return static + * + * @deprecated 4.6.4 Never used. */ public static function forNoHiddenValue() { diff --git a/system/I18n/Exceptions/I18nException.php b/system/I18n/Exceptions/I18nException.php index 79c9e8326ad0..ec9dd3277e1e 100644 --- a/system/I18n/Exceptions/I18nException.php +++ b/system/I18n/Exceptions/I18nException.php @@ -72,7 +72,7 @@ public static function forInvalidOverDay(string $lastDay, string $day) */ public static function forInvalidHour(string $hour) { - return new static(lang('Time.invalidHour', [$hour])); + return new static(lang('Time.invalidHours', [$hour])); } /** diff --git a/system/I18n/TimeTrait.php b/system/I18n/TimeTrait.php index 42278c960c43..7742c73a65ac 100644 --- a/system/I18n/TimeTrait.php +++ b/system/I18n/TimeTrait.php @@ -73,7 +73,7 @@ trait TimeTrait */ public function __construct(?string $time = null, $timezone = null, ?string $locale = null) { - $this->locale = $locale !== null && $locale !== '' && $locale !== '0' ? $locale : Locale::getDefault(); + $this->locale = in_array($locale, [null, '', '0'], true) ? Locale::getDefault() : $locale; $time ??= ''; @@ -940,7 +940,7 @@ public function sameAs($testTime, ?string $timezone = null): bool if ($testTime instanceof DateTimeInterface) { $testTime = $testTime->format('Y-m-d H:i:s.u O'); } elseif (is_string($testTime)) { - $timezone = $timezone !== null && $timezone !== '' && $timezone !== '0' ? $timezone : $this->timezone; + $timezone = in_array($timezone, [null, '', '0'], true) ? $this->timezone : $timezone; $timezone = $timezone instanceof DateTimeZone ? $timezone : new DateTimeZone($timezone); $testTime = new DateTime($testTime, $timezone); $testTime = $testTime->format('Y-m-d H:i:s.u O'); @@ -1102,7 +1102,7 @@ public function getUTCObject($time, ?string $timezone = null) if ($time instanceof static) { $time = $time->toDateTime(); } elseif (is_string($time)) { - $timezone = $timezone !== null && $timezone !== '' && $timezone !== '0' ? $timezone : $this->timezone; + $timezone = in_array($timezone, [null, '', '0'], true) ? $this->timezone : $timezone; $timezone = $timezone instanceof DateTimeZone ? $timezone : new DateTimeZone($timezone); $time = new DateTime($time, $timezone); } diff --git a/system/Images/Handlers/ImageMagickHandler.php b/system/Images/Handlers/ImageMagickHandler.php index 233ea2d07149..bae055b17166 100644 --- a/system/Images/Handlers/ImageMagickHandler.php +++ b/system/Images/Handlers/ImageMagickHandler.php @@ -72,7 +72,7 @@ public function __construct($config = null) */ public function _resize(bool $maintainRatio = false) { - $source = ! empty($this->resource) ? $this->resource : $this->image()->getPathname(); + $source = empty($this->resource) ? $this->image()->getPathname() : $this->resource; $destination = $this->getResourcePath(); $escape = '\\'; @@ -99,7 +99,7 @@ public function _resize(bool $maintainRatio = false) */ public function _crop() { - $source = ! empty($this->resource) ? $this->resource : $this->image()->getPathname(); + $source = empty($this->resource) ? $this->image()->getPathname() : $this->resource; $destination = $this->getResourcePath(); $extent = ' '; @@ -126,7 +126,7 @@ protected function _rotate(int $angle) { $angle = '-rotate ' . $angle; - $source = ! empty($this->resource) ? $this->resource : $this->image()->getPathname(); + $source = empty($this->resource) ? $this->image()->getPathname() : $this->resource; $destination = $this->getResourcePath(); $action = ' ' . $angle . ' ' . escapeshellarg($source) . ' ' . escapeshellarg($destination); @@ -147,7 +147,7 @@ protected function _flatten(int $red = 255, int $green = 255, int $blue = 255) { $flatten = "-background 'rgb({$red},{$green},{$blue})' -flatten"; - $source = ! empty($this->resource) ? $this->resource : $this->image()->getPathname(); + $source = empty($this->resource) ? $this->image()->getPathname() : $this->resource; $destination = $this->getResourcePath(); $action = ' ' . $flatten . ' ' . escapeshellarg($source) . ' ' . escapeshellarg($destination); @@ -168,7 +168,7 @@ protected function _flip(string $direction) { $angle = $direction === 'horizontal' ? '-flop' : '-flip'; - $source = ! empty($this->resource) ? $this->resource : $this->image()->getPathname(); + $source = empty($this->resource) ? $this->image()->getPathname() : $this->resource; $destination = $this->getResourcePath(); $action = ' ' . $angle . ' ' . escapeshellarg($source) . ' ' . escapeshellarg($destination); @@ -317,12 +317,8 @@ protected function ensureResource() */ protected function supportedFormatCheck() { - switch ($this->image()->imageType) { - case IMAGETYPE_WEBP: - if (! in_array('WEBP', Imagick::queryFormats(), true)) { - throw ImageException::forInvalidImageCreate(lang('images.webpNotSupported')); - } - break; + if ($this->image()->imageType === IMAGETYPE_WEBP && ! in_array('WEBP', Imagick::queryFormats(), true)) { + throw ImageException::forInvalidImageCreate(lang('Images.webpNotSupported')); } } @@ -411,7 +407,7 @@ protected function _text(string $text, array $options = []) // Text $cmd .= ' -annotate 0 ' . escapeshellarg($text); - $source = ! empty($this->resource) ? $this->resource : $this->image()->getPathname(); + $source = empty($this->resource) ? $this->image()->getPathname() : $this->resource; $destination = $this->getResourcePath(); $cmd = ' ' . escapeshellarg($source) . ' ' . $cmd . ' ' . escapeshellarg($destination); diff --git a/system/Language/Language.php b/system/Language/Language.php index a4034bdf6b90..652d17a5b68d 100644 --- a/system/Language/Language.php +++ b/system/Language/Language.php @@ -21,6 +21,8 @@ * * Locale-based, built on top of PHP internationalization. * + * @phpstan-type LoadedStrings array|string>|string|list> + * * @see \CodeIgniter\Language\LanguageTest */ class Language @@ -30,20 +32,19 @@ class Language * from files for faster retrieval on * second use. * - * @var array + * @var array> */ protected $language = []; /** - * The current language/locale to work with. + * The current locale to work with. * - * @var string + * @var non-empty-string */ protected $locale; /** - * Boolean value whether the intl - * libraries exist on the system. + * Boolean value whether the `intl` extension exists on the system. * * @var bool */ @@ -53,10 +54,13 @@ class Language * Stores filenames that have been * loaded so that we don't load them again. * - * @var array + * @var array> */ protected $loadedFiles = []; + /** + * @param non-empty-string $locale + */ public function __construct(string $locale) { $this->locale = $locale; @@ -69,6 +73,8 @@ public function __construct(string $locale) /** * Sets the current locale to use when performing string lookups. * + * @param non-empty-string|null $locale + * * @return $this */ public function setLocale(?string $locale = null) @@ -89,22 +95,24 @@ public function getLocale(): string * Parses the language string for a file, loads the file, if necessary, * getting the line. * + * @param array $args + * * @return list|string */ public function getLine(string $line, array $args = []) { - // if no file is given, just parse the line + // 1. Format the line as-is if it does not have a file. if (! str_contains($line, '.')) { return $this->formatMessage($line, $args); } - // Parse out the file name and the actual alias. - // Will load the language file and strings. + // 2. Get the formatted line using the file and line extracted from $line and the current locale. [$file, $parsedLine] = $this->parseLine($line, $this->locale); $output = $this->getTranslationOutput($this->locale, $file, $parsedLine); - if ($output === null && strpos($this->locale, '-')) { + // 3. If not found, try the locale without region (e.g., 'en-US' -> 'en'). + if ($output === null && str_contains($this->locale, '-')) { [$locale] = explode('-', $this->locale, 2); [$file, $parsedLine] = $this->parseLine($line, $locale); @@ -112,57 +120,66 @@ public function getLine(string $line, array $args = []) $output = $this->getTranslationOutput($locale, $file, $parsedLine); } - // if still not found, try English + // 4. If still not found, try English. if ($output === null) { [$file, $parsedLine] = $this->parseLine($line, 'en'); $output = $this->getTranslationOutput('en', $file, $parsedLine); } + // 5. Fallback to the original line if no translation was found. $output ??= $line; return $this->formatMessage($output, $args); } /** - * @return array|string|null + * @return list|string|null */ protected function getTranslationOutput(string $locale, string $file, string $parsedLine) { $output = $this->language[$locale][$file][$parsedLine] ?? null; + if ($output !== null) { return $output; } - foreach (explode('.', $parsedLine) as $row) { - if (! isset($current)) { - $current = $this->language[$locale][$file] ?? null; - } + // Fallback: try to traverse dot notation + $current = $this->language[$locale][$file] ?? null; + + if (is_array($current)) { + foreach (explode('.', $parsedLine) as $segment) { + $output = $current[$segment] ?? null; + + if ($output === null) { + break; + } - $output = $current[$row] ?? null; - if (is_array($output)) { - $current = $output; + if (is_array($output)) { + $current = $output; + } } - } - if ($output !== null) { - return $output; + if ($output !== null && ! is_array($output)) { + return $output; + } } - $row = current(explode('.', $parsedLine)); - $key = substr($parsedLine, strlen($row) + 1); + // Final fallback: try two-level access manually + [$first, $rest] = explode('.', $parsedLine, 2) + ['', '']; - return $this->language[$locale][$file][$row][$key] ?? null; + return $this->language[$locale][$file][$first][$rest] ?? null; } /** * Parses the language string which should include the * filename as the first segment (separated by period). + * + * @return array{non-empty-string, non-empty-string} */ protected function parseLine(string $line, string $locale): array { - $file = substr($line, 0, strpos($line, '.')); - $line = substr($line, strlen($file) + 1); + [$file, $line] = explode('.', $line, 2); if (! isset($this->language[$locale][$file]) || ! array_key_exists($line, $this->language[$locale][$file])) { $this->load($file, $locale); @@ -174,10 +191,10 @@ protected function parseLine(string $line, string $locale): array /** * Advanced message formatting. * - * @param array|string $message - * @param list $args + * @param list|string $message + * @param array $args * - * @return array|string + * @return ($message is list ? list : string) */ protected function formatMessage($message, array $args = []) { @@ -194,32 +211,27 @@ protected function formatMessage($message, array $args = []) } $formatted = MessageFormatter::formatMessage($this->locale, $message, $args); + if ($formatted === false) { // Format again to get the error message. try { - $fmt = new MessageFormatter($this->locale, $message); - $formatted = $fmt->format($args); - $fmtError = '"' . $fmt->getErrorMessage() . '" (' . $fmt->getErrorCode() . ')'; + $formatter = new MessageFormatter($this->locale, $message); + $formatted = $formatter->format($args); + $fmtError = sprintf('"%s" (%d)', $formatter->getErrorMessage(), $formatter->getErrorCode()); } catch (IntlException $e) { - $fmtError = '"' . $e->getMessage() . '" (' . $e->getCode() . ')'; + $fmtError = sprintf('"%s" (%d)', $e->getMessage(), $e->getCode()); } - $argsString = implode( - ', ', - array_map(static fn ($element): string => '"' . $element . '"', $args), - ); - $argsUrlEncoded = implode( - ', ', - array_map(static fn ($element): string => '"' . rawurlencode($element) . '"', $args), - ); - - log_message( - 'error', - 'Language.invalidMessageFormat: $message: "' . $message - . '", $args: ' . $argsString - . ' (urlencoded: ' . $argsUrlEncoded . '),' - . ' MessageFormatter Error: ' . $fmtError, - ); + $argsAsString = sprintf('"%s"', implode('", "', $args)); + $urlEncodedArgs = sprintf('"%s"', implode('", "', array_map(rawurlencode(...), $args))); + + log_message('error', sprintf( + 'Invalid message format: $message: "%s", $args: %s (urlencoded: %s), MessageFormatter Error: %s', + $message, + $argsAsString, + $urlEncodedArgs, + $fmtError, + )); return $message . "\n【Warning】Also, invalid string(s) was passed to the Language class. See log file for details."; } @@ -232,7 +244,7 @@ protected function formatMessage($message, array $args = []) * will return the file's contents, otherwise will merge with * the existing language lines. * - * @return list|null + * @return ($return is true ? LoadedStrings : null) */ protected function load(string $file, string $locale, bool $return = false) { @@ -270,8 +282,9 @@ protected function load(string $file, string $locale, bool $return = false) } /** - * A simple method for including files that can be - * overridden during testing. + * A simple method for including files that can be overridden during testing. + * + * @return LoadedStrings */ protected function requireFile(string $path): array { @@ -279,20 +292,25 @@ protected function requireFile(string $path): array $strings = []; foreach ($files as $file) { - // On some OS's we were seeing failures - // on this command returning boolean instead - // of array during testing, so we've removed - // the require_once for now. if (is_file($file)) { - $strings[] = require $file; + // On some OS, we were seeing failures on this command returning boolean instead + // of array during testing, so we've removed the require_once for now. + $loadedStrings = require $file; + + if (is_array($loadedStrings)) { + /** @var LoadedStrings $loadedStrings */ + $strings[] = $loadedStrings; + } } } - if (isset($strings[1])) { - $string = array_shift($strings); + $count = count($strings); + + if ($count > 1) { + $base = array_shift($strings); - $strings = array_replace_recursive($string, ...$strings); - } elseif (isset($strings[0])) { + $strings = array_replace_recursive($base, ...$strings); + } elseif ($count === 1) { $strings = $strings[0]; } diff --git a/system/Language/en/Honeypot.php b/system/Language/en/Honeypot.php new file mode 100644 index 000000000000..65676da56017 --- /dev/null +++ b/system/Language/en/Honeypot.php @@ -0,0 +1,19 @@ + + * + * For the full copyright and license information, please view + * the LICENSE file that was distributed with this source code. + */ + +// Honeypot language settings +return [ + 'noTemplate' => 'The HTML template for the Honeypot is not configured.', + 'noNameField' => 'The name of the Honeypot field is not set.', + 'theClientIsABot' => 'The Honeypot client may be a bot.', +]; diff --git a/system/Language/en/Language.php b/system/Language/en/Language.php index 16456c3cc472..2d638c8e3f54 100644 --- a/system/Language/en/Language.php +++ b/system/Language/en/Language.php @@ -13,5 +13,6 @@ // "Language" language settings return [ + // @deprecated v4.6.3 - never used 'invalidMessageFormat' => 'Invalid message format: "{0}", args: "{1}"', ]; diff --git a/system/Language/en/Router.php b/system/Language/en/Router.php index 7bb55860198b..a073d98d4ada 100644 --- a/system/Language/en/Router.php +++ b/system/Language/en/Router.php @@ -16,5 +16,5 @@ 'invalidParameter' => 'A parameter does not match the expected type.', 'missingDefaultRoute' => 'Unable to determine what should be displayed. A default route has not been specified in the routing file.', 'invalidDynamicController' => 'A dynamic controller is not allowed for security reasons. Route handler: "{0}"', - 'invalidControllerName' => 'The namespace delimiter is a backslash (\), not a slash (/). Route handler: "{0}"', + 'invalidControllerName' => 'The namespace delimiter is a backslash (\\), not a slash (/). Route handler: "{0}"', ]; diff --git a/system/Model.php b/system/Model.php index 44ed52a0edd0..60759b9e201f 100644 --- a/system/Model.php +++ b/system/Model.php @@ -396,7 +396,7 @@ protected function doInsert(array $row) // If insertion succeeded then save the insert ID if ($result) { - $this->insertID = ! $this->useAutoIncrement ? $row[$this->primaryKey] : $this->db->insertID(); + $this->insertID = $this->useAutoIncrement ? $this->db->insertID() : $row[$this->primaryKey]; } return $result; diff --git a/system/Pager/PagerRenderer.php b/system/Pager/PagerRenderer.php index 2352a98460e3..f970ee551f19 100644 --- a/system/Pager/PagerRenderer.php +++ b/system/Pager/PagerRenderer.php @@ -29,9 +29,12 @@ class PagerRenderer /** * First page number in the set of links to be displayed. * + * `first` and `last` will be updated by `setSurroundCount()`. + * You must call `setSurroundCount()` after instantiation. + * * @var int */ - protected $first; + protected $first = 1; /** * Last page number in the set of links to be displayed. @@ -102,10 +105,7 @@ class PagerRenderer */ public function __construct(array $details) { - // `first` and `last` will be updated by `setSurroundCount()`. - // You must call `setSurroundCount()` after instantiation. - $this->first = 1; - $this->last = $details['pageCount']; + $this->last = $details['pageCount']; $this->current = $details['currentPage']; $this->total = $details['total']; diff --git a/system/Router/AutoRouterImproved.php b/system/Router/AutoRouterImproved.php index c14c8fe97ebe..a00c04d265d7 100644 --- a/system/Router/AutoRouterImproved.php +++ b/system/Router/AutoRouterImproved.php @@ -209,7 +209,7 @@ private function searchLastDefaultController(): bool } $namespaces = array_map( - fn ($segment): string => $this->translateURI($segment), + $this->translateURI(...), $segments, ); diff --git a/system/Router/Exceptions/RouterException.php b/system/Router/Exceptions/RouterException.php index 378647289a72..7a65603d84b2 100644 --- a/system/Router/Exceptions/RouterException.php +++ b/system/Router/Exceptions/RouterException.php @@ -28,7 +28,7 @@ class RouterException extends FrameworkException implements ExceptionInterface */ public static function forInvalidParameterType() { - return new static(lang('Router.invalidParameterType')); + return new static(lang('Router.invalidParameter')); } /** diff --git a/system/Router/RouteCollection.php b/system/Router/RouteCollection.php index 7379d014cc09..feb161bdfc92 100644 --- a/system/Router/RouteCollection.php +++ b/system/Router/RouteCollection.php @@ -1574,7 +1574,7 @@ private function checkHostname($hostname): bool // Has multiple hostnames if (is_array($hostname)) { - $hostnameLower = array_map('strtolower', $hostname); + $hostnameLower = array_map(strtolower(...), $hostname); return in_array(strtolower($this->httpHost), $hostnameLower, true); } diff --git a/system/Security/CheckPhpIni.php b/system/Security/CheckPhpIni.php index 35431c35af57..949c1d10aa48 100644 --- a/system/Security/CheckPhpIni.php +++ b/system/Security/CheckPhpIni.php @@ -17,7 +17,7 @@ use CodeIgniter\View\Table; /** - * Checks php.ini settings + * Checks php.ini settings in production environment. * * @used-by \CodeIgniter\Commands\Utilities\PhpIniCheck * @see \CodeIgniter\Security\CheckPhpIniTest @@ -27,30 +27,33 @@ class CheckPhpIni /** * @param bool $isCli Set false if you run via Web * - * @return string|null HTML string or void in CLI + * @return ($isCli is true ? null : string) */ public static function run(bool $isCli = true, ?string $argument = null) { - $output = static::checkIni($argument); + $output = self::checkIni($argument); $thead = ['Directive', 'Global', 'Current', 'Recommended', 'Remark']; - $tbody = []; - // CLI if ($isCli) { - self::outputForCli($output, $thead, $tbody); + self::outputForCli($output, $thead); return null; } - // Web - return self::outputForWeb($output, $thead, $tbody); + return self::outputForWeb($output, $thead); } - private static function outputForCli(array $output, array $thead, array $tbody): void + /** + * @param array $output + * @param array{string, string, string, string, string} $thead + */ + private static function outputForCli(array $output, array $thead): void { + $tbody = []; + foreach ($output as $directive => $values) { - $current = $values['current'] ?? ''; + $current = $values['current']; $notRecommended = false; if ($values['recommended'] !== '') { @@ -64,16 +67,27 @@ private static function outputForCli(array $output, array $thead, array $tbody): } $directive = $notRecommended ? CLI::color($directive, 'red') : $directive; - $tbody[] = [ - $directive, $values['global'], $current, $values['recommended'], $values['remark'], + + $tbody[] = [ + $directive, + $values['global'], + $current, + $values['recommended'], + $values['remark'], ]; } CLI::table($tbody, $thead); } - private static function outputForWeb(array $output, array $thead, array $tbody): string + /** + * @param array $output + * @param array{string, string, string, string, string} $thead + */ + private static function outputForWeb(array $output, array $thead): string { + $tbody = []; + foreach ($output as $directive => $values) { $current = $values['current']; $notRecommended = false; @@ -95,27 +109,27 @@ private static function outputForWeb(array $output, array $thead, array $tbody): $directive = $notRecommended ? '' . $directive . '' : $directive; + $tbody[] = [ - $directive, $values['global'], $current, $values['recommended'], $values['remark'], + $directive, + $values['global'], + $current, + $values['recommended'], + $values['remark'], ]; } - $table = new Table(); - $template = [ - 'table_open' => '', - ]; - $table->setTemplate($template); - + $table = new Table(); + $table->setTemplate(['table_open' => '
']); $table->setHeading($thead); return '
' . $table->generate($tbody) . '
'; } /** - * @internal Used for testing purposes only. - * @testTag + * @return array */ - public static function checkIni(?string $argument = null): array + private static function checkIni(?string $argument = null): array { // Default items $items = [ @@ -151,17 +165,19 @@ public static function checkIni(?string $argument = null): array 'opcache.interned_strings_buffer' => ['recommended' => '16'], 'opcache.max_accelerated_files' => ['remark' => 'Adjust based on the number of PHP files in your project (e.g.: find your_project/ -iname \'*.php\'|wc -l)'], 'opcache.max_wasted_percentage' => ['recommended' => '10'], - 'opcache.validate_timestamps' => ['recommended' => '0', 'remark' => 'When you disabled, opcache hold your code into shared memory. Restart webserver needed'], + 'opcache.validate_timestamps' => ['recommended' => '0', 'remark' => 'When disabled, opcache will hold your code into shared memory. Restart webserver as needed'], 'opcache.revalidate_freq' => [], 'opcache.file_cache' => ['remark' => 'Location file caching, It should improve performance when SHM memory is full'], - 'opcache.file_cache_only' => ['remark' => 'Opcode caching in shared memory, Disabled when you using Windows'], - 'opcache.file_cache_fallback' => ['remark' => 'Set enable when you using Windows'], - 'opcache.save_comments' => ['recommended' => '0', 'remark' => 'Enable when you using package require docblock annotation'], + 'opcache.file_cache_only' => ['remark' => 'Opcode caching in shared memory, Disabled when you are using Windows'], + 'opcache.file_cache_fallback' => ['remark' => 'Enable when you are using Windows'], + 'opcache.save_comments' => ['recommended' => '0', 'remark' => 'Enable when your code requires to read docblock annotations at runtime'], ]; } $output = []; - $ini = ini_get_all(); + + $ini = ini_get_all(); + assert(is_array($ini)); foreach ($items as $key => $values) { $hasKeyInIni = array_key_exists($key, $ini); @@ -173,7 +189,6 @@ public static function checkIni(?string $argument = null): array ]; } - // [directive => [current_value, recommended_value]] return $output; } } diff --git a/system/Test/CIUnitTestCase.php b/system/Test/CIUnitTestCase.php index 4780a1bbdefd..81d669138422 100644 --- a/system/Test/CIUnitTestCase.php +++ b/system/Test/CIUnitTestCase.php @@ -19,6 +19,7 @@ use CodeIgniter\Database\MigrationRunner; use CodeIgniter\Database\Seeder; use CodeIgniter\Events\Events; +use CodeIgniter\HTTP\Header; use CodeIgniter\Router\RouteCollection; use CodeIgniter\Session\Handlers\ArrayHandler; use CodeIgniter\Test\Mock\MockCache; @@ -72,6 +73,8 @@ abstract class CIUnitTestCase extends TestCase /** * Store of identified traits. + * + * @var array|null */ private ?array $traits = null; @@ -109,9 +112,9 @@ abstract class CIUnitTestCase extends TestCase /** * The seed file(s) used for all tests within this test case. - * Should be fully-namespaced or relative to $basePath + * Should be fully-namespaced or relative to $basePath. * - * @var class-string|list> + * @var ''|class-string|list> */ protected $seed = ''; @@ -127,9 +130,9 @@ abstract class CIUnitTestCase extends TestCase * The namespace(s) to help us find the migration classes. * `null` is equivalent to running `spark migrate --all`. * Note that running "all" runs migrations in date order, - * but specifying namespaces runs them in namespace order (then date) + * but specifying namespaces runs them in namespace order (then date). * - * @var array|string|null + * @var list|string|null */ protected $namespace = 'Tests\Support'; @@ -156,17 +159,17 @@ abstract class CIUnitTestCase extends TestCase protected $migrations; /** - * Seeder instance + * Seeder instance. * - * @var Seeder + * @var Seeder|null */ protected $seeder; /** * Stores information needed to remove any - * rows inserted via $this->hasInDatabase(); + * rows inserted via $this->hasInDatabase(). * - * @var array + * @var list> */ protected $insertCache = []; @@ -186,27 +189,27 @@ abstract class CIUnitTestCase extends TestCase * Values to be set in the SESSION global * before running the test. * - * @var array + * @var array */ protected $session = []; /** - * Enabled auto clean op buffer after request call + * Enabled auto clean op buffer after request call. * * @var bool */ protected $clean = true; /** - * Custom request's headers + * Custom request's headers. * - * @var array + * @var array> */ protected $headers = []; /** * Allows for formatting the request body to what - * the controller is going to expect + * the controller is going to expect. * * @var string */ @@ -276,7 +279,7 @@ protected function tearDown(): void * Checks for traits with corresponding * methods for setUp or tearDown. * - * @param string $stage 'setUp' or 'tearDown' + * @param 'setUp'|'tearDown' $stage */ private function callTraitMethods(string $stage): void { @@ -298,7 +301,7 @@ private function callTraitMethods(string $stage): void // -------------------------------------------------------------------- /** - * Resets shared instanced for all Factories components + * Resets shared instanced for all Factories components. * * @return void */ @@ -308,7 +311,7 @@ protected function resetFactories() } /** - * Resets shared instanced for all Services + * Resets shared instanced for all Services. * * @return void */ @@ -318,7 +321,7 @@ protected function resetServices(bool $initAutoloader = true) } /** - * Injects the mock Cache driver to prevent filesystem collisions + * Injects the mock Cache driver to prevent filesystem collisions. * * @return void */ @@ -328,7 +331,7 @@ protected function mockCache() } /** - * Injects the mock email driver so no emails really send + * Injects the mock email driver so no emails really send. * * @return void */ @@ -338,7 +341,7 @@ protected function mockEmail() } /** - * Injects the mock session driver into Services + * Injects the mock session driver into Services. * * @return void */ diff --git a/system/Test/DatabaseTestTrait.php b/system/Test/DatabaseTestTrait.php index c0d4473c7b9e..14c47c95cee7 100644 --- a/system/Test/DatabaseTestTrait.php +++ b/system/Test/DatabaseTestTrait.php @@ -14,11 +14,13 @@ namespace CodeIgniter\Test; use CodeIgniter\Database\BaseBuilder; +use CodeIgniter\Database\BaseConnection; use CodeIgniter\Database\Exceptions\DatabaseException; +use CodeIgniter\Database\MigrationRunner; +use CodeIgniter\Database\Seeder; use CodeIgniter\Test\Constraints\SeeInDatabase; use Config\Database; use Config\Migrations; -use Config\Services; use PHPUnit\Framework\Attributes\AfterClass; /** @@ -27,6 +29,12 @@ * Provides functionality for refreshing/seeding * the database during testing. * + * @property BaseConnection $db + * @property list> $insertCache + * @property Seeder|null $seeder + * @property MigrationRunner|null $migrations + * @property list|string|null $namespace + * * @mixin CIUnitTestCase */ trait DatabaseTestTrait @@ -88,7 +96,7 @@ public function loadDependencies() $config = new Migrations(); $config->enabled = true; - $this->migrations = Services::migrations($config, $this->db, false); + $this->migrations = service('migrations', $config, $this->db, false); $this->migrations->setSilent(false); } diff --git a/system/Test/Fabricator.php b/system/Test/Fabricator.php index 1a7c5c8f392f..b366464d5a26 100644 --- a/system/Test/Fabricator.php +++ b/system/Test/Fabricator.php @@ -168,7 +168,7 @@ public static function resetCounts() */ public static function getCount(string $table): int { - return ! isset(self::$tableCounts[$table]) ? 0 : self::$tableCounts[$table]; + return self::$tableCounts[$table] ?? 0; } /** diff --git a/system/Test/FeatureTestTrait.php b/system/Test/FeatureTestTrait.php index eaf49a0a9147..c3b974448e43 100644 --- a/system/Test/FeatureTestTrait.php +++ b/system/Test/FeatureTestTrait.php @@ -13,13 +13,17 @@ namespace CodeIgniter\Test; +use Closure; use CodeIgniter\Events\Events; use CodeIgniter\HTTP\Exceptions\RedirectException; +use CodeIgniter\HTTP\Header; use CodeIgniter\HTTP\IncomingRequest; use CodeIgniter\HTTP\Method; use CodeIgniter\HTTP\Request; +use CodeIgniter\HTTP\ResponseInterface; use CodeIgniter\HTTP\SiteURI; use CodeIgniter\HTTP\URI; +use CodeIgniter\Router\RouteCollection; use Config\App; use Config\Services; use Exception; @@ -30,6 +34,12 @@ * * Provides additional utilities for doing full HTTP testing * against your application in trait format. + * + * @property array $session + * @property array> $headers + * @property RouteCollection|null $routes + * + * @mixin CIUnitTestCase */ trait FeatureTestTrait { @@ -42,7 +52,12 @@ trait FeatureTestTrait * ['GET', 'home', 'Home::index'], * ] * - * @param array|null $routes Array to set routes + * @param array + * }>|null $routes Array to set routes * * @return $this */ @@ -84,7 +99,7 @@ protected function withRoutes(?array $routes = null) /** * Sets any values that should exist during this session. * - * @param array|null $values Array of values, or null to use the current $_SESSION + * @param array|null $values Array of values, or null to use the current $_SESSION * * @return $this */ @@ -103,7 +118,7 @@ public function withSession(?array $values = null) * 'Authorization' => 'Token' * ]) * - * @param array $headers Array of headers + * @param array> $headers Array of headers * * @return $this */ @@ -213,7 +228,7 @@ public function call(string $method, string $path, ?array $params = null) ->run($routes, true); // Reset directory if it has been set - service('router')->setDirectory(null); + service('router')->setDirectory(); return new TestResponse($response); } @@ -385,11 +400,11 @@ protected function populateGlobals(string $name, Request $request, ?array $param $request->setGlobal($name, $params); $request->setGlobal( 'request', - $request->fetchGlobal('post') + $request->fetchGlobal('get'), + (array) $request->fetchGlobal('post') + (array) $request->fetchGlobal('get'), ); } - $_SESSION = $this->session ?? []; + $_SESSION = $this->session; return $request; } diff --git a/system/Test/Mock/MockCache.php b/system/Test/Mock/MockCache.php index 67f8aee86ad1..6699ad266c63 100644 --- a/system/Test/Mock/MockCache.php +++ b/system/Test/Mock/MockCache.php @@ -62,7 +62,7 @@ public function get(string $key) { $key = static::validateKey($key, $this->prefix); - return array_key_exists($key, $this->cache) ? $this->cache[$key] : null; + return $this->cache[$key] ?? null; } /** diff --git a/system/Test/Mock/MockLanguage.php b/system/Test/Mock/MockLanguage.php index 4ae1196ca053..3102bb91755b 100644 --- a/system/Test/Mock/MockLanguage.php +++ b/system/Test/Mock/MockLanguage.php @@ -15,13 +15,16 @@ use CodeIgniter\Language\Language; +/** + * @phpstan-import-type LoadedStrings from Language + */ class MockLanguage extends Language { /** * Stores the data that should be * returned by the 'requireFile()' method. * - * @var mixed + * @var LoadedStrings|null */ protected $data; @@ -30,18 +33,24 @@ class MockLanguage extends Language * 'requireFile()' method to allow easy overrides * during testing. * + * @param LoadedStrings $data + * * @return $this */ public function setData(string $file, array $data, ?string $locale = null) { $this->language[$locale ?? $this->locale][$file] = $data; + $this->data = $data; + return $this; } /** * Provides an override that allows us to set custom * data to be returned easily during testing. + * + * @return LoadedStrings */ protected function requireFile(string $path): array { diff --git a/system/ThirdParty/Escaper/Escaper.php b/system/ThirdParty/Escaper/Escaper.php index 39d9b0b1cdac..25119a0e5158 100644 --- a/system/ThirdParty/Escaper/Escaper.php +++ b/system/ThirdParty/Escaper/Escaper.php @@ -247,7 +247,7 @@ public function escapeCss(string $string) protected function htmlAttrMatcher($matches) { $chr = $matches[0]; - $ord = ord($chr); + $ord = ord($chr[0]); /** * The following replaces characters undefined in HTML with the diff --git a/system/ThirdParty/Kint/CallFinder.php b/system/ThirdParty/Kint/CallFinder.php index 11c40ad85526..cc34123a72c8 100644 --- a/system/ThirdParty/Kint/CallFinder.php +++ b/system/ThirdParty/Kint/CallFinder.php @@ -148,11 +148,11 @@ class CallFinder ]; /** - * @psalm-param callable-array|callable-string $function - * - * @psalm-return list, modifiers: list}> + * @psalm-param callable-string|(callable-array&list{class-string, non-empty-string}) $function * * @return array List of matching calls on the relevant line + * + * @psalm-return list, modifiers: list}> */ public static function getFunctionCalls(string $source, int $line, $function): array { @@ -198,6 +198,11 @@ public static function getFunctionCalls(string $source, int $line, $function): a self::$operator[T_NEW] = true; // @codeCoverageIgnore } + if (KINT_PHP85) { + /** @psalm-suppress UndefinedConstant */ + self::$operator[T_PIPE] = true; + } + /** @psalm-var list */ $tokens = \token_get_all($source); $function_calls = []; @@ -212,10 +217,6 @@ public static function getFunctionCalls(string $source, int $line, $function): a $function = \strtolower($function[1]); } else { $class = null; - /** - * @psalm-suppress RedundantFunctionCallGivenDocblockType - * Psalm bug #11075 - */ $function = \strtolower($function); } @@ -294,6 +295,8 @@ public static function getFunctionCalls(string $source, int $line, $function): a $params = []; // All our collected parameters $shortparam = []; // The short version of the parameter $param_start = $offset; // The distance to the start of the parameter + $quote = null; // Buffer to store quote type for shortparam + $in_ternary = false; // Loop through the following tokens until the function call ends while (isset($tokens[$offset])) { @@ -341,6 +344,26 @@ public static function getFunctionCalls(string $source, int $line, $function): a $instring = !$instring; $shortparam[] = $token; + } elseif (T_START_HEREDOC === $token[0]) { + if (1 === $depth) { + $quote = \ltrim($token[1], " \t<")[0]; + if ("'" !== $quote) { + $quote = '"'; + } + $shortparam[] = [T_START_HEREDOC, $quote]; + $instring = true; + } + + ++$depth; + } elseif (T_END_HEREDOC === $token[0]) { + --$depth; + + if (1 === $depth) { + if ($realtokens) { + $shortparam[] = '...'; + } + $shortparam[] = [T_END_HEREDOC, $quote]; + } } elseif (1 === $depth) { if (',' === $token[0]) { $params[] = [ @@ -349,6 +372,7 @@ public static function getFunctionCalls(string $source, int $line, $function): a ]; $shortparam = []; $paramrealtokens = false; + $in_ternary = false; $param_start = $offset + 1; } elseif (T_CONSTANT_ENCAPSED_STRING === $token[0]) { $quote = $token[1][0]; @@ -364,6 +388,15 @@ public static function getFunctionCalls(string $source, int $line, $function): a } $shortparam[] = $token; } else { + // We can't tell the order of named parameters or if they're splatting + // without parsing the called function and that's too much work for this + // edge case so we'll just skip parameters altogether. + if ('?' === $token) { + $in_ternary = true; + } elseif (!$in_ternary && ':' === $token) { + $params = []; + break; + } $shortparam[] = $token; } } @@ -400,13 +433,26 @@ public static function getFunctionCalls(string $source, int $line, $function): a $literal = false; $new_without_parens = false; - foreach ($name as $token) { + foreach ($name as $name_index => $token) { + if (KINT_PHP85 && T_CLONE === $token[0]) { + $nextReal = self::realTokenIndex($name, $name_index + 1); + + if (null !== $nextReal && '(' === $name[$nextReal]) { + continue; + } + } + if (self::tokenIsOperator($token)) { $expression = true; break; } } + if (!$expression && T_START_HEREDOC === $name[0][0]) { + $expression = true; + $literal = true; + } + // As of 8.4 new is only an expression when parentheses are // omitted. In that case we can cheat and add them ourselves. // @@ -593,6 +639,7 @@ private static function tokensTrim(array $tokens): array return \array_reverse($tokens); } + /** @psalm-return list */ private static function tokensFormatted(array $tokens): array { $tokens = self::tokensTrim($tokens); diff --git a/system/ThirdParty/Kint/Kint.php b/system/ThirdParty/Kint/Kint.php index 6c55593d4ab2..4348aab090b3 100644 --- a/system/ThirdParty/Kint/Kint.php +++ b/system/ThirdParty/Kint/Kint.php @@ -36,6 +36,7 @@ use Kint\Renderer\TextRenderer; use Kint\Value\Context\BaseContext; use Kint\Value\Context\ContextInterface; +use Kint\Value\TraceFrameValue; use Kint\Value\UninitializedValue; /** @@ -43,8 +44,16 @@ * Psalm bug #8523 * * @psalm-import-type CallParameter from CallFinder + * @psalm-import-type TraceFrame from TraceFrameValue * - * @psalm-type KintMode = Kint::MODE_*|bool + * @psalm-type KintMode = array-key|bool + * @psalm-type KintCallInfo = array{ + * params: ?list, + * modifiers: array, + * callee: ?callable, + * caller: ?callable, + * trace: TraceFrame[], + * } * * @psalm-api */ @@ -396,9 +405,9 @@ public static function getBasesFromParamInfo(array $params, int $argc): array * @param array[] $trace Backtrace * @param array $args Arguments * - * @return array Call info - * * @psalm-param list $trace + * + * @return KintCallInfo Call info */ public static function getCallInfo(array $aliases, array $trace, array $args): array { @@ -622,8 +631,8 @@ protected static function getSingleCall(array $frame, array $args): ?array foreach ($keys as $key) { $call['parameters'][] = [ - 'name' => \substr($param['name'], 3).'['.\var_export($key, true).']', - 'path' => \substr($param['path'], 3).'['.\var_export($key, true).']', + 'name' => ((string) \substr($param['name'], 3)).'['.\var_export($key, true).']', + 'path' => ((string) \substr($param['path'], 3)).'['.\var_export($key, true).']', 'expression' => false, 'literal' => false, 'new_without_parens' => false, @@ -634,8 +643,8 @@ protected static function getSingleCall(array $frame, array $args): ?array // through array_values so we can't access them directly at all for ($j = 0; $j + $i < $argc; ++$j) { $call['parameters'][] = [ - 'name' => 'array_values('.\substr($param['name'], 3).')['.$j.']', - 'path' => 'array_values('.\substr($param['path'], 3).')['.$j.']', + 'name' => 'array_values('.((string) \substr($param['name'], 3)).')['.$j.']', + 'path' => 'array_values('.((string) \substr($param['path'], 3)).')['.$j.']', 'expression' => false, 'literal' => false, 'new_without_parens' => false, diff --git a/system/ThirdParty/Kint/Parser/ClassStaticsPlugin.php b/system/ThirdParty/Kint/Parser/ClassStaticsPlugin.php index 8a18a00aee31..0b5e616fc716 100644 --- a/system/ThirdParty/Kint/Parser/ClassStaticsPlugin.php +++ b/system/ThirdParty/Kint/Parser/ClassStaticsPlugin.php @@ -136,7 +136,9 @@ private function buildStaticValue(ReflectionProperty $pr, int $depth): AbstractV $context->access_path = '\\'.$context->owner_class.'::$'.$context->name; } - $pr->setAccessible(true); + if (KINT_PHP81 === false) { + $pr->setAccessible(true); + } /** * @psalm-suppress TooFewArguments diff --git a/system/ThirdParty/Kint/Parser/ColorPlugin.php b/system/ThirdParty/Kint/Parser/ColorPlugin.php index fc160a4342ee..ffdedd7cfb4d 100644 --- a/system/ThirdParty/Kint/Parser/ColorPlugin.php +++ b/system/ThirdParty/Kint/Parser/ColorPlugin.php @@ -57,7 +57,7 @@ public function parseComplete(&$var, AbstractValue $v, int $trigger): AbstractVa $trimmed = \strtolower(\trim($var)); - if (!isset(ColorRepresentation::$color_map[$trimmed]) && !\preg_match('/^(?:(?:rgb|hsl)[^\\)]{6,}\\)|#[0-9a-fA-F]{3,8})$/', $trimmed)) { + if (!isset(ColorRepresentation::$color_map[$trimmed]) && !\preg_match('/^(?:(?:rgb|hsl)a?[^\\)]{6,}\\)|#[0-9a-f]{3,8})$/', $trimmed)) { return $v; } diff --git a/system/ThirdParty/Kint/Parser/DomPlugin.php b/system/ThirdParty/Kint/Parser/DomPlugin.php index 358c0b917094..7de5eb8db301 100644 --- a/system/ThirdParty/Kint/Parser/DomPlugin.php +++ b/system/ThirdParty/Kint/Parser/DomPlugin.php @@ -55,11 +55,12 @@ use Kint\Value\Representation\ContainerRepresentation; use Kint\Value\StringValue; use LogicException; +use ReflectionClass; class DomPlugin extends AbstractPlugin implements PluginBeginInterface { /** - * Reflection doesn't work below 8.1, also it won't show readonly status. + * Reflection doesn't show readonly status. * * In order to ensure this is stable enough we're only going to provide * properties for element and node. If subclasses like attr or document @@ -102,12 +103,9 @@ class DomPlugin extends AbstractPlugin implements PluginBeginInterface 'previousElementSibling' => true, 'nextElementSibling' => true, 'innerHTML' => false, - 'outerHTML' => false, + 'outerHTML' => true, 'substitutedNodeValue' => false, - ]; - - public const DOM_NS_VERSIONS = [ - 'outerHTML' => KINT_PHP85, + 'children' => true, ]; /** @@ -208,6 +206,9 @@ class DomPlugin extends AbstractPlugin implements PluginBeginInterface */ public static bool $verbose = false; + /** @psalm-var array> cache of properties for getKnownProperties */ + protected static array $property_cache = []; + protected ClassMethodsPlugin $methods_plugin; protected ClassStaticsPlugin $statics_plugin; @@ -259,12 +260,14 @@ public function parseBegin(&$var, ContextInterface $c): ?AbstractValue /** @psalm-param Node|DOMNode $var */ private function parseProperty(object $var, string $prop, ContextInterface $c): AbstractValue { - if (!isset($var->{$prop})) { + // Suppress deprecation message + if (@!isset($var->{$prop})) { return new FixedWidthValue($c, null); } $parser = $this->getParser(); - $value = $var->{$prop}; + // Suppress deprecation message + @$value = $var->{$prop}; if (\is_scalar($value)) { return $parser->parse($value, $c); @@ -450,29 +453,42 @@ private function parseNode(object $var, ContextInterface $c): DomNodeValue */ public static function getKnownProperties(object $var): array { - if ($var instanceof Node) { - $known_properties = self::NODE_PROPS; - if ($var instanceof Element) { - $known_properties += self::ELEMENT_PROPS; - } - - if ($var instanceof Document) { - $known_properties['textContent'] = true; - } + if (KINT_PHP81) { + $r = new ReflectionClass($var); + $classname = $r->getName(); + + if (!isset(self::$property_cache[$classname])) { + self::$property_cache[$classname] = []; + + foreach ($r->getProperties() as $prop) { + if ($prop->isStatic()) { + continue; + } + + $declaring = $prop->getDeclaringClass()->getName(); + $name = $prop->name; + + if (\in_array($declaring, [Node::class, Element::class], true)) { + $readonly = self::NODE_PROPS[$name] ?? self::ELEMENT_PROPS[$name]; + } elseif (\in_array($declaring, [DOMNode::class, DOMElement::class], true)) { + $readonly = self::DOMNODE_PROPS[$name] ?? self::DOMELEMENT_PROPS[$name]; + } else { + continue; + } + + self::$property_cache[$classname][$prop->name] = $readonly; + } - if ($var instanceof Attr || $var instanceof CharacterData) { - $known_properties['nodeValue'] = false; - } + if ($var instanceof Document) { + self::$property_cache[$classname]['textContent'] = true; + } - foreach (self::DOM_NS_VERSIONS as $key => $val) { - /** - * @psalm-var bool $val - * Psalm bug #4509 - */ - if (false === $val) { - unset($known_properties[$key]); // @codeCoverageIgnore + if ($var instanceof Attr || $var instanceof CharacterData) { + self::$property_cache[$classname]['nodeValue'] = false; } } + + $known_properties = self::$property_cache[$classname]; } else { $known_properties = self::DOMNODE_PROPS; if ($var instanceof DOMElement) { @@ -480,10 +496,6 @@ public static function getKnownProperties(object $var): array } foreach (self::DOM_VERSIONS as $key => $val) { - /** - * @psalm-var bool $val - * Psalm bug #4509 - */ if (false === $val) { unset($known_properties[$key]); // @codeCoverageIgnore } diff --git a/system/ThirdParty/Kint/Parser/HtmlPlugin.php b/system/ThirdParty/Kint/Parser/HtmlPlugin.php index 4df7ad1993fd..bc1a4f268168 100644 --- a/system/ThirdParty/Kint/Parser/HtmlPlugin.php +++ b/system/ThirdParty/Kint/Parser/HtmlPlugin.php @@ -52,7 +52,7 @@ public function getTriggers(): int public function parseComplete(&$var, AbstractValue $v, int $trigger): AbstractValue { - if ('' !== \strtolower(\substr($var, 0, 15))) { + if ('' !== \strtolower((string) \substr($var, 0, 15))) { return $v; } diff --git a/system/ThirdParty/Kint/Parser/IteratorPlugin.php b/system/ThirdParty/Kint/Parser/IteratorPlugin.php index 31b037acc0f4..fc31d78fab7d 100644 --- a/system/ThirdParty/Kint/Parser/IteratorPlugin.php +++ b/system/ThirdParty/Kint/Parser/IteratorPlugin.php @@ -86,10 +86,6 @@ public function parseComplete(&$var, AbstractValue $v, int $trigger): AbstractVa $c = $v->getContext(); foreach (self::$blacklist as $class) { - /** - * @psalm-suppress RedundantCondition - * Psalm bug #11076 - */ if ($var instanceof $class) { $base = new BaseContext($class.' Iterator Contents'); $base->depth = $c->getDepth() + 1; diff --git a/system/ThirdParty/Kint/Parser/Parser.php b/system/ThirdParty/Kint/Parser/Parser.php index a3c2fbb01468..5b28157ab29e 100644 --- a/system/ThirdParty/Kint/Parser/Parser.php +++ b/system/ThirdParty/Kint/Parser/Parser.php @@ -229,7 +229,7 @@ protected function noRecurseCall(): void $bt = \debug_backtrace(DEBUG_BACKTRACE_PROVIDE_OBJECT | DEBUG_BACKTRACE_IGNORE_ARGS); \reset($bt); - /** @psalm-var class-string $caller_frame['class'] */ + /** @psalm-var array{class: class-string, function: string, ...} $caller_frame */ $caller_frame = \next($bt); foreach ($bt as $frame) { @@ -401,7 +401,10 @@ private function parseObject(object &$var, ContextInterface $c): AbstractValue $properties = []; foreach ($props as $rprop) { - $rprop->setAccessible(true); + if (KINT_PHP81 === false) { + $rprop->setAccessible(true); + } + $name = $rprop->getName(); // Casting object to array: @@ -460,6 +463,21 @@ private function parseObject(object &$var, ContextInterface $c): AbstractValue } } } + + if (KINT_PHP8412) { + $proto_prop = $rprop; + while (($parent_class = $proto_prop->getDeclaringClass()->getParentClass()) && + $parent_class->hasProperty($name) && + ($parent_prop = $parent_class->getProperty($name)) && + !$parent_prop->isPrivate()) { + $proto_prop = $parent_prop; + } + + $proto_class = $proto_prop->getDeclaringClass()->getName(); + if ($proto_class !== $child->owner_class) { + $child->proto_class = $proto_prop->getDeclaringClass()->getName(); + } + } } else { $child = new ClassOwnedContext($name, $rprop->getDeclaringClass()->getName()); } diff --git a/system/ThirdParty/Kint/Parser/ProfilePlugin.php b/system/ThirdParty/Kint/Parser/ProfilePlugin.php index ec5bb0a17dd6..836357b24eda 100644 --- a/system/ThirdParty/Kint/Parser/ProfilePlugin.php +++ b/system/ThirdParty/Kint/Parser/ProfilePlugin.php @@ -71,11 +71,19 @@ public function parseBegin(&$var, ContextInterface $c): ?AbstractValue $this->instance_count_stack[$hash] ??= 0; if (0 === $this->instance_count_stack[$hash]) { + /** + * @psalm-suppress PossiblyFalseIterator + * Psalm bug #11392 + */ foreach (\class_parents($var) as $class) { $this->class_count_stack[$class] ??= 0; ++$this->class_count_stack[$class]; } + /** + * @psalm-suppress PossiblyFalseIterator + * Psalm bug #11392 + */ foreach (\class_implements($var) as $iface) { $this->class_count_stack[$iface] ??= 0; ++$this->class_count_stack[$iface]; @@ -94,10 +102,18 @@ public function parseComplete(&$var, AbstractValue $v, int $trigger): AbstractVa --$this->instance_count_stack[$v->getSplObjectHash()]; if (0 === $this->instance_count_stack[$v->getSplObjectHash()]) { + /** + * @psalm-suppress PossiblyFalseIterator + * Psalm bug #11392 + */ foreach (\class_parents($var) as $class) { --$this->class_count_stack[$class]; } + /** + * @psalm-suppress PossiblyFalseIterator + * Psalm bug #11392 + */ foreach (\class_implements($var) as $iface) { --$this->class_count_stack[$iface]; } @@ -130,6 +146,10 @@ public function parseComplete(&$var, AbstractValue $v, int $trigger): AbstractVa $this->class_complexity[$v->getClassName()] ??= 0; $this->class_complexity[$v->getClassName()] += $sub_complexity; + /** + * @psalm-suppress PossiblyFalseIterator + * Psalm bug #11392 + */ foreach (\class_parents($var) as $class) { $this->class_complexity[$class] ??= 0; if (0 === $this->class_count_stack[$class]) { @@ -137,6 +157,10 @@ public function parseComplete(&$var, AbstractValue $v, int $trigger): AbstractVa } } + /** + * @psalm-suppress PossiblyFalseIterator + * Psalm bug #11392 + */ foreach (\class_implements($var) as $iface) { $this->class_complexity[$iface] ??= 0; if (0 === $this->class_count_stack[$iface]) { diff --git a/system/ThirdParty/Kint/Parser/SimpleXMLElementPlugin.php b/system/ThirdParty/Kint/Parser/SimpleXMLElementPlugin.php index 4511c0b76f9e..65b1671757ba 100644 --- a/system/ThirdParty/Kint/Parser/SimpleXMLElementPlugin.php +++ b/system/ThirdParty/Kint/Parser/SimpleXMLElementPlugin.php @@ -208,41 +208,45 @@ protected function getChildren(ContextInterface $c, SimpleXMLElement $var): arra $contents = []; foreach ($namespaces as $nsAlias => $_) { - if ((bool) $nsChildren = $var->children($nsAlias, true)) { - $nsap = []; - foreach ($nsChildren as $name => $child) { - $base = new ClassOwnedContext((string) $name, SimpleXMLElement::class); - $base->depth = $cdepth + 1; + $nsChildren = $var->children($nsAlias, true); + if (!(bool) $nsChildren) { + continue; + } - if ('' !== $nsAlias) { - $base->name = $nsAlias.':'.$name; - } + $nsap = []; - if (null !== $ap) { - if ('' === $nsAlias) { - $base->access_path = $ap.'->'; - } else { - $base->access_path = $ap.'->children('.\var_export($nsAlias, true).', true)->'; - } + foreach ($nsChildren as $name => $child) { + $base = new ClassOwnedContext((string) $name, SimpleXMLElement::class); + $base->depth = $cdepth + 1; - if (Utils::isValidPhpName((string) $name)) { - $base->access_path .= (string) $name; - } else { - $base->access_path .= '{'.\var_export((string) $name, true).'}'; - } + if ('' !== $nsAlias) { + $base->name = $nsAlias.':'.$name; + } - if (isset($nsap[$base->access_path])) { - ++$nsap[$base->access_path]; - $base->access_path .= '['.$nsap[$base->access_path].']'; - } else { - $nsap[$base->access_path] = 0; - } + if (null !== $ap) { + if ('' === $nsAlias) { + $base->access_path = $ap.'->'; + } else { + $base->access_path = $ap.'->children('.\var_export($nsAlias, true).', true)->'; + } + + if (Utils::isValidPhpName((string) $name)) { + $base->access_path .= (string) $name; + } else { + $base->access_path .= '{'.\var_export((string) $name, true).'}'; } - $v = $this->parseElement($child, $base); - $v->flags |= AbstractValue::FLAG_GENERATED; - $contents[] = $v; + if (isset($nsap[$base->access_path])) { + ++$nsap[$base->access_path]; + $base->access_path .= '['.$nsap[$base->access_path].']'; + } else { + $nsap[$base->access_path] = 0; + } } + + $v = $this->parseElement($child, $base); + $v->flags |= AbstractValue::FLAG_GENERATED; + $contents[] = $v; } } diff --git a/system/ThirdParty/Kint/Parser/TracePlugin.php b/system/ThirdParty/Kint/Parser/TracePlugin.php index 533456472609..d01ebd9d066d 100644 --- a/system/ThirdParty/Kint/Parser/TracePlugin.php +++ b/system/ThirdParty/Kint/Parser/TracePlugin.php @@ -91,11 +91,11 @@ public function parseComplete(&$var, AbstractValue $v, int $trigger): AbstractVa $index = $frame->getContext()->getName(); - if (!isset($trace[$index]) || Utils::traceFrameIsListed($trace[$index], self::$blacklist)) { + if (!isset($trace[$index]['file']) || Utils::traceFrameIsListed($trace[$index], self::$blacklist)) { continue; } - if (isset($trace[$index]['file']) && false !== ($realfile = \realpath($trace[$index]['file']))) { + if (false !== ($realfile = \realpath($trace[$index]['file']))) { foreach ($path_blacklist as $path) { if (0 === \strpos($realfile, $path)) { continue 2; @@ -144,7 +144,7 @@ protected static function normalizePaths(array $paths): array foreach ($paths as $path) { $realpath = \realpath($path); - if (\is_dir($realpath)) { + if (false !== $realpath && \is_dir($realpath)) { $realpath .= DIRECTORY_SEPARATOR; } diff --git a/system/ThirdParty/Kint/Renderer/Rich/BinaryPlugin.php b/system/ThirdParty/Kint/Renderer/Rich/BinaryPlugin.php index 54c403350d56..75921625dfd8 100644 --- a/system/ThirdParty/Kint/Renderer/Rich/BinaryPlugin.php +++ b/system/ThirdParty/Kint/Renderer/Rich/BinaryPlugin.php @@ -49,7 +49,7 @@ public function renderTab(RepresentationInterface $r, AbstractValue $v): ?string $lines = \str_split($r->getValue(), self::$line_length); foreach ($lines as $index => $line) { - $out .= \sprintf('%08X', $index * self::$line_length).":\t"; + $out .= ((string) \sprintf('%08X', $index * self::$line_length)).":\t"; $chunks = \str_split(\str_pad(\bin2hex($line), 2 * self::$line_length, ' '), 2 * self::$chunk_length); diff --git a/system/ThirdParty/Kint/Renderer/RichRenderer.php b/system/ThirdParty/Kint/Renderer/RichRenderer.php index 3a8fdc6f8dab..a494938d5d68 100644 --- a/system/ThirdParty/Kint/Renderer/RichRenderer.php +++ b/system/ThirdParty/Kint/Renderer/RichRenderer.php @@ -290,7 +290,7 @@ public function renderHeader(AbstractValue $v): string } if (null !== ($s = $v->getDisplayValue())) { - $s = \preg_replace('/\\s+/', ' ', $s); + $s = (string) \preg_replace('/\\s+/', ' ', $s); if (self::$strlen_max) { $s = Utils::truncateString($s, self::$strlen_max); @@ -322,7 +322,7 @@ public function renderChildren(AbstractValue $v): string $output = '
'; if (1 === \count($tabs) && $tabs[0]->labelIsImplicit()) { - $output .= \reset($contents); + $output .= (string) \reset($contents); } else { $output .= '
    '; diff --git a/system/ThirdParty/Kint/Utils.php b/system/ThirdParty/Kint/Utils.php index 0fcdc47889d9..f39d2c1dc3da 100644 --- a/system/ThirdParty/Kint/Utils.php +++ b/system/ThirdParty/Kint/Utils.php @@ -313,7 +313,7 @@ public static function errorSanitizeString(string $input): string return $input; } - return \strtok($input, "\0"); // @codeCoverageIgnore + return (string) \strtok($input, "\0"); // @codeCoverageIgnore } /** @psalm-pure */ @@ -435,7 +435,7 @@ public static function substr(string $string, int $start, ?int $length = null, $ return ''; } - return \substr($string, $start, $length ?? PHP_INT_MAX); + return (string) \substr($string, $start, $length ?? PHP_INT_MAX); } public static function shortenPath(string $file): string @@ -512,7 +512,7 @@ public static function composerGetExtras(string $key = 'kint'): array $installed = $folder.'/composer/installed.json'; if (\file_exists($installed) && \is_readable($installed)) { - $packages = \json_decode(\file_get_contents($installed), true); + $packages = \json_decode((string) \file_get_contents($installed), true); if (!\is_array($packages)) { continue; @@ -529,7 +529,7 @@ public static function composerGetExtras(string $key = 'kint'): array $folder = \dirname($folder); if (\file_exists($folder.'/composer.json') && \is_readable($folder.'/composer.json')) { - $composer = \json_decode(\file_get_contents($folder.'/composer.json'), true); + $composer = \json_decode((string) \file_get_contents($folder.'/composer.json'), true); if (\is_array($composer['extra'][$key] ?? null)) { $extras = \array_replace($extras, $composer['extra'][$key]); diff --git a/system/ThirdParty/Kint/Value/Context/ClassDeclaredContext.php b/system/ThirdParty/Kint/Value/Context/ClassDeclaredContext.php index 79aeeb7286ff..9243833aff6e 100644 --- a/system/ThirdParty/Kint/Value/Context/ClassDeclaredContext.php +++ b/system/ThirdParty/Kint/Value/Context/ClassDeclaredContext.php @@ -38,6 +38,9 @@ abstract class ClassDeclaredContext extends ClassOwnedContext /** @psalm-var self::ACCESS_* */ public int $access; + /** @psalm-var class-string */ + public ?string $proto_class = null; + /** * @psalm-param class-string $owner_class * @psalm-param self::ACCESS_* $access @@ -69,12 +72,22 @@ public function isAccessible(?string $scope): bool return $scope === $this->owner_class; } - if (\is_a($scope, $this->owner_class, true)) { - return true; - } - - if (\is_a($this->owner_class, $scope, true)) { - return true; + if (KINT_PHP8412 && null !== $this->proto_class) { + if (\is_a($scope, $this->proto_class, true)) { + return true; + } + + if (\is_a($this->proto_class, $scope, true)) { + return true; + } + } else { + if (\is_a($scope, $this->owner_class, true)) { + return true; + } + + if (\is_a($this->owner_class, $scope, true)) { + return true; + } } return false; diff --git a/system/ThirdParty/Kint/Value/MethodValue.php b/system/ThirdParty/Kint/Value/MethodValue.php index 424672756fd1..6f2e94c08c50 100644 --- a/system/ThirdParty/Kint/Value/MethodValue.php +++ b/system/ThirdParty/Kint/Value/MethodValue.php @@ -127,7 +127,7 @@ public function getPhpDocUrl(): ?string $funcname = \str_replace('_', '-', \strtolower($c->getName())); if (0 === \strpos($funcname, '--') && 0 !== \strpos($funcname, '-', 2)) { - $funcname = \substr($funcname, 2); + $funcname = (string) \substr($funcname, 2); } return 'https://www.php.net/'.$class.'.'.$funcname; diff --git a/system/ThirdParty/Kint/Value/Representation/AbstractRepresentation.php b/system/ThirdParty/Kint/Value/Representation/AbstractRepresentation.php index 3c8180e69348..5c80ee5b53c5 100644 --- a/system/ThirdParty/Kint/Value/Representation/AbstractRepresentation.php +++ b/system/ThirdParty/Kint/Value/Representation/AbstractRepresentation.php @@ -39,7 +39,9 @@ abstract class AbstractRepresentation implements RepresentationInterface public function __construct(string $label, ?string $name = null, bool $implicit_label = false) { $this->label = $label; - $this->name = \preg_replace('/[^a-z0-9]+/', '_', \strtolower($name ?? $label)); + /** @psalm-var string $name */ + $name = \preg_replace('/[^a-z0-9]+/', '_', \strtolower($name ?? $label)); + $this->name = $name; $this->implicit_label = $implicit_label; } diff --git a/system/ThirdParty/Kint/Value/Representation/CallableDefinitionRepresentation.php b/system/ThirdParty/Kint/Value/Representation/CallableDefinitionRepresentation.php index 4625f343bffa..a26467e9ce56 100644 --- a/system/ThirdParty/Kint/Value/Representation/CallableDefinitionRepresentation.php +++ b/system/ThirdParty/Kint/Value/Representation/CallableDefinitionRepresentation.php @@ -104,7 +104,8 @@ public function getDocstringWithoutComments(): ?string return null; } - $string = \substr($ds, 3, -2); + $string = (string) \substr($ds, 3, -2); + /** @psalm-var string $string */ $string = \preg_replace('/^\\s*\\*\\s*?(\\S|$)/m', '\\1', $string); return \trim($string); diff --git a/system/ThirdParty/Kint/Value/Representation/ColorRepresentation.php b/system/ThirdParty/Kint/Value/Representation/ColorRepresentation.php index 4221ccce70e0..27315789a4b4 100644 --- a/system/ThirdParty/Kint/Value/Representation/ColorRepresentation.php +++ b/system/ThirdParty/Kint/Value/Representation/ColorRepresentation.php @@ -335,7 +335,7 @@ protected function setValues(string $value): void $this->setValuesFromHex(self::$color_map[$value]); $variant = self::COLOR_NAME; } elseif ('#' === $value[0]) { - $variant = $this->setValuesFromHex(\substr($value, 1)); + $variant = $this->setValuesFromHex((string) \substr($value, 1)); } else { $variant = $this->setValuesFromFunction($value); } @@ -381,7 +381,7 @@ protected function setValuesFromHex(string $hex): int $this->b = \hexdec($hex[2]) * 0x11; break; case self::COLOR_HEX_8: - $this->a = \hexdec(\substr($hex, 6, 2)) / 0xFF; + $this->a = \hexdec((string) \substr($hex, 6, 2)) / 0xFF; // no break case self::COLOR_HEX_6: $hex = \str_split($hex, 2); @@ -397,6 +397,9 @@ protected function setValuesFromHex(string $hex): int /** @psalm-return self::COLOR_* */ protected function setValuesFromFunction(string $value): int { + // We're not even going to attempt to support other color functions or + // angle values. If that's ever going to be a thing we'll depend on a + // color library and use php scopes for the phar file. if (!\preg_match('/^((?:rgb|hsl)a?)\\s*\\(([0-9\\.%,\\s\\/\\-]+)\\)$/i', $value, $match)) { throw new InvalidArgumentException('Couldn\'t parse color function string'); } @@ -419,14 +422,30 @@ protected function setValuesFromFunction(string $value): int throw new InvalidArgumentException('Color functions must be one of rgb/rgba/hsl/hsla'); // @codeCoverageIgnore } - $params = \preg_replace('/[,\\s\\/]+/', ',', \trim($match[2])); - $params = \explode(',', $params); - $params = \array_map('trim', $params); + \preg_match('/^\\s*([^,\\s\\/]+)([,\\s]+)((?1))((?2))((?1))(?:([,\\s\\/]+)((?1)))?\\s*$/', $match[2], $match); + + if (!$match || + \trim($match[2]) !== \trim($match[4]) || + (isset($match[6]) && ( + ('' === \trim($match[2]) && '/' !== \trim($match[6])) || + ('' !== \trim($match[2]) && \trim($match[2]) !== \trim($match[6])) + )) + ) { + throw new InvalidArgumentException('Couldn\'t parse color function string'); + } - if (\count($params) < 3 || \count($params) > 4) { - throw new InvalidArgumentException('Color functions must have 3 or 4 arguments'); + $params = [ + $match[1], + $match[3], + $match[5], + ]; + + if (isset($match[7])) { + $params[] = $match[7]; } + $params = \array_map('trim', $params); + foreach ($params as $i => &$color) { if (false !== \strpos($color, '%')) { $color = (float) \str_replace('%', '', $color); diff --git a/system/ThirdParty/Kint/Value/Representation/SourceRepresentation.php b/system/ThirdParty/Kint/Value/Representation/SourceRepresentation.php index 1645409d1cbf..9d7377524069 100644 --- a/system/ThirdParty/Kint/Value/Representation/SourceRepresentation.php +++ b/system/ThirdParty/Kint/Value/Representation/SourceRepresentation.php @@ -108,7 +108,9 @@ private static function readSource(string $filename, int $start_line = 1, ?int $ throw new RuntimeException("Couldn't read file"); } - $source = \preg_split("/\r\n|\n|\r/", \file_get_contents($filename)); + /** @psalm-var non-empty-array $source */ + $source = \preg_split("/\r\n|\n|\r/", (string) \file_get_contents($filename)); + /** @psalm-var array $source */ $source = \array_combine(\range(1, \count($source)), $source); $source = \array_slice($source, $start_line - 1, $length, true); diff --git a/system/ThirdParty/Kint/Value/StringValue.php b/system/ThirdParty/Kint/Value/StringValue.php index ca2c17f46f1d..c7ff67e2f58b 100644 --- a/system/ThirdParty/Kint/Value/StringValue.php +++ b/system/ThirdParty/Kint/Value/StringValue.php @@ -72,7 +72,10 @@ public function getValueUtf8(): string return $this->value; } - return \mb_convert_encoding($this->value, 'UTF-8', $this->encoding); + /** @psalm-var string $encoded */ + $encoded = \mb_convert_encoding($this->value, 'UTF-8', $this->encoding); + + return $encoded; } /** @psalm-api */ diff --git a/system/ThirdParty/Kint/init.php b/system/ThirdParty/Kint/init.php index 60e58f667cdc..9787a159004b 100644 --- a/system/ThirdParty/Kint/init.php +++ b/system/ThirdParty/Kint/init.php @@ -44,6 +44,7 @@ \define('KINT_PHP82', \version_compare(PHP_VERSION, '8.2') >= 0); \define('KINT_PHP83', \version_compare(PHP_VERSION, '8.3') >= 0); \define('KINT_PHP84', \version_compare(PHP_VERSION, '8.4') >= 0); +\define('KINT_PHP8412', \version_compare(PHP_VERSION, '8.4.12') >= 0); \define('KINT_PHP85', \version_compare(PHP_VERSION, '8.5') >= 0); // Dynamic default settings @@ -58,7 +59,7 @@ // Suppressed for unreadable document roots (related to open_basedir) if (false !== @\realpath($_SERVER['DOCUMENT_ROOT'])) { - /** @psalm-suppress PropertyTypeCoercion */ + /** @psalm-suppress InvalidPropertyAssignmentValue */ Utils::$path_aliases[\realpath($_SERVER['DOCUMENT_ROOT'])] = ''; } } diff --git a/system/ThirdParty/Kint/resources/compiled/aante-dark.css b/system/ThirdParty/Kint/resources/compiled/aante-dark.css index 36f8e75b5e07..7095cba4934d 100644 --- a/system/ThirdParty/Kint/resources/compiled/aante-dark.css +++ b/system/ThirdParty/Kint/resources/compiled/aante-dark.css @@ -1 +1 @@ -.kint-rich{--spacing: 4px;--nav-size: 15px;--backdrop-color: rgba(255, 255, 255, 0.9);--main-background: #e0eaef;--secondary-background: #c1d4df;--text-color: #1d1e1e;--variable-name-color: #1d1e1e;--variable-type-color: #0092db;--variable-type-color-hover: #5cb730;--border-color: #b6cedb;--border-color-hover: #0092db;--border: 1px solid var(--border-color);--foldout-max-size: calc(100vh - 100px);--foldout-zindex: 999999;--caret-image: url("data:image/svg+xml;utf8,");--ap-image: url("data:image/svg+xml;utf8,");--folder-image: url("data:image/svg+xml;utf8,");--search-image: url("data:image/svg+xml;utf8,");font-size:13px;overflow-x:auto;white-space:nowrap;background:var(--backdrop-color);direction:ltr;contain:content}.kint-rich.kint-folder{position:fixed;bottom:0;left:0;right:0;z-index:var(--foldout-zindex);width:100%;margin:0;display:block}.kint-rich.kint-folder dd.kint-foldout{max-height:var(--foldout-max-size);padding-right:calc(var(--spacing)*2);overflow-y:scroll;display:none}.kint-rich.kint-folder dd.kint-foldout.kint-show{display:block}.kint-rich::selection{background:var(--border-color-hover);color:var(--text-color)}.kint-rich .kint-focused{box-shadow:0 0 3px 3px var(--variable-type-color-hover)}.kint-rich .kint-focused.kint-weak-focus{box-shadow:0 0 3px 1px color-mix(in srgb, var(--variable-type-color-hover) 50%, transparent)}.kint-rich,.kint-rich::before,.kint-rich::after,.kint-rich *,.kint-rich *::before,.kint-rich *::after{box-sizing:border-box;border-radius:0;color:var(--text-color);float:none !important;font-family:Consolas,Menlo,Monaco,Lucida Console,Liberation Mono,DejaVu Sans Mono,Bitstream Vera Sans Mono,Courier New,monospace,serif;line-height:15px;margin:0;padding:0;text-align:left}.kint-rich{margin:calc(var(--spacing)*2) 0}.kint-rich dt,.kint-rich dl{width:auto}.kint-rich dt,.kint-rich div.access-path{background:var(--main-background);border:var(--border);color:var(--text-color);display:block;font-weight:bold;list-style:none outside none;overflow:auto;padding:var(--spacing)}.kint-rich dt:hover,.kint-rich div.access-path:hover{border-color:var(--border-color-hover)}.kint-rich>dl dl{padding:0 0 0 calc(var(--spacing)*3)}.kint-rich dt.kint-parent>nav,.kint-rich>footer>nav{background:var(--caret-image) no-repeat scroll 0 0/var(--nav-size) 75px rgba(0,0,0,0);cursor:pointer;display:inline-block;height:var(--nav-size);width:var(--nav-size);margin-right:3px;vertical-align:middle}.kint-rich dt.kint-parent:hover>nav,.kint-rich>footer>nav:hover{background-position:0 25%}.kint-rich dt.kint-parent.kint-show>nav,.kint-rich>footer.kint-show>nav{background-position:0 50%}.kint-rich dt.kint-parent.kint-show:hover>nav,.kint-rich>footer.kint-show>nav:hover{background-position:0 75%}.kint-rich dt.kint-parent.kint-locked>nav{background-position:0 100%}.kint-rich dt.kint-parent+dd{display:none;border-left:1px dashed var(--border-color);contain:strict}.kint-rich dt.kint-parent.kint-show+dd{display:block;contain:content}.kint-rich var,.kint-rich var a{color:var(--variable-type-color);font-style:normal}.kint-rich dt:hover var,.kint-rich dt:hover var a{color:var(--variable-type-color-hover)}.kint-rich dfn{font-style:normal;font-family:monospace;color:var(--variable-name-color)}.kint-rich pre{color:var(--text-color);margin:0 0 0 calc(var(--spacing)*3);padding:5px;overflow-y:hidden;border-top:0;border:var(--border);background:var(--main-background);display:block;word-break:normal}.kint-rich .kint-access-path-trigger,.kint-rich .kint-folder-trigger,.kint-rich .kint-search-trigger{background:color-mix(in srgb, var(--text-color) 80%, transparent);border-radius:3px;padding:2px;height:var(--nav-size);width:var(--nav-size);font-size:var(--nav-size);margin-left:5px;font-weight:bold;text-align:center;line-height:1;float:right !important;cursor:pointer;position:relative;overflow:hidden}.kint-rich .kint-access-path-trigger::before,.kint-rich .kint-folder-trigger::before,.kint-rich .kint-search-trigger::before{display:block;content:"";width:100%;height:100%;background:var(--main-background);mask:center/contain no-repeat alpha}.kint-rich .kint-access-path-trigger:hover,.kint-rich .kint-folder-trigger:hover,.kint-rich .kint-search-trigger:hover{background:var(--main-background)}.kint-rich .kint-access-path-trigger:hover::before,.kint-rich .kint-folder-trigger:hover::before,.kint-rich .kint-search-trigger:hover::before{background:var(--text-color)}.kint-rich .kint-access-path-trigger::before{mask-image:var(--ap-image)}.kint-rich .kint-folder-trigger::before{mask-image:var(--folder-image)}.kint-rich .kint-search-trigger::before{mask-image:var(--search-image)}.kint-rich input.kint-search{display:none;border:var(--border);border-top-width:0;border-bottom-width:0;padding:var(--spacing);float:right !important;margin:calc(var(--spacing)*-1) 0;color:var(--variable-name-color);background:var(--secondary-background);height:calc(var(--nav-size) + var(--spacing)*2);width:calc(var(--nav-size)*10);position:relative;z-index:100}.kint-rich input.kint-search.kint-show{display:block}.kint-rich .kint-search-root ul.kint-tabs>li:not(.kint-search-match){background:var(--secondary-background);filter:saturate(0);opacity:.5}.kint-rich .kint-search-root dl:not(.kint-search-match){opacity:.5}.kint-rich .kint-search-root dl:not(.kint-search-match)>dt{background:var(--main-background);filter:saturate(0)}.kint-rich .kint-search-root dl:not(.kint-search-match) dl,.kint-rich .kint-search-root dl:not(.kint-search-match) ul.kint-tabs>li:not(.kint-search-match){opacity:1}.kint-rich div.access-path{background:var(--secondary-background);display:none;margin-top:5px;padding:4px;white-space:pre}.kint-rich div.access-path.kint-show{display:block}.kint-rich footer{padding:0 3px 3px;font-size:9px;background:rgba(0,0,0,0)}.kint-rich footer>.kint-folder-trigger{background:rgba(0,0,0,0)}.kint-rich footer>.kint-folder-trigger::before{background:var(--text-color)}.kint-rich footer nav{height:10px;width:10px;background-size:10px 50px}.kint-rich footer>ol{display:none;margin-left:32px}.kint-rich footer.kint-show>ol{display:block}.kint-rich a{color:var(--text-color);text-shadow:none;text-decoration:underline}.kint-rich a:hover{color:var(--variable-name-color);border-bottom:1px dotted var(--variable-name-color)}.kint-rich ul{list-style:none;padding-left:calc(var(--spacing)*3)}.kint-rich ul:not(.kint-tabs) li{border-left:1px dashed var(--border-color)}.kint-rich ul:not(.kint-tabs) li>dl{border-left:none}.kint-rich ul.kint-tabs{margin:0 0 0 calc(var(--spacing)*3);padding-left:0;background:var(--main-background);border:var(--border);border-top:0}.kint-rich ul.kint-tabs>li{background:var(--secondary-background);border:var(--border);cursor:pointer;display:inline-block;height:calc(var(--spacing)*6);margin:calc(var(--spacing)/2);padding:0 calc(2px + var(--spacing)*2.5);vertical-align:top}.kint-rich ul.kint-tabs>li:hover,.kint-rich ul.kint-tabs>li.kint-active-tab:hover{border-color:var(--border-color-hover);color:var(--variable-type-color-hover)}.kint-rich ul.kint-tabs>li.kint-active-tab{background:var(--main-background);border-top:0;margin-top:-1px;height:27px;line-height:24px}.kint-rich ul.kint-tabs>li:not(.kint-active-tab){line-height:calc(var(--spacing)*5)}.kint-rich ul.kint-tabs li+li{margin-left:0}.kint-rich ul.kint-tab-contents>li{display:none;contain:strict}.kint-rich ul.kint-tab-contents>li.kint-show{display:block;contain:content}.kint-rich dt:hover+dd>ul>li.kint-active-tab{border-color:var(--border-color-hover);color:var(--variable-type-color-hover)}.kint-rich dt>.kint-color-preview{width:var(--nav-size);height:var(--nav-size);display:inline-block;vertical-align:middle;margin-left:10px;border:var(--border);background-color:#ccc;background-image:url('data:image/svg+xml;utf8,');background-size:min(20px,100%)}.kint-rich dt>.kint-color-preview:hover{border-color:var(--border-color-hover)}.kint-rich dt>.kint-color-preview>div{width:100%;height:100%}.kint-rich table{border-collapse:collapse;empty-cells:show;border-spacing:0}.kint-rich table *{font-size:12px}.kint-rich table dt{background:none;padding:calc(var(--spacing)/2)}.kint-rich table dt .kint-parent{min-width:100%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.kint-rich table td,.kint-rich table th{border:var(--border);padding:calc(var(--spacing)/2);vertical-align:center}.kint-rich table th{cursor:alias}.kint-rich table td:first-child,.kint-rich table th{font-weight:bold;background:var(--secondary-background);color:var(--variable-name-color)}.kint-rich table td{background:var(--main-background);white-space:pre}.kint-rich table td>dl{padding:0}.kint-rich table pre{border-top:0;border-right:0}.kint-rich table thead th:first-child{background:none;border:0}.kint-rich table tr:hover>td{box-shadow:0 0 1px 0 var(--border-color-hover) inset}.kint-rich table tr:hover var{color:var(--variable-type-color-hover)}.kint-rich table ul.kint-tabs li.kint-active-tab{height:20px;line-height:17px}.kint-rich pre.kint-source{margin-left:-1px}.kint-rich pre.kint-source[data-kint-filename]:before{display:block;content:attr(data-kint-filename);margin-bottom:var(--spacing);padding-bottom:var(--spacing);border-bottom:1px solid var(--secondary-background)}.kint-rich pre.kint-source>div:before{display:inline-block;content:counter(kint-l);counter-increment:kint-l;border-right:1px solid var(--border-color-hover);padding-right:calc(var(--spacing)*2);margin-right:calc(var(--spacing)*2)}.kint-rich pre.kint-source>div.kint-highlight{background:var(--secondary-background)}.kint-rich .kint-microtime-js .kint-microtime-lap{text-shadow:-1px 0 var(--border-color-hover),0 1px var(--border-color-hover),1px 0 var(--border-color-hover),0 -1px var(--border-color-hover);color:var(--main-background);font-weight:bold}input.kint-note-input{width:100%}.kint-rich{--main-background: #f8f8f8;--secondary-background: #f8f8f8;--variable-type-color: #06f;--variable-type-color-hover: #f00;--border-color: #d7d7d7;--border-color-hover: #aaa;--alternative-background: #fff;--highlight-color: #cfc;--caret-image: url("data:image/svg+xml;utf8,")}.kint-rich .kint-focused{box-shadow:0 0 3px 2px var(--variable-type-color-hover)}.kint-rich dt{font-weight:normal}.kint-rich dt.kint-parent{margin-top:4px}.kint-rich dl dl{margin-top:4px;padding-left:25px;border-left:none}.kint-rich>dl>dt{background:var(--secondary-background)}.kint-rich ul{margin:0;padding-left:0}.kint-rich ul:not(.kint-tabs)>li{border-left:0}.kint-rich ul.kint-tabs{background:var(--secondary-background);border:var(--border);border-width:0 1px 1px 1px;padding:4px 0 0 12px;margin-left:-1px;margin-top:-1px}.kint-rich ul.kint-tabs li,.kint-rich ul.kint-tabs li+li{margin:0 0 0 4px}.kint-rich ul.kint-tabs li{border-bottom-width:0;height:calc(var(--spacing)*6 + 1px)}.kint-rich ul.kint-tabs li:first-child{margin-left:0}.kint-rich ul.kint-tabs li.kint-active-tab{border-top:var(--border);background:var(--alternative-background);font-weight:bold;padding-top:0;border-bottom:1px solid var(--alternative-background) !important;margin-bottom:-1px}.kint-rich ul.kint-tabs li.kint-active-tab:hover{border-bottom:1px solid var(--alternative-background)}.kint-rich ul>li>pre{border:var(--border)}.kint-rich dt:hover+dd>ul{border-color:var(--border-color-hover)}.kint-rich pre{background:var(--alternative-background);margin-top:4px;margin-left:25px}.kint-rich .kint-source{margin-left:-1px}.kint-rich .kint-source .kint-highlight{background:var(--highlight-color)}.kint-rich .kint-parent.kint-show>.kint-search{border-bottom-width:1px}.kint-rich table td{background:var(--alternative-background)}.kint-rich table td>dl{padding:0;margin:0}.kint-rich table td>dl>dt.kint-parent{margin:0}.kint-rich table td:first-child,.kint-rich table td,.kint-rich table th{padding:2px 4px}.kint-rich table dd,.kint-rich table dt{background:var(--alternative-background)}.kint-rich table tr:hover>td{box-shadow:none;background:var(--highlight-color)}.kint-rich{--main-background: #070707;--secondary-background: #070707;--variable-type-color: #ff9900;--variable-type-color-hover: aqua;--border-color: #282828;--border-color-hover: #555555;--backdrop-color: rgba(0, 0, 0, 0.9);--text-color: #e2e1e1;--variable-name-color: #e2e1e1;--alternative-background: black;--highlight-color: #330033;--caret-image: url("data:image/svg+xml;utf8,")} +.kint-rich{--spacing: 4px;--nav-size: 15px;--backdrop-color: rgba(255, 255, 255, 0.9);--main-background: #e0eaef;--secondary-background: #c1d4df;--text-color: #1d1e1e;--variable-name-color: #1d1e1e;--variable-type-color: #0092db;--variable-type-color-hover: #5cb730;--border-color: #b6cedb;--border-color-hover: #0092db;--border: 1px solid var(--border-color);--foldout-max-size: calc(100vh - 100px);--foldout-zindex: 999999;--caret-image: url("data:image/svg+xml;utf8,");--ap-image: url("data:image/svg+xml;utf8,");--folder-image: url("data:image/svg+xml;utf8,");--search-image: url("data:image/svg+xml;utf8,");font-size:13px;overflow-x:auto;white-space:nowrap;background:var(--backdrop-color);direction:ltr;contain:content}.kint-rich.kint-folder{position:fixed;bottom:0;left:0;right:0;z-index:var(--foldout-zindex);width:100%;margin:0;display:block}.kint-rich.kint-folder dd.kint-foldout{max-height:var(--foldout-max-size);padding-right:calc(var(--spacing)*2);overflow-y:scroll;display:none}.kint-rich.kint-folder dd.kint-foldout.kint-show{display:block}.kint-rich::selection{background:var(--border-color-hover);color:var(--text-color)}.kint-rich .kint-focused{box-shadow:0 0 3px 3px var(--variable-type-color-hover)}.kint-rich .kint-focused.kint-weak-focus{box-shadow:0 0 3px 1px color-mix(in srgb, var(--variable-type-color-hover) 50%, transparent)}.kint-rich,.kint-rich::before,.kint-rich::after,.kint-rich *,.kint-rich *::before,.kint-rich *::after{box-sizing:border-box;border-radius:0;color:var(--text-color);float:none !important;font-family:Consolas,Menlo,Monaco,Lucida Console,Liberation Mono,DejaVu Sans Mono,Bitstream Vera Sans Mono,Courier New,monospace,serif;line-height:15px;margin:0;padding:0;text-align:left}.kint-rich{margin:calc(var(--spacing)*2) 0}.kint-rich dt,.kint-rich dl{width:auto}.kint-rich dt,.kint-rich div.access-path{background:var(--main-background);border:var(--border);color:var(--text-color);display:block;font-weight:bold;list-style:none outside none;overflow:auto;padding:var(--spacing)}.kint-rich dt:hover,.kint-rich div.access-path:hover{border-color:var(--border-color-hover)}.kint-rich>dl dl{padding:0 0 0 calc(var(--spacing)*3)}.kint-rich dt.kint-parent>nav,.kint-rich>footer>nav{background:var(--caret-image) no-repeat scroll 0 0/var(--nav-size) 75px rgba(0,0,0,0);cursor:pointer;display:inline-block;height:var(--nav-size);width:var(--nav-size);margin-right:3px;vertical-align:middle}.kint-rich dt.kint-parent:hover>nav,.kint-rich>footer>nav:hover{background-position:0 25%}.kint-rich dt.kint-parent.kint-show>nav,.kint-rich>footer.kint-show>nav{background-position:0 50%}.kint-rich dt.kint-parent.kint-show:hover>nav,.kint-rich>footer.kint-show>nav:hover{background-position:0 75%}.kint-rich dt.kint-parent.kint-locked>nav{background-position:0 100%}.kint-rich dt.kint-parent+dd{display:none;border-left:1px dashed var(--border-color);contain:strict}.kint-rich dt.kint-parent.kint-show+dd{display:block;contain:content}.kint-rich var,.kint-rich var a{color:var(--variable-type-color);font-style:normal}.kint-rich dt:hover var,.kint-rich dt:hover var a{color:var(--variable-type-color-hover)}.kint-rich dfn{font-style:normal;font-family:monospace;color:var(--variable-name-color)}.kint-rich pre{color:var(--text-color);margin:0 0 0 calc(var(--spacing)*3);padding:5px;overflow-y:hidden;border-top:0;border:var(--border);background:var(--main-background);display:block;word-break:normal}.kint-rich .kint-access-path-trigger,.kint-rich .kint-folder-trigger,.kint-rich .kint-search-trigger{background:color-mix(in srgb, var(--text-color) 80%, transparent);border-radius:3px;padding:2px;height:var(--nav-size);width:var(--nav-size);font-size:var(--nav-size);margin-left:5px;font-weight:bold;text-align:center;line-height:1;float:right !important;cursor:pointer;position:relative;overflow:hidden}.kint-rich .kint-access-path-trigger::before,.kint-rich .kint-folder-trigger::before,.kint-rich .kint-search-trigger::before{display:block;content:"";width:100%;height:100%;background:var(--main-background);mask:center/contain no-repeat alpha}.kint-rich .kint-access-path-trigger:hover,.kint-rich .kint-folder-trigger:hover,.kint-rich .kint-search-trigger:hover{background:var(--main-background)}.kint-rich .kint-access-path-trigger:hover::before,.kint-rich .kint-folder-trigger:hover::before,.kint-rich .kint-search-trigger:hover::before{background:var(--text-color)}.kint-rich .kint-access-path-trigger::before{mask-image:var(--ap-image)}.kint-rich .kint-folder-trigger::before{mask-image:var(--folder-image)}.kint-rich .kint-search-trigger::before{mask-image:var(--search-image)}.kint-rich input.kint-search{display:none;border:var(--border);border-top-width:0;border-bottom-width:0;padding:var(--spacing);float:right !important;margin:calc(var(--spacing)*-1) 0;color:var(--variable-name-color);background:var(--secondary-background);height:calc(var(--nav-size) + var(--spacing)*2);width:calc(var(--nav-size)*10);position:relative;z-index:100}.kint-rich input.kint-search.kint-show{display:block}.kint-rich .kint-search-root ul.kint-tabs>li:not(.kint-search-match){background:var(--secondary-background);filter:saturate(0);opacity:.5}.kint-rich .kint-search-root dl:not(.kint-search-match){opacity:.5}.kint-rich .kint-search-root dl:not(.kint-search-match)>dt{background:var(--main-background);filter:saturate(0)}.kint-rich .kint-search-root dl:not(.kint-search-match) dl,.kint-rich .kint-search-root dl:not(.kint-search-match) ul.kint-tabs>li:not(.kint-search-match){opacity:1}.kint-rich div.access-path{background:var(--secondary-background);display:none;margin-top:5px;padding:4px;white-space:pre}.kint-rich div.access-path.kint-show{display:block}.kint-rich footer{padding:0 3px 3px;font-size:9px;background:rgba(0,0,0,0)}.kint-rich footer>.kint-folder-trigger{background:rgba(0,0,0,0)}.kint-rich footer>.kint-folder-trigger::before{background:var(--text-color)}.kint-rich footer nav{height:10px;width:10px;background-size:10px 50px}.kint-rich footer>ol{display:none;margin-left:32px}.kint-rich footer.kint-show>ol{display:block}.kint-rich a{color:var(--text-color);text-shadow:none;text-decoration:underline}.kint-rich a:hover{color:var(--variable-name-color);border-bottom:1px dotted var(--variable-name-color)}.kint-rich ul{list-style:none;padding-left:calc(var(--spacing)*3)}.kint-rich ul:not(.kint-tabs) li{border-left:1px dashed var(--border-color)}.kint-rich ul:not(.kint-tabs) li>dl{border-left:none}.kint-rich ul.kint-tabs{margin:0 0 0 calc(var(--spacing)*3);padding-left:0;background:var(--main-background);border:var(--border);border-top:0}.kint-rich ul.kint-tabs>li{background:var(--secondary-background);border:var(--border);cursor:pointer;display:inline-block;height:calc(var(--spacing)*6);margin:calc(var(--spacing)/2);padding:0 calc(2px + var(--spacing)*2.5);vertical-align:top}.kint-rich ul.kint-tabs>li:hover,.kint-rich ul.kint-tabs>li.kint-active-tab:hover{border-color:var(--border-color-hover);color:var(--variable-type-color-hover)}.kint-rich ul.kint-tabs>li.kint-active-tab{background:var(--main-background);border-top:0;margin-top:-1px;height:27px;line-height:24px}.kint-rich ul.kint-tabs>li:not(.kint-active-tab){line-height:calc(var(--spacing)*5)}.kint-rich ul.kint-tabs li+li{margin-left:0}.kint-rich ul.kint-tab-contents>li{display:none;contain:strict}.kint-rich ul.kint-tab-contents>li.kint-show{display:block;contain:content}.kint-rich dt:hover+dd>ul>li.kint-active-tab{border-color:var(--border-color-hover);color:var(--variable-type-color-hover)}.kint-rich dt>.kint-color-preview{width:var(--nav-size);height:var(--nav-size);display:inline-block;vertical-align:middle;margin-left:10px;border:var(--border);background-color:#ccc;background-image:url('data:image/svg+xml;utf8,');background-size:min(20px,100%)}.kint-rich dt>.kint-color-preview:hover{border-color:var(--border-color-hover)}.kint-rich dt>.kint-color-preview>div{width:100%;height:100%}.kint-rich table{border-collapse:collapse;empty-cells:show;border-spacing:0}.kint-rich table *{font-size:12px}.kint-rich table dt{background:none;padding:calc(var(--spacing)/2)}.kint-rich table dt .kint-parent{min-width:100%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.kint-rich table td,.kint-rich table th{border:var(--border);padding:calc(var(--spacing)/2);vertical-align:center}.kint-rich table th{cursor:alias}.kint-rich table td:first-child,.kint-rich table th{font-weight:bold;background:var(--secondary-background);color:var(--variable-name-color)}.kint-rich table td{background:var(--main-background);white-space:pre}.kint-rich table td>dl{padding:0}.kint-rich table pre{border-top:0;border-right:0}.kint-rich table thead th:first-child{background:none;border:0}.kint-rich table tr:hover>td{box-shadow:0 0 1px 0 var(--border-color-hover) inset}.kint-rich table tr:hover var{color:var(--variable-type-color-hover)}.kint-rich table ul.kint-tabs li.kint-active-tab{height:20px;line-height:17px}.kint-rich pre.kint-source{margin-left:-1px}.kint-rich pre.kint-source[data-kint-filename]:before{display:block;content:attr(data-kint-filename);margin-bottom:var(--spacing);padding-bottom:var(--spacing);border-bottom:1px solid var(--secondary-background)}.kint-rich pre.kint-source>div:before{display:inline-block;content:counter(kint-l);counter-increment:kint-l;border-right:1px solid var(--border-color-hover);padding-right:calc(var(--spacing)*2);margin-right:calc(var(--spacing)*2)}.kint-rich pre.kint-source>div.kint-highlight{background:var(--secondary-background)}.kint-rich .kint-microtime-js .kint-microtime-lap{text-shadow:-1px 0 var(--border-color-hover),0 1px var(--border-color-hover),1px 0 var(--border-color-hover),0 -1px var(--border-color-hover);color:var(--main-background);font-weight:bold}.kint-rich{--main-background: #070707;--secondary-background: #070707;--variable-type-color: #ff9900;--variable-type-color-hover: aqua;--border-color: #282828;--border-color-hover: #555555;--backdrop-color: rgba(0, 0, 0, 0.9);--text-color: #e2e1e1;--variable-name-color: #e2e1e1;--alternative-background: black;--highlight-color: #330033;--caret-image: url("data:image/svg+xml;utf8,")} diff --git a/system/ThirdParty/Kint/resources/compiled/aante-light.css b/system/ThirdParty/Kint/resources/compiled/aante-light.css index 08bd4030ca56..621594dda91e 100644 --- a/system/ThirdParty/Kint/resources/compiled/aante-light.css +++ b/system/ThirdParty/Kint/resources/compiled/aante-light.css @@ -1 +1 @@ -.kint-rich{--spacing: 4px;--nav-size: 15px;--backdrop-color: rgba(255, 255, 255, 0.9);--main-background: #e0eaef;--secondary-background: #c1d4df;--text-color: #1d1e1e;--variable-name-color: #1d1e1e;--variable-type-color: #0092db;--variable-type-color-hover: #5cb730;--border-color: #b6cedb;--border-color-hover: #0092db;--border: 1px solid var(--border-color);--foldout-max-size: calc(100vh - 100px);--foldout-zindex: 999999;--caret-image: url("data:image/svg+xml;utf8,");--ap-image: url("data:image/svg+xml;utf8,");--folder-image: url("data:image/svg+xml;utf8,");--search-image: url("data:image/svg+xml;utf8,");font-size:13px;overflow-x:auto;white-space:nowrap;background:var(--backdrop-color);direction:ltr;contain:content}.kint-rich.kint-folder{position:fixed;bottom:0;left:0;right:0;z-index:var(--foldout-zindex);width:100%;margin:0;display:block}.kint-rich.kint-folder dd.kint-foldout{max-height:var(--foldout-max-size);padding-right:calc(var(--spacing)*2);overflow-y:scroll;display:none}.kint-rich.kint-folder dd.kint-foldout.kint-show{display:block}.kint-rich::selection{background:var(--border-color-hover);color:var(--text-color)}.kint-rich .kint-focused{box-shadow:0 0 3px 3px var(--variable-type-color-hover)}.kint-rich .kint-focused.kint-weak-focus{box-shadow:0 0 3px 1px color-mix(in srgb, var(--variable-type-color-hover) 50%, transparent)}.kint-rich,.kint-rich::before,.kint-rich::after,.kint-rich *,.kint-rich *::before,.kint-rich *::after{box-sizing:border-box;border-radius:0;color:var(--text-color);float:none !important;font-family:Consolas,Menlo,Monaco,Lucida Console,Liberation Mono,DejaVu Sans Mono,Bitstream Vera Sans Mono,Courier New,monospace,serif;line-height:15px;margin:0;padding:0;text-align:left}.kint-rich{margin:calc(var(--spacing)*2) 0}.kint-rich dt,.kint-rich dl{width:auto}.kint-rich dt,.kint-rich div.access-path{background:var(--main-background);border:var(--border);color:var(--text-color);display:block;font-weight:bold;list-style:none outside none;overflow:auto;padding:var(--spacing)}.kint-rich dt:hover,.kint-rich div.access-path:hover{border-color:var(--border-color-hover)}.kint-rich>dl dl{padding:0 0 0 calc(var(--spacing)*3)}.kint-rich dt.kint-parent>nav,.kint-rich>footer>nav{background:var(--caret-image) no-repeat scroll 0 0/var(--nav-size) 75px rgba(0,0,0,0);cursor:pointer;display:inline-block;height:var(--nav-size);width:var(--nav-size);margin-right:3px;vertical-align:middle}.kint-rich dt.kint-parent:hover>nav,.kint-rich>footer>nav:hover{background-position:0 25%}.kint-rich dt.kint-parent.kint-show>nav,.kint-rich>footer.kint-show>nav{background-position:0 50%}.kint-rich dt.kint-parent.kint-show:hover>nav,.kint-rich>footer.kint-show>nav:hover{background-position:0 75%}.kint-rich dt.kint-parent.kint-locked>nav{background-position:0 100%}.kint-rich dt.kint-parent+dd{display:none;border-left:1px dashed var(--border-color);contain:strict}.kint-rich dt.kint-parent.kint-show+dd{display:block;contain:content}.kint-rich var,.kint-rich var a{color:var(--variable-type-color);font-style:normal}.kint-rich dt:hover var,.kint-rich dt:hover var a{color:var(--variable-type-color-hover)}.kint-rich dfn{font-style:normal;font-family:monospace;color:var(--variable-name-color)}.kint-rich pre{color:var(--text-color);margin:0 0 0 calc(var(--spacing)*3);padding:5px;overflow-y:hidden;border-top:0;border:var(--border);background:var(--main-background);display:block;word-break:normal}.kint-rich .kint-access-path-trigger,.kint-rich .kint-folder-trigger,.kint-rich .kint-search-trigger{background:color-mix(in srgb, var(--text-color) 80%, transparent);border-radius:3px;padding:2px;height:var(--nav-size);width:var(--nav-size);font-size:var(--nav-size);margin-left:5px;font-weight:bold;text-align:center;line-height:1;float:right !important;cursor:pointer;position:relative;overflow:hidden}.kint-rich .kint-access-path-trigger::before,.kint-rich .kint-folder-trigger::before,.kint-rich .kint-search-trigger::before{display:block;content:"";width:100%;height:100%;background:var(--main-background);mask:center/contain no-repeat alpha}.kint-rich .kint-access-path-trigger:hover,.kint-rich .kint-folder-trigger:hover,.kint-rich .kint-search-trigger:hover{background:var(--main-background)}.kint-rich .kint-access-path-trigger:hover::before,.kint-rich .kint-folder-trigger:hover::before,.kint-rich .kint-search-trigger:hover::before{background:var(--text-color)}.kint-rich .kint-access-path-trigger::before{mask-image:var(--ap-image)}.kint-rich .kint-folder-trigger::before{mask-image:var(--folder-image)}.kint-rich .kint-search-trigger::before{mask-image:var(--search-image)}.kint-rich input.kint-search{display:none;border:var(--border);border-top-width:0;border-bottom-width:0;padding:var(--spacing);float:right !important;margin:calc(var(--spacing)*-1) 0;color:var(--variable-name-color);background:var(--secondary-background);height:calc(var(--nav-size) + var(--spacing)*2);width:calc(var(--nav-size)*10);position:relative;z-index:100}.kint-rich input.kint-search.kint-show{display:block}.kint-rich .kint-search-root ul.kint-tabs>li:not(.kint-search-match){background:var(--secondary-background);filter:saturate(0);opacity:.5}.kint-rich .kint-search-root dl:not(.kint-search-match){opacity:.5}.kint-rich .kint-search-root dl:not(.kint-search-match)>dt{background:var(--main-background);filter:saturate(0)}.kint-rich .kint-search-root dl:not(.kint-search-match) dl,.kint-rich .kint-search-root dl:not(.kint-search-match) ul.kint-tabs>li:not(.kint-search-match){opacity:1}.kint-rich div.access-path{background:var(--secondary-background);display:none;margin-top:5px;padding:4px;white-space:pre}.kint-rich div.access-path.kint-show{display:block}.kint-rich footer{padding:0 3px 3px;font-size:9px;background:rgba(0,0,0,0)}.kint-rich footer>.kint-folder-trigger{background:rgba(0,0,0,0)}.kint-rich footer>.kint-folder-trigger::before{background:var(--text-color)}.kint-rich footer nav{height:10px;width:10px;background-size:10px 50px}.kint-rich footer>ol{display:none;margin-left:32px}.kint-rich footer.kint-show>ol{display:block}.kint-rich a{color:var(--text-color);text-shadow:none;text-decoration:underline}.kint-rich a:hover{color:var(--variable-name-color);border-bottom:1px dotted var(--variable-name-color)}.kint-rich ul{list-style:none;padding-left:calc(var(--spacing)*3)}.kint-rich ul:not(.kint-tabs) li{border-left:1px dashed var(--border-color)}.kint-rich ul:not(.kint-tabs) li>dl{border-left:none}.kint-rich ul.kint-tabs{margin:0 0 0 calc(var(--spacing)*3);padding-left:0;background:var(--main-background);border:var(--border);border-top:0}.kint-rich ul.kint-tabs>li{background:var(--secondary-background);border:var(--border);cursor:pointer;display:inline-block;height:calc(var(--spacing)*6);margin:calc(var(--spacing)/2);padding:0 calc(2px + var(--spacing)*2.5);vertical-align:top}.kint-rich ul.kint-tabs>li:hover,.kint-rich ul.kint-tabs>li.kint-active-tab:hover{border-color:var(--border-color-hover);color:var(--variable-type-color-hover)}.kint-rich ul.kint-tabs>li.kint-active-tab{background:var(--main-background);border-top:0;margin-top:-1px;height:27px;line-height:24px}.kint-rich ul.kint-tabs>li:not(.kint-active-tab){line-height:calc(var(--spacing)*5)}.kint-rich ul.kint-tabs li+li{margin-left:0}.kint-rich ul.kint-tab-contents>li{display:none;contain:strict}.kint-rich ul.kint-tab-contents>li.kint-show{display:block;contain:content}.kint-rich dt:hover+dd>ul>li.kint-active-tab{border-color:var(--border-color-hover);color:var(--variable-type-color-hover)}.kint-rich dt>.kint-color-preview{width:var(--nav-size);height:var(--nav-size);display:inline-block;vertical-align:middle;margin-left:10px;border:var(--border);background-color:#ccc;background-image:url('data:image/svg+xml;utf8,');background-size:min(20px,100%)}.kint-rich dt>.kint-color-preview:hover{border-color:var(--border-color-hover)}.kint-rich dt>.kint-color-preview>div{width:100%;height:100%}.kint-rich table{border-collapse:collapse;empty-cells:show;border-spacing:0}.kint-rich table *{font-size:12px}.kint-rich table dt{background:none;padding:calc(var(--spacing)/2)}.kint-rich table dt .kint-parent{min-width:100%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.kint-rich table td,.kint-rich table th{border:var(--border);padding:calc(var(--spacing)/2);vertical-align:center}.kint-rich table th{cursor:alias}.kint-rich table td:first-child,.kint-rich table th{font-weight:bold;background:var(--secondary-background);color:var(--variable-name-color)}.kint-rich table td{background:var(--main-background);white-space:pre}.kint-rich table td>dl{padding:0}.kint-rich table pre{border-top:0;border-right:0}.kint-rich table thead th:first-child{background:none;border:0}.kint-rich table tr:hover>td{box-shadow:0 0 1px 0 var(--border-color-hover) inset}.kint-rich table tr:hover var{color:var(--variable-type-color-hover)}.kint-rich table ul.kint-tabs li.kint-active-tab{height:20px;line-height:17px}.kint-rich pre.kint-source{margin-left:-1px}.kint-rich pre.kint-source[data-kint-filename]:before{display:block;content:attr(data-kint-filename);margin-bottom:var(--spacing);padding-bottom:var(--spacing);border-bottom:1px solid var(--secondary-background)}.kint-rich pre.kint-source>div:before{display:inline-block;content:counter(kint-l);counter-increment:kint-l;border-right:1px solid var(--border-color-hover);padding-right:calc(var(--spacing)*2);margin-right:calc(var(--spacing)*2)}.kint-rich pre.kint-source>div.kint-highlight{background:var(--secondary-background)}.kint-rich .kint-microtime-js .kint-microtime-lap{text-shadow:-1px 0 var(--border-color-hover),0 1px var(--border-color-hover),1px 0 var(--border-color-hover),0 -1px var(--border-color-hover);color:var(--main-background);font-weight:bold}input.kint-note-input{width:100%}.kint-rich{--main-background: #f8f8f8;--secondary-background: #f8f8f8;--variable-type-color: #06f;--variable-type-color-hover: #f00;--border-color: #d7d7d7;--border-color-hover: #aaa;--alternative-background: #fff;--highlight-color: #cfc;--caret-image: url("data:image/svg+xml;utf8,")}.kint-rich .kint-focused{box-shadow:0 0 3px 2px var(--variable-type-color-hover)}.kint-rich dt{font-weight:normal}.kint-rich dt.kint-parent{margin-top:4px}.kint-rich dl dl{margin-top:4px;padding-left:25px;border-left:none}.kint-rich>dl>dt{background:var(--secondary-background)}.kint-rich ul{margin:0;padding-left:0}.kint-rich ul:not(.kint-tabs)>li{border-left:0}.kint-rich ul.kint-tabs{background:var(--secondary-background);border:var(--border);border-width:0 1px 1px 1px;padding:4px 0 0 12px;margin-left:-1px;margin-top:-1px}.kint-rich ul.kint-tabs li,.kint-rich ul.kint-tabs li+li{margin:0 0 0 4px}.kint-rich ul.kint-tabs li{border-bottom-width:0;height:calc(var(--spacing)*6 + 1px)}.kint-rich ul.kint-tabs li:first-child{margin-left:0}.kint-rich ul.kint-tabs li.kint-active-tab{border-top:var(--border);background:var(--alternative-background);font-weight:bold;padding-top:0;border-bottom:1px solid var(--alternative-background) !important;margin-bottom:-1px}.kint-rich ul.kint-tabs li.kint-active-tab:hover{border-bottom:1px solid var(--alternative-background)}.kint-rich ul>li>pre{border:var(--border)}.kint-rich dt:hover+dd>ul{border-color:var(--border-color-hover)}.kint-rich pre{background:var(--alternative-background);margin-top:4px;margin-left:25px}.kint-rich .kint-source{margin-left:-1px}.kint-rich .kint-source .kint-highlight{background:var(--highlight-color)}.kint-rich .kint-parent.kint-show>.kint-search{border-bottom-width:1px}.kint-rich table td{background:var(--alternative-background)}.kint-rich table td>dl{padding:0;margin:0}.kint-rich table td>dl>dt.kint-parent{margin:0}.kint-rich table td:first-child,.kint-rich table td,.kint-rich table th{padding:2px 4px}.kint-rich table dd,.kint-rich table dt{background:var(--alternative-background)}.kint-rich table tr:hover>td{box-shadow:none;background:var(--highlight-color)} +.kint-rich{--spacing: 4px;--nav-size: 15px;--backdrop-color: rgba(255, 255, 255, 0.9);--main-background: #e0eaef;--secondary-background: #c1d4df;--text-color: #1d1e1e;--variable-name-color: #1d1e1e;--variable-type-color: #0092db;--variable-type-color-hover: #5cb730;--border-color: #b6cedb;--border-color-hover: #0092db;--border: 1px solid var(--border-color);--foldout-max-size: calc(100vh - 100px);--foldout-zindex: 999999;--caret-image: url("data:image/svg+xml;utf8,");--ap-image: url("data:image/svg+xml;utf8,");--folder-image: url("data:image/svg+xml;utf8,");--search-image: url("data:image/svg+xml;utf8,");font-size:13px;overflow-x:auto;white-space:nowrap;background:var(--backdrop-color);direction:ltr;contain:content}.kint-rich.kint-folder{position:fixed;bottom:0;left:0;right:0;z-index:var(--foldout-zindex);width:100%;margin:0;display:block}.kint-rich.kint-folder dd.kint-foldout{max-height:var(--foldout-max-size);padding-right:calc(var(--spacing)*2);overflow-y:scroll;display:none}.kint-rich.kint-folder dd.kint-foldout.kint-show{display:block}.kint-rich::selection{background:var(--border-color-hover);color:var(--text-color)}.kint-rich .kint-focused{box-shadow:0 0 3px 3px var(--variable-type-color-hover)}.kint-rich .kint-focused.kint-weak-focus{box-shadow:0 0 3px 1px color-mix(in srgb, var(--variable-type-color-hover) 50%, transparent)}.kint-rich,.kint-rich::before,.kint-rich::after,.kint-rich *,.kint-rich *::before,.kint-rich *::after{box-sizing:border-box;border-radius:0;color:var(--text-color);float:none !important;font-family:Consolas,Menlo,Monaco,Lucida Console,Liberation Mono,DejaVu Sans Mono,Bitstream Vera Sans Mono,Courier New,monospace,serif;line-height:15px;margin:0;padding:0;text-align:left}.kint-rich{margin:calc(var(--spacing)*2) 0}.kint-rich dt,.kint-rich dl{width:auto}.kint-rich dt,.kint-rich div.access-path{background:var(--main-background);border:var(--border);color:var(--text-color);display:block;font-weight:bold;list-style:none outside none;overflow:auto;padding:var(--spacing)}.kint-rich dt:hover,.kint-rich div.access-path:hover{border-color:var(--border-color-hover)}.kint-rich>dl dl{padding:0 0 0 calc(var(--spacing)*3)}.kint-rich dt.kint-parent>nav,.kint-rich>footer>nav{background:var(--caret-image) no-repeat scroll 0 0/var(--nav-size) 75px rgba(0,0,0,0);cursor:pointer;display:inline-block;height:var(--nav-size);width:var(--nav-size);margin-right:3px;vertical-align:middle}.kint-rich dt.kint-parent:hover>nav,.kint-rich>footer>nav:hover{background-position:0 25%}.kint-rich dt.kint-parent.kint-show>nav,.kint-rich>footer.kint-show>nav{background-position:0 50%}.kint-rich dt.kint-parent.kint-show:hover>nav,.kint-rich>footer.kint-show>nav:hover{background-position:0 75%}.kint-rich dt.kint-parent.kint-locked>nav{background-position:0 100%}.kint-rich dt.kint-parent+dd{display:none;border-left:1px dashed var(--border-color);contain:strict}.kint-rich dt.kint-parent.kint-show+dd{display:block;contain:content}.kint-rich var,.kint-rich var a{color:var(--variable-type-color);font-style:normal}.kint-rich dt:hover var,.kint-rich dt:hover var a{color:var(--variable-type-color-hover)}.kint-rich dfn{font-style:normal;font-family:monospace;color:var(--variable-name-color)}.kint-rich pre{color:var(--text-color);margin:0 0 0 calc(var(--spacing)*3);padding:5px;overflow-y:hidden;border-top:0;border:var(--border);background:var(--main-background);display:block;word-break:normal}.kint-rich .kint-access-path-trigger,.kint-rich .kint-folder-trigger,.kint-rich .kint-search-trigger{background:color-mix(in srgb, var(--text-color) 80%, transparent);border-radius:3px;padding:2px;height:var(--nav-size);width:var(--nav-size);font-size:var(--nav-size);margin-left:5px;font-weight:bold;text-align:center;line-height:1;float:right !important;cursor:pointer;position:relative;overflow:hidden}.kint-rich .kint-access-path-trigger::before,.kint-rich .kint-folder-trigger::before,.kint-rich .kint-search-trigger::before{display:block;content:"";width:100%;height:100%;background:var(--main-background);mask:center/contain no-repeat alpha}.kint-rich .kint-access-path-trigger:hover,.kint-rich .kint-folder-trigger:hover,.kint-rich .kint-search-trigger:hover{background:var(--main-background)}.kint-rich .kint-access-path-trigger:hover::before,.kint-rich .kint-folder-trigger:hover::before,.kint-rich .kint-search-trigger:hover::before{background:var(--text-color)}.kint-rich .kint-access-path-trigger::before{mask-image:var(--ap-image)}.kint-rich .kint-folder-trigger::before{mask-image:var(--folder-image)}.kint-rich .kint-search-trigger::before{mask-image:var(--search-image)}.kint-rich input.kint-search{display:none;border:var(--border);border-top-width:0;border-bottom-width:0;padding:var(--spacing);float:right !important;margin:calc(var(--spacing)*-1) 0;color:var(--variable-name-color);background:var(--secondary-background);height:calc(var(--nav-size) + var(--spacing)*2);width:calc(var(--nav-size)*10);position:relative;z-index:100}.kint-rich input.kint-search.kint-show{display:block}.kint-rich .kint-search-root ul.kint-tabs>li:not(.kint-search-match){background:var(--secondary-background);filter:saturate(0);opacity:.5}.kint-rich .kint-search-root dl:not(.kint-search-match){opacity:.5}.kint-rich .kint-search-root dl:not(.kint-search-match)>dt{background:var(--main-background);filter:saturate(0)}.kint-rich .kint-search-root dl:not(.kint-search-match) dl,.kint-rich .kint-search-root dl:not(.kint-search-match) ul.kint-tabs>li:not(.kint-search-match){opacity:1}.kint-rich div.access-path{background:var(--secondary-background);display:none;margin-top:5px;padding:4px;white-space:pre}.kint-rich div.access-path.kint-show{display:block}.kint-rich footer{padding:0 3px 3px;font-size:9px;background:rgba(0,0,0,0)}.kint-rich footer>.kint-folder-trigger{background:rgba(0,0,0,0)}.kint-rich footer>.kint-folder-trigger::before{background:var(--text-color)}.kint-rich footer nav{height:10px;width:10px;background-size:10px 50px}.kint-rich footer>ol{display:none;margin-left:32px}.kint-rich footer.kint-show>ol{display:block}.kint-rich a{color:var(--text-color);text-shadow:none;text-decoration:underline}.kint-rich a:hover{color:var(--variable-name-color);border-bottom:1px dotted var(--variable-name-color)}.kint-rich ul{list-style:none;padding-left:calc(var(--spacing)*3)}.kint-rich ul:not(.kint-tabs) li{border-left:1px dashed var(--border-color)}.kint-rich ul:not(.kint-tabs) li>dl{border-left:none}.kint-rich ul.kint-tabs{margin:0 0 0 calc(var(--spacing)*3);padding-left:0;background:var(--main-background);border:var(--border);border-top:0}.kint-rich ul.kint-tabs>li{background:var(--secondary-background);border:var(--border);cursor:pointer;display:inline-block;height:calc(var(--spacing)*6);margin:calc(var(--spacing)/2);padding:0 calc(2px + var(--spacing)*2.5);vertical-align:top}.kint-rich ul.kint-tabs>li:hover,.kint-rich ul.kint-tabs>li.kint-active-tab:hover{border-color:var(--border-color-hover);color:var(--variable-type-color-hover)}.kint-rich ul.kint-tabs>li.kint-active-tab{background:var(--main-background);border-top:0;margin-top:-1px;height:27px;line-height:24px}.kint-rich ul.kint-tabs>li:not(.kint-active-tab){line-height:calc(var(--spacing)*5)}.kint-rich ul.kint-tabs li+li{margin-left:0}.kint-rich ul.kint-tab-contents>li{display:none;contain:strict}.kint-rich ul.kint-tab-contents>li.kint-show{display:block;contain:content}.kint-rich dt:hover+dd>ul>li.kint-active-tab{border-color:var(--border-color-hover);color:var(--variable-type-color-hover)}.kint-rich dt>.kint-color-preview{width:var(--nav-size);height:var(--nav-size);display:inline-block;vertical-align:middle;margin-left:10px;border:var(--border);background-color:#ccc;background-image:url('data:image/svg+xml;utf8,');background-size:min(20px,100%)}.kint-rich dt>.kint-color-preview:hover{border-color:var(--border-color-hover)}.kint-rich dt>.kint-color-preview>div{width:100%;height:100%}.kint-rich table{border-collapse:collapse;empty-cells:show;border-spacing:0}.kint-rich table *{font-size:12px}.kint-rich table dt{background:none;padding:calc(var(--spacing)/2)}.kint-rich table dt .kint-parent{min-width:100%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.kint-rich table td,.kint-rich table th{border:var(--border);padding:calc(var(--spacing)/2);vertical-align:center}.kint-rich table th{cursor:alias}.kint-rich table td:first-child,.kint-rich table th{font-weight:bold;background:var(--secondary-background);color:var(--variable-name-color)}.kint-rich table td{background:var(--main-background);white-space:pre}.kint-rich table td>dl{padding:0}.kint-rich table pre{border-top:0;border-right:0}.kint-rich table thead th:first-child{background:none;border:0}.kint-rich table tr:hover>td{box-shadow:0 0 1px 0 var(--border-color-hover) inset}.kint-rich table tr:hover var{color:var(--variable-type-color-hover)}.kint-rich table ul.kint-tabs li.kint-active-tab{height:20px;line-height:17px}.kint-rich pre.kint-source{margin-left:-1px}.kint-rich pre.kint-source[data-kint-filename]:before{display:block;content:attr(data-kint-filename);margin-bottom:var(--spacing);padding-bottom:var(--spacing);border-bottom:1px solid var(--secondary-background)}.kint-rich pre.kint-source>div:before{display:inline-block;content:counter(kint-l);counter-increment:kint-l;border-right:1px solid var(--border-color-hover);padding-right:calc(var(--spacing)*2);margin-right:calc(var(--spacing)*2)}.kint-rich pre.kint-source>div.kint-highlight{background:var(--secondary-background)}.kint-rich .kint-microtime-js .kint-microtime-lap{text-shadow:-1px 0 var(--border-color-hover),0 1px var(--border-color-hover),1px 0 var(--border-color-hover),0 -1px var(--border-color-hover);color:var(--main-background);font-weight:bold}.kint-rich{--main-background: #f8f8f8;--secondary-background: #f8f8f8;--variable-type-color: #06f;--variable-type-color-hover: #f00;--border-color: #d7d7d7;--border-color-hover: #aaa;--alternative-background: #fff;--highlight-color: #cfc;--caret-image: url("data:image/svg+xml;utf8,")}.kint-rich .kint-focused{box-shadow:0 0 3px 2px var(--variable-type-color-hover)}.kint-rich dt{font-weight:normal}.kint-rich dt.kint-parent{margin-top:4px}.kint-rich dl dl{margin-top:4px;padding-left:25px;border-left:none}.kint-rich>dl>dt{background:var(--secondary-background)}.kint-rich ul{margin:0;padding-left:0}.kint-rich ul:not(.kint-tabs)>li{border-left:0}.kint-rich ul.kint-tabs{background:var(--secondary-background);border:var(--border);border-width:0 1px 1px 1px;padding:4px 0 0 12px;margin-left:-1px;margin-top:-1px}.kint-rich ul.kint-tabs li,.kint-rich ul.kint-tabs li+li{margin:0 0 0 4px}.kint-rich ul.kint-tabs li{border-bottom-width:0;height:calc(var(--spacing)*6 + 1px)}.kint-rich ul.kint-tabs li:first-child{margin-left:0}.kint-rich ul.kint-tabs li.kint-active-tab{border-top:var(--border);background:var(--alternative-background);font-weight:bold;padding-top:0;border-bottom:1px solid var(--alternative-background) !important;margin-bottom:-1px}.kint-rich ul.kint-tabs li.kint-active-tab:hover{border-bottom:1px solid var(--alternative-background)}.kint-rich ul>li>pre{border:var(--border)}.kint-rich dt:hover+dd>ul{border-color:var(--border-color-hover)}.kint-rich pre{background:var(--alternative-background);margin-top:4px;margin-left:25px}.kint-rich .kint-source{margin-left:-1px}.kint-rich .kint-source .kint-highlight{background:var(--highlight-color)}.kint-rich .kint-parent.kint-show>.kint-search{border-bottom-width:1px}.kint-rich table td{background:var(--alternative-background)}.kint-rich table td>dl{padding:0;margin:0}.kint-rich table td>dl>dt.kint-parent{margin:0}.kint-rich table td:first-child,.kint-rich table td,.kint-rich table th{padding:2px 4px}.kint-rich table dd,.kint-rich table dt{background:var(--alternative-background)}.kint-rich table tr:hover>td{box-shadow:none;background:var(--highlight-color)} diff --git a/system/ThirdParty/Kint/resources/compiled/main.js b/system/ThirdParty/Kint/resources/compiled/main.js index b1fab3885307..c88e6b90b91d 100644 --- a/system/ThirdParty/Kint/resources/compiled/main.js +++ b/system/ThirdParty/Kint/resources/compiled/main.js @@ -1 +1 @@ -"use strict";(()=>{function m(n){if(!(n instanceof Element))throw new Error("Invalid argument to dedupeElement()");let t=n.ownerDocument,e=E(n);for(let s of t.querySelectorAll(e))n!==s&&s.parentNode.removeChild(s)}function d(n){return n instanceof Element?n.ownerDocument.contains(n):!1}function E(n){if(!(n instanceof Element))throw new Error("Invalid argument to buildClassSelector()");return[n.nodeName,...n.classList].join(".")}function f(n){if(!(n instanceof Element))throw new Error("Invalid argument to selectText()");let t=n.ownerDocument,e=t.getSelection(),s=t.createRange();s.selectNodeContents(n),e.removeAllRanges(),e.addRange(s)}function I(n,t){let e;return function(...s){clearTimeout(e),e=setTimeout(function(){n(...s)},t)}}function x(n){if(!(n instanceof Element))throw new Error("Invalid argument to offsetTop()");return n.offsetTop+(n.offsetParent?x(n.offsetParent):0)}var u=class n{static#e=new Set;static toggleSearchBox(t,e){let s=t.querySelector(".kint-search"),i=t.parentNode;if(s)if(s.classList.toggle("kint-show",e)){if(s.focus(),s.select(),!n.#e.has(s)){let r=i.querySelectorAll("dl").length,o=200;r>1e4&&(o=700),s.addEventListener("keyup",I(n.#t.bind(null,s),o)),n.#e.add(s)}n.#t(s)}else i.classList.remove("kint-search-root")}static#t(t){let e=t.closest(".kint-parent")?.parentNode;if(e)if(t.classList.contains("kint-show")&&t.value.length){let s=e.dataset.lastSearch;if(e.classList.add("kint-search-root"),s!==t.value){e.dataset.lastSearch=t.value,e.classList.remove("kint-search-match");for(let i of e.querySelectorAll(".kint-search-match"))i.classList.remove("kint-search-match");n.#s(e,t.value.toUpperCase())}}else e.classList.remove("kint-search-root")}static#s(t,e){let s=t.cloneNode(!0);for(let c of s.querySelectorAll(".access-path"))c.remove();if(!s.textContent.toUpperCase().includes(e))return;t.classList.add("kint-search-match");let i=t.firstElementChild;for(;i&&i.tagName!=="DT";)i=i.nextElementSibling;if(!i)return;let r=a.getChildContainer(i);if(!r)return;let o,l;for(let c of r.children)c.tagName==="DL"?n.#s(c,e):c.tagName==="UL"&&(c.classList.contains("kint-tabs")?o=c.children:c.classList.contains("kint-tab-contents")&&(l=c.children));if(!(!o||o.length!==l?.length))for(let c=o.length;c--;){let k=!1,F=!1;o[c].textContent.toUpperCase().includes(e)&&(k=!0);let O=l[c].cloneNode(!0);for(let v of O.querySelectorAll(".access-path"))v.remove();if(O.textContent.toUpperCase().includes(e)&&(k=!0,F=!0),k&&o[c].classList.add("kint-search-match"),F)for(let v of l[c].children)v.tagName==="DL"&&n.#s(v,e)}}};var g=class{static sort(t,e){let s=t.dataset.kintTableSort,i=parseInt(s)===e?-1:1,r=t.tBodies[0];[...r.rows].sort(function(o,l){o=o.cells[e].textContent.trim().toLocaleLowerCase(),l=l.cells[e].textContent.trim().toLocaleLowerCase();let c=0;return!isNaN(o)&&!isNaN(l)?(o=parseFloat(o),l=parseFloat(l),c=o-l):isNaN(o)&&!isNaN(l)?c=1:isNaN(l)&&!isNaN(o)?c=-1:c=(""+o).localeCompare(""+l),c*i}).forEach(o=>r.appendChild(o)),i<0?t.dataset.kintTableSort=null:t.dataset.kintTableSort=e}};var a=class n{#e;#t;#s;constructor(t){if(!(t instanceof h))throw new Error("Invalid argument to Rich.constructor()");this.#e=t,this.#e.runOnInit(this.#i.bind(this));let e=new q(this,t);new b(this,t.window,e)}#i(){let t=this.#e.window.document;if(d(this.#t)||(this.#t=t.querySelector("style.kint-rich-style")),this.#t&&m(this.#t),t.querySelector(".kint-rich.kint-file")){this.setupFolder(t);let e=this.#s.querySelector("dd.kint-foldout"),s=Array.from(t.querySelectorAll(".kint-rich.kint-file"));for(let i of s)i.parentNode!==e&&e.appendChild(i);this.#s.classList.add("kint-show")}}addToFolder(t){let e=t.closest(".kint-rich");if(!e)throw new Error("Bad addToFolder");let s=this.#e.window.document;if(this.setupFolder(s),this.folder.contains(t))throw new Error("Bad addToFolder");let i=this.#s.querySelector("dd.kint-foldout"),r=t.closest(".kint-parent, .kint-rich"),o=Array.from(e.querySelectorAll(".kint-folder-trigger"));if(e===r||e.querySelectorAll(".kint-rich > dl").length===1){for(let l of o)l.remove();e.classList.add("kint-file"),i.insertBefore(e,i.firstChild)}else{let l=s.createElement("div");l.classList.add("kint-rich"),l.classList.add("kint-file"),l.appendChild(r.closest(".kint-rich > dl"));let c=e.lastElementChild;c.matches(".kint-rich > footer")&&l.appendChild(c.cloneNode(!0));for(let k of o)k.remove();i.insertBefore(l,i.firstChild)}n.toggle(this.#s.querySelector(".kint-parent"),!0)}setupFolder(t){if(this.#s)d(this.#s)||(this.#s=t.querySelector(".kint-rich.kint-folder"));else{let e=t.createElement("template");e.innerHTML='
    Kint
    ',this.#s=e.content.firstChild,t.body.appendChild(this.#s)}}get folder(){return d(this.#s)||(this.#s=this.#e.window.document.querySelector(".kint-rich.kint-folder")),this.#s&&m(this.#s),this.#s}isFolderOpen(){let t=this.#s?.querySelector("dd.kint-foldout");if(t)return t.previousSibling.classList.contains("kint-show")}static getChildContainer(t){let e=t.nextElementSibling;for(;e&&!e.matches("dd");)e=e.nextElementSibling;return e}static toggle(t,e){let s=n.getChildContainer(t);s&&(e=t.classList.toggle("kint-show",e),n.#n(s,e))}static switchTab(t){t.parentNode.getElementsByClassName("kint-active-tab")[0].classList.remove("kint-active-tab"),t.classList.add("kint-active-tab");let e=t,s=0;for(;e=e.previousElementSibling;)s++;let i=t.parentNode.nextSibling.children;for(let r=i.length;r--;)r===s?(i[r].classList.add("kint-show"),n.#n(i[r],!0)):i[r].classList.remove("kint-show")}static toggleChildren(t,e){let s=n.getChildContainer(t);if(!s)return;e===void 0&&(e=t.classList.contains("kint-show"));let i=Array.from(s.getElementsByClassName("kint-parent"));for(let r of i)r.classList.toggle("kint-show",e)}static toggleAccessPath(t,e){let s=t.querySelector(".access-path");s?.classList.toggle("kint-show",e)&&f(s)}static#n(t,e){if(t.children.length===2&&t.lastElementChild.matches("ul.kint-tab-contents"))for(let s of t.lastElementChild.children)s.matches("li.kint-show")&&(t=s);if(t.children.length===1&&t.firstElementChild.matches("dl")){let s=t.firstElementChild.firstElementChild;s?.classList?.contains("kint-parent")&&n.toggle(s,e)}}},b=class{#e;#t;#s;#i=null;#n=null;#o=0;constructor(t,e,s){this.#e=t,this.#t=s,this.#s=e,this.#s.addEventListener("click",this.#a.bind(this),!0)}#r(){clearTimeout(this.#i),this.#i=setTimeout(this.#l.bind(this),250)}#l(){clearTimeout(this.#i),this.#i=null,this.#n=null,this.#o=0}#c(){let t=this.#n;if(!t.matches(".kint-parent > nav"))return;let e=t.parentNode;if(this.#o===1)a.toggleChildren(e),this.#t.onTreeChanged(),this.#r(),this.#o=2;else if(this.#o===2){this.#l();let s=e.classList.contains("kint-show"),i=this.#e.folder?.querySelector(".kint-parent"),r=Array.from(this.#s.document.getElementsByClassName("kint-parent"));for(let o of r)o!==i&&o.classList.toggle("kint-show",s);this.#t.onTreeChanged(),this.#t.scrollToFocus()}}#a(t){if(this.#o){this.#c();return}let e=t.target;if(!e.closest(".kint-rich"))return;if(e.tagName==="DFN"&&f(e),e.tagName==="TH"){t.ctrlKey||g.sort(e.closest("table"),e.cellIndex);return}if(e.tagName==="LI"&&e.parentNode.className==="kint-tabs"){if(e.className!=="kint-active-tab"){let i=e.closest("dl")?.querySelector(".kint-parent > nav")??e;a.switchTab(e),this.#t.onTreeChanged(),this.#t.setCursor(i)}return}let s=e.closest("dt");if(e.tagName==="NAV")e.parentNode.tagName==="FOOTER"?(this.#t.setCursor(e),e.parentNode.classList.toggle("kint-show")):s?.classList.contains("kint-parent")&&(a.toggle(s),this.#t.onTreeChanged(),this.#t.setCursor(e),this.#r(),this.#o=1,this.#n=e);else if(e.classList.contains("kint-access-path-trigger"))s&&a.toggleAccessPath(s);else if(e.classList.contains("kint-search-trigger"))s?.matches(".kint-rich > dl > dt.kint-parent")&&u.toggleSearchBox(s);else if(e.classList.contains("kint-folder-trigger")){if(s?.matches(".kint-rich > dl > dt.kint-parent"))this.#e.addToFolder(e),this.#t.onTreeChanged(),this.#t.setCursor(s.querySelector("nav")),this.#t.scrollToFocus();else if(e.parentNode.tagName==="FOOTER"){let i=e.closest(".kint-rich").querySelector(".kint-parent > nav, .kint-rich > footer > nav");this.#e.addToFolder(e),this.#t.onTreeChanged(),this.#t.setCursor(i),this.#t.scrollToFocus()}}else e.classList.contains("kint-search")||(e.tagName==="PRE"&&t.detail===3?f(e):e.closest(".kint-source")&&t.detail===3?f(e.closest(".kint-source")):e.classList.contains("access-path")?f(e):e.tagName!=="A"&&s?.classList.contains("kint-parent")&&(a.toggle(s),this.#t.onTreeChanged(),this.#t.setCursor(s.querySelector("nav"))))}},j=65,G=68,A=70,S=72,K=74,D=75,p=76,V=83,P=9,T=13,B=27,L=32,N=37,R=38,C=39,H=40,M=".kint-rich .kint-parent > nav, .kint-rich > footer > nav, .kint-rich .kint-tabs > li:not(.kint-active-tab)",q=class{#e=[];#t=0;#s=!1;#i;#n;constructor(t,e){this.#i=t,this.#n=e.window,this.#n.addEventListener("keydown",this.#c.bind(this),!0),e.runOnInit(this.onTreeChanged.bind(this))}scrollToFocus(){let t=this.#e[this.#t];if(!t)return;let e=this.#i.folder;if(t===e?.querySelector(".kint-parent > nav"))return;let s=x(t);if(this.#i.isFolderOpen()){let i=e.querySelector("dd.kint-foldout");i.scrollTo(0,s-i.clientHeight/2)}else this.#n.scrollTo(0,s-this.#n.innerHeight/2)}onTreeChanged(){let t=this.#e[this.#t];this.#e=[];let e=this.#i.folder,s=e?.querySelector(".kint-parent > nav"),i=this.#n.document;this.#i.isFolderOpen()&&(i=e,this.#e.push(s));let r=Array.from(i.querySelectorAll(M));for(let o of r)o.offsetParent!==null&&o!==s&&this.#e.push(o);if(s&&!this.#i.isFolderOpen()&&this.#e.push(s),this.#e.length===0){this.#s=!1,this.#r();return}t&&this.#e.indexOf(t)!==-1?this.#t=this.#e.indexOf(t):this.#r()}setCursor(t){if(this.#i.isFolderOpen()&&!this.#i.folder.contains(t)||!t.matches(M))return!1;let e=this.#e.indexOf(t);if(e===-1&&(this.onTreeChanged(),e=this.#e.indexOf(t)),e!==-1){if(e!==this.#t)return this.#t=e,this.#r(),!0;this.#e[e]?.classList.remove("kint-weak-focus")}else console.error("setCursor failed to find target in list",t),console.info("Please report this as a bug in Kint at https://github.com/kint-php/kint");return!1}#o(t){if(this.#e.length===0)return this.#t=0,null;for(this.#t+=t;this.#t<0;)this.#t+=this.#e.length;for(;this.#t>=this.#e.length;)this.#t-=this.#e.length;return this.#r(),this.#t}#r(){let t=this.#n.document.querySelector(".kint-focused");t&&(t.classList.remove("kint-focused"),t.classList.remove("kint-weak-focus")),this.#s&&this.#e[this.#t]?.classList.add("kint-focused")}#l(t){let e=t.closest(".kint-rich .kint-parent ~ dd")?.parentNode.querySelector(".kint-parent > nav");e&&(this.setCursor(e),this.scrollToFocus())}#c(t){if(this.#s&&t.keyCode===B&&t.target.matches(".kint-search")){t.target.blur(),this.#r();return}if(t.target!==this.#n.document.body||t.altKey||t.ctrlKey)return;if(t.keyCode===G){if(this.#s)this.#s=!1;else{if(this.#s=!0,this.onTreeChanged(),this.#e.length===0){this.#s=!1;return}this.scrollToFocus()}this.#r(),t.preventDefault();return}else if(t.keyCode===B){this.#s&&(this.#s=!1,this.#r(),t.preventDefault());return}else if(!this.#s)return;t.preventDefault(),d(this.#e[this.#t])||this.onTreeChanged();let e=this.#e[this.#t];if([P,R,D,H,K].includes(t.keyCode)){t.keyCode===P?this.#o(t.shiftKey?-1:1):t.keyCode===R||t.keyCode===D?this.#o(-1):(t.keyCode===H||t.keyCode===K)&&this.#o(1),this.scrollToFocus();return}if(e.tagName==="LI"&&[L,T,C,p,N,S].includes(t.keyCode)){t.keyCode===L||t.keyCode===T?(a.switchTab(e),this.onTreeChanged()):t.keyCode===C||t.keyCode===p?this.#o(1):(t.keyCode===N||t.keyCode===S)&&this.#o(-1),this.scrollToFocus();return}if(e.parentNode.tagName==="FOOTER"&&e.closest(".kint-rich")){if(t.keyCode===L||t.keyCode===T)e.parentNode.classList.toggle("kint-show");else if(t.keyCode===N||t.keyCode===S)if(e.parentNode.classList.contains("kint-show"))e.parentNode.classList.remove("kint-show");else{this.#l(e.closest(".kint-rich"));return}else if(t.keyCode===C||t.keyCode===p)e.parentNode.classList.add("kint-show");else if(t.keyCode===A&&!this.#i.isFolderOpen()&&e.matches(".kint-rich > footer > nav")){let i=e.closest(".kint-rich").querySelector(".kint-parent > nav, .kint-rich > footer > nav");this.#i.addToFolder(e),this.onTreeChanged(),this.setCursor(i),this.scrollToFocus()}return}let s=e.closest(".kint-parent");if(s){if(t.keyCode===j){a.toggleAccessPath(s);return}if(t.keyCode===A){!this.#i.isFolderOpen()&&s.matches(".kint-rich:not(.kint-folder) > dl > .kint-parent")&&(this.#i.addToFolder(e),this.onTreeChanged(),this.setCursor(e),this.scrollToFocus());return}if(t.keyCode===V){let i=s.closest(".kint-rich > dl")?.querySelector(".kint-search")?.closest(".kint-parent");if(i){e.classList.add("kint-weak-focus"),u.toggleSearchBox(i,!0);return}}if(t.keyCode===L||t.keyCode===T){a.toggle(s),this.onTreeChanged();return}if([C,p,N,S].includes(t.keyCode)){let i=s.classList.contains("kint-show");if(t.keyCode===C||t.keyCode===p){i&&a.toggleChildren(s,!0),a.toggle(s,!0),this.onTreeChanged();return}else if(i){a.toggleChildren(s,!1),a.toggle(s,!1),this.onTreeChanged();return}else{this.#l(s);return}}}}};var y=class{#e;#t;constructor(t){if(!(t instanceof h))throw new Error("Invalid argument to Plain.constructor()");this.#e=t.window,t.runOnInit(this.#s.bind(this))}#s(){d(this.#t)||(this.#t=this.#e.document.querySelector("style.kint-plain-style")),this.#t&&m(this.#t)}};var w=class{#e;constructor(t){if(!(t instanceof h))throw new Error("Invalid argument to Microtime.constructor()");this.#e=t.window,t.runOnInit(this.#t.bind(this))}#t(){let t={},e=this.#e.document.querySelectorAll("[data-kint-microtime-group]");for(let s of e){let i=s.querySelector(".kint-microtime-lap");if(!i)continue;let r=s.dataset.kintMicrotimeGroup,o=parseFloat(i.textContent),l=parseFloat(s.querySelector(".kint-microtime-avg").textContent);t[r]??={min:o,max:o,avg:l},t[r].min>o&&(t[r].min=o),t[r].maxo.avg){let l=(r-o.avg)/(o.max-o.avg);i.style.background="hsl("+(40-40*l)+", 100%, 65%)"}else{let l=0;o.avg!==o.min&&(l=(o.avg-r)/(o.avg-o.min)),i.style.background="hsl("+(40+80*l)+", 100%, 65%)"}}}};var U=Symbol(),h=class n{static#e=null;#t;#s=[];#i=new Set;static init(t){return n.#e??=new n(t,U),n.#e.#n(),n.#e.runOnLoad(n.#r),n.#e}get window(){return this.#t}constructor(t,e){if(U!==e)throw new Error("Kint constructor is private. Use Kint.init()");if(!(t instanceof Window))throw new Error("Invalid argument to Kint.init()");this.#t=t,this.runOnInit(this.#o.bind(this)),new y(this),new a(this),new w(this)}runOnLoad(t){if(this.#t.document.readyState==="complete")try{t()}catch{}else this.#t.addEventListener("load",t)}runOnInit(t){this.#s.push(t)}#n(){this.#t.document.currentScript&&(this.#i.add(E(window.document.currentScript)),window.document.currentScript.remove())}#o(){for(let t of this.#i.keys())for(let e of this.#t.document.querySelectorAll(t))e.remove()}static#r(){for(let t of n.#e.#s)t()}};window.Kint||(window.Kint=h);window.Kint.init(window);})(); +"use strict";(()=>{function m(n){if(!(n instanceof Element))throw new Error("Invalid argument to dedupeElement()");let t=n.ownerDocument,e=E(n);for(let s of t.querySelectorAll(e))n!==s&&s.parentNode.removeChild(s)}function d(n){return n instanceof Element?n.ownerDocument.contains(n):!1}function E(n){if(!(n instanceof Element))throw new Error("Invalid argument to buildClassSelector()");return[n.nodeName,...n.classList].join(".")}function f(n){if(!(n instanceof Element))throw new Error("Invalid argument to selectText()");let t=n.ownerDocument,e=t.getSelection(),s=t.createRange();s.selectNodeContents(n),e.removeAllRanges(),e.addRange(s)}function I(n,t){let e;return function(...s){clearTimeout(e),e=setTimeout(function(){n(...s)},t)}}function x(n){if(!(n instanceof Element))throw new Error("Invalid argument to offsetTop()");return n.offsetTop+(n.offsetParent?x(n.offsetParent):0)}var u=class n{static#e=new Set;static toggleSearchBox(t,e){let s=t.querySelector(".kint-search"),i=t.parentNode;if(s)if(s.classList.toggle("kint-show",e)){if(s.focus(),s.select(),!n.#e.has(s)){let r=i.querySelectorAll("dl").length,o=200;r>1e4&&(o=700),s.addEventListener("keyup",I(n.#t.bind(null,s),o)),n.#e.add(s)}n.#t(s)}else i.classList.remove("kint-search-root")}static#t(t){let e=t.closest(".kint-parent")?.parentNode;if(e)if(t.classList.contains("kint-show")&&t.value.length){let s=e.dataset.lastSearch;if(e.classList.add("kint-search-root"),s!==t.value){e.dataset.lastSearch=t.value,e.classList.remove("kint-search-match");for(let i of e.querySelectorAll(".kint-search-match"))i.classList.remove("kint-search-match");n.#s(e,t.value.toUpperCase())}}else e.classList.remove("kint-search-root")}static#s(t,e){let s=t.cloneNode(!0);for(let c of s.querySelectorAll(".access-path"))c.remove();if(!s.textContent.toUpperCase().includes(e))return;t.classList.add("kint-search-match");let i=t.firstElementChild;for(;i&&i.tagName!=="DT";)i=i.nextElementSibling;if(!i)return;let r=a.getChildContainer(i);if(!r)return;let o,l;for(let c of r.children)c.tagName==="DL"?n.#s(c,e):c.tagName==="UL"&&(c.classList.contains("kint-tabs")?o=c.children:c.classList.contains("kint-tab-contents")&&(l=c.children));if(!(!o||o.length!==l?.length))for(let c=o.length;c--;){let k=!1,F=!1;o[c].textContent.toUpperCase().includes(e)&&(k=!0);let O=l[c].cloneNode(!0);for(let v of O.querySelectorAll(".access-path"))v.remove();if(O.textContent.toUpperCase().includes(e)&&(k=!0,F=!0),k&&o[c].classList.add("kint-search-match"),F)for(let v of l[c].children)v.tagName==="DL"&&n.#s(v,e)}}};var g=class{static sort(t,e){let s=t.dataset.kintTableSort,i=parseInt(s)===e?-1:1,r=t.tBodies[0];[...r.rows].sort(function(o,l){o=o.cells[e].textContent.trim().toLocaleLowerCase(),l=l.cells[e].textContent.trim().toLocaleLowerCase();let c=0;return!isNaN(o)&&!isNaN(l)?(o=parseFloat(o),l=parseFloat(l),c=o-l):isNaN(o)&&!isNaN(l)?c=1:isNaN(l)&&!isNaN(o)?c=-1:c=(""+o).localeCompare(""+l),c*i}).forEach(o=>r.appendChild(o)),i<0?t.dataset.kintTableSort=null:t.dataset.kintTableSort=e}};var a=class n{#e;#t;#s;constructor(t){if(!(t instanceof h))throw new Error("Invalid argument to Rich.constructor()");this.#e=t,this.#e.runOnInit(this.#i.bind(this));let e=new q(this,t);new b(this,t.window,e)}#i(){let t=this.#e.window.document;if(d(this.#t)||(this.#t=t.querySelector("style.kint-rich-style")),this.#t&&m(this.#t),t.querySelector(".kint-rich.kint-file")){this.setupFolder(t);let e=this.#s.querySelector("dd.kint-foldout"),s=Array.from(t.querySelectorAll(".kint-rich.kint-file"));for(let i of s)i.parentNode!==e&&e.appendChild(i);this.#s.classList.add("kint-show")}}addToFolder(t){let e=t.closest(".kint-rich");if(!e)throw new Error("Bad addToFolder");let s=this.#e.window.document;if(this.setupFolder(s),this.folder.contains(t))throw new Error("Bad addToFolder");let i=this.#s.querySelector("dd.kint-foldout"),r=t.closest(".kint-parent, .kint-rich"),o=Array.from(e.querySelectorAll(".kint-folder-trigger"));if(e===r||e.querySelectorAll(".kint-rich > dl").length===1){for(let l of o)l.remove();e.classList.add("kint-file"),i.insertBefore(e,i.firstChild)}else{let l=s.createElement("div");l.classList.add("kint-rich"),l.classList.add("kint-file"),l.appendChild(r.closest(".kint-rich > dl"));let c=e.lastElementChild;c.matches(".kint-rich > footer")&&l.appendChild(c.cloneNode(!0));for(let k of o)k.remove();i.insertBefore(l,i.firstChild)}n.toggle(this.#s.querySelector(".kint-parent"),!0)}setupFolder(t){if(this.#s)d(this.#s)||(this.#s=t.querySelector(".kint-rich.kint-folder"));else{let e=t.createElement("template");e.innerHTML='
    Kint
    ',this.#s=e.content.firstChild,t.body.appendChild(this.#s)}}get folder(){return d(this.#s)||(this.#s=this.#e.window.document.querySelector(".kint-rich.kint-folder")),this.#s&&m(this.#s),this.#s}isFolderOpen(){let t=this.#s?.querySelector("dd.kint-foldout");if(t)return t.previousSibling.classList.contains("kint-show")}static getChildContainer(t){let e=t.nextElementSibling;for(;e&&!e.matches("dd");)e=e.nextElementSibling;return e}static toggle(t,e){let s=n.getChildContainer(t);s&&(e=t.classList.toggle("kint-show",e),n.#n(s,e))}static switchTab(t){t.parentNode.getElementsByClassName("kint-active-tab")[0].classList.remove("kint-active-tab"),t.classList.add("kint-active-tab");let e=t,s=0;for(;e=e.previousElementSibling;)s++;let i=t.parentNode.nextSibling.children;for(let r=i.length;r--;)r===s?(i[r].classList.add("kint-show"),n.#n(i[r],!0)):i[r].classList.remove("kint-show")}static toggleChildren(t,e){let s=n.getChildContainer(t);if(!s)return;e===void 0&&(e=t.classList.contains("kint-show"));let i=Array.from(s.getElementsByClassName("kint-parent"));for(let r of i)r.classList.toggle("kint-show",e)}static toggleAccessPath(t,e){let s=t.querySelector(".access-path");s?.classList.toggle("kint-show",e)&&f(s)}static#n(t,e){if(t.children.length===2&&t.lastElementChild.matches("ul.kint-tab-contents"))for(let s of t.lastElementChild.children)s.matches("li.kint-show")&&(t=s);if(t.children.length===1&&t.firstElementChild.matches("dl")){let s=t.firstElementChild.firstElementChild;s?.classList?.contains("kint-parent")&&n.toggle(s,e)}}},b=class{#e;#t;#s;#i=null;#n=null;#o=0;constructor(t,e,s){this.#e=t,this.#t=s,this.#s=e,this.#s.addEventListener("click",this.#a.bind(this),!0)}#r(){clearTimeout(this.#i),this.#i=setTimeout(this.#l.bind(this),250)}#l(){clearTimeout(this.#i),this.#i=null,this.#n=null,this.#o=0}#c(){let t=this.#n;if(!t.matches(".kint-parent > nav"))return;let e=t.parentNode;if(this.#o===1)a.toggleChildren(e),this.#t.onTreeChanged(),this.#r(),this.#o=2;else if(this.#o===2){this.#l();let s=e.classList.contains("kint-show"),i=this.#e.folder?.querySelector(".kint-parent"),r=Array.from(this.#s.document.getElementsByClassName("kint-parent"));for(let o of r)o!==i&&o.classList.toggle("kint-show",s);this.#t.onTreeChanged(),this.#t.scrollToFocus()}}#a(t){if(this.#o){this.#c();return}let e=t.target;if(!e.closest(".kint-rich"))return;if(e.tagName==="DFN"&&f(e),e.tagName==="TH"){t.ctrlKey||g.sort(e.closest("table"),e.cellIndex);return}if(e.tagName==="LI"&&e.parentNode.className==="kint-tabs"){if(e.className!=="kint-active-tab"){let i=e.closest("dl")?.querySelector(".kint-parent > nav")??e;a.switchTab(e),this.#t.onTreeChanged(),this.#t.setCursor(i)}return}let s=e.closest("dt");if(e.tagName==="NAV")e.parentNode.tagName==="FOOTER"?(this.#t.setCursor(e),e.parentNode.classList.toggle("kint-show")):s?.classList.contains("kint-parent")&&(a.toggle(s),this.#t.onTreeChanged(),this.#t.setCursor(e),this.#r(),this.#o=1,this.#n=e);else if(e.classList.contains("kint-access-path-trigger"))s&&a.toggleAccessPath(s);else if(e.classList.contains("kint-search-trigger"))s?.matches(".kint-rich > dl > dt.kint-parent")&&u.toggleSearchBox(s);else if(e.classList.contains("kint-folder-trigger")){if(s?.matches(".kint-rich > dl > dt.kint-parent"))this.#e.addToFolder(e),this.#t.onTreeChanged(),this.#t.setCursor(s.querySelector("nav")),this.#t.scrollToFocus();else if(e.parentNode.tagName==="FOOTER"){let i=e.closest(".kint-rich").querySelector(".kint-parent > nav, .kint-rich > footer > nav");this.#e.addToFolder(e),this.#t.onTreeChanged(),this.#t.setCursor(i),this.#t.scrollToFocus()}}else e.classList.contains("kint-search")||(e.tagName==="PRE"&&t.detail===3?f(e):e.closest(".kint-source")&&t.detail===3?f(e.closest(".kint-source")):e.classList.contains("access-path")?f(e):e.tagName!=="A"&&s?.classList.contains("kint-parent")&&(a.toggle(s),this.#t.onTreeChanged(),this.#t.setCursor(s.querySelector("nav"))))}},j=65,G=68,A=70,S=72,K=74,D=75,p=76,V=83,P=9,T=13,B=27,L=32,N=37,R=38,C=39,H=40,M=".kint-rich .kint-parent > nav, .kint-rich > footer > nav, .kint-rich .kint-tabs > li:not(.kint-active-tab)",q=class{#e=[];#t=0;#s=!1;#i;#n;constructor(t,e){this.#i=t,this.#n=e.window,this.#n.addEventListener("keydown",this.#c.bind(this),!0),e.runOnInit(this.onTreeChanged.bind(this))}scrollToFocus(){let t=this.#e[this.#t];if(!t)return;let e=this.#i.folder;if(t===e?.querySelector(".kint-parent > nav"))return;let s=x(t);if(this.#i.isFolderOpen()){let i=e.querySelector("dd.kint-foldout");i.scrollTo(0,s-i.clientHeight/2)}else this.#n.scrollTo(0,s-this.#n.innerHeight/2)}onTreeChanged(){let t=this.#e[this.#t];this.#e=[];let e=this.#i.folder,s=e?.querySelector(".kint-parent > nav"),i=this.#n.document;this.#i.isFolderOpen()&&(i=e,this.#e.push(s));let r=Array.from(i.querySelectorAll(M));for(let o of r)o.offsetParent!==null&&o!==s&&this.#e.push(o);if(s&&!this.#i.isFolderOpen()&&this.#e.push(s),this.#e.length===0){this.#s=!1,this.#r();return}t&&this.#e.indexOf(t)!==-1?this.#t=this.#e.indexOf(t):this.#r()}setCursor(t){if(this.#i.isFolderOpen()&&!this.#i.folder.contains(t)||!t.matches(M))return!1;let e=this.#e.indexOf(t);if(e===-1&&(this.onTreeChanged(),e=this.#e.indexOf(t)),e!==-1){if(e!==this.#t)return this.#t=e,this.#r(),!0;this.#e[e]?.classList.remove("kint-weak-focus")}else console.error("setCursor failed to find target in list",t),console.info("Please report this as a bug in Kint at https://github.com/kint-php/kint");return!1}#o(t){if(this.#e.length===0)return this.#t=0,null;for(this.#t+=t;this.#t<0;)this.#t+=this.#e.length;for(;this.#t>=this.#e.length;)this.#t-=this.#e.length;return this.#r(),this.#t}#r(){let t=this.#n.document.querySelector(".kint-focused");t&&(t.classList.remove("kint-focused"),t.classList.remove("kint-weak-focus")),this.#s&&this.#e[this.#t]?.classList.add("kint-focused")}#l(t){let e=t.closest(".kint-rich .kint-parent ~ dd")?.parentNode.querySelector(".kint-parent > nav");e&&(this.setCursor(e),this.scrollToFocus())}#c(t){if(t.keyCode===B&&t.target.matches(".kint-search")){t.target.blur(),this.#s&&this.#r();return}if(t.target!==this.#n.document.body||t.altKey||t.ctrlKey)return;if(t.keyCode===G){if(this.#s)this.#s=!1;else{if(this.#s=!0,this.onTreeChanged(),this.#e.length===0){this.#s=!1;return}this.scrollToFocus()}this.#r(),t.preventDefault();return}else if(t.keyCode===B){this.#s&&(this.#s=!1,this.#r(),t.preventDefault());return}else if(!this.#s)return;t.preventDefault(),d(this.#e[this.#t])||this.onTreeChanged();let e=this.#e[this.#t];if([P,R,D,H,K].includes(t.keyCode)){t.keyCode===P?this.#o(t.shiftKey?-1:1):t.keyCode===R||t.keyCode===D?this.#o(-1):(t.keyCode===H||t.keyCode===K)&&this.#o(1),this.scrollToFocus();return}if(e.tagName==="LI"&&[L,T,C,p,N,S].includes(t.keyCode)){t.keyCode===L||t.keyCode===T?(a.switchTab(e),this.onTreeChanged()):t.keyCode===C||t.keyCode===p?this.#o(1):(t.keyCode===N||t.keyCode===S)&&this.#o(-1),this.scrollToFocus();return}if(e.parentNode.tagName==="FOOTER"&&e.closest(".kint-rich")){if(t.keyCode===L||t.keyCode===T)e.parentNode.classList.toggle("kint-show");else if(t.keyCode===N||t.keyCode===S)if(e.parentNode.classList.contains("kint-show"))e.parentNode.classList.remove("kint-show");else{this.#l(e.closest(".kint-rich"));return}else if(t.keyCode===C||t.keyCode===p)e.parentNode.classList.add("kint-show");else if(t.keyCode===A&&!this.#i.isFolderOpen()&&e.matches(".kint-rich > footer > nav")){let i=e.closest(".kint-rich").querySelector(".kint-parent > nav, .kint-rich > footer > nav");this.#i.addToFolder(e),this.onTreeChanged(),this.setCursor(i),this.scrollToFocus()}return}let s=e.closest(".kint-parent");if(s){if(t.keyCode===j){a.toggleAccessPath(s);return}if(t.keyCode===A){!this.#i.isFolderOpen()&&s.matches(".kint-rich:not(.kint-folder) > dl > .kint-parent")&&(this.#i.addToFolder(e),this.onTreeChanged(),this.setCursor(e),this.scrollToFocus());return}if(t.keyCode===V){let i=s.closest(".kint-rich > dl")?.querySelector(".kint-search")?.closest(".kint-parent");if(i){e.classList.add("kint-weak-focus"),u.toggleSearchBox(i,!0);return}}if(t.keyCode===L||t.keyCode===T){a.toggle(s),this.onTreeChanged();return}if([C,p,N,S].includes(t.keyCode)){let i=s.classList.contains("kint-show");if(t.keyCode===C||t.keyCode===p){i&&a.toggleChildren(s,!0),a.toggle(s,!0),this.onTreeChanged();return}else if(i){a.toggleChildren(s,!1),a.toggle(s,!1),this.onTreeChanged();return}else{this.#l(s);return}}}}};var y=class{#e;#t;constructor(t){if(!(t instanceof h))throw new Error("Invalid argument to Plain.constructor()");this.#e=t.window,t.runOnInit(this.#s.bind(this))}#s(){d(this.#t)||(this.#t=this.#e.document.querySelector("style.kint-plain-style")),this.#t&&m(this.#t)}};var w=class{#e;constructor(t){if(!(t instanceof h))throw new Error("Invalid argument to Microtime.constructor()");this.#e=t.window,t.runOnInit(this.#t.bind(this))}#t(){let t={},e=this.#e.document.querySelectorAll("[data-kint-microtime-group]");for(let s of e){let i=s.querySelector(".kint-microtime-lap");if(!i)continue;let r=s.dataset.kintMicrotimeGroup,o=parseFloat(i.textContent),l=parseFloat(s.querySelector(".kint-microtime-avg").textContent);t[r]??={min:o,max:o,avg:l},t[r].min>o&&(t[r].min=o),t[r].maxo.avg){let l=(r-o.avg)/(o.max-o.avg);i.style.background="hsl("+(40-40*l)+", 100%, 65%)"}else{let l=0;o.avg!==o.min&&(l=(o.avg-r)/(o.avg-o.min)),i.style.background="hsl("+(40+80*l)+", 100%, 65%)"}}}};var U=Symbol(),h=class n{static#e=null;#t;#s=[];#i=new Set;static init(t){return n.#e??=new n(t,U),n.#e.#n(),n.#e.runOnLoad(n.#r),n.#e}get window(){return this.#t}constructor(t,e){if(U!==e)throw new Error("Kint constructor is private. Use Kint.init()");if(!(t instanceof Window))throw new Error("Invalid argument to Kint.init()");this.#t=t,this.runOnInit(this.#o.bind(this)),new y(this),new a(this),new w(this)}runOnLoad(t){if(this.#t.document.readyState==="complete")try{t()}catch{}else this.#t.addEventListener("load",t)}runOnInit(t){this.#s.push(t)}#n(){this.#t.document.currentScript&&(this.#i.add(E(window.document.currentScript)),window.document.currentScript.remove())}#o(){for(let t of this.#i.keys())for(let e of this.#t.document.querySelectorAll(t))e.remove()}static#r(){for(let t of n.#e.#s)t()}};window.Kint||(window.Kint=h);window.Kint.init(window);})(); diff --git a/system/ThirdParty/Kint/resources/compiled/original.css b/system/ThirdParty/Kint/resources/compiled/original.css index d4993ab24e94..765e5633785a 100644 --- a/system/ThirdParty/Kint/resources/compiled/original.css +++ b/system/ThirdParty/Kint/resources/compiled/original.css @@ -1 +1 @@ -.kint-rich{--spacing: 4px;--nav-size: 15px;--backdrop-color: rgba(255, 255, 255, 0.9);--main-background: #e0eaef;--secondary-background: #c1d4df;--text-color: #1d1e1e;--variable-name-color: #1d1e1e;--variable-type-color: #0092db;--variable-type-color-hover: #5cb730;--border-color: #b6cedb;--border-color-hover: #0092db;--border: 1px solid var(--border-color);--foldout-max-size: calc(100vh - 100px);--foldout-zindex: 999999;--caret-image: url("data:image/svg+xml;utf8,");--ap-image: url("data:image/svg+xml;utf8,");--folder-image: url("data:image/svg+xml;utf8,");--search-image: url("data:image/svg+xml;utf8,");font-size:13px;overflow-x:auto;white-space:nowrap;background:var(--backdrop-color);direction:ltr;contain:content}.kint-rich.kint-folder{position:fixed;bottom:0;left:0;right:0;z-index:var(--foldout-zindex);width:100%;margin:0;display:block}.kint-rich.kint-folder dd.kint-foldout{max-height:var(--foldout-max-size);padding-right:calc(var(--spacing)*2);overflow-y:scroll;display:none}.kint-rich.kint-folder dd.kint-foldout.kint-show{display:block}.kint-rich::selection{background:var(--border-color-hover);color:var(--text-color)}.kint-rich .kint-focused{box-shadow:0 0 3px 3px var(--variable-type-color-hover)}.kint-rich .kint-focused.kint-weak-focus{box-shadow:0 0 3px 1px color-mix(in srgb, var(--variable-type-color-hover) 50%, transparent)}.kint-rich,.kint-rich::before,.kint-rich::after,.kint-rich *,.kint-rich *::before,.kint-rich *::after{box-sizing:border-box;border-radius:0;color:var(--text-color);float:none !important;font-family:Consolas,Menlo,Monaco,Lucida Console,Liberation Mono,DejaVu Sans Mono,Bitstream Vera Sans Mono,Courier New,monospace,serif;line-height:15px;margin:0;padding:0;text-align:left}.kint-rich{margin:calc(var(--spacing)*2) 0}.kint-rich dt,.kint-rich dl{width:auto}.kint-rich dt,.kint-rich div.access-path{background:var(--main-background);border:var(--border);color:var(--text-color);display:block;font-weight:bold;list-style:none outside none;overflow:auto;padding:var(--spacing)}.kint-rich dt:hover,.kint-rich div.access-path:hover{border-color:var(--border-color-hover)}.kint-rich>dl dl{padding:0 0 0 calc(var(--spacing)*3)}.kint-rich dt.kint-parent>nav,.kint-rich>footer>nav{background:var(--caret-image) no-repeat scroll 0 0/var(--nav-size) 75px rgba(0,0,0,0);cursor:pointer;display:inline-block;height:var(--nav-size);width:var(--nav-size);margin-right:3px;vertical-align:middle}.kint-rich dt.kint-parent:hover>nav,.kint-rich>footer>nav:hover{background-position:0 25%}.kint-rich dt.kint-parent.kint-show>nav,.kint-rich>footer.kint-show>nav{background-position:0 50%}.kint-rich dt.kint-parent.kint-show:hover>nav,.kint-rich>footer.kint-show>nav:hover{background-position:0 75%}.kint-rich dt.kint-parent.kint-locked>nav{background-position:0 100%}.kint-rich dt.kint-parent+dd{display:none;border-left:1px dashed var(--border-color);contain:strict}.kint-rich dt.kint-parent.kint-show+dd{display:block;contain:content}.kint-rich var,.kint-rich var a{color:var(--variable-type-color);font-style:normal}.kint-rich dt:hover var,.kint-rich dt:hover var a{color:var(--variable-type-color-hover)}.kint-rich dfn{font-style:normal;font-family:monospace;color:var(--variable-name-color)}.kint-rich pre{color:var(--text-color);margin:0 0 0 calc(var(--spacing)*3);padding:5px;overflow-y:hidden;border-top:0;border:var(--border);background:var(--main-background);display:block;word-break:normal}.kint-rich .kint-access-path-trigger,.kint-rich .kint-folder-trigger,.kint-rich .kint-search-trigger{background:color-mix(in srgb, var(--text-color) 80%, transparent);border-radius:3px;padding:2px;height:var(--nav-size);width:var(--nav-size);font-size:var(--nav-size);margin-left:5px;font-weight:bold;text-align:center;line-height:1;float:right !important;cursor:pointer;position:relative;overflow:hidden}.kint-rich .kint-access-path-trigger::before,.kint-rich .kint-folder-trigger::before,.kint-rich .kint-search-trigger::before{display:block;content:"";width:100%;height:100%;background:var(--main-background);mask:center/contain no-repeat alpha}.kint-rich .kint-access-path-trigger:hover,.kint-rich .kint-folder-trigger:hover,.kint-rich .kint-search-trigger:hover{background:var(--main-background)}.kint-rich .kint-access-path-trigger:hover::before,.kint-rich .kint-folder-trigger:hover::before,.kint-rich .kint-search-trigger:hover::before{background:var(--text-color)}.kint-rich .kint-access-path-trigger::before{mask-image:var(--ap-image)}.kint-rich .kint-folder-trigger::before{mask-image:var(--folder-image)}.kint-rich .kint-search-trigger::before{mask-image:var(--search-image)}.kint-rich input.kint-search{display:none;border:var(--border);border-top-width:0;border-bottom-width:0;padding:var(--spacing);float:right !important;margin:calc(var(--spacing)*-1) 0;color:var(--variable-name-color);background:var(--secondary-background);height:calc(var(--nav-size) + var(--spacing)*2);width:calc(var(--nav-size)*10);position:relative;z-index:100}.kint-rich input.kint-search.kint-show{display:block}.kint-rich .kint-search-root ul.kint-tabs>li:not(.kint-search-match){background:var(--secondary-background);filter:saturate(0);opacity:.5}.kint-rich .kint-search-root dl:not(.kint-search-match){opacity:.5}.kint-rich .kint-search-root dl:not(.kint-search-match)>dt{background:var(--main-background);filter:saturate(0)}.kint-rich .kint-search-root dl:not(.kint-search-match) dl,.kint-rich .kint-search-root dl:not(.kint-search-match) ul.kint-tabs>li:not(.kint-search-match){opacity:1}.kint-rich div.access-path{background:var(--secondary-background);display:none;margin-top:5px;padding:4px;white-space:pre}.kint-rich div.access-path.kint-show{display:block}.kint-rich footer{padding:0 3px 3px;font-size:9px;background:rgba(0,0,0,0)}.kint-rich footer>.kint-folder-trigger{background:rgba(0,0,0,0)}.kint-rich footer>.kint-folder-trigger::before{background:var(--text-color)}.kint-rich footer nav{height:10px;width:10px;background-size:10px 50px}.kint-rich footer>ol{display:none;margin-left:32px}.kint-rich footer.kint-show>ol{display:block}.kint-rich a{color:var(--text-color);text-shadow:none;text-decoration:underline}.kint-rich a:hover{color:var(--variable-name-color);border-bottom:1px dotted var(--variable-name-color)}.kint-rich ul{list-style:none;padding-left:calc(var(--spacing)*3)}.kint-rich ul:not(.kint-tabs) li{border-left:1px dashed var(--border-color)}.kint-rich ul:not(.kint-tabs) li>dl{border-left:none}.kint-rich ul.kint-tabs{margin:0 0 0 calc(var(--spacing)*3);padding-left:0;background:var(--main-background);border:var(--border);border-top:0}.kint-rich ul.kint-tabs>li{background:var(--secondary-background);border:var(--border);cursor:pointer;display:inline-block;height:calc(var(--spacing)*6);margin:calc(var(--spacing)/2);padding:0 calc(2px + var(--spacing)*2.5);vertical-align:top}.kint-rich ul.kint-tabs>li:hover,.kint-rich ul.kint-tabs>li.kint-active-tab:hover{border-color:var(--border-color-hover);color:var(--variable-type-color-hover)}.kint-rich ul.kint-tabs>li.kint-active-tab{background:var(--main-background);border-top:0;margin-top:-1px;height:27px;line-height:24px}.kint-rich ul.kint-tabs>li:not(.kint-active-tab){line-height:calc(var(--spacing)*5)}.kint-rich ul.kint-tabs li+li{margin-left:0}.kint-rich ul.kint-tab-contents>li{display:none;contain:strict}.kint-rich ul.kint-tab-contents>li.kint-show{display:block;contain:content}.kint-rich dt:hover+dd>ul>li.kint-active-tab{border-color:var(--border-color-hover);color:var(--variable-type-color-hover)}.kint-rich dt>.kint-color-preview{width:var(--nav-size);height:var(--nav-size);display:inline-block;vertical-align:middle;margin-left:10px;border:var(--border);background-color:#ccc;background-image:url('data:image/svg+xml;utf8,');background-size:min(20px,100%)}.kint-rich dt>.kint-color-preview:hover{border-color:var(--border-color-hover)}.kint-rich dt>.kint-color-preview>div{width:100%;height:100%}.kint-rich table{border-collapse:collapse;empty-cells:show;border-spacing:0}.kint-rich table *{font-size:12px}.kint-rich table dt{background:none;padding:calc(var(--spacing)/2)}.kint-rich table dt .kint-parent{min-width:100%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.kint-rich table td,.kint-rich table th{border:var(--border);padding:calc(var(--spacing)/2);vertical-align:center}.kint-rich table th{cursor:alias}.kint-rich table td:first-child,.kint-rich table th{font-weight:bold;background:var(--secondary-background);color:var(--variable-name-color)}.kint-rich table td{background:var(--main-background);white-space:pre}.kint-rich table td>dl{padding:0}.kint-rich table pre{border-top:0;border-right:0}.kint-rich table thead th:first-child{background:none;border:0}.kint-rich table tr:hover>td{box-shadow:0 0 1px 0 var(--border-color-hover) inset}.kint-rich table tr:hover var{color:var(--variable-type-color-hover)}.kint-rich table ul.kint-tabs li.kint-active-tab{height:20px;line-height:17px}.kint-rich pre.kint-source{margin-left:-1px}.kint-rich pre.kint-source[data-kint-filename]:before{display:block;content:attr(data-kint-filename);margin-bottom:var(--spacing);padding-bottom:var(--spacing);border-bottom:1px solid var(--secondary-background)}.kint-rich pre.kint-source>div:before{display:inline-block;content:counter(kint-l);counter-increment:kint-l;border-right:1px solid var(--border-color-hover);padding-right:calc(var(--spacing)*2);margin-right:calc(var(--spacing)*2)}.kint-rich pre.kint-source>div.kint-highlight{background:var(--secondary-background)}.kint-rich .kint-microtime-js .kint-microtime-lap{text-shadow:-1px 0 var(--border-color-hover),0 1px var(--border-color-hover),1px 0 var(--border-color-hover),0 -1px var(--border-color-hover);color:var(--main-background);font-weight:bold}input.kint-note-input{width:100%}.kint-rich{--gradient-start: #e3ecf0;--gradient-end: #c0d4df;--tabs-gradient-start: #9dbed0;--tabs-gradient-end: #b2ccda}.kint-rich>dl>dt{background:linear-gradient(to bottom, var(--gradient-start) 0%, var(--gradient-end) 100%)}.kint-rich>dl>dd>ul.kint-tabs li{background:var(--main-background)}.kint-rich>dl>dd>ul.kint-tabs li.kint-active-tab{background:var(--secondary-background)}.kint-rich ul.kint-tabs{background:linear-gradient(to bottom, var(--tabs-gradient-start) 0%, var(--tabs-gradient-end) 100%)} +.kint-rich{--spacing: 4px;--nav-size: 15px;--backdrop-color: rgba(255, 255, 255, 0.9);--main-background: #e0eaef;--secondary-background: #c1d4df;--text-color: #1d1e1e;--variable-name-color: #1d1e1e;--variable-type-color: #0092db;--variable-type-color-hover: #5cb730;--border-color: #b6cedb;--border-color-hover: #0092db;--border: 1px solid var(--border-color);--foldout-max-size: calc(100vh - 100px);--foldout-zindex: 999999;--caret-image: url("data:image/svg+xml;utf8,");--ap-image: url("data:image/svg+xml;utf8,");--folder-image: url("data:image/svg+xml;utf8,");--search-image: url("data:image/svg+xml;utf8,");font-size:13px;overflow-x:auto;white-space:nowrap;background:var(--backdrop-color);direction:ltr;contain:content}.kint-rich.kint-folder{position:fixed;bottom:0;left:0;right:0;z-index:var(--foldout-zindex);width:100%;margin:0;display:block}.kint-rich.kint-folder dd.kint-foldout{max-height:var(--foldout-max-size);padding-right:calc(var(--spacing)*2);overflow-y:scroll;display:none}.kint-rich.kint-folder dd.kint-foldout.kint-show{display:block}.kint-rich::selection{background:var(--border-color-hover);color:var(--text-color)}.kint-rich .kint-focused{box-shadow:0 0 3px 3px var(--variable-type-color-hover)}.kint-rich .kint-focused.kint-weak-focus{box-shadow:0 0 3px 1px color-mix(in srgb, var(--variable-type-color-hover) 50%, transparent)}.kint-rich,.kint-rich::before,.kint-rich::after,.kint-rich *,.kint-rich *::before,.kint-rich *::after{box-sizing:border-box;border-radius:0;color:var(--text-color);float:none !important;font-family:Consolas,Menlo,Monaco,Lucida Console,Liberation Mono,DejaVu Sans Mono,Bitstream Vera Sans Mono,Courier New,monospace,serif;line-height:15px;margin:0;padding:0;text-align:left}.kint-rich{margin:calc(var(--spacing)*2) 0}.kint-rich dt,.kint-rich dl{width:auto}.kint-rich dt,.kint-rich div.access-path{background:var(--main-background);border:var(--border);color:var(--text-color);display:block;font-weight:bold;list-style:none outside none;overflow:auto;padding:var(--spacing)}.kint-rich dt:hover,.kint-rich div.access-path:hover{border-color:var(--border-color-hover)}.kint-rich>dl dl{padding:0 0 0 calc(var(--spacing)*3)}.kint-rich dt.kint-parent>nav,.kint-rich>footer>nav{background:var(--caret-image) no-repeat scroll 0 0/var(--nav-size) 75px rgba(0,0,0,0);cursor:pointer;display:inline-block;height:var(--nav-size);width:var(--nav-size);margin-right:3px;vertical-align:middle}.kint-rich dt.kint-parent:hover>nav,.kint-rich>footer>nav:hover{background-position:0 25%}.kint-rich dt.kint-parent.kint-show>nav,.kint-rich>footer.kint-show>nav{background-position:0 50%}.kint-rich dt.kint-parent.kint-show:hover>nav,.kint-rich>footer.kint-show>nav:hover{background-position:0 75%}.kint-rich dt.kint-parent.kint-locked>nav{background-position:0 100%}.kint-rich dt.kint-parent+dd{display:none;border-left:1px dashed var(--border-color);contain:strict}.kint-rich dt.kint-parent.kint-show+dd{display:block;contain:content}.kint-rich var,.kint-rich var a{color:var(--variable-type-color);font-style:normal}.kint-rich dt:hover var,.kint-rich dt:hover var a{color:var(--variable-type-color-hover)}.kint-rich dfn{font-style:normal;font-family:monospace;color:var(--variable-name-color)}.kint-rich pre{color:var(--text-color);margin:0 0 0 calc(var(--spacing)*3);padding:5px;overflow-y:hidden;border-top:0;border:var(--border);background:var(--main-background);display:block;word-break:normal}.kint-rich .kint-access-path-trigger,.kint-rich .kint-folder-trigger,.kint-rich .kint-search-trigger{background:color-mix(in srgb, var(--text-color) 80%, transparent);border-radius:3px;padding:2px;height:var(--nav-size);width:var(--nav-size);font-size:var(--nav-size);margin-left:5px;font-weight:bold;text-align:center;line-height:1;float:right !important;cursor:pointer;position:relative;overflow:hidden}.kint-rich .kint-access-path-trigger::before,.kint-rich .kint-folder-trigger::before,.kint-rich .kint-search-trigger::before{display:block;content:"";width:100%;height:100%;background:var(--main-background);mask:center/contain no-repeat alpha}.kint-rich .kint-access-path-trigger:hover,.kint-rich .kint-folder-trigger:hover,.kint-rich .kint-search-trigger:hover{background:var(--main-background)}.kint-rich .kint-access-path-trigger:hover::before,.kint-rich .kint-folder-trigger:hover::before,.kint-rich .kint-search-trigger:hover::before{background:var(--text-color)}.kint-rich .kint-access-path-trigger::before{mask-image:var(--ap-image)}.kint-rich .kint-folder-trigger::before{mask-image:var(--folder-image)}.kint-rich .kint-search-trigger::before{mask-image:var(--search-image)}.kint-rich input.kint-search{display:none;border:var(--border);border-top-width:0;border-bottom-width:0;padding:var(--spacing);float:right !important;margin:calc(var(--spacing)*-1) 0;color:var(--variable-name-color);background:var(--secondary-background);height:calc(var(--nav-size) + var(--spacing)*2);width:calc(var(--nav-size)*10);position:relative;z-index:100}.kint-rich input.kint-search.kint-show{display:block}.kint-rich .kint-search-root ul.kint-tabs>li:not(.kint-search-match){background:var(--secondary-background);filter:saturate(0);opacity:.5}.kint-rich .kint-search-root dl:not(.kint-search-match){opacity:.5}.kint-rich .kint-search-root dl:not(.kint-search-match)>dt{background:var(--main-background);filter:saturate(0)}.kint-rich .kint-search-root dl:not(.kint-search-match) dl,.kint-rich .kint-search-root dl:not(.kint-search-match) ul.kint-tabs>li:not(.kint-search-match){opacity:1}.kint-rich div.access-path{background:var(--secondary-background);display:none;margin-top:5px;padding:4px;white-space:pre}.kint-rich div.access-path.kint-show{display:block}.kint-rich footer{padding:0 3px 3px;font-size:9px;background:rgba(0,0,0,0)}.kint-rich footer>.kint-folder-trigger{background:rgba(0,0,0,0)}.kint-rich footer>.kint-folder-trigger::before{background:var(--text-color)}.kint-rich footer nav{height:10px;width:10px;background-size:10px 50px}.kint-rich footer>ol{display:none;margin-left:32px}.kint-rich footer.kint-show>ol{display:block}.kint-rich a{color:var(--text-color);text-shadow:none;text-decoration:underline}.kint-rich a:hover{color:var(--variable-name-color);border-bottom:1px dotted var(--variable-name-color)}.kint-rich ul{list-style:none;padding-left:calc(var(--spacing)*3)}.kint-rich ul:not(.kint-tabs) li{border-left:1px dashed var(--border-color)}.kint-rich ul:not(.kint-tabs) li>dl{border-left:none}.kint-rich ul.kint-tabs{margin:0 0 0 calc(var(--spacing)*3);padding-left:0;background:var(--main-background);border:var(--border);border-top:0}.kint-rich ul.kint-tabs>li{background:var(--secondary-background);border:var(--border);cursor:pointer;display:inline-block;height:calc(var(--spacing)*6);margin:calc(var(--spacing)/2);padding:0 calc(2px + var(--spacing)*2.5);vertical-align:top}.kint-rich ul.kint-tabs>li:hover,.kint-rich ul.kint-tabs>li.kint-active-tab:hover{border-color:var(--border-color-hover);color:var(--variable-type-color-hover)}.kint-rich ul.kint-tabs>li.kint-active-tab{background:var(--main-background);border-top:0;margin-top:-1px;height:27px;line-height:24px}.kint-rich ul.kint-tabs>li:not(.kint-active-tab){line-height:calc(var(--spacing)*5)}.kint-rich ul.kint-tabs li+li{margin-left:0}.kint-rich ul.kint-tab-contents>li{display:none;contain:strict}.kint-rich ul.kint-tab-contents>li.kint-show{display:block;contain:content}.kint-rich dt:hover+dd>ul>li.kint-active-tab{border-color:var(--border-color-hover);color:var(--variable-type-color-hover)}.kint-rich dt>.kint-color-preview{width:var(--nav-size);height:var(--nav-size);display:inline-block;vertical-align:middle;margin-left:10px;border:var(--border);background-color:#ccc;background-image:url('data:image/svg+xml;utf8,');background-size:min(20px,100%)}.kint-rich dt>.kint-color-preview:hover{border-color:var(--border-color-hover)}.kint-rich dt>.kint-color-preview>div{width:100%;height:100%}.kint-rich table{border-collapse:collapse;empty-cells:show;border-spacing:0}.kint-rich table *{font-size:12px}.kint-rich table dt{background:none;padding:calc(var(--spacing)/2)}.kint-rich table dt .kint-parent{min-width:100%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.kint-rich table td,.kint-rich table th{border:var(--border);padding:calc(var(--spacing)/2);vertical-align:center}.kint-rich table th{cursor:alias}.kint-rich table td:first-child,.kint-rich table th{font-weight:bold;background:var(--secondary-background);color:var(--variable-name-color)}.kint-rich table td{background:var(--main-background);white-space:pre}.kint-rich table td>dl{padding:0}.kint-rich table pre{border-top:0;border-right:0}.kint-rich table thead th:first-child{background:none;border:0}.kint-rich table tr:hover>td{box-shadow:0 0 1px 0 var(--border-color-hover) inset}.kint-rich table tr:hover var{color:var(--variable-type-color-hover)}.kint-rich table ul.kint-tabs li.kint-active-tab{height:20px;line-height:17px}.kint-rich pre.kint-source{margin-left:-1px}.kint-rich pre.kint-source[data-kint-filename]:before{display:block;content:attr(data-kint-filename);margin-bottom:var(--spacing);padding-bottom:var(--spacing);border-bottom:1px solid var(--secondary-background)}.kint-rich pre.kint-source>div:before{display:inline-block;content:counter(kint-l);counter-increment:kint-l;border-right:1px solid var(--border-color-hover);padding-right:calc(var(--spacing)*2);margin-right:calc(var(--spacing)*2)}.kint-rich pre.kint-source>div.kint-highlight{background:var(--secondary-background)}.kint-rich .kint-microtime-js .kint-microtime-lap{text-shadow:-1px 0 var(--border-color-hover),0 1px var(--border-color-hover),1px 0 var(--border-color-hover),0 -1px var(--border-color-hover);color:var(--main-background);font-weight:bold}.kint-rich{--gradient-start: #e3ecf0;--gradient-end: #c0d4df;--tabs-gradient-start: #9dbed0;--tabs-gradient-end: #b2ccda}.kint-rich>dl>dt{background:linear-gradient(to bottom, var(--gradient-start) 0%, var(--gradient-end) 100%)}.kint-rich>dl>dd>ul.kint-tabs li{background:var(--main-background)}.kint-rich>dl>dd>ul.kint-tabs li.kint-active-tab{background:var(--secondary-background)}.kint-rich ul.kint-tabs{background:linear-gradient(to bottom, var(--tabs-gradient-start) 0%, var(--tabs-gradient-end) 100%)} diff --git a/system/ThirdParty/Kint/resources/compiled/plain.css b/system/ThirdParty/Kint/resources/compiled/plain.css index 8d47b53a78e5..0dd9b2d0acb3 100644 --- a/system/ThirdParty/Kint/resources/compiled/plain.css +++ b/system/ThirdParty/Kint/resources/compiled/plain.css @@ -1 +1 @@ -.kint-plain{background:rgba(255,255,255,.9);white-space:pre;display:block;font-family:monospace;color:#222;line-height:normal}.kint-plain i{color:#d00;font-style:normal}.kint-plain u{color:#030;text-decoration:none;font-weight:bold}.kint-plain .kint-microtime-js .kint-microtime-lap{text-shadow:1px 0 #d00,0 1px #d00,-1px 0 #d00,0 -1px #d00;color:#fff;font-weight:bold} +.kint-plain{background:hsla(0,0%,100%,.9);white-space:pre;display:block;font-family:monospace;color:#222;line-height:normal}.kint-plain i{color:#d00;font-style:normal}.kint-plain u{color:#030;text-decoration:none;font-weight:bold}.kint-plain .kint-microtime-js .kint-microtime-lap{text-shadow:1px 0 #d00,0 1px #d00,-1px 0 #d00,0 -1px #d00;color:#fff;font-weight:bold} diff --git a/system/ThirdParty/Kint/resources/compiled/solarized-dark.css b/system/ThirdParty/Kint/resources/compiled/solarized-dark.css index 529a9ce44a58..87b7206eb282 100644 --- a/system/ThirdParty/Kint/resources/compiled/solarized-dark.css +++ b/system/ThirdParty/Kint/resources/compiled/solarized-dark.css @@ -1 +1 @@ -.kint-rich{--spacing: 4px;--nav-size: 15px;--backdrop-color: rgba(255, 255, 255, 0.9);--main-background: #e0eaef;--secondary-background: #c1d4df;--text-color: #1d1e1e;--variable-name-color: #1d1e1e;--variable-type-color: #0092db;--variable-type-color-hover: #5cb730;--border-color: #b6cedb;--border-color-hover: #0092db;--border: 1px solid var(--border-color);--foldout-max-size: calc(100vh - 100px);--foldout-zindex: 999999;--caret-image: url("data:image/svg+xml;utf8,");--ap-image: url("data:image/svg+xml;utf8,");--folder-image: url("data:image/svg+xml;utf8,");--search-image: url("data:image/svg+xml;utf8,");font-size:13px;overflow-x:auto;white-space:nowrap;background:var(--backdrop-color);direction:ltr;contain:content}.kint-rich.kint-folder{position:fixed;bottom:0;left:0;right:0;z-index:var(--foldout-zindex);width:100%;margin:0;display:block}.kint-rich.kint-folder dd.kint-foldout{max-height:var(--foldout-max-size);padding-right:calc(var(--spacing)*2);overflow-y:scroll;display:none}.kint-rich.kint-folder dd.kint-foldout.kint-show{display:block}.kint-rich::selection{background:var(--border-color-hover);color:var(--text-color)}.kint-rich .kint-focused{box-shadow:0 0 3px 3px var(--variable-type-color-hover)}.kint-rich .kint-focused.kint-weak-focus{box-shadow:0 0 3px 1px color-mix(in srgb, var(--variable-type-color-hover) 50%, transparent)}.kint-rich,.kint-rich::before,.kint-rich::after,.kint-rich *,.kint-rich *::before,.kint-rich *::after{box-sizing:border-box;border-radius:0;color:var(--text-color);float:none !important;font-family:Consolas,Menlo,Monaco,Lucida Console,Liberation Mono,DejaVu Sans Mono,Bitstream Vera Sans Mono,Courier New,monospace,serif;line-height:15px;margin:0;padding:0;text-align:left}.kint-rich{margin:calc(var(--spacing)*2) 0}.kint-rich dt,.kint-rich dl{width:auto}.kint-rich dt,.kint-rich div.access-path{background:var(--main-background);border:var(--border);color:var(--text-color);display:block;font-weight:bold;list-style:none outside none;overflow:auto;padding:var(--spacing)}.kint-rich dt:hover,.kint-rich div.access-path:hover{border-color:var(--border-color-hover)}.kint-rich>dl dl{padding:0 0 0 calc(var(--spacing)*3)}.kint-rich dt.kint-parent>nav,.kint-rich>footer>nav{background:var(--caret-image) no-repeat scroll 0 0/var(--nav-size) 75px rgba(0,0,0,0);cursor:pointer;display:inline-block;height:var(--nav-size);width:var(--nav-size);margin-right:3px;vertical-align:middle}.kint-rich dt.kint-parent:hover>nav,.kint-rich>footer>nav:hover{background-position:0 25%}.kint-rich dt.kint-parent.kint-show>nav,.kint-rich>footer.kint-show>nav{background-position:0 50%}.kint-rich dt.kint-parent.kint-show:hover>nav,.kint-rich>footer.kint-show>nav:hover{background-position:0 75%}.kint-rich dt.kint-parent.kint-locked>nav{background-position:0 100%}.kint-rich dt.kint-parent+dd{display:none;border-left:1px dashed var(--border-color);contain:strict}.kint-rich dt.kint-parent.kint-show+dd{display:block;contain:content}.kint-rich var,.kint-rich var a{color:var(--variable-type-color);font-style:normal}.kint-rich dt:hover var,.kint-rich dt:hover var a{color:var(--variable-type-color-hover)}.kint-rich dfn{font-style:normal;font-family:monospace;color:var(--variable-name-color)}.kint-rich pre{color:var(--text-color);margin:0 0 0 calc(var(--spacing)*3);padding:5px;overflow-y:hidden;border-top:0;border:var(--border);background:var(--main-background);display:block;word-break:normal}.kint-rich .kint-access-path-trigger,.kint-rich .kint-folder-trigger,.kint-rich .kint-search-trigger{background:color-mix(in srgb, var(--text-color) 80%, transparent);border-radius:3px;padding:2px;height:var(--nav-size);width:var(--nav-size);font-size:var(--nav-size);margin-left:5px;font-weight:bold;text-align:center;line-height:1;float:right !important;cursor:pointer;position:relative;overflow:hidden}.kint-rich .kint-access-path-trigger::before,.kint-rich .kint-folder-trigger::before,.kint-rich .kint-search-trigger::before{display:block;content:"";width:100%;height:100%;background:var(--main-background);mask:center/contain no-repeat alpha}.kint-rich .kint-access-path-trigger:hover,.kint-rich .kint-folder-trigger:hover,.kint-rich .kint-search-trigger:hover{background:var(--main-background)}.kint-rich .kint-access-path-trigger:hover::before,.kint-rich .kint-folder-trigger:hover::before,.kint-rich .kint-search-trigger:hover::before{background:var(--text-color)}.kint-rich .kint-access-path-trigger::before{mask-image:var(--ap-image)}.kint-rich .kint-folder-trigger::before{mask-image:var(--folder-image)}.kint-rich .kint-search-trigger::before{mask-image:var(--search-image)}.kint-rich input.kint-search{display:none;border:var(--border);border-top-width:0;border-bottom-width:0;padding:var(--spacing);float:right !important;margin:calc(var(--spacing)*-1) 0;color:var(--variable-name-color);background:var(--secondary-background);height:calc(var(--nav-size) + var(--spacing)*2);width:calc(var(--nav-size)*10);position:relative;z-index:100}.kint-rich input.kint-search.kint-show{display:block}.kint-rich .kint-search-root ul.kint-tabs>li:not(.kint-search-match){background:var(--secondary-background);filter:saturate(0);opacity:.5}.kint-rich .kint-search-root dl:not(.kint-search-match){opacity:.5}.kint-rich .kint-search-root dl:not(.kint-search-match)>dt{background:var(--main-background);filter:saturate(0)}.kint-rich .kint-search-root dl:not(.kint-search-match) dl,.kint-rich .kint-search-root dl:not(.kint-search-match) ul.kint-tabs>li:not(.kint-search-match){opacity:1}.kint-rich div.access-path{background:var(--secondary-background);display:none;margin-top:5px;padding:4px;white-space:pre}.kint-rich div.access-path.kint-show{display:block}.kint-rich footer{padding:0 3px 3px;font-size:9px;background:rgba(0,0,0,0)}.kint-rich footer>.kint-folder-trigger{background:rgba(0,0,0,0)}.kint-rich footer>.kint-folder-trigger::before{background:var(--text-color)}.kint-rich footer nav{height:10px;width:10px;background-size:10px 50px}.kint-rich footer>ol{display:none;margin-left:32px}.kint-rich footer.kint-show>ol{display:block}.kint-rich a{color:var(--text-color);text-shadow:none;text-decoration:underline}.kint-rich a:hover{color:var(--variable-name-color);border-bottom:1px dotted var(--variable-name-color)}.kint-rich ul{list-style:none;padding-left:calc(var(--spacing)*3)}.kint-rich ul:not(.kint-tabs) li{border-left:1px dashed var(--border-color)}.kint-rich ul:not(.kint-tabs) li>dl{border-left:none}.kint-rich ul.kint-tabs{margin:0 0 0 calc(var(--spacing)*3);padding-left:0;background:var(--main-background);border:var(--border);border-top:0}.kint-rich ul.kint-tabs>li{background:var(--secondary-background);border:var(--border);cursor:pointer;display:inline-block;height:calc(var(--spacing)*6);margin:calc(var(--spacing)/2);padding:0 calc(2px + var(--spacing)*2.5);vertical-align:top}.kint-rich ul.kint-tabs>li:hover,.kint-rich ul.kint-tabs>li.kint-active-tab:hover{border-color:var(--border-color-hover);color:var(--variable-type-color-hover)}.kint-rich ul.kint-tabs>li.kint-active-tab{background:var(--main-background);border-top:0;margin-top:-1px;height:27px;line-height:24px}.kint-rich ul.kint-tabs>li:not(.kint-active-tab){line-height:calc(var(--spacing)*5)}.kint-rich ul.kint-tabs li+li{margin-left:0}.kint-rich ul.kint-tab-contents>li{display:none;contain:strict}.kint-rich ul.kint-tab-contents>li.kint-show{display:block;contain:content}.kint-rich dt:hover+dd>ul>li.kint-active-tab{border-color:var(--border-color-hover);color:var(--variable-type-color-hover)}.kint-rich dt>.kint-color-preview{width:var(--nav-size);height:var(--nav-size);display:inline-block;vertical-align:middle;margin-left:10px;border:var(--border);background-color:#ccc;background-image:url('data:image/svg+xml;utf8,');background-size:min(20px,100%)}.kint-rich dt>.kint-color-preview:hover{border-color:var(--border-color-hover)}.kint-rich dt>.kint-color-preview>div{width:100%;height:100%}.kint-rich table{border-collapse:collapse;empty-cells:show;border-spacing:0}.kint-rich table *{font-size:12px}.kint-rich table dt{background:none;padding:calc(var(--spacing)/2)}.kint-rich table dt .kint-parent{min-width:100%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.kint-rich table td,.kint-rich table th{border:var(--border);padding:calc(var(--spacing)/2);vertical-align:center}.kint-rich table th{cursor:alias}.kint-rich table td:first-child,.kint-rich table th{font-weight:bold;background:var(--secondary-background);color:var(--variable-name-color)}.kint-rich table td{background:var(--main-background);white-space:pre}.kint-rich table td>dl{padding:0}.kint-rich table pre{border-top:0;border-right:0}.kint-rich table thead th:first-child{background:none;border:0}.kint-rich table tr:hover>td{box-shadow:0 0 1px 0 var(--border-color-hover) inset}.kint-rich table tr:hover var{color:var(--variable-type-color-hover)}.kint-rich table ul.kint-tabs li.kint-active-tab{height:20px;line-height:17px}.kint-rich pre.kint-source{margin-left:-1px}.kint-rich pre.kint-source[data-kint-filename]:before{display:block;content:attr(data-kint-filename);margin-bottom:var(--spacing);padding-bottom:var(--spacing);border-bottom:1px solid var(--secondary-background)}.kint-rich pre.kint-source>div:before{display:inline-block;content:counter(kint-l);counter-increment:kint-l;border-right:1px solid var(--border-color-hover);padding-right:calc(var(--spacing)*2);margin-right:calc(var(--spacing)*2)}.kint-rich pre.kint-source>div.kint-highlight{background:var(--secondary-background)}.kint-rich .kint-microtime-js .kint-microtime-lap{text-shadow:-1px 0 var(--border-color-hover),0 1px var(--border-color-hover),1px 0 var(--border-color-hover),0 -1px var(--border-color-hover);color:var(--main-background);font-weight:bold}input.kint-note-input{width:100%}.kint-rich{--spacing: 5px;--main-background: #002b36;--secondary-background: #073642;--backdrop-color: var(--secondary-background);--text-color: #839496;--variable-name-color: #93a1a1;--variable-type-color: #268bd2;--variable-type-color-hover: #2aa198;--border-color: #586e75;--border-color-hover: #268bd2;--caret-image: url("data:image/svg+xml;utf8,")}.kint-rich .kint-focused{box-shadow:0 0 3px 2px #859900 inset;border-radius:7px}.kint-rich>dl>dt,.kint-rich ul.kint-tabs{box-shadow:4px 0 2px -3px var(--variable-type-color) inset}.kint-rich ul.kint-tabs li.kint-active-tab{padding-top:7px;height:34px}.kint-rich footer li{color:#ddd} +.kint-rich{--spacing: 4px;--nav-size: 15px;--backdrop-color: rgba(255, 255, 255, 0.9);--main-background: #e0eaef;--secondary-background: #c1d4df;--text-color: #1d1e1e;--variable-name-color: #1d1e1e;--variable-type-color: #0092db;--variable-type-color-hover: #5cb730;--border-color: #b6cedb;--border-color-hover: #0092db;--border: 1px solid var(--border-color);--foldout-max-size: calc(100vh - 100px);--foldout-zindex: 999999;--caret-image: url("data:image/svg+xml;utf8,");--ap-image: url("data:image/svg+xml;utf8,");--folder-image: url("data:image/svg+xml;utf8,");--search-image: url("data:image/svg+xml;utf8,");font-size:13px;overflow-x:auto;white-space:nowrap;background:var(--backdrop-color);direction:ltr;contain:content}.kint-rich.kint-folder{position:fixed;bottom:0;left:0;right:0;z-index:var(--foldout-zindex);width:100%;margin:0;display:block}.kint-rich.kint-folder dd.kint-foldout{max-height:var(--foldout-max-size);padding-right:calc(var(--spacing)*2);overflow-y:scroll;display:none}.kint-rich.kint-folder dd.kint-foldout.kint-show{display:block}.kint-rich::selection{background:var(--border-color-hover);color:var(--text-color)}.kint-rich .kint-focused{box-shadow:0 0 3px 3px var(--variable-type-color-hover)}.kint-rich .kint-focused.kint-weak-focus{box-shadow:0 0 3px 1px color-mix(in srgb, var(--variable-type-color-hover) 50%, transparent)}.kint-rich,.kint-rich::before,.kint-rich::after,.kint-rich *,.kint-rich *::before,.kint-rich *::after{box-sizing:border-box;border-radius:0;color:var(--text-color);float:none !important;font-family:Consolas,Menlo,Monaco,Lucida Console,Liberation Mono,DejaVu Sans Mono,Bitstream Vera Sans Mono,Courier New,monospace,serif;line-height:15px;margin:0;padding:0;text-align:left}.kint-rich{margin:calc(var(--spacing)*2) 0}.kint-rich dt,.kint-rich dl{width:auto}.kint-rich dt,.kint-rich div.access-path{background:var(--main-background);border:var(--border);color:var(--text-color);display:block;font-weight:bold;list-style:none outside none;overflow:auto;padding:var(--spacing)}.kint-rich dt:hover,.kint-rich div.access-path:hover{border-color:var(--border-color-hover)}.kint-rich>dl dl{padding:0 0 0 calc(var(--spacing)*3)}.kint-rich dt.kint-parent>nav,.kint-rich>footer>nav{background:var(--caret-image) no-repeat scroll 0 0/var(--nav-size) 75px rgba(0,0,0,0);cursor:pointer;display:inline-block;height:var(--nav-size);width:var(--nav-size);margin-right:3px;vertical-align:middle}.kint-rich dt.kint-parent:hover>nav,.kint-rich>footer>nav:hover{background-position:0 25%}.kint-rich dt.kint-parent.kint-show>nav,.kint-rich>footer.kint-show>nav{background-position:0 50%}.kint-rich dt.kint-parent.kint-show:hover>nav,.kint-rich>footer.kint-show>nav:hover{background-position:0 75%}.kint-rich dt.kint-parent.kint-locked>nav{background-position:0 100%}.kint-rich dt.kint-parent+dd{display:none;border-left:1px dashed var(--border-color);contain:strict}.kint-rich dt.kint-parent.kint-show+dd{display:block;contain:content}.kint-rich var,.kint-rich var a{color:var(--variable-type-color);font-style:normal}.kint-rich dt:hover var,.kint-rich dt:hover var a{color:var(--variable-type-color-hover)}.kint-rich dfn{font-style:normal;font-family:monospace;color:var(--variable-name-color)}.kint-rich pre{color:var(--text-color);margin:0 0 0 calc(var(--spacing)*3);padding:5px;overflow-y:hidden;border-top:0;border:var(--border);background:var(--main-background);display:block;word-break:normal}.kint-rich .kint-access-path-trigger,.kint-rich .kint-folder-trigger,.kint-rich .kint-search-trigger{background:color-mix(in srgb, var(--text-color) 80%, transparent);border-radius:3px;padding:2px;height:var(--nav-size);width:var(--nav-size);font-size:var(--nav-size);margin-left:5px;font-weight:bold;text-align:center;line-height:1;float:right !important;cursor:pointer;position:relative;overflow:hidden}.kint-rich .kint-access-path-trigger::before,.kint-rich .kint-folder-trigger::before,.kint-rich .kint-search-trigger::before{display:block;content:"";width:100%;height:100%;background:var(--main-background);mask:center/contain no-repeat alpha}.kint-rich .kint-access-path-trigger:hover,.kint-rich .kint-folder-trigger:hover,.kint-rich .kint-search-trigger:hover{background:var(--main-background)}.kint-rich .kint-access-path-trigger:hover::before,.kint-rich .kint-folder-trigger:hover::before,.kint-rich .kint-search-trigger:hover::before{background:var(--text-color)}.kint-rich .kint-access-path-trigger::before{mask-image:var(--ap-image)}.kint-rich .kint-folder-trigger::before{mask-image:var(--folder-image)}.kint-rich .kint-search-trigger::before{mask-image:var(--search-image)}.kint-rich input.kint-search{display:none;border:var(--border);border-top-width:0;border-bottom-width:0;padding:var(--spacing);float:right !important;margin:calc(var(--spacing)*-1) 0;color:var(--variable-name-color);background:var(--secondary-background);height:calc(var(--nav-size) + var(--spacing)*2);width:calc(var(--nav-size)*10);position:relative;z-index:100}.kint-rich input.kint-search.kint-show{display:block}.kint-rich .kint-search-root ul.kint-tabs>li:not(.kint-search-match){background:var(--secondary-background);filter:saturate(0);opacity:.5}.kint-rich .kint-search-root dl:not(.kint-search-match){opacity:.5}.kint-rich .kint-search-root dl:not(.kint-search-match)>dt{background:var(--main-background);filter:saturate(0)}.kint-rich .kint-search-root dl:not(.kint-search-match) dl,.kint-rich .kint-search-root dl:not(.kint-search-match) ul.kint-tabs>li:not(.kint-search-match){opacity:1}.kint-rich div.access-path{background:var(--secondary-background);display:none;margin-top:5px;padding:4px;white-space:pre}.kint-rich div.access-path.kint-show{display:block}.kint-rich footer{padding:0 3px 3px;font-size:9px;background:rgba(0,0,0,0)}.kint-rich footer>.kint-folder-trigger{background:rgba(0,0,0,0)}.kint-rich footer>.kint-folder-trigger::before{background:var(--text-color)}.kint-rich footer nav{height:10px;width:10px;background-size:10px 50px}.kint-rich footer>ol{display:none;margin-left:32px}.kint-rich footer.kint-show>ol{display:block}.kint-rich a{color:var(--text-color);text-shadow:none;text-decoration:underline}.kint-rich a:hover{color:var(--variable-name-color);border-bottom:1px dotted var(--variable-name-color)}.kint-rich ul{list-style:none;padding-left:calc(var(--spacing)*3)}.kint-rich ul:not(.kint-tabs) li{border-left:1px dashed var(--border-color)}.kint-rich ul:not(.kint-tabs) li>dl{border-left:none}.kint-rich ul.kint-tabs{margin:0 0 0 calc(var(--spacing)*3);padding-left:0;background:var(--main-background);border:var(--border);border-top:0}.kint-rich ul.kint-tabs>li{background:var(--secondary-background);border:var(--border);cursor:pointer;display:inline-block;height:calc(var(--spacing)*6);margin:calc(var(--spacing)/2);padding:0 calc(2px + var(--spacing)*2.5);vertical-align:top}.kint-rich ul.kint-tabs>li:hover,.kint-rich ul.kint-tabs>li.kint-active-tab:hover{border-color:var(--border-color-hover);color:var(--variable-type-color-hover)}.kint-rich ul.kint-tabs>li.kint-active-tab{background:var(--main-background);border-top:0;margin-top:-1px;height:27px;line-height:24px}.kint-rich ul.kint-tabs>li:not(.kint-active-tab){line-height:calc(var(--spacing)*5)}.kint-rich ul.kint-tabs li+li{margin-left:0}.kint-rich ul.kint-tab-contents>li{display:none;contain:strict}.kint-rich ul.kint-tab-contents>li.kint-show{display:block;contain:content}.kint-rich dt:hover+dd>ul>li.kint-active-tab{border-color:var(--border-color-hover);color:var(--variable-type-color-hover)}.kint-rich dt>.kint-color-preview{width:var(--nav-size);height:var(--nav-size);display:inline-block;vertical-align:middle;margin-left:10px;border:var(--border);background-color:#ccc;background-image:url('data:image/svg+xml;utf8,');background-size:min(20px,100%)}.kint-rich dt>.kint-color-preview:hover{border-color:var(--border-color-hover)}.kint-rich dt>.kint-color-preview>div{width:100%;height:100%}.kint-rich table{border-collapse:collapse;empty-cells:show;border-spacing:0}.kint-rich table *{font-size:12px}.kint-rich table dt{background:none;padding:calc(var(--spacing)/2)}.kint-rich table dt .kint-parent{min-width:100%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.kint-rich table td,.kint-rich table th{border:var(--border);padding:calc(var(--spacing)/2);vertical-align:center}.kint-rich table th{cursor:alias}.kint-rich table td:first-child,.kint-rich table th{font-weight:bold;background:var(--secondary-background);color:var(--variable-name-color)}.kint-rich table td{background:var(--main-background);white-space:pre}.kint-rich table td>dl{padding:0}.kint-rich table pre{border-top:0;border-right:0}.kint-rich table thead th:first-child{background:none;border:0}.kint-rich table tr:hover>td{box-shadow:0 0 1px 0 var(--border-color-hover) inset}.kint-rich table tr:hover var{color:var(--variable-type-color-hover)}.kint-rich table ul.kint-tabs li.kint-active-tab{height:20px;line-height:17px}.kint-rich pre.kint-source{margin-left:-1px}.kint-rich pre.kint-source[data-kint-filename]:before{display:block;content:attr(data-kint-filename);margin-bottom:var(--spacing);padding-bottom:var(--spacing);border-bottom:1px solid var(--secondary-background)}.kint-rich pre.kint-source>div:before{display:inline-block;content:counter(kint-l);counter-increment:kint-l;border-right:1px solid var(--border-color-hover);padding-right:calc(var(--spacing)*2);margin-right:calc(var(--spacing)*2)}.kint-rich pre.kint-source>div.kint-highlight{background:var(--secondary-background)}.kint-rich .kint-microtime-js .kint-microtime-lap{text-shadow:-1px 0 var(--border-color-hover),0 1px var(--border-color-hover),1px 0 var(--border-color-hover),0 -1px var(--border-color-hover);color:var(--main-background);font-weight:bold}.kint-rich{--spacing: 5px;--main-background: #002b36;--secondary-background: #073642;--backdrop-color: var(--secondary-background);--text-color: #839496;--variable-name-color: #93a1a1;--variable-type-color: #268bd2;--variable-type-color-hover: #2aa198;--border-color: #586e75;--border-color-hover: #268bd2;--caret-image: url("data:image/svg+xml;utf8,")}.kint-rich .kint-focused{box-shadow:0 0 3px 2px #859900 inset;border-radius:7px}.kint-rich>dl>dt,.kint-rich ul.kint-tabs{box-shadow:4px 0 2px -3px var(--variable-type-color) inset}.kint-rich ul.kint-tabs li.kint-active-tab{padding-top:7px;height:34px}.kint-rich footer li{color:#ddd} diff --git a/system/ThirdParty/Kint/resources/compiled/solarized.css b/system/ThirdParty/Kint/resources/compiled/solarized.css index 0db55c01a5bf..1c469b508a1c 100644 --- a/system/ThirdParty/Kint/resources/compiled/solarized.css +++ b/system/ThirdParty/Kint/resources/compiled/solarized.css @@ -1 +1 @@ -.kint-rich{--spacing: 4px;--nav-size: 15px;--backdrop-color: rgba(255, 255, 255, 0.9);--main-background: #e0eaef;--secondary-background: #c1d4df;--text-color: #1d1e1e;--variable-name-color: #1d1e1e;--variable-type-color: #0092db;--variable-type-color-hover: #5cb730;--border-color: #b6cedb;--border-color-hover: #0092db;--border: 1px solid var(--border-color);--foldout-max-size: calc(100vh - 100px);--foldout-zindex: 999999;--caret-image: url("data:image/svg+xml;utf8,");--ap-image: url("data:image/svg+xml;utf8,");--folder-image: url("data:image/svg+xml;utf8,");--search-image: url("data:image/svg+xml;utf8,");font-size:13px;overflow-x:auto;white-space:nowrap;background:var(--backdrop-color);direction:ltr;contain:content}.kint-rich.kint-folder{position:fixed;bottom:0;left:0;right:0;z-index:var(--foldout-zindex);width:100%;margin:0;display:block}.kint-rich.kint-folder dd.kint-foldout{max-height:var(--foldout-max-size);padding-right:calc(var(--spacing)*2);overflow-y:scroll;display:none}.kint-rich.kint-folder dd.kint-foldout.kint-show{display:block}.kint-rich::selection{background:var(--border-color-hover);color:var(--text-color)}.kint-rich .kint-focused{box-shadow:0 0 3px 3px var(--variable-type-color-hover)}.kint-rich .kint-focused.kint-weak-focus{box-shadow:0 0 3px 1px color-mix(in srgb, var(--variable-type-color-hover) 50%, transparent)}.kint-rich,.kint-rich::before,.kint-rich::after,.kint-rich *,.kint-rich *::before,.kint-rich *::after{box-sizing:border-box;border-radius:0;color:var(--text-color);float:none !important;font-family:Consolas,Menlo,Monaco,Lucida Console,Liberation Mono,DejaVu Sans Mono,Bitstream Vera Sans Mono,Courier New,monospace,serif;line-height:15px;margin:0;padding:0;text-align:left}.kint-rich{margin:calc(var(--spacing)*2) 0}.kint-rich dt,.kint-rich dl{width:auto}.kint-rich dt,.kint-rich div.access-path{background:var(--main-background);border:var(--border);color:var(--text-color);display:block;font-weight:bold;list-style:none outside none;overflow:auto;padding:var(--spacing)}.kint-rich dt:hover,.kint-rich div.access-path:hover{border-color:var(--border-color-hover)}.kint-rich>dl dl{padding:0 0 0 calc(var(--spacing)*3)}.kint-rich dt.kint-parent>nav,.kint-rich>footer>nav{background:var(--caret-image) no-repeat scroll 0 0/var(--nav-size) 75px rgba(0,0,0,0);cursor:pointer;display:inline-block;height:var(--nav-size);width:var(--nav-size);margin-right:3px;vertical-align:middle}.kint-rich dt.kint-parent:hover>nav,.kint-rich>footer>nav:hover{background-position:0 25%}.kint-rich dt.kint-parent.kint-show>nav,.kint-rich>footer.kint-show>nav{background-position:0 50%}.kint-rich dt.kint-parent.kint-show:hover>nav,.kint-rich>footer.kint-show>nav:hover{background-position:0 75%}.kint-rich dt.kint-parent.kint-locked>nav{background-position:0 100%}.kint-rich dt.kint-parent+dd{display:none;border-left:1px dashed var(--border-color);contain:strict}.kint-rich dt.kint-parent.kint-show+dd{display:block;contain:content}.kint-rich var,.kint-rich var a{color:var(--variable-type-color);font-style:normal}.kint-rich dt:hover var,.kint-rich dt:hover var a{color:var(--variable-type-color-hover)}.kint-rich dfn{font-style:normal;font-family:monospace;color:var(--variable-name-color)}.kint-rich pre{color:var(--text-color);margin:0 0 0 calc(var(--spacing)*3);padding:5px;overflow-y:hidden;border-top:0;border:var(--border);background:var(--main-background);display:block;word-break:normal}.kint-rich .kint-access-path-trigger,.kint-rich .kint-folder-trigger,.kint-rich .kint-search-trigger{background:color-mix(in srgb, var(--text-color) 80%, transparent);border-radius:3px;padding:2px;height:var(--nav-size);width:var(--nav-size);font-size:var(--nav-size);margin-left:5px;font-weight:bold;text-align:center;line-height:1;float:right !important;cursor:pointer;position:relative;overflow:hidden}.kint-rich .kint-access-path-trigger::before,.kint-rich .kint-folder-trigger::before,.kint-rich .kint-search-trigger::before{display:block;content:"";width:100%;height:100%;background:var(--main-background);mask:center/contain no-repeat alpha}.kint-rich .kint-access-path-trigger:hover,.kint-rich .kint-folder-trigger:hover,.kint-rich .kint-search-trigger:hover{background:var(--main-background)}.kint-rich .kint-access-path-trigger:hover::before,.kint-rich .kint-folder-trigger:hover::before,.kint-rich .kint-search-trigger:hover::before{background:var(--text-color)}.kint-rich .kint-access-path-trigger::before{mask-image:var(--ap-image)}.kint-rich .kint-folder-trigger::before{mask-image:var(--folder-image)}.kint-rich .kint-search-trigger::before{mask-image:var(--search-image)}.kint-rich input.kint-search{display:none;border:var(--border);border-top-width:0;border-bottom-width:0;padding:var(--spacing);float:right !important;margin:calc(var(--spacing)*-1) 0;color:var(--variable-name-color);background:var(--secondary-background);height:calc(var(--nav-size) + var(--spacing)*2);width:calc(var(--nav-size)*10);position:relative;z-index:100}.kint-rich input.kint-search.kint-show{display:block}.kint-rich .kint-search-root ul.kint-tabs>li:not(.kint-search-match){background:var(--secondary-background);filter:saturate(0);opacity:.5}.kint-rich .kint-search-root dl:not(.kint-search-match){opacity:.5}.kint-rich .kint-search-root dl:not(.kint-search-match)>dt{background:var(--main-background);filter:saturate(0)}.kint-rich .kint-search-root dl:not(.kint-search-match) dl,.kint-rich .kint-search-root dl:not(.kint-search-match) ul.kint-tabs>li:not(.kint-search-match){opacity:1}.kint-rich div.access-path{background:var(--secondary-background);display:none;margin-top:5px;padding:4px;white-space:pre}.kint-rich div.access-path.kint-show{display:block}.kint-rich footer{padding:0 3px 3px;font-size:9px;background:rgba(0,0,0,0)}.kint-rich footer>.kint-folder-trigger{background:rgba(0,0,0,0)}.kint-rich footer>.kint-folder-trigger::before{background:var(--text-color)}.kint-rich footer nav{height:10px;width:10px;background-size:10px 50px}.kint-rich footer>ol{display:none;margin-left:32px}.kint-rich footer.kint-show>ol{display:block}.kint-rich a{color:var(--text-color);text-shadow:none;text-decoration:underline}.kint-rich a:hover{color:var(--variable-name-color);border-bottom:1px dotted var(--variable-name-color)}.kint-rich ul{list-style:none;padding-left:calc(var(--spacing)*3)}.kint-rich ul:not(.kint-tabs) li{border-left:1px dashed var(--border-color)}.kint-rich ul:not(.kint-tabs) li>dl{border-left:none}.kint-rich ul.kint-tabs{margin:0 0 0 calc(var(--spacing)*3);padding-left:0;background:var(--main-background);border:var(--border);border-top:0}.kint-rich ul.kint-tabs>li{background:var(--secondary-background);border:var(--border);cursor:pointer;display:inline-block;height:calc(var(--spacing)*6);margin:calc(var(--spacing)/2);padding:0 calc(2px + var(--spacing)*2.5);vertical-align:top}.kint-rich ul.kint-tabs>li:hover,.kint-rich ul.kint-tabs>li.kint-active-tab:hover{border-color:var(--border-color-hover);color:var(--variable-type-color-hover)}.kint-rich ul.kint-tabs>li.kint-active-tab{background:var(--main-background);border-top:0;margin-top:-1px;height:27px;line-height:24px}.kint-rich ul.kint-tabs>li:not(.kint-active-tab){line-height:calc(var(--spacing)*5)}.kint-rich ul.kint-tabs li+li{margin-left:0}.kint-rich ul.kint-tab-contents>li{display:none;contain:strict}.kint-rich ul.kint-tab-contents>li.kint-show{display:block;contain:content}.kint-rich dt:hover+dd>ul>li.kint-active-tab{border-color:var(--border-color-hover);color:var(--variable-type-color-hover)}.kint-rich dt>.kint-color-preview{width:var(--nav-size);height:var(--nav-size);display:inline-block;vertical-align:middle;margin-left:10px;border:var(--border);background-color:#ccc;background-image:url('data:image/svg+xml;utf8,');background-size:min(20px,100%)}.kint-rich dt>.kint-color-preview:hover{border-color:var(--border-color-hover)}.kint-rich dt>.kint-color-preview>div{width:100%;height:100%}.kint-rich table{border-collapse:collapse;empty-cells:show;border-spacing:0}.kint-rich table *{font-size:12px}.kint-rich table dt{background:none;padding:calc(var(--spacing)/2)}.kint-rich table dt .kint-parent{min-width:100%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.kint-rich table td,.kint-rich table th{border:var(--border);padding:calc(var(--spacing)/2);vertical-align:center}.kint-rich table th{cursor:alias}.kint-rich table td:first-child,.kint-rich table th{font-weight:bold;background:var(--secondary-background);color:var(--variable-name-color)}.kint-rich table td{background:var(--main-background);white-space:pre}.kint-rich table td>dl{padding:0}.kint-rich table pre{border-top:0;border-right:0}.kint-rich table thead th:first-child{background:none;border:0}.kint-rich table tr:hover>td{box-shadow:0 0 1px 0 var(--border-color-hover) inset}.kint-rich table tr:hover var{color:var(--variable-type-color-hover)}.kint-rich table ul.kint-tabs li.kint-active-tab{height:20px;line-height:17px}.kint-rich pre.kint-source{margin-left:-1px}.kint-rich pre.kint-source[data-kint-filename]:before{display:block;content:attr(data-kint-filename);margin-bottom:var(--spacing);padding-bottom:var(--spacing);border-bottom:1px solid var(--secondary-background)}.kint-rich pre.kint-source>div:before{display:inline-block;content:counter(kint-l);counter-increment:kint-l;border-right:1px solid var(--border-color-hover);padding-right:calc(var(--spacing)*2);margin-right:calc(var(--spacing)*2)}.kint-rich pre.kint-source>div.kint-highlight{background:var(--secondary-background)}.kint-rich .kint-microtime-js .kint-microtime-lap{text-shadow:-1px 0 var(--border-color-hover),0 1px var(--border-color-hover),1px 0 var(--border-color-hover),0 -1px var(--border-color-hover);color:var(--main-background);font-weight:bold}input.kint-note-input{width:100%}.kint-rich{--spacing: 5px;--main-background: #fdf6e3;--secondary-background: #eee8d5;--text-color: #657b83;--variable-name-color: #586e75;--variable-type-color: #268bd2;--variable-type-color-hover: #2aa198;--border-color: #93a1a1;--border-color-hover: #268bd2;--caret-image: url("data:image/svg+xml;utf8,")}.kint-rich .kint-focused{box-shadow:0 0 3px 2px #859900 inset;border-radius:7px}.kint-rich>dl>dt,.kint-rich ul.kint-tabs{box-shadow:4px 0 2px -3px var(--variable-type-color) inset}.kint-rich ul.kint-tabs li.kint-active-tab{padding-top:7px;height:34px} +.kint-rich{--spacing: 4px;--nav-size: 15px;--backdrop-color: rgba(255, 255, 255, 0.9);--main-background: #e0eaef;--secondary-background: #c1d4df;--text-color: #1d1e1e;--variable-name-color: #1d1e1e;--variable-type-color: #0092db;--variable-type-color-hover: #5cb730;--border-color: #b6cedb;--border-color-hover: #0092db;--border: 1px solid var(--border-color);--foldout-max-size: calc(100vh - 100px);--foldout-zindex: 999999;--caret-image: url("data:image/svg+xml;utf8,");--ap-image: url("data:image/svg+xml;utf8,");--folder-image: url("data:image/svg+xml;utf8,");--search-image: url("data:image/svg+xml;utf8,");font-size:13px;overflow-x:auto;white-space:nowrap;background:var(--backdrop-color);direction:ltr;contain:content}.kint-rich.kint-folder{position:fixed;bottom:0;left:0;right:0;z-index:var(--foldout-zindex);width:100%;margin:0;display:block}.kint-rich.kint-folder dd.kint-foldout{max-height:var(--foldout-max-size);padding-right:calc(var(--spacing)*2);overflow-y:scroll;display:none}.kint-rich.kint-folder dd.kint-foldout.kint-show{display:block}.kint-rich::selection{background:var(--border-color-hover);color:var(--text-color)}.kint-rich .kint-focused{box-shadow:0 0 3px 3px var(--variable-type-color-hover)}.kint-rich .kint-focused.kint-weak-focus{box-shadow:0 0 3px 1px color-mix(in srgb, var(--variable-type-color-hover) 50%, transparent)}.kint-rich,.kint-rich::before,.kint-rich::after,.kint-rich *,.kint-rich *::before,.kint-rich *::after{box-sizing:border-box;border-radius:0;color:var(--text-color);float:none !important;font-family:Consolas,Menlo,Monaco,Lucida Console,Liberation Mono,DejaVu Sans Mono,Bitstream Vera Sans Mono,Courier New,monospace,serif;line-height:15px;margin:0;padding:0;text-align:left}.kint-rich{margin:calc(var(--spacing)*2) 0}.kint-rich dt,.kint-rich dl{width:auto}.kint-rich dt,.kint-rich div.access-path{background:var(--main-background);border:var(--border);color:var(--text-color);display:block;font-weight:bold;list-style:none outside none;overflow:auto;padding:var(--spacing)}.kint-rich dt:hover,.kint-rich div.access-path:hover{border-color:var(--border-color-hover)}.kint-rich>dl dl{padding:0 0 0 calc(var(--spacing)*3)}.kint-rich dt.kint-parent>nav,.kint-rich>footer>nav{background:var(--caret-image) no-repeat scroll 0 0/var(--nav-size) 75px rgba(0,0,0,0);cursor:pointer;display:inline-block;height:var(--nav-size);width:var(--nav-size);margin-right:3px;vertical-align:middle}.kint-rich dt.kint-parent:hover>nav,.kint-rich>footer>nav:hover{background-position:0 25%}.kint-rich dt.kint-parent.kint-show>nav,.kint-rich>footer.kint-show>nav{background-position:0 50%}.kint-rich dt.kint-parent.kint-show:hover>nav,.kint-rich>footer.kint-show>nav:hover{background-position:0 75%}.kint-rich dt.kint-parent.kint-locked>nav{background-position:0 100%}.kint-rich dt.kint-parent+dd{display:none;border-left:1px dashed var(--border-color);contain:strict}.kint-rich dt.kint-parent.kint-show+dd{display:block;contain:content}.kint-rich var,.kint-rich var a{color:var(--variable-type-color);font-style:normal}.kint-rich dt:hover var,.kint-rich dt:hover var a{color:var(--variable-type-color-hover)}.kint-rich dfn{font-style:normal;font-family:monospace;color:var(--variable-name-color)}.kint-rich pre{color:var(--text-color);margin:0 0 0 calc(var(--spacing)*3);padding:5px;overflow-y:hidden;border-top:0;border:var(--border);background:var(--main-background);display:block;word-break:normal}.kint-rich .kint-access-path-trigger,.kint-rich .kint-folder-trigger,.kint-rich .kint-search-trigger{background:color-mix(in srgb, var(--text-color) 80%, transparent);border-radius:3px;padding:2px;height:var(--nav-size);width:var(--nav-size);font-size:var(--nav-size);margin-left:5px;font-weight:bold;text-align:center;line-height:1;float:right !important;cursor:pointer;position:relative;overflow:hidden}.kint-rich .kint-access-path-trigger::before,.kint-rich .kint-folder-trigger::before,.kint-rich .kint-search-trigger::before{display:block;content:"";width:100%;height:100%;background:var(--main-background);mask:center/contain no-repeat alpha}.kint-rich .kint-access-path-trigger:hover,.kint-rich .kint-folder-trigger:hover,.kint-rich .kint-search-trigger:hover{background:var(--main-background)}.kint-rich .kint-access-path-trigger:hover::before,.kint-rich .kint-folder-trigger:hover::before,.kint-rich .kint-search-trigger:hover::before{background:var(--text-color)}.kint-rich .kint-access-path-trigger::before{mask-image:var(--ap-image)}.kint-rich .kint-folder-trigger::before{mask-image:var(--folder-image)}.kint-rich .kint-search-trigger::before{mask-image:var(--search-image)}.kint-rich input.kint-search{display:none;border:var(--border);border-top-width:0;border-bottom-width:0;padding:var(--spacing);float:right !important;margin:calc(var(--spacing)*-1) 0;color:var(--variable-name-color);background:var(--secondary-background);height:calc(var(--nav-size) + var(--spacing)*2);width:calc(var(--nav-size)*10);position:relative;z-index:100}.kint-rich input.kint-search.kint-show{display:block}.kint-rich .kint-search-root ul.kint-tabs>li:not(.kint-search-match){background:var(--secondary-background);filter:saturate(0);opacity:.5}.kint-rich .kint-search-root dl:not(.kint-search-match){opacity:.5}.kint-rich .kint-search-root dl:not(.kint-search-match)>dt{background:var(--main-background);filter:saturate(0)}.kint-rich .kint-search-root dl:not(.kint-search-match) dl,.kint-rich .kint-search-root dl:not(.kint-search-match) ul.kint-tabs>li:not(.kint-search-match){opacity:1}.kint-rich div.access-path{background:var(--secondary-background);display:none;margin-top:5px;padding:4px;white-space:pre}.kint-rich div.access-path.kint-show{display:block}.kint-rich footer{padding:0 3px 3px;font-size:9px;background:rgba(0,0,0,0)}.kint-rich footer>.kint-folder-trigger{background:rgba(0,0,0,0)}.kint-rich footer>.kint-folder-trigger::before{background:var(--text-color)}.kint-rich footer nav{height:10px;width:10px;background-size:10px 50px}.kint-rich footer>ol{display:none;margin-left:32px}.kint-rich footer.kint-show>ol{display:block}.kint-rich a{color:var(--text-color);text-shadow:none;text-decoration:underline}.kint-rich a:hover{color:var(--variable-name-color);border-bottom:1px dotted var(--variable-name-color)}.kint-rich ul{list-style:none;padding-left:calc(var(--spacing)*3)}.kint-rich ul:not(.kint-tabs) li{border-left:1px dashed var(--border-color)}.kint-rich ul:not(.kint-tabs) li>dl{border-left:none}.kint-rich ul.kint-tabs{margin:0 0 0 calc(var(--spacing)*3);padding-left:0;background:var(--main-background);border:var(--border);border-top:0}.kint-rich ul.kint-tabs>li{background:var(--secondary-background);border:var(--border);cursor:pointer;display:inline-block;height:calc(var(--spacing)*6);margin:calc(var(--spacing)/2);padding:0 calc(2px + var(--spacing)*2.5);vertical-align:top}.kint-rich ul.kint-tabs>li:hover,.kint-rich ul.kint-tabs>li.kint-active-tab:hover{border-color:var(--border-color-hover);color:var(--variable-type-color-hover)}.kint-rich ul.kint-tabs>li.kint-active-tab{background:var(--main-background);border-top:0;margin-top:-1px;height:27px;line-height:24px}.kint-rich ul.kint-tabs>li:not(.kint-active-tab){line-height:calc(var(--spacing)*5)}.kint-rich ul.kint-tabs li+li{margin-left:0}.kint-rich ul.kint-tab-contents>li{display:none;contain:strict}.kint-rich ul.kint-tab-contents>li.kint-show{display:block;contain:content}.kint-rich dt:hover+dd>ul>li.kint-active-tab{border-color:var(--border-color-hover);color:var(--variable-type-color-hover)}.kint-rich dt>.kint-color-preview{width:var(--nav-size);height:var(--nav-size);display:inline-block;vertical-align:middle;margin-left:10px;border:var(--border);background-color:#ccc;background-image:url('data:image/svg+xml;utf8,');background-size:min(20px,100%)}.kint-rich dt>.kint-color-preview:hover{border-color:var(--border-color-hover)}.kint-rich dt>.kint-color-preview>div{width:100%;height:100%}.kint-rich table{border-collapse:collapse;empty-cells:show;border-spacing:0}.kint-rich table *{font-size:12px}.kint-rich table dt{background:none;padding:calc(var(--spacing)/2)}.kint-rich table dt .kint-parent{min-width:100%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.kint-rich table td,.kint-rich table th{border:var(--border);padding:calc(var(--spacing)/2);vertical-align:center}.kint-rich table th{cursor:alias}.kint-rich table td:first-child,.kint-rich table th{font-weight:bold;background:var(--secondary-background);color:var(--variable-name-color)}.kint-rich table td{background:var(--main-background);white-space:pre}.kint-rich table td>dl{padding:0}.kint-rich table pre{border-top:0;border-right:0}.kint-rich table thead th:first-child{background:none;border:0}.kint-rich table tr:hover>td{box-shadow:0 0 1px 0 var(--border-color-hover) inset}.kint-rich table tr:hover var{color:var(--variable-type-color-hover)}.kint-rich table ul.kint-tabs li.kint-active-tab{height:20px;line-height:17px}.kint-rich pre.kint-source{margin-left:-1px}.kint-rich pre.kint-source[data-kint-filename]:before{display:block;content:attr(data-kint-filename);margin-bottom:var(--spacing);padding-bottom:var(--spacing);border-bottom:1px solid var(--secondary-background)}.kint-rich pre.kint-source>div:before{display:inline-block;content:counter(kint-l);counter-increment:kint-l;border-right:1px solid var(--border-color-hover);padding-right:calc(var(--spacing)*2);margin-right:calc(var(--spacing)*2)}.kint-rich pre.kint-source>div.kint-highlight{background:var(--secondary-background)}.kint-rich .kint-microtime-js .kint-microtime-lap{text-shadow:-1px 0 var(--border-color-hover),0 1px var(--border-color-hover),1px 0 var(--border-color-hover),0 -1px var(--border-color-hover);color:var(--main-background);font-weight:bold}.kint-rich{--spacing: 5px;--main-background: #fdf6e3;--secondary-background: #eee8d5;--text-color: #657b83;--variable-name-color: #586e75;--variable-type-color: #268bd2;--variable-type-color-hover: #2aa198;--border-color: #93a1a1;--border-color-hover: #268bd2;--caret-image: url("data:image/svg+xml;utf8,")}.kint-rich .kint-focused{box-shadow:0 0 3px 2px #859900 inset;border-radius:7px}.kint-rich>dl>dt,.kint-rich ul.kint-tabs{box-shadow:4px 0 2px -3px var(--variable-type-color) inset}.kint-rich ul.kint-tabs li.kint-active-tab{padding-top:7px;height:34px} diff --git a/system/Throttle/Throttler.php b/system/Throttle/Throttler.php index c023b5e4d052..fba7665de4a8 100644 --- a/system/Throttle/Throttler.php +++ b/system/Throttle/Throttler.php @@ -90,8 +90,6 @@ public function getTokenTime(): int * @param int $capacity The number of requests the "bucket" can hold * @param int $seconds The time it takes the "bucket" to completely refill * @param int $cost The number of tokens this action uses. - * - * @internal param int $maxRequests */ public function check(string $key, int $capacity, int $seconds, int $cost = 1): bool { diff --git a/system/Validation/FormatRules.php b/system/Validation/FormatRules.php index 502f3ae09c82..e28ef97706f3 100644 --- a/system/Validation/FormatRules.php +++ b/system/Validation/FormatRules.php @@ -284,7 +284,13 @@ public function valid_base64($str = null): bool $str = (string) $str; } - return base64_encode(base64_decode($str, true)) === $str; + $decoded = base64_decode($str, true); + + if ($decoded === false) { + return false; + } + + return base64_encode($decoded) === $str; } /** @@ -416,7 +422,7 @@ public function valid_url($str = null): bool */ public function valid_url_strict($str = null, ?string $validSchemes = null): bool { - if ($str === null || $str === '' || $str === '0') { + if (in_array($str, [null, '', '0'], true)) { return false; } diff --git a/system/Validation/Validation.php b/system/Validation/Validation.php index d3f2a3dc828f..37cf552499d9 100644 --- a/system/Validation/Validation.php +++ b/system/Validation/Validation.php @@ -918,7 +918,7 @@ protected function getErrorMessage( $args = [ 'field' => ($label === null || $label === '') ? $field : lang($label), - 'param' => (! isset($this->rules[$param]['label'])) ? $param : lang($this->rules[$param]['label']), + 'param' => isset($this->rules[$param]['label']) ? lang($this->rules[$param]['label']) : $param, 'value' => $value ?? '', ]; diff --git a/system/View/Cell.php b/system/View/Cell.php index 8325accc7223..3a3e9595e3f5 100644 --- a/system/View/Cell.php +++ b/system/View/Cell.php @@ -125,7 +125,7 @@ public function render(string $library, $params = null, int $ttl = 0, ?string $c public function prepareParams($params) { if ( - ($params === null || $params === '' || $params === []) + in_array($params, [null, '', []], true) || (! is_string($params) && ! is_array($params)) ) { return []; @@ -154,10 +154,6 @@ public function prepareParams($params) unset($newParams); } - if ($params === []) { - return []; - } - return $params; } diff --git a/system/View/Cells/Cell.php b/system/View/Cells/Cell.php index ffe652baa3da..581499028e4b 100644 --- a/system/View/Cells/Cell.php +++ b/system/View/Cells/Cell.php @@ -85,7 +85,7 @@ final protected function view(?string $view, array $data = []): string $viewName = decamelize(class_basename(static::class)); $directory = dirname((new ReflectionClass($this))->getFileName()) . DIRECTORY_SEPARATOR; - $possibleView1 = $directory . substr($viewName, 0, strrpos($viewName, '_cell')) . '.php'; + $possibleView1 = $directory . substr($viewName, 0, (int) strrpos($viewName, '_cell')) . '.php'; $possibleView2 = $directory . $viewName . '.php'; } diff --git a/tests/_support/Config/Registrar.php b/tests/_support/Config/Registrar.php index b92c5e24bb16..8759dcb5a1a2 100644 --- a/tests/_support/Config/Registrar.php +++ b/tests/_support/Config/Registrar.php @@ -83,6 +83,7 @@ class Registrar 'failover' => [], 'port' => 3306, 'foreignKeys' => true, + 'synchronous' => 0, ], 'SQLSRV' => [ 'DSN' => '', @@ -134,9 +135,9 @@ public static function Database(): array // Under GitHub Actions, we can set an ENV var named 'DB' // so that we can test against multiple databases. - if (($group = getenv('DB')) && isset(self::$dbConfig[$group])) { - $config['tests'] = self::$dbConfig[$group]; - } + $group = env('DB', 'SQLite3'); + + $config['tests'] = self::$dbConfig[$group] ?? []; return $config; } diff --git a/tests/_support/Entity/CustomUser.php b/tests/_support/Entity/CustomUser.php index 94a6ae3345ab..67d381ca6fde 100644 --- a/tests/_support/Entity/CustomUser.php +++ b/tests/_support/Entity/CustomUser.php @@ -38,6 +38,9 @@ private function __construct( ) { } + /** + * @param array|string|Time|null> $data + */ public static function reconstruct(array $data): static { return new self( diff --git a/tests/_support/Language/SecondMockLanguage.php b/tests/_support/Language/SecondMockLanguage.php index 2f667312e499..cf7da6ff1599 100644 --- a/tests/_support/Language/SecondMockLanguage.php +++ b/tests/_support/Language/SecondMockLanguage.php @@ -15,20 +15,27 @@ use CodeIgniter\Language\Language; +/** + * @phpstan-import-type LoadedStrings from Language + */ class SecondMockLanguage extends Language { /** * Expose the protected *load* method + * + * @return ($return is true ? LoadedStrings : null) */ - public function loadem(string $file, string $locale = 'en', bool $return = false) + public function loadem(string $file, string $locale = 'en', bool $return = false): ?array { return $this->load($file, $locale, $return); } /** * Expose the loaded language files + * + * @return list */ - public function loaded(string $locale = 'en') + public function loaded(string $locale = 'en'): array { return $this->loadedFiles[$locale]; } diff --git a/tests/_support/Log/Handlers/TestHandler.php b/tests/_support/Log/Handlers/TestHandler.php index b87b5aff743b..025943ffe588 100644 --- a/tests/_support/Log/Handlers/TestHandler.php +++ b/tests/_support/Log/Handlers/TestHandler.php @@ -35,6 +35,8 @@ class TestHandler extends FileHandler /** * Where would the log be written? + * + * @param array $config */ public function __construct(array $config) { diff --git a/tests/_support/Models/EventModel.php b/tests/_support/Models/EventModel.php index 4057c05d2f6f..00a11ac132fc 100644 --- a/tests/_support/Models/EventModel.php +++ b/tests/_support/Models/EventModel.php @@ -129,6 +129,9 @@ protected function afterDeleteMethod(array $data) return $data; } + /** + * @param array $data + */ protected function beforeFindMethod(array $data) { $this->tokens[] = 'beforeFind'; diff --git a/tests/system/Cache/Handlers/PredisHandlerTest.php b/tests/system/Cache/Handlers/PredisHandlerTest.php index eec292f280ad..96857fc6a9f2 100644 --- a/tests/system/Cache/Handlers/PredisHandlerTest.php +++ b/tests/system/Cache/Handlers/PredisHandlerTest.php @@ -160,6 +160,11 @@ public function testDeleteMatchingSuffix(): void $this->assertSame('90', $this->handler->getCacheInfo()['Keyspace']['db0']['keys']); } + public function testDeleteMatchingNothing(): void + { + $this->assertSame(0, $this->handler->deleteMatching('user_1_info*')); + } + public function testClean(): void { $this->handler->save(self::$key1, 1); diff --git a/tests/system/Cache/Handlers/RedisHandlerTest.php b/tests/system/Cache/Handlers/RedisHandlerTest.php index 467abc675372..47c92aaff372 100644 --- a/tests/system/Cache/Handlers/RedisHandlerTest.php +++ b/tests/system/Cache/Handlers/RedisHandlerTest.php @@ -184,6 +184,11 @@ public static function provideDeleteMatching(): iterable yield 'cache-prefix' => ['key_1*', 13, 'foo_']; } + public function testDeleteMatchingNothing(): void + { + $this->assertSame(0, $this->handler->deleteMatching('user_1_info*')); + } + public function testIncrementAndDecrement(): void { $this->handler->save('counter', 100); diff --git a/tests/system/Commands/BaseCommandTest.php b/tests/system/Commands/BaseCommandTest.php index cffb7963af44..47ca2a6f6a1b 100644 --- a/tests/system/Commands/BaseCommandTest.php +++ b/tests/system/Commands/BaseCommandTest.php @@ -36,14 +36,14 @@ public function testMagicIssetTrue(): void { $command = new AppInfo($this->logger, service('commands')); - $this->assertTrue(isset($command->group)); + $this->assertSame($command->group !== null, isset($command->group)); // @phpstan-ignore isset.property } public function testMagicIssetFalse(): void { $command = new AppInfo($this->logger, service('commands')); - $this->assertFalse(isset($command->foobar)); + $this->assertFalse(isset($command->foobar)); // @phpstan-ignore property.notFound } public function testMagicGet(): void @@ -57,6 +57,6 @@ public function testMagicGetMissing(): void { $command = new AppInfo($this->logger, service('commands')); - $this->assertNull($command->foobar); + $this->assertNull($command->foobar); // @phpstan-ignore property.notFound } } diff --git a/tests/system/Commands/CreateDatabaseTest.php b/tests/system/Commands/CreateDatabaseTest.php index af5b6d3b1682..a7e0fe11638f 100644 --- a/tests/system/Commands/CreateDatabaseTest.php +++ b/tests/system/Commands/CreateDatabaseTest.php @@ -14,7 +14,6 @@ namespace CodeIgniter\Commands; use CodeIgniter\Database\BaseConnection; -use CodeIgniter\Database\Database as DatabaseFactory; use CodeIgniter\Database\OCI8\Connection as OCI8Connection; use CodeIgniter\Database\SQLite3\Connection as SQLite3Connection; use CodeIgniter\Test\CIUnitTestCase; @@ -51,16 +50,13 @@ protected function tearDown(): void private function dropDatabase(): void { if ($this->connection instanceof SQLite3Connection) { - $file = WRITEPATH . 'foobar.db'; + $file = WRITEPATH . 'database.db'; + if (is_file($file)) { unlink($file); } - } else { - $util = (new DatabaseFactory())->loadUtils($this->connection); - - if ($util->databaseExists('foobar')) { - Database::forge()->dropDatabase('foobar'); - } + } elseif (Database::utils('tests')->databaseExists('database')) { + Database::forge()->dropDatabase('database'); } } @@ -75,7 +71,7 @@ public function testCreateDatabase(): void $this->markTestSkipped('Needs to run on non-OCI8 drivers.'); } - command('db:create foobar'); + command('db:create database'); $this->assertStringContainsString('successfully created.', $this->getBuffer()); } @@ -85,10 +81,10 @@ public function testSqliteDatabaseDuplicated(): void $this->markTestSkipped('Needs to run on SQLite3.'); } - command('db:create foobar'); + command('db:create database'); $this->resetStreamFilterBuffer(); - command('db:create foobar --ext db'); + command('db:create database --ext db'); $this->assertStringContainsString('already exists.', $this->getBuffer()); } @@ -98,10 +94,10 @@ public function testOtherDriverDuplicatedDatabase(): void $this->markTestSkipped('Needs to run on non-SQLite3 and non-OCI8 drivers.'); } - command('db:create foobar'); + command('db:create database'); $this->resetStreamFilterBuffer(); - command('db:create foobar'); + command('db:create database'); $this->assertStringContainsString('Unable to create the specified database.', $this->getBuffer()); } } diff --git a/tests/system/Commands/Database/MigrateStatusTest.php b/tests/system/Commands/Database/MigrateStatusTest.php index b08557790de0..c9d9b20cc489 100644 --- a/tests/system/Commands/Database/MigrateStatusTest.php +++ b/tests/system/Commands/Database/MigrateStatusTest.php @@ -15,6 +15,7 @@ use CodeIgniter\CLI\CLI; use CodeIgniter\Test\CIUnitTestCase; +use CodeIgniter\Test\DatabaseTestTrait; use CodeIgniter\Test\StreamFilterTrait; use Config\Database; use PHPUnit\Framework\Attributes\Group; @@ -26,17 +27,18 @@ final class MigrateStatusTest extends CIUnitTestCase { use StreamFilterTrait; + use DatabaseTestTrait; private string $migrationFileFrom = SUPPORTPATH . 'MigrationTestMigrations/Database/Migrations/2018-01-24-102301_Some_migration.php'; private string $migrationFileTo = APPPATH . 'Database/Migrations/2018-01-24-102301_Some_migration.php'; protected function setUp(): void { - $forge = Database::forge(); - $forge->dropTable('foo', true); - parent::setUp(); + Database::connect()->table('migrations')->emptyTable(); + Database::forge()->dropTable('foo', true); + if (! is_file($this->migrationFileFrom)) { $this->fail(clean_path($this->migrationFileFrom) . ' is not found.'); } @@ -63,8 +65,7 @@ protected function tearDown(): void { parent::tearDown(); - $db = db_connect(); - $db->table('migrations')->emptyTable(); + Database::connect()->table('migrations')->emptyTable(); if (is_file($this->migrationFileTo)) { @unlink($this->migrationFileTo); diff --git a/tests/system/CommonFunctionsTest.php b/tests/system/CommonFunctionsTest.php index 715ea3051735..bc09ef6e9f57 100644 --- a/tests/system/CommonFunctionsTest.php +++ b/tests/system/CommonFunctionsTest.php @@ -243,13 +243,13 @@ public function testEscapeWithDifferentEncodings(): void public function testEscapeBadContext(): void { $this->expectException('InvalidArgumentException'); - esc(['width' => '800', 'height' => '600'], 'bogus'); + esc(['width' => '800', 'height' => '600'], 'bogus'); // @phpstan-ignore argument.type } public function testEscapeBadContextZero(): void { $this->expectException('InvalidArgumentException'); - esc('