From 97a424eb994d0ad7f7b7c58daac10bbe880a30e0 Mon Sep 17 00:00:00 2001 From: Igor Ilic Date: Thu, 29 Sep 2022 18:16:27 +0200 Subject: [PATCH] Fix manual injection value (#17) * Change how values are passed with DI * Fixes #16 * Fix tests --- .github/workflows/documentation.yml | 104 +- .github/workflows/php-pest-tests.yml | 62 +- README.md | 536 +-- composer.json | 126 +- composer.lock | 5716 +++++++++++++------------- sample/HomeController.php | 94 +- sample/InjectController.php | 32 +- sample/InjectedClass.php | 28 +- sample/Middleware.php | 58 +- sample/index.php | 424 +- sample/nestedClasses.php | 46 +- src/DIContainer.php | 252 +- src/Request.php | 384 +- src/Routes.php | 1074 ++--- tests/DIContainerTest.php | 92 +- tests/RoutesTest.php | 179 +- 16 files changed, 4612 insertions(+), 4595 deletions(-) diff --git a/.github/workflows/documentation.yml b/.github/workflows/documentation.yml index e0c7ab0..ffa32ec 100644 --- a/.github/workflows/documentation.yml +++ b/.github/workflows/documentation.yml @@ -1,53 +1,53 @@ -name: Automatically update project documentation - -on: - push: - branches: - - main -env: - extensions: 'json,mbstring' - defaultPHPVersion: '8.1.10' - -jobs: - generate_docs: - runs-on: ubuntu-latest - - steps: - - uses: actions/checkout@v2 - - - name: Setup PHP - uses: shivammathur/setup-php@master - with: - php-version: ${{ env.defaultPHPVersion }} - extensions: ${{ env.extensions }} - ini-values: memory_limit=2G, display_errors=On, error_reporting=-1 - tools: pecl - - - name: Cache dependencies - uses: actions/cache@v2 - with: - path: ~/.composer/cache/files - key: dependencies-composer-${{ hashFiles('composer.lock') }} - - - name: Install Composer dependencies - run: composer install -q --no-ansi --no-interaction --no-progress --prefer-dist --optimize-autoloader - - - name: Generate Documentation - run: | - git config --global user.email "${{ secrets.DOCS_GITHUB_EMAIL }}" - git config --global user.name "${{ secrets.DOCS_GITHUB_USER }}" - git remote set-url origin https://gigili:${{ secrets.WIKI_GITHUB_UPDATE_TOKEN }}@github.com/gigili/PHP-routing.git - mkdir bin - cd bin/ - wget https://phpdoc.org/phpDocumentor.phar - cd .. - mkdir -p ./docs - php bin/phpDocumentor.phar run -d ./ -t ./docs --ignore vendor/ --ignore sample/ --ignore tests/ --setting="guides.enabled=true" --force -v - rm -r bin/ - git add . - if [[ $(git commit -am "[AUTO] Update documentation") != *"Nothing to commit"* ]]; then - echo "::debug::Pushing new documentation changes" - git push origin main - else - echo "::debug::Nothing to commit and skipping push" +name: Automatically update project documentation + +on: + push: + branches: + - main +env: + extensions: 'json,mbstring' + defaultPHPVersion: '8.1.10' + +jobs: + generate_docs: + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v2 + + - name: Setup PHP + uses: shivammathur/setup-php@master + with: + php-version: ${{ env.defaultPHPVersion }} + extensions: ${{ env.extensions }} + ini-values: memory_limit=2G, display_errors=On, error_reporting=-1 + tools: pecl + + - name: Cache dependencies + uses: actions/cache@v2 + with: + path: ~/.composer/cache/files + key: dependencies-composer-${{ hashFiles('composer.lock') }} + + - name: Install Composer dependencies + run: composer install -q --no-ansi --no-interaction --no-progress --prefer-dist --optimize-autoloader + + - name: Generate Documentation + run: | + git config --global user.email "${{ secrets.DOCS_GITHUB_EMAIL }}" + git config --global user.name "${{ secrets.DOCS_GITHUB_USER }}" + git remote set-url origin https://gigili:${{ secrets.WIKI_GITHUB_UPDATE_TOKEN }}@github.com/gigili/PHP-routing.git + mkdir bin + cd bin/ + wget https://phpdoc.org/phpDocumentor.phar + cd .. + mkdir -p ./docs + php bin/phpDocumentor.phar run -d ./ -t ./docs --ignore vendor/ --ignore sample/ --ignore tests/ --setting="guides.enabled=true" --force -v + rm -r bin/ + git add . + if [[ $(git commit -am "[AUTO] Update documentation") != *"Nothing to commit"* ]]; then + echo "::debug::Pushing new documentation changes" + git push origin main + else + echo "::debug::Nothing to commit and skipping push" fi \ No newline at end of file diff --git a/.github/workflows/php-pest-tests.yml b/.github/workflows/php-pest-tests.yml index 508ecf2..d5fe781 100644 --- a/.github/workflows/php-pest-tests.yml +++ b/.github/workflows/php-pest-tests.yml @@ -1,32 +1,32 @@ -name: PHP Tests - -on: - push: - branches: [ main ] - pull_request: - branches: [ main ] - -jobs: - build: - runs-on: ubuntu-latest - steps: - - name: Checkout - uses: actions/checkout@v2 - - - name: Setup PHP with Xdebug - uses: shivammathur/setup-php@v2 - with: - php-version: '8.1' - coverage: xdebug - - - name: Cache dependencies - uses: actions/cache@v2 - with: - path: ~/.composer/cache/files - key: dependencies-composer-${{ hashFiles('composer.lock') }} - - - name: Install Dependencies - run: composer install -q --no-ansi --no-interaction --no-progress --prefer-dist --optimize-autoloader - - - name: Execute tests +name: PHP Tests + +on: + push: + branches: [ main ] + pull_request: + branches: [ main ] + +jobs: + build: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v2 + + - name: Setup PHP with Xdebug + uses: shivammathur/setup-php@v2 + with: + php-version: '8.1' + coverage: xdebug + + - name: Cache dependencies + uses: actions/cache@v2 + with: + path: ~/.composer/cache/files + key: dependencies-composer-${{ hashFiles('composer.lock') }} + + - name: Install Dependencies + run: composer install -q --no-ansi --no-interaction --no-progress --prefer-dist --optimize-autoloader + + - name: Execute tests run: vendor/bin/pest \ No newline at end of file diff --git a/README.md b/README.md index 46cf413..f9ceb07 100644 --- a/README.md +++ b/README.md @@ -1,268 +1,268 @@ -# Routing library for PHP - -This library allows you to create static or dynamic routes. This library was inspired -by [PHP Slim framework](https://www.slimframework.com/) - -[![PHP Tests](https://github.com/gigili/PHP-routing/actions/workflows/php-pest-tests.yml/badge.svg)](https://github.com/gigili/PHP-routing/actions/workflows/php-pest-tests.yml) -[![License](https://poser.pugx.org/gac/routing/license)](https://packagist.org/packages/gac/routing) -[![Total Downloads](https://poser.pugx.org/gac/routing/downloads)](https://packagist.org/packages/gac/routing) - -## Install via composer - -```shell -composer require gac/routing -``` - -## Manual install - -Download the latest release from the [Releases page](https://github.com/gigili/PHP-routing/releases). - -Don't forget to add these `include_once` statements to your php files: - -```php -include_once "./Exceptions/CallbackNotFound.php"; -include_once "./Exceptions/RouteNotFoundException.php"; -include_once "./Request.php"; -include_once "./Routes.php"; -``` - -## Post install - -To use this library properly you will need to create a `.htaccess` file at the root of the project. - -Example of the `.htaccess` file would look like this: - -```apacheconf -RewriteEngine On - -RewriteBase / -RewriteCond %{REQUEST_FILENAME} !-f -RewriteCond %{REQUEST_FILENAME} !-d - -RewriteRule ^(.+)$ index.php [QSA,L] -``` - -### Note - -If you've named your main file differently, replace `index.php` in the `.htaccess` file with whatever your main -application file is. - -## Quick start - -Sample code to allow you to quickly start with your development. - -```php -use Gac\Routing\Exceptions\CallbackNotFound; -use Gac\Routing\Exceptions\RouteNotFoundException; -use Gac\Routing\Request;use Gac\Routing\Routes; - -include_once "vendor/autoload.php"; # IF YOU'RE USING composer - -$routes = new Routes(); -try { - $routes->add('/', function (Request $request) { - $request - ->status(200, "OK") - ->send(["message" => "Welcome"]); - }); - - $routes->route('/', function (Request $request) { - $request - ->status(201, "OK") - ->send(["message" => "Welcome"]); - }, [Routes::POST])->save(); - - $routes->route(); -} catch (RouteNotFoundException $ex) { - $routes->request->status(404, "Route not found")->send(["error" => ["message" => $ex->getMessage()]]); -} catch (CallbackNotFound $ex) { - $routes->request->status(404, "Callback method not found")->send(["error" => ["message" => $ex->getMessage()]]); -} catch (Exception $ex) { - $code = $ex->getCode() ?? 500; - $routes->request->status($code)->send(["error" => ["message" => $ex->getMessage()]]); -} -``` - -## Examples - -### Dynamic routes example - -```php -$routes->add('/test/{int:userID}-{username}/{float:amount}/{bool:valid}', function ( - Request $request, - int $userID, - string $username, - float $amount, - bool $valid -) { - echo 'Dynamic route content here'; -}); -``` - -### Chained routes - -When using chained methods either use `->save()` or `->add()` as the last method to indicate the end of a chain - -**NOTE** - -* `->save(true|false)` method can still be chained onto if needed - * Passing `false` (the default value is `true`) to the `->save()` method will preserve all the previous prefixes and middlewares in that chain -* `->add()` **CAN NOT** be chained onto and should be the last call in chain - -```php -$routes - ->prefix('/user') // all the routes added will have the /user prefix - ->middleware([ 'verify_token' ]) // all the routes added will have the verify_token middleware applied - ->route('/', [ HomeController::class, 'getUsers' ], Routes::GET) - ->route('/', [ HomeController::class, 'addUser' ], Routes::POST) - ->route('/', [ HomeController::class, 'updateUser' ], Routes::PATCH) - ->route('/', [ HomeController::class, 'replaceUser' ], Routes::PUT) - ->add('/test', [ HomeController::class, 'deleteUser' ], Routes::DELETE); -``` - -#### Chained routes with save at the end - -```php -$routes - ->prefix("/test") - ->middleware(['decode_token']) - ->route("/t0", function(Request $request){}) - ->get("/t1", function (){}) - ->post("/t2", function (){}) - ->put("/t3", function (){}) - ->patch("/t4", function (){}) - ->delete("/t5", function (){}) - ->save(); -``` - -#### Chained routes with multiple chains in one call - -```php -$routes - ->prefix("/test") - ->middleware([ 'decode_token' ]) - ->get("/t1", function () { }) // route would be: /test/t1 - ->get("/t2", function () { }) // route would be: /test/t2 - ->get("/t3", function () { }) // route would be: /test/t3 - ->save(false) // by passing the false argument here, we keep all the previous shared data from the chain (previous prefix(es) and middlewares) - ->prefix("/test2") - ->middleware([ "verify_token" ]) - ->get("/t4", function () { }) // route would be: /test/test2/t4 - ->get("/t5", function () { }) // route would be: /test/test2/t5 - ->get("/t6", function () { }) // route would be: /test/test2/t6 - ->save() // by not passing the false argument here, we are removing all shared data from the previous chains (previous prefix(es) and middlewares) - ->prefix("/test3") - ->middleware([ "verify_token" ]) - ->get("/t7", function () { }) // route would be: /test3/t7 - ->get("/t8", function () { }) // route would be: /test3/t8 - ->get("/t9", function () { }) // route would be: /test3/t9 - ->add(); //using save or add at the end makes the chaining stop and allows for other independent routes to be added -``` - -### Passing arguments to middleware methods - -When working with middlewares you can also pass them arguments if you need to - -```php -$routes - ->middleware([ - 'test_middleware', - 'has_roles' => 'admin,user', - [ Middleware::class, 'test_method' ], - [ Middleware::class, 'has_role', 'Admin', 'Moderator', [ 'User', 'Bot' ] ], - ]) - ->add('/test', function (Request $request) { - $request->send([ 'msg' => 'testing' ]); - }); -``` - -Every middleware function can also accept an argument of type `Gac\Routing\Request` at any position as long as it has -the proper type specified. - -### Dependency injection on route classes - -When using classes to handle your route callback, and those classes have some dependencies that need to be injected -through a constructor, you can specify them as an array of arguments to be injected or -let the library try to auto-inject classes. - -```php -$routes->add( - '/demo', - [ - HomeController::class, - 'dependency_injection_test', - [ new InjectedClass() ] - ], - Routes::GET -); -``` - -You can also use named arguments or mix and match them - -```php -$routes->add( - '/demo', - [ - HomeController::class, - 'dependency_injection_test', - [ "injected_var" => new InjectedClass(), new Middleware ] - ], - Routes::GET -); -``` - -Letting the library auto-inject classes into the constructor - -```php -$routes->add( - '/demo', - [ InjectController::class ], - Routes::GET -); -``` - -**NOTE** - -The library will always try to auto-inject classes (***will skip ones with null as default value***) if non are -provided, and you're using a class for callbacks. - -### Use `__invoke` instead for single method classes - -```php -$routes->add( - '/invoke', - [ HomeController::class ], - Routes::GET -); -``` - -You can also use `__invoke` with dependency injection as well: - -```php -$routes->add( - '/invoke', - [ - HomeController::class, - [ new InjectedClass() ] - ], - Routes::GET -); -``` - -For more examples look in the [sample folder](/sample) `index.php` file - -## Documentation - -Source code documentation can be found at [PHP Routing documentation](https://gigili.github.io/PHP-routing/) page - -## Features - -* [x] Static routes -* [x] Dynamic routes -* [x] Middlewares - * [x] Pass arguments to middlewares -* [x] Route prefixes -* [x] Method chaining -* [x] Dependency injection on classes - * [x] Manual injection - * [x] Auto-injection +# Routing library for PHP + +This library allows you to create static or dynamic routes. This library was inspired +by [PHP Slim framework](https://www.slimframework.com/) + +[![PHP Tests](https://github.com/gigili/PHP-routing/actions/workflows/php-pest-tests.yml/badge.svg)](https://github.com/gigili/PHP-routing/actions/workflows/php-pest-tests.yml) +[![License](https://poser.pugx.org/gac/routing/license)](https://packagist.org/packages/gac/routing) +[![Total Downloads](https://poser.pugx.org/gac/routing/downloads)](https://packagist.org/packages/gac/routing) + +## Install via composer + +```shell +composer require gac/routing +``` + +## Manual install + +Download the latest release from the [Releases page](https://github.com/gigili/PHP-routing/releases). + +Don't forget to add these `include_once` statements to your php files: + +```php +include_once "./Exceptions/CallbackNotFound.php"; +include_once "./Exceptions/RouteNotFoundException.php"; +include_once "./Request.php"; +include_once "./Routes.php"; +``` + +## Post install + +To use this library properly you will need to create a `.htaccess` file at the root of the project. + +Example of the `.htaccess` file would look like this: + +```apacheconf +RewriteEngine On + +RewriteBase / +RewriteCond %{REQUEST_FILENAME} !-f +RewriteCond %{REQUEST_FILENAME} !-d + +RewriteRule ^(.+)$ index.php [QSA,L] +``` + +### Note + +If you've named your main file differently, replace `index.php` in the `.htaccess` file with whatever your main +application file is. + +## Quick start + +Sample code to allow you to quickly start with your development. + +```php +use Gac\Routing\Exceptions\CallbackNotFound; +use Gac\Routing\Exceptions\RouteNotFoundException; +use Gac\Routing\Request;use Gac\Routing\Routes; + +include_once "vendor/autoload.php"; # IF YOU'RE USING composer + +$routes = new Routes(); +try { + $routes->add('/', function (Request $request) { + $request + ->status(200, "OK") + ->send(["message" => "Welcome"]); + }); + + $routes->route('/', function (Request $request) { + $request + ->status(201, "OK") + ->send(["message" => "Welcome"]); + }, [Routes::POST])->save(); + + $routes->route(); +} catch (RouteNotFoundException $ex) { + $routes->request->status(404, "Route not found")->send(["error" => ["message" => $ex->getMessage()]]); +} catch (CallbackNotFound $ex) { + $routes->request->status(404, "Callback method not found")->send(["error" => ["message" => $ex->getMessage()]]); +} catch (Exception $ex) { + $code = $ex->getCode() ?? 500; + $routes->request->status($code)->send(["error" => ["message" => $ex->getMessage()]]); +} +``` + +## Examples + +### Dynamic routes example + +```php +$routes->add('/test/{int:userID}-{username}/{float:amount}/{bool:valid}', function ( + Request $request, + int $userID, + string $username, + float $amount, + bool $valid +) { + echo 'Dynamic route content here'; +}); +``` + +### Chained routes + +When using chained methods either use `->save()` or `->add()` as the last method to indicate the end of a chain + +**NOTE** + +* `->save(true|false)` method can still be chained onto if needed + * Passing `false` (the default value is `true`) to the `->save()` method will preserve all the previous prefixes and middlewares in that chain +* `->add()` **CAN NOT** be chained onto and should be the last call in chain + +```php +$routes + ->prefix('/user') // all the routes added will have the /user prefix + ->middleware([ 'verify_token' ]) // all the routes added will have the verify_token middleware applied + ->route('/', [ HomeController::class, 'getUsers' ], Routes::GET) + ->route('/', [ HomeController::class, 'addUser' ], Routes::POST) + ->route('/', [ HomeController::class, 'updateUser' ], Routes::PATCH) + ->route('/', [ HomeController::class, 'replaceUser' ], Routes::PUT) + ->add('/test', [ HomeController::class, 'deleteUser' ], Routes::DELETE); +``` + +#### Chained routes with save at the end + +```php +$routes + ->prefix("/test") + ->middleware(['decode_token']) + ->route("/t0", function(Request $request){}) + ->get("/t1", function (){}) + ->post("/t2", function (){}) + ->put("/t3", function (){}) + ->patch("/t4", function (){}) + ->delete("/t5", function (){}) + ->save(); +``` + +#### Chained routes with multiple chains in one call + +```php +$routes + ->prefix("/test") + ->middleware([ 'decode_token' ]) + ->get("/t1", function () { }) // route would be: /test/t1 + ->get("/t2", function () { }) // route would be: /test/t2 + ->get("/t3", function () { }) // route would be: /test/t3 + ->save(false) // by passing the false argument here, we keep all the previous shared data from the chain (previous prefix(es) and middlewares) + ->prefix("/test2") + ->middleware([ "verify_token" ]) + ->get("/t4", function () { }) // route would be: /test/test2/t4 + ->get("/t5", function () { }) // route would be: /test/test2/t5 + ->get("/t6", function () { }) // route would be: /test/test2/t6 + ->save() // by not passing the false argument here, we are removing all shared data from the previous chains (previous prefix(es) and middlewares) + ->prefix("/test3") + ->middleware([ "verify_token" ]) + ->get("/t7", function () { }) // route would be: /test3/t7 + ->get("/t8", function () { }) // route would be: /test3/t8 + ->get("/t9", function () { }) // route would be: /test3/t9 + ->add(); //using save or add at the end makes the chaining stop and allows for other independent routes to be added +``` + +### Passing arguments to middleware methods + +When working with middlewares you can also pass them arguments if you need to + +```php +$routes + ->middleware([ + 'test_middleware', + 'has_roles' => 'admin,user', + [ Middleware::class, 'test_method' ], + [ Middleware::class, 'has_role', 'Admin', 'Moderator', [ 'User', 'Bot' ] ], + ]) + ->add('/test', function (Request $request) { + $request->send([ 'msg' => 'testing' ]); + }); +``` + +Every middleware function can also accept an argument of type `Gac\Routing\Request` at any position as long as it has +the proper type specified. + +### Dependency injection on route classes + +When using classes to handle your route callback, and those classes have some dependencies that need to be injected +through a constructor, you can specify them as an array of arguments to be injected or +let the library try to auto-inject classes. + +```php +$routes->add( + '/demo', + [ + HomeController::class, + 'dependency_injection_test', + [ new InjectedClass() ] + ], + Routes::GET +); +``` + +You can also use named arguments or mix and match them + +```php +$routes->add( + '/demo', + [ + HomeController::class, + 'dependency_injection_test', + [ "injected_var" => new InjectedClass(), new Middleware ] + ], + Routes::GET +); +``` + +Letting the library auto-inject classes into the constructor + +```php +$routes->add( + '/demo', + [ InjectController::class ], + Routes::GET +); +``` + +**NOTE** + +The library will always try to auto-inject classes (***will skip ones with null as default value***) if non are +provided, and you're using a class for callbacks. + +### Use `__invoke` instead for single method classes + +```php +$routes->add( + '/invoke', + [ HomeController::class ], + Routes::GET +); +``` + +You can also use `__invoke` with dependency injection as well: + +```php +$routes->add( + '/invoke', + [ + HomeController::class, + [ new InjectedClass() ] + ], + Routes::GET +); +``` + +For more examples look in the [sample folder](/sample) `index.php` file + +## Documentation + +Source code documentation can be found at [PHP Routing documentation](https://gigili.github.io/PHP-routing/) page + +## Features + +* [x] Static routes +* [x] Dynamic routes +* [x] Middlewares + * [x] Pass arguments to middlewares +* [x] Route prefixes +* [x] Method chaining +* [x] Dependency injection on classes + * [x] Manual injection + * [x] Auto-injection diff --git a/composer.json b/composer.json index 01000f9..1da812a 100644 --- a/composer.json +++ b/composer.json @@ -1,64 +1,64 @@ -{ - "name": "gac/routing", - "type": "library", - "description": "Custom routing library especially useful for fast API development", - "homepage": "https://github.com/gigili/PHP-routing", - "license": "GPL-3.0-only", - "keywords": [ - "route", - "routing", - "libray", - "middleware", - "api" - ], - "authors": [ - { - "name": "Igor Ilić", - "email": "github@igorilic.net", - "role": "Developer" - } - ], - "support": { - "email": "github@igorilic.net", - "issues": "https://github.com/gigili/PHP-routing" - }, - "funding": [ - { - "type": "paypal", - "url": "https://paypal.me/igorili" - }, - { - "type": "ko-fi", - "url": "https://ko-fi.com/igorilic" - } - ], - "require": { - "php": ">=8.0", - "ext-json": "*", - "ext-mbstring": "*" - }, - "autoload": { - "psr-4": { - "Gac\\Routing\\": "./src", - "Gac\\Routing\\Exceptions\\" : "./src/Exceptions" - } - }, - "require-dev" : { - "pestphp/pest" : "^1.21" - }, - "config" : { - "sort-packages" : true, - "allow-plugins" : { - "pestphp/pest-plugin" : true - }, - "optimize-autoloader" : true, - "preferred-install" : "dist" - }, - "extra" : { - "branch-alias" : { - "dev-master" : "3.x-dev" - } - }, - "prefer-stable" : true, - "minimum-stability" : "dev" +{ + "name": "gac/routing", + "type": "library", + "description": "Custom routing library especially useful for fast API development", + "homepage": "https://github.com/gigili/PHP-routing", + "license": "GPL-3.0-only", + "keywords": [ + "route", + "routing", + "libray", + "middleware", + "api" + ], + "authors": [ + { + "name": "Igor Ilić", + "email": "github@igorilic.net", + "role": "Developer" + } + ], + "support": { + "email": "github@igorilic.net", + "issues": "https://github.com/gigili/PHP-routing" + }, + "funding": [ + { + "type": "paypal", + "url": "https://paypal.me/igorili" + }, + { + "type": "ko-fi", + "url": "https://ko-fi.com/igorilic" + } + ], + "require": { + "php": ">=8.0", + "ext-json": "*", + "ext-mbstring": "*" + }, + "autoload": { + "psr-4": { + "Gac\\Routing\\": "./src", + "Gac\\Routing\\Exceptions\\" : "./src/Exceptions" + } + }, + "require-dev" : { + "pestphp/pest" : "^1.21" + }, + "config" : { + "sort-packages" : true, + "allow-plugins" : { + "pestphp/pest-plugin" : true + }, + "optimize-autoloader" : true, + "preferred-install" : "dist" + }, + "extra" : { + "branch-alias" : { + "dev-master" : "3.x-dev" + } + }, + "prefer-stable" : true, + "minimum-stability" : "dev" } \ No newline at end of file diff --git a/composer.lock b/composer.lock index 308c649..736f64d 100644 --- a/composer.lock +++ b/composer.lock @@ -1,2859 +1,2859 @@ -{ - "_readme": [ - "This file locks the dependencies of your project to a known state", - "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", - "This file is @generated automatically" - ], - "content-hash": "dd66f76a8b680d6fe1cb8729ac66d299", - "packages": [], - "packages-dev": [ - { - "name": "doctrine/instantiator", - "version": "1.4.1", - "source": { - "type": "git", - "url": "https://github.com/doctrine/instantiator.git", - "reference": "10dcfce151b967d20fde1b34ae6640712c3891bc" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/doctrine/instantiator/zipball/10dcfce151b967d20fde1b34ae6640712c3891bc", - "reference": "10dcfce151b967d20fde1b34ae6640712c3891bc", - "shasum": "" - }, - "require": { - "php": "^7.1 || ^8.0" - }, - "require-dev": { - "doctrine/coding-standard": "^9", - "ext-pdo": "*", - "ext-phar": "*", - "phpbench/phpbench": "^0.16 || ^1", - "phpstan/phpstan": "^1.4", - "phpstan/phpstan-phpunit": "^1", - "phpunit/phpunit": "^7.5 || ^8.5 || ^9.5", - "vimeo/psalm": "^4.22" - }, - "type": "library", - "autoload": { - "psr-4": { - "Doctrine\\Instantiator\\": "src/Doctrine/Instantiator/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Marco Pivetta", - "email": "ocramius@gmail.com", - "homepage": "https://ocramius.github.io/" - } - ], - "description": "A small, lightweight utility to instantiate objects in PHP without invoking their constructors", - "homepage": "https://www.doctrine-project.org/projects/instantiator.html", - "keywords": [ - "constructor", - "instantiate" - ], - "support": { - "issues": "https://github.com/doctrine/instantiator/issues", - "source": "https://github.com/doctrine/instantiator/tree/1.4.1" - }, - "funding": [ - { - "url": "https://www.doctrine-project.org/sponsorship.html", - "type": "custom" - }, - { - "url": "https://www.patreon.com/phpdoctrine", - "type": "patreon" - }, - { - "url": "https://tidelift.com/funding/github/packagist/doctrine%2Finstantiator", - "type": "tidelift" - } - ], - "time": "2022-03-03T08:28:38+00:00" - }, - { - "name": "filp/whoops", - "version": "2.14.5", - "source": { - "type": "git", - "url": "https://github.com/filp/whoops.git", - "reference": "a63e5e8f26ebbebf8ed3c5c691637325512eb0dc" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/filp/whoops/zipball/a63e5e8f26ebbebf8ed3c5c691637325512eb0dc", - "reference": "a63e5e8f26ebbebf8ed3c5c691637325512eb0dc", - "shasum": "" - }, - "require": { - "php": "^5.5.9 || ^7.0 || ^8.0", - "psr/log": "^1.0.1 || ^2.0 || ^3.0" - }, - "require-dev": { - "mockery/mockery": "^0.9 || ^1.0", - "phpunit/phpunit": "^4.8.36 || ^5.7.27 || ^6.5.14 || ^7.5.20 || ^8.5.8 || ^9.3.3", - "symfony/var-dumper": "^2.6 || ^3.0 || ^4.0 || ^5.0" - }, - "suggest": { - "symfony/var-dumper": "Pretty print complex values better with var-dumper available", - "whoops/soap": "Formats errors as SOAP responses" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.7-dev" - } - }, - "autoload": { - "psr-4": { - "Whoops\\": "src/Whoops/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Filipe Dobreira", - "homepage": "https://github.com/filp", - "role": "Developer" - } - ], - "description": "php error handling for cool kids", - "homepage": "https://filp.github.io/whoops/", - "keywords": [ - "error", - "exception", - "handling", - "library", - "throwable", - "whoops" - ], - "support": { - "issues": "https://github.com/filp/whoops/issues", - "source": "https://github.com/filp/whoops/tree/2.14.5" - }, - "funding": [ - { - "url": "https://github.com/denis-sokolov", - "type": "github" - } - ], - "time": "2022-01-07T12:00:00+00:00" - }, - { - "name": "myclabs/deep-copy", - "version": "1.11.0", - "source": { - "type": "git", - "url": "https://github.com/myclabs/DeepCopy.git", - "reference": "14daed4296fae74d9e3201d2c4925d1acb7aa614" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/14daed4296fae74d9e3201d2c4925d1acb7aa614", - "reference": "14daed4296fae74d9e3201d2c4925d1acb7aa614", - "shasum": "" - }, - "require": { - "php": "^7.1 || ^8.0" - }, - "conflict": { - "doctrine/collections": "<1.6.8", - "doctrine/common": "<2.13.3 || >=3,<3.2.2" - }, - "require-dev": { - "doctrine/collections": "^1.6.8", - "doctrine/common": "^2.13.3 || ^3.2.2", - "phpunit/phpunit": "^7.5.20 || ^8.5.23 || ^9.5.13" - }, - "type": "library", - "autoload": { - "files": [ - "src/DeepCopy/deep_copy.php" - ], - "psr-4": { - "DeepCopy\\": "src/DeepCopy/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "description": "Create deep copies (clones) of your objects", - "keywords": [ - "clone", - "copy", - "duplicate", - "object", - "object graph" - ], - "support": { - "issues": "https://github.com/myclabs/DeepCopy/issues", - "source": "https://github.com/myclabs/DeepCopy/tree/1.11.0" - }, - "funding": [ - { - "url": "https://tidelift.com/funding/github/packagist/myclabs/deep-copy", - "type": "tidelift" - } - ], - "time": "2022-03-03T13:19:32+00:00" - }, - { - "name" : "nikic/php-parser", - "version" : "v4.15.1", - "source" : { - "type" : "git", - "url" : "https://github.com/nikic/PHP-Parser.git", - "reference" : "0ef6c55a3f47f89d7a374e6f835197a0b5fcf900" - }, - "dist" : { - "type" : "zip", - "url" : "https://api.github.com/repos/nikic/PHP-Parser/zipball/0ef6c55a3f47f89d7a374e6f835197a0b5fcf900", - "reference" : "0ef6c55a3f47f89d7a374e6f835197a0b5fcf900", - "shasum" : "" - }, - "require" : { - "ext-tokenizer" : "*", - "php" : ">=7.0" - }, - "require-dev" : { - "ircmaxell/php-yacc" : "^0.0.7", - "phpunit/phpunit" : "^6.5 || ^7.0 || ^8.0 || ^9.0" - }, - "bin" : [ - "bin/php-parse" - ], - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "4.9-dev" - } - }, - "autoload": { - "psr-4": { - "PhpParser\\": "lib/PhpParser" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Nikita Popov" - } - ], - "description": "A PHP parser written in PHP", - "keywords" : [ - "parser", - "php" - ], - "support" : { - "issues" : "https://github.com/nikic/PHP-Parser/issues", - "source" : "https://github.com/nikic/PHP-Parser/tree/v4.15.1" - }, - "time" : "2022-09-04T07:30:47+00:00" - }, - { - "name" : "nunomaduro/collision", - "version" : "v6.3.0", - "source" : { - "type" : "git", - "url" : "https://github.com/nunomaduro/collision.git", - "reference" : "17f600e2e8872856ff2846243efb74ad4b6da531" - }, - "dist" : { - "type" : "zip", - "url" : "https://api.github.com/repos/nunomaduro/collision/zipball/17f600e2e8872856ff2846243efb74ad4b6da531", - "reference" : "17f600e2e8872856ff2846243efb74ad4b6da531", - "shasum" : "" - }, - "require" : { - "filp/whoops" : "^2.14.5", - "php" : "^8.0.0", - "symfony/console" : "^6.0.2" - }, - "require-dev" : { - "brianium/paratest" : "^6.4.1", - "laravel/framework" : "^9.26.1", - "laravel/pint" : "^1.1.1", - "nunomaduro/larastan" : "^1.0.3", - "nunomaduro/mock-final-classes" : "^1.1.0", - "orchestra/testbench" : "^7.7", - "phpunit/phpunit" : "^9.5.23", - "spatie/ignition" : "^1.4.1" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-develop": "6.x-dev" - }, - "laravel": { - "providers": [ - "NunoMaduro\\Collision\\Adapters\\Laravel\\CollisionServiceProvider" - ] - } - }, - "autoload": { - "psr-4": { - "NunoMaduro\\Collision\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Nuno Maduro", - "email": "enunomaduro@gmail.com" - } - ], - "description": "Cli error handling for console/command-line PHP applications.", - "keywords": [ - "artisan", - "cli", - "command-line", - "console", - "error", - "handling", - "laravel", - "laravel-zero", - "php", - "symfony" - ], - "support": { - "issues": "https://github.com/nunomaduro/collision/issues", - "source": "https://github.com/nunomaduro/collision" - }, - "funding": [ - { - "url": "https://www.paypal.com/paypalme/enunomaduro", - "type": "custom" - }, - { - "url" : "https://github.com/nunomaduro", - "type" : "github" - }, - { - "url" : "https://www.patreon.com/nunomaduro", - "type" : "patreon" - } - ], - "time" : "2022-08-29T09:11:20+00:00" - }, - { - "name" : "pestphp/pest", - "version" : "v1.22.1", - "source" : { - "type" : "git", - "url" : "https://github.com/pestphp/pest.git", - "reference" : "af6240b4eed8b049ac43c91184141ee337305df7" - }, - "dist" : { - "type" : "zip", - "url" : "https://api.github.com/repos/pestphp/pest/zipball/af6240b4eed8b049ac43c91184141ee337305df7", - "reference" : "af6240b4eed8b049ac43c91184141ee337305df7", - "shasum" : "" - }, - "require" : { - "nunomaduro/collision" : "^5.10.0|^6.0", - "pestphp/pest-plugin" : "^1.0.0", - "php" : "^7.3 || ^8.0", - "phpunit/phpunit" : "^9.5.5" - }, - "require-dev" : { - "illuminate/console" : "^8.47.0", - "illuminate/support" : "^8.47.0", - "laravel/dusk" : "^6.15.0", - "pestphp/pest-dev-tools" : "dev-master", - "pestphp/pest-plugin-parallel" : "^1.0" - }, - "bin" : [ - "bin/pest" - ], - "type" : "library", - "extra" : { - "branch-alias" : { - "dev-1.x" : "1.x-dev" - }, - "pest": { - "plugins": [ - "Pest\\Plugins\\Coverage", - "Pest\\Plugins\\Init", - "Pest\\Plugins\\Version", - "Pest\\Plugins\\Environment" - ] - }, - "laravel": { - "providers": [ - "Pest\\Laravel\\PestServiceProvider" - ] - } - }, - "autoload": { - "files": [ - "src/Functions.php", - "src/Pest.php" - ], - "psr-4": { - "Pest\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Nuno Maduro", - "email": "enunomaduro@gmail.com" - } - ], - "description": "An elegant PHP Testing Framework.", - "keywords": [ - "framework", - "pest", - "php", - "test", - "testing", - "unit" - ], - "support": { - "issues": "https://github.com/pestphp/pest/issues", - "source" : "https://github.com/pestphp/pest/tree/v1.22.1" - }, - "funding": [ - { - "url": "https://www.paypal.com/paypalme/enunomaduro", - "type": "custom" - }, - { - "url": "https://github.com/lukeraymonddowning", - "type": "github" - }, - { - "url": "https://github.com/nunomaduro", - "type": "github" - }, - { - "url": "https://github.com/octoper", - "type": "github" - }, - { - "url": "https://github.com/olivernybroe", - "type": "github" - }, - { - "url": "https://github.com/owenvoke", - "type": "github" - }, - { - "url": "https://www.patreon.com/nunomaduro", - "type": "patreon" - } - ], - "time" : "2022-08-29T10:42:13+00:00" - }, - { - "name": "pestphp/pest-plugin", - "version": "v1.0.0", - "source": { - "type": "git", - "url": "https://github.com/pestphp/pest-plugin.git", - "reference": "fc8519de148699fe612d9c669be60554cd2db4fa" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/pestphp/pest-plugin/zipball/fc8519de148699fe612d9c669be60554cd2db4fa", - "reference": "fc8519de148699fe612d9c669be60554cd2db4fa", - "shasum": "" - }, - "require": { - "composer-plugin-api": "^1.1 || ^2.0", - "php": "^7.3 || ^8.0" - }, - "conflict": { - "pestphp/pest": "<1.0" - }, - "require-dev": { - "composer/composer": "^1.10.19", - "pestphp/pest": "^1.0", - "pestphp/pest-dev-tools": "dev-master" - }, - "type": "composer-plugin", - "extra": { - "branch-alias": { - "dev-master": "1.x-dev" - }, - "class": "Pest\\Plugin\\Manager" - }, - "autoload": { - "psr-4": { - "Pest\\Plugin\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "description": "The Pest plugin manager", - "keywords": [ - "framework", - "manager", - "pest", - "php", - "plugin", - "test", - "testing", - "unit" - ], - "support": { - "source": "https://github.com/pestphp/pest-plugin/tree/v1.0.0" - }, - "funding": [ - { - "url": "https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=66BYDWAT92N6L", - "type": "custom" - }, - { - "url": "https://github.com/nunomaduro", - "type": "github" - }, - { - "url": "https://www.patreon.com/nunomaduro", - "type": "patreon" - } - ], - "time": "2021-01-03T15:53:42+00:00" - }, - { - "name": "phar-io/manifest", - "version": "2.0.3", - "source": { - "type": "git", - "url": "https://github.com/phar-io/manifest.git", - "reference": "97803eca37d319dfa7826cc2437fc020857acb53" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/phar-io/manifest/zipball/97803eca37d319dfa7826cc2437fc020857acb53", - "reference": "97803eca37d319dfa7826cc2437fc020857acb53", - "shasum": "" - }, - "require": { - "ext-dom": "*", - "ext-phar": "*", - "ext-xmlwriter": "*", - "phar-io/version": "^3.0.1", - "php": "^7.2 || ^8.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.0.x-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Arne Blankerts", - "email": "arne@blankerts.de", - "role": "Developer" - }, - { - "name": "Sebastian Heuer", - "email": "sebastian@phpeople.de", - "role": "Developer" - }, - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "Developer" - } - ], - "description": "Component for reading phar.io manifest information from a PHP Archive (PHAR)", - "support": { - "issues": "https://github.com/phar-io/manifest/issues", - "source": "https://github.com/phar-io/manifest/tree/2.0.3" - }, - "time": "2021-07-20T11:28:43+00:00" - }, - { - "name": "phar-io/version", - "version": "3.2.1", - "source": { - "type": "git", - "url": "https://github.com/phar-io/version.git", - "reference": "4f7fd7836c6f332bb2933569e566a0d6c4cbed74" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/phar-io/version/zipball/4f7fd7836c6f332bb2933569e566a0d6c4cbed74", - "reference": "4f7fd7836c6f332bb2933569e566a0d6c4cbed74", - "shasum": "" - }, - "require": { - "php": "^7.2 || ^8.0" - }, - "type": "library", - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Arne Blankerts", - "email": "arne@blankerts.de", - "role": "Developer" - }, - { - "name": "Sebastian Heuer", - "email": "sebastian@phpeople.de", - "role": "Developer" - }, - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role" : "Developer" - } - ], - "description" : "Library for handling version information and constraints", - "support" : { - "issues" : "https://github.com/phar-io/version/issues", - "source" : "https://github.com/phar-io/version/tree/3.2.1" - }, - "time" : "2022-02-21T01:04:05+00:00" - }, - { - "name" : "phpunit/php-code-coverage", - "version" : "9.2.17", - "source" : { - "type" : "git", - "url" : "https://github.com/sebastianbergmann/php-code-coverage.git", - "reference" : "aa94dc41e8661fe90c7316849907cba3007b10d8" - }, - "dist" : { - "type" : "zip", - "url" : "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/aa94dc41e8661fe90c7316849907cba3007b10d8", - "reference" : "aa94dc41e8661fe90c7316849907cba3007b10d8", - "shasum" : "" - }, - "require" : { - "ext-dom" : "*", - "ext-libxml" : "*", - "ext-xmlwriter" : "*", - "nikic/php-parser" : "^4.14", - "php" : ">=7.3", - "phpunit/php-file-iterator" : "^3.0.3", - "phpunit/php-text-template" : "^2.0.2", - "sebastian/code-unit-reverse-lookup" : "^2.0.2", - "sebastian/complexity" : "^2.0", - "sebastian/environment" : "^5.1.2", - "sebastian/lines-of-code" : "^1.0.3", - "sebastian/version" : "^3.0.1", - "theseer/tokenizer" : "^1.2.0" - }, - "require-dev": { - "phpunit/phpunit": "^9.3" - }, - "suggest": { - "ext-pcov": "*", - "ext-xdebug": "*" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "9.2-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "lead" - } - ], - "description": "Library that provides collection, processing, and rendering functionality for PHP code coverage information.", - "homepage": "https://github.com/sebastianbergmann/php-code-coverage", - "keywords": [ - "coverage", - "testing", - "xunit" - ], - "support": { - "issues": "https://github.com/sebastianbergmann/php-code-coverage/issues", - "source" : "https://github.com/sebastianbergmann/php-code-coverage/tree/9.2.17" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time" : "2022-08-30T12:24:04+00:00" - }, - { - "name": "phpunit/php-file-iterator", - "version": "3.0.6", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/php-file-iterator.git", - "reference": "cf1c2e7c203ac650e352f4cc675a7021e7d1b3cf" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/cf1c2e7c203ac650e352f4cc675a7021e7d1b3cf", - "reference": "cf1c2e7c203ac650e352f4cc675a7021e7d1b3cf", - "shasum": "" - }, - "require": { - "php": ">=7.3" - }, - "require-dev": { - "phpunit/phpunit": "^9.3" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "3.0-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "lead" - } - ], - "description": "FilterIterator implementation that filters files based on a list of suffixes.", - "homepage": "https://github.com/sebastianbergmann/php-file-iterator/", - "keywords": [ - "filesystem", - "iterator" - ], - "support": { - "issues": "https://github.com/sebastianbergmann/php-file-iterator/issues", - "source": "https://github.com/sebastianbergmann/php-file-iterator/tree/3.0.6" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2021-12-02T12:48:52+00:00" - }, - { - "name": "phpunit/php-invoker", - "version": "3.1.1", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/php-invoker.git", - "reference": "5a10147d0aaf65b58940a0b72f71c9ac0423cc67" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-invoker/zipball/5a10147d0aaf65b58940a0b72f71c9ac0423cc67", - "reference": "5a10147d0aaf65b58940a0b72f71c9ac0423cc67", - "shasum": "" - }, - "require": { - "php": ">=7.3" - }, - "require-dev": { - "ext-pcntl": "*", - "phpunit/phpunit": "^9.3" - }, - "suggest": { - "ext-pcntl": "*" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "3.1-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "lead" - } - ], - "description": "Invoke callables with a timeout", - "homepage": "https://github.com/sebastianbergmann/php-invoker/", - "keywords": [ - "process" - ], - "support": { - "issues": "https://github.com/sebastianbergmann/php-invoker/issues", - "source": "https://github.com/sebastianbergmann/php-invoker/tree/3.1.1" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2020-09-28T05:58:55+00:00" - }, - { - "name": "phpunit/php-text-template", - "version": "2.0.4", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/php-text-template.git", - "reference": "5da5f67fc95621df9ff4c4e5a84d6a8a2acf7c28" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-text-template/zipball/5da5f67fc95621df9ff4c4e5a84d6a8a2acf7c28", - "reference": "5da5f67fc95621df9ff4c4e5a84d6a8a2acf7c28", - "shasum": "" - }, - "require": { - "php": ">=7.3" - }, - "require-dev": { - "phpunit/phpunit": "^9.3" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.0-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "lead" - } - ], - "description": "Simple template engine.", - "homepage": "https://github.com/sebastianbergmann/php-text-template/", - "keywords": [ - "template" - ], - "support": { - "issues": "https://github.com/sebastianbergmann/php-text-template/issues", - "source": "https://github.com/sebastianbergmann/php-text-template/tree/2.0.4" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2020-10-26T05:33:50+00:00" - }, - { - "name": "phpunit/php-timer", - "version": "5.0.3", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/php-timer.git", - "reference": "5a63ce20ed1b5bf577850e2c4e87f4aa902afbd2" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/5a63ce20ed1b5bf577850e2c4e87f4aa902afbd2", - "reference": "5a63ce20ed1b5bf577850e2c4e87f4aa902afbd2", - "shasum": "" - }, - "require": { - "php": ">=7.3" - }, - "require-dev": { - "phpunit/phpunit": "^9.3" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "5.0-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "lead" - } - ], - "description": "Utility class for timing", - "homepage": "https://github.com/sebastianbergmann/php-timer/", - "keywords": [ - "timer" - ], - "support": { - "issues": "https://github.com/sebastianbergmann/php-timer/issues", - "source" : "https://github.com/sebastianbergmann/php-timer/tree/5.0.3" - }, - "funding" : [ - { - "url" : "https://github.com/sebastianbergmann", - "type" : "github" - } - ], - "time" : "2020-10-26T13:16:10+00:00" - }, - { - "name" : "phpunit/phpunit", - "version" : "9.5.24", - "source" : { - "type" : "git", - "url" : "https://github.com/sebastianbergmann/phpunit.git", - "reference" : "d0aa6097bef9fd42458a9b3c49da32c6ce6129c5" - }, - "dist" : { - "type" : "zip", - "url" : "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/d0aa6097bef9fd42458a9b3c49da32c6ce6129c5", - "reference" : "d0aa6097bef9fd42458a9b3c49da32c6ce6129c5", - "shasum" : "" - }, - "require" : { - "doctrine/instantiator" : "^1.3.1", - "ext-dom" : "*", - "ext-json" : "*", - "ext-libxml" : "*", - "ext-mbstring" : "*", - "ext-xml" : "*", - "ext-xmlwriter" : "*", - "myclabs/deep-copy" : "^1.10.1", - "phar-io/manifest" : "^2.0.3", - "phar-io/version" : "^3.0.2", - "php" : ">=7.3", - "phpunit/php-code-coverage" : "^9.2.13", - "phpunit/php-file-iterator" : "^3.0.5", - "phpunit/php-invoker" : "^3.1.1", - "phpunit/php-text-template" : "^2.0.3", - "phpunit/php-timer" : "^5.0.2", - "sebastian/cli-parser" : "^1.0.1", - "sebastian/code-unit" : "^1.0.6", - "sebastian/comparator" : "^4.0.5", - "sebastian/diff" : "^4.0.3", - "sebastian/environment" : "^5.1.3", - "sebastian/exporter" : "^4.0.3", - "sebastian/global-state" : "^5.0.1", - "sebastian/object-enumerator" : "^4.0.3", - "sebastian/resource-operations" : "^3.0.3", - "sebastian/type" : "^3.1", - "sebastian/version" : "^3.0.2" - }, - "suggest": { - "ext-soap": "*", - "ext-xdebug": "*" - }, - "bin": [ - "phpunit" - ], - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "9.5-dev" - } - }, - "autoload": { - "files": [ - "src/Framework/Assert/Functions.php" - ], - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "lead" - } - ], - "description": "The PHP Unit Testing framework.", - "homepage": "https://phpunit.de/", - "keywords": [ - "phpunit", - "testing", - "xunit" - ], - "support": { - "issues": "https://github.com/sebastianbergmann/phpunit/issues", - "source" : "https://github.com/sebastianbergmann/phpunit/tree/9.5.24" - }, - "funding": [ - { - "url": "https://phpunit.de/sponsors.html", - "type": "custom" - }, - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time" : "2022-08-30T07:42:16+00:00" - }, - { - "name": "psr/container", - "version": "2.0.2", - "source": { - "type": "git", - "url": "https://github.com/php-fig/container.git", - "reference": "c71ecc56dfe541dbd90c5360474fbc405f8d5963" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/php-fig/container/zipball/c71ecc56dfe541dbd90c5360474fbc405f8d5963", - "reference": "c71ecc56dfe541dbd90c5360474fbc405f8d5963", - "shasum": "" - }, - "require": { - "php": ">=7.4.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.0.x-dev" - } - }, - "autoload": { - "psr-4": { - "Psr\\Container\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "PHP-FIG", - "homepage": "https://www.php-fig.org/" - } - ], - "description": "Common Container Interface (PHP FIG PSR-11)", - "homepage": "https://github.com/php-fig/container", - "keywords": [ - "PSR-11", - "container", - "container-interface", - "container-interop", - "psr" - ], - "support": { - "issues": "https://github.com/php-fig/container/issues", - "source": "https://github.com/php-fig/container/tree/2.0.2" - }, - "time": "2021-11-05T16:47:00+00:00" - }, - { - "name": "psr/log", - "version": "3.0.0", - "source": { - "type": "git", - "url": "https://github.com/php-fig/log.git", - "reference": "fe5ea303b0887d5caefd3d431c3e61ad47037001" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/php-fig/log/zipball/fe5ea303b0887d5caefd3d431c3e61ad47037001", - "reference": "fe5ea303b0887d5caefd3d431c3e61ad47037001", - "shasum": "" - }, - "require": { - "php": ">=8.0.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "3.x-dev" - } - }, - "autoload": { - "psr-4": { - "Psr\\Log\\": "src" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "PHP-FIG", - "homepage": "https://www.php-fig.org/" - } - ], - "description": "Common interface for logging libraries", - "homepage": "https://github.com/php-fig/log", - "keywords": [ - "log", - "psr", - "psr-3" - ], - "support": { - "source": "https://github.com/php-fig/log/tree/3.0.0" - }, - "time": "2021-07-14T16:46:02+00:00" - }, - { - "name": "sebastian/cli-parser", - "version": "1.0.1", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/cli-parser.git", - "reference": "442e7c7e687e42adc03470c7b668bc4b2402c0b2" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/cli-parser/zipball/442e7c7e687e42adc03470c7b668bc4b2402c0b2", - "reference": "442e7c7e687e42adc03470c7b668bc4b2402c0b2", - "shasum": "" - }, - "require": { - "php": ">=7.3" - }, - "require-dev": { - "phpunit/phpunit": "^9.3" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.0-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "lead" - } - ], - "description": "Library for parsing CLI options", - "homepage": "https://github.com/sebastianbergmann/cli-parser", - "support": { - "issues": "https://github.com/sebastianbergmann/cli-parser/issues", - "source": "https://github.com/sebastianbergmann/cli-parser/tree/1.0.1" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2020-09-28T06:08:49+00:00" - }, - { - "name": "sebastian/code-unit", - "version": "1.0.8", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/code-unit.git", - "reference": "1fc9f64c0927627ef78ba436c9b17d967e68e120" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/code-unit/zipball/1fc9f64c0927627ef78ba436c9b17d967e68e120", - "reference": "1fc9f64c0927627ef78ba436c9b17d967e68e120", - "shasum": "" - }, - "require": { - "php": ">=7.3" - }, - "require-dev": { - "phpunit/phpunit": "^9.3" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.0-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "lead" - } - ], - "description": "Collection of value objects that represent the PHP code units", - "homepage": "https://github.com/sebastianbergmann/code-unit", - "support": { - "issues": "https://github.com/sebastianbergmann/code-unit/issues", - "source": "https://github.com/sebastianbergmann/code-unit/tree/1.0.8" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2020-10-26T13:08:54+00:00" - }, - { - "name": "sebastian/code-unit-reverse-lookup", - "version": "2.0.3", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/code-unit-reverse-lookup.git", - "reference": "ac91f01ccec49fb77bdc6fd1e548bc70f7faa3e5" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/code-unit-reverse-lookup/zipball/ac91f01ccec49fb77bdc6fd1e548bc70f7faa3e5", - "reference": "ac91f01ccec49fb77bdc6fd1e548bc70f7faa3e5", - "shasum": "" - }, - "require": { - "php": ">=7.3" - }, - "require-dev": { - "phpunit/phpunit": "^9.3" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.0-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" - } - ], - "description": "Looks up which function or method a line of code belongs to", - "homepage": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/", - "support": { - "issues": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/issues", - "source" : "https://github.com/sebastianbergmann/code-unit-reverse-lookup/tree/2.0.3" - }, - "funding" : [ - { - "url" : "https://github.com/sebastianbergmann", - "type" : "github" - } - ], - "time" : "2020-09-28T05:30:19+00:00" - }, - { - "name" : "sebastian/comparator", - "version" : "4.0.8", - "source" : { - "type" : "git", - "url" : "https://github.com/sebastianbergmann/comparator.git", - "reference" : "fa0f136dd2334583309d32b62544682ee972b51a" - }, - "dist" : { - "type" : "zip", - "url" : "https://api.github.com/repos/sebastianbergmann/comparator/zipball/fa0f136dd2334583309d32b62544682ee972b51a", - "reference" : "fa0f136dd2334583309d32b62544682ee972b51a", - "shasum" : "" - }, - "require" : { - "php" : ">=7.3", - "sebastian/diff" : "^4.0", - "sebastian/exporter" : "^4.0" - }, - "require-dev" : { - "phpunit/phpunit" : "^9.3" - }, - "type" : "library", - "extra" : { - "branch-alias": { - "dev-master": "4.0-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" - }, - { - "name": "Jeff Welch", - "email": "whatthejeff@gmail.com" - }, - { - "name": "Volker Dusch", - "email": "github@wallbash.com" - }, - { - "name": "Bernhard Schussek", - "email": "bschussek@2bepublished.at" - } - ], - "description": "Provides the functionality to compare PHP values for equality", - "homepage": "https://github.com/sebastianbergmann/comparator", - "keywords": [ - "comparator", - "compare", - "equality" - ], - "support": { - "issues": "https://github.com/sebastianbergmann/comparator/issues", - "source" : "https://github.com/sebastianbergmann/comparator/tree/4.0.8" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time" : "2022-09-14T12:41:17+00:00" - }, - { - "name": "sebastian/complexity", - "version": "2.0.2", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/complexity.git", - "reference": "739b35e53379900cc9ac327b2147867b8b6efd88" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/complexity/zipball/739b35e53379900cc9ac327b2147867b8b6efd88", - "reference": "739b35e53379900cc9ac327b2147867b8b6efd88", - "shasum": "" - }, - "require": { - "nikic/php-parser": "^4.7", - "php": ">=7.3" - }, - "require-dev": { - "phpunit/phpunit": "^9.3" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.0-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "lead" - } - ], - "description": "Library for calculating the complexity of PHP code units", - "homepage": "https://github.com/sebastianbergmann/complexity", - "support": { - "issues": "https://github.com/sebastianbergmann/complexity/issues", - "source": "https://github.com/sebastianbergmann/complexity/tree/2.0.2" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2020-10-26T15:52:27+00:00" - }, - { - "name": "sebastian/diff", - "version": "4.0.4", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/diff.git", - "reference": "3461e3fccc7cfdfc2720be910d3bd73c69be590d" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/3461e3fccc7cfdfc2720be910d3bd73c69be590d", - "reference": "3461e3fccc7cfdfc2720be910d3bd73c69be590d", - "shasum": "" - }, - "require": { - "php": ">=7.3" - }, - "require-dev": { - "phpunit/phpunit": "^9.3", - "symfony/process": "^4.2 || ^5" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "4.0-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" - }, - { - "name": "Kore Nordmann", - "email": "mail@kore-nordmann.de" - } - ], - "description": "Diff implementation", - "homepage": "https://github.com/sebastianbergmann/diff", - "keywords": [ - "diff", - "udiff", - "unidiff", - "unified diff" - ], - "support": { - "issues": "https://github.com/sebastianbergmann/diff/issues", - "source": "https://github.com/sebastianbergmann/diff/tree/4.0.4" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2020-10-26T13:10:38+00:00" - }, - { - "name": "sebastian/environment", - "version": "5.1.4", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/environment.git", - "reference": "1b5dff7bb151a4db11d49d90e5408e4e938270f7" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/1b5dff7bb151a4db11d49d90e5408e4e938270f7", - "reference": "1b5dff7bb151a4db11d49d90e5408e4e938270f7", - "shasum": "" - }, - "require": { - "php": ">=7.3" - }, - "require-dev": { - "phpunit/phpunit": "^9.3" - }, - "suggest": { - "ext-posix": "*" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "5.1-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" - } - ], - "description": "Provides functionality to handle HHVM/PHP environments", - "homepage": "http://www.github.com/sebastianbergmann/environment", - "keywords": [ - "Xdebug", - "environment", - "hhvm" - ], - "support": { - "issues": "https://github.com/sebastianbergmann/environment/issues", - "source" : "https://github.com/sebastianbergmann/environment/tree/5.1.4" - }, - "funding" : [ - { - "url" : "https://github.com/sebastianbergmann", - "type" : "github" - } - ], - "time" : "2022-04-03T09:37:03+00:00" - }, - { - "name" : "sebastian/exporter", - "version" : "4.0.5", - "source" : { - "type" : "git", - "url" : "https://github.com/sebastianbergmann/exporter.git", - "reference" : "ac230ed27f0f98f597c8a2b6eb7ac563af5e5b9d" - }, - "dist" : { - "type" : "zip", - "url" : "https://api.github.com/repos/sebastianbergmann/exporter/zipball/ac230ed27f0f98f597c8a2b6eb7ac563af5e5b9d", - "reference" : "ac230ed27f0f98f597c8a2b6eb7ac563af5e5b9d", - "shasum" : "" - }, - "require" : { - "php" : ">=7.3", - "sebastian/recursion-context" : "^4.0" - }, - "require-dev" : { - "ext-mbstring" : "*", - "phpunit/phpunit" : "^9.3" - }, - "type" : "library", - "extra" : { - "branch-alias": { - "dev-master": "4.0-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" - }, - { - "name": "Jeff Welch", - "email": "whatthejeff@gmail.com" - }, - { - "name": "Volker Dusch", - "email": "github@wallbash.com" - }, - { - "name": "Adam Harvey", - "email": "aharvey@php.net" - }, - { - "name": "Bernhard Schussek", - "email": "bschussek@gmail.com" - } - ], - "description": "Provides the functionality to export PHP variables for visualization", - "homepage": "https://www.github.com/sebastianbergmann/exporter", - "keywords": [ - "export", - "exporter" - ], - "support": { - "issues": "https://github.com/sebastianbergmann/exporter/issues", - "source" : "https://github.com/sebastianbergmann/exporter/tree/4.0.5" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time" : "2022-09-14T06:03:37+00:00" - }, - { - "name": "sebastian/global-state", - "version": "5.0.5", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/global-state.git", - "reference": "0ca8db5a5fc9c8646244e629625ac486fa286bf2" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/0ca8db5a5fc9c8646244e629625ac486fa286bf2", - "reference": "0ca8db5a5fc9c8646244e629625ac486fa286bf2", - "shasum": "" - }, - "require": { - "php": ">=7.3", - "sebastian/object-reflector": "^2.0", - "sebastian/recursion-context": "^4.0" - }, - "require-dev": { - "ext-dom": "*", - "phpunit/phpunit": "^9.3" - }, - "suggest": { - "ext-uopz": "*" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "5.0-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" - } - ], - "description": "Snapshotting of global state", - "homepage": "http://www.github.com/sebastianbergmann/global-state", - "keywords": [ - "global state" - ], - "support": { - "issues": "https://github.com/sebastianbergmann/global-state/issues", - "source": "https://github.com/sebastianbergmann/global-state/tree/5.0.5" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2022-02-14T08:28:10+00:00" - }, - { - "name": "sebastian/lines-of-code", - "version": "1.0.3", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/lines-of-code.git", - "reference": "c1c2e997aa3146983ed888ad08b15470a2e22ecc" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/lines-of-code/zipball/c1c2e997aa3146983ed888ad08b15470a2e22ecc", - "reference": "c1c2e997aa3146983ed888ad08b15470a2e22ecc", - "shasum": "" - }, - "require": { - "nikic/php-parser": "^4.6", - "php": ">=7.3" - }, - "require-dev": { - "phpunit/phpunit": "^9.3" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.0-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "lead" - } - ], - "description": "Library for counting the lines of code in PHP source code", - "homepage": "https://github.com/sebastianbergmann/lines-of-code", - "support": { - "issues": "https://github.com/sebastianbergmann/lines-of-code/issues", - "source": "https://github.com/sebastianbergmann/lines-of-code/tree/1.0.3" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2020-11-28T06:42:11+00:00" - }, - { - "name": "sebastian/object-enumerator", - "version": "4.0.4", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/object-enumerator.git", - "reference": "5c9eeac41b290a3712d88851518825ad78f45c71" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/object-enumerator/zipball/5c9eeac41b290a3712d88851518825ad78f45c71", - "reference": "5c9eeac41b290a3712d88851518825ad78f45c71", - "shasum": "" - }, - "require": { - "php": ">=7.3", - "sebastian/object-reflector": "^2.0", - "sebastian/recursion-context": "^4.0" - }, - "require-dev": { - "phpunit/phpunit": "^9.3" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "4.0-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" - } - ], - "description": "Traverses array structures and object graphs to enumerate all referenced objects", - "homepage": "https://github.com/sebastianbergmann/object-enumerator/", - "support": { - "issues": "https://github.com/sebastianbergmann/object-enumerator/issues", - "source": "https://github.com/sebastianbergmann/object-enumerator/tree/4.0.4" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2020-10-26T13:12:34+00:00" - }, - { - "name": "sebastian/object-reflector", - "version": "2.0.4", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/object-reflector.git", - "reference": "b4f479ebdbf63ac605d183ece17d8d7fe49c15c7" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/object-reflector/zipball/b4f479ebdbf63ac605d183ece17d8d7fe49c15c7", - "reference": "b4f479ebdbf63ac605d183ece17d8d7fe49c15c7", - "shasum": "" - }, - "require": { - "php": ">=7.3" - }, - "require-dev": { - "phpunit/phpunit": "^9.3" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.0-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" - } - ], - "description": "Allows reflection of object attributes, including inherited and non-public ones", - "homepage": "https://github.com/sebastianbergmann/object-reflector/", - "support": { - "issues": "https://github.com/sebastianbergmann/object-reflector/issues", - "source": "https://github.com/sebastianbergmann/object-reflector/tree/2.0.4" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2020-10-26T13:14:26+00:00" - }, - { - "name": "sebastian/recursion-context", - "version": "4.0.4", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/recursion-context.git", - "reference": "cd9d8cf3c5804de4341c283ed787f099f5506172" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/cd9d8cf3c5804de4341c283ed787f099f5506172", - "reference": "cd9d8cf3c5804de4341c283ed787f099f5506172", - "shasum": "" - }, - "require": { - "php": ">=7.3" - }, - "require-dev": { - "phpunit/phpunit": "^9.3" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "4.0-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" - }, - { - "name": "Jeff Welch", - "email": "whatthejeff@gmail.com" - }, - { - "name": "Adam Harvey", - "email": "aharvey@php.net" - } - ], - "description": "Provides functionality to recursively process PHP variables", - "homepage": "http://www.github.com/sebastianbergmann/recursion-context", - "support": { - "issues": "https://github.com/sebastianbergmann/recursion-context/issues", - "source": "https://github.com/sebastianbergmann/recursion-context/tree/4.0.4" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2020-10-26T13:17:30+00:00" - }, - { - "name": "sebastian/resource-operations", - "version": "3.0.3", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/resource-operations.git", - "reference": "0f4443cb3a1d92ce809899753bc0d5d5a8dd19a8" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/resource-operations/zipball/0f4443cb3a1d92ce809899753bc0d5d5a8dd19a8", - "reference": "0f4443cb3a1d92ce809899753bc0d5d5a8dd19a8", - "shasum": "" - }, - "require": { - "php": ">=7.3" - }, - "require-dev": { - "phpunit/phpunit": "^9.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "3.0-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" - } - ], - "description": "Provides a list of PHP built-in functions that operate on resources", - "homepage": "https://www.github.com/sebastianbergmann/resource-operations", - "support": { - "issues": "https://github.com/sebastianbergmann/resource-operations/issues", - "source" : "https://github.com/sebastianbergmann/resource-operations/tree/3.0.3" - }, - "funding" : [ - { - "url" : "https://github.com/sebastianbergmann", - "type" : "github" - } - ], - "time" : "2020-09-28T06:45:17+00:00" - }, - { - "name" : "sebastian/type", - "version" : "3.2.0", - "source" : { - "type" : "git", - "url" : "https://github.com/sebastianbergmann/type.git", - "reference" : "fb3fe09c5f0bae6bc27ef3ce933a1e0ed9464b6e" - }, - "dist" : { - "type" : "zip", - "url" : "https://api.github.com/repos/sebastianbergmann/type/zipball/fb3fe09c5f0bae6bc27ef3ce933a1e0ed9464b6e", - "reference" : "fb3fe09c5f0bae6bc27ef3ce933a1e0ed9464b6e", - "shasum" : "" - }, - "require" : { - "php" : ">=7.3" - }, - "require-dev" : { - "phpunit/phpunit" : "^9.5" - }, - "type" : "library", - "extra" : { - "branch-alias" : { - "dev-master" : "3.2-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "lead" - } - ], - "description": "Collection of value objects that represent the types of the PHP type system", - "homepage": "https://github.com/sebastianbergmann/type", - "support": { - "issues": "https://github.com/sebastianbergmann/type/issues", - "source" : "https://github.com/sebastianbergmann/type/tree/3.2.0" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time" : "2022-09-12T14:47:03+00:00" - }, - { - "name": "sebastian/version", - "version": "3.0.2", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/version.git", - "reference": "c6c1022351a901512170118436c764e473f6de8c" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/c6c1022351a901512170118436c764e473f6de8c", - "reference": "c6c1022351a901512170118436c764e473f6de8c", - "shasum": "" - }, - "require": { - "php": ">=7.3" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "3.0-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "lead" - } - ], - "description": "Library that helps with managing the version number of Git-hosted PHP projects", - "homepage": "https://github.com/sebastianbergmann/version", - "support": { - "issues": "https://github.com/sebastianbergmann/version/issues", - "source" : "https://github.com/sebastianbergmann/version/tree/3.0.2" - }, - "funding" : [ - { - "url" : "https://github.com/sebastianbergmann", - "type" : "github" - } - ], - "time" : "2020-09-28T06:39:44+00:00" - }, - { - "name" : "symfony/console", - "version" : "v6.1.4", - "source" : { - "type" : "git", - "url" : "https://github.com/symfony/console.git", - "reference" : "7fccea8728aa2d431a6725b02b3ce759049fc84d" - }, - "dist" : { - "type" : "zip", - "url" : "https://api.github.com/repos/symfony/console/zipball/7fccea8728aa2d431a6725b02b3ce759049fc84d", - "reference" : "7fccea8728aa2d431a6725b02b3ce759049fc84d", - "shasum" : "" - }, - "require" : { - "php" : ">=8.1", - "symfony/deprecation-contracts" : "^2.1|^3", - "symfony/polyfill-mbstring" : "~1.0", - "symfony/service-contracts" : "^1.1|^2|^3", - "symfony/string" : "^5.4|^6.0" - }, - "conflict" : { - "symfony/dependency-injection" : "<5.4", - "symfony/dotenv" : "<5.4", - "symfony/event-dispatcher": "<5.4", - "symfony/lock": "<5.4", - "symfony/process": "<5.4" - }, - "provide": { - "psr/log-implementation": "1.0|2.0|3.0" - }, - "require-dev": { - "psr/log": "^1|^2|^3", - "symfony/config": "^5.4|^6.0", - "symfony/dependency-injection": "^5.4|^6.0", - "symfony/event-dispatcher": "^5.4|^6.0", - "symfony/lock": "^5.4|^6.0", - "symfony/process": "^5.4|^6.0", - "symfony/var-dumper": "^5.4|^6.0" - }, - "suggest": { - "psr/log": "For using the console logger", - "symfony/event-dispatcher": "", - "symfony/lock": "", - "symfony/process": "" - }, - "type": "library", - "autoload": { - "psr-4": { - "Symfony\\Component\\Console\\": "" - }, - "exclude-from-classmap": [ - "/Tests/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors" : [ - { - "name" : "Fabien Potencier", - "email" : "fabien@symfony.com" - }, - { - "name" : "Symfony Community", - "homepage" : "https://symfony.com/contributors" - } - ], - "description" : "Eases the creation of beautiful and testable command line interfaces", - "homepage" : "https://symfony.com", - "keywords" : [ - "cli", - "command line", - "console", - "terminal" - ], - "support" : { - "source" : "https://github.com/symfony/console/tree/v6.1.4" - }, - "funding" : [ - { - "url" : "https://symfony.com/sponsor", - "type" : "custom" - }, - { - "url" : "https://github.com/fabpot", - "type" : "github" - }, - { - "url" : "https://tidelift.com/funding/github/packagist/symfony/symfony", - "type" : "tidelift" - } - ], - "time" : "2022-08-26T10:32:31+00:00" - }, - { - "name" : "symfony/deprecation-contracts", - "version" : "v3.1.1", - "source" : { - "type" : "git", - "url" : "https://github.com/symfony/deprecation-contracts.git", - "reference" : "07f1b9cc2ffee6aaafcf4b710fbc38ff736bd918" - }, - "dist" : { - "type" : "zip", - "url" : "https://api.github.com/repos/symfony/deprecation-contracts/zipball/07f1b9cc2ffee6aaafcf4b710fbc38ff736bd918", - "reference" : "07f1b9cc2ffee6aaafcf4b710fbc38ff736bd918", - "shasum" : "" - }, - "require" : { - "php" : ">=8.1" - }, - "type" : "library", - "extra" : { - "branch-alias" : { - "dev-main" : "3.1-dev" - }, - "thanks" : { - "name" : "symfony/contracts", - "url" : "https://github.com/symfony/contracts" - } - }, - "autoload" : { - "files" : [ - "function.php" - ] - }, - "notification-url" : "https://packagist.org/downloads/", - "license" : [ - "MIT" - ], - "authors" : [ - { - "name" : "Nicolas Grekas", - "email" : "p@tchwork.com" - }, - { - "name" : "Symfony Community", - "homepage" : "https://symfony.com/contributors" - } - ], - "description" : "A generic function and convention to trigger deprecation notices", - "homepage" : "https://symfony.com", - "support" : { - "source" : "https://github.com/symfony/deprecation-contracts/tree/v3.1.1" - }, - "funding" : [ - { - "url" : "https://symfony.com/sponsor", - "type" : "custom" - }, - { - "url" : "https://github.com/fabpot", - "type" : "github" - }, - { - "url" : "https://tidelift.com/funding/github/packagist/symfony/symfony", - "type" : "tidelift" - } - ], - "time" : "2022-02-25T11:15:52+00:00" - }, - { - "name" : "symfony/polyfill-ctype", - "version" : "v1.26.0", - "source" : { - "type" : "git", - "url" : "https://github.com/symfony/polyfill-ctype.git", - "reference" : "6fd1b9a79f6e3cf65f9e679b23af304cd9e010d4" - }, - "dist" : { - "type" : "zip", - "url" : "https://api.github.com/repos/symfony/polyfill-ctype/zipball/6fd1b9a79f6e3cf65f9e679b23af304cd9e010d4", - "reference" : "6fd1b9a79f6e3cf65f9e679b23af304cd9e010d4", - "shasum" : "" - }, - "require" : { - "php" : ">=7.1" - }, - "provide" : { - "ext-ctype" : "*" - }, - "suggest" : { - "ext-ctype" : "For best performance" - }, - "type" : "library", - "extra": { - "branch-alias": { - "dev-main" : "1.26-dev" - }, - "thanks": { - "name": "symfony/polyfill", - "url": "https://github.com/symfony/polyfill" - } - }, - "autoload": { - "files": [ - "bootstrap.php" - ], - "psr-4": { - "Symfony\\Polyfill\\Ctype\\": "" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Gert de Pagter", - "email": "BackEndTea@gmail.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Symfony polyfill for ctype functions", - "homepage": "https://symfony.com", - "keywords": [ - "compatibility", - "ctype", - "polyfill", - "portable" - ], - "support": { - "source" : "https://github.com/symfony/polyfill-ctype/tree/v1.26.0" - }, - "funding": [ - { - "url": "https://symfony.com/sponsor", - "type": "custom" - }, - { - "url" : "https://github.com/fabpot", - "type" : "github" - }, - { - "url" : "https://tidelift.com/funding/github/packagist/symfony/symfony", - "type" : "tidelift" - } - ], - "time" : "2022-05-24T11:49:31+00:00" - }, - { - "name" : "symfony/polyfill-intl-grapheme", - "version" : "v1.26.0", - "source" : { - "type" : "git", - "url" : "https://github.com/symfony/polyfill-intl-grapheme.git", - "reference" : "433d05519ce6990bf3530fba6957499d327395c2" - }, - "dist" : { - "type" : "zip", - "url" : "https://api.github.com/repos/symfony/polyfill-intl-grapheme/zipball/433d05519ce6990bf3530fba6957499d327395c2", - "reference" : "433d05519ce6990bf3530fba6957499d327395c2", - "shasum" : "" - }, - "require" : { - "php" : ">=7.1" - }, - "suggest" : { - "ext-intl" : "For best performance" - }, - "type" : "library", - "extra" : { - "branch-alias" : { - "dev-main" : "1.26-dev" - }, - "thanks": { - "name": "symfony/polyfill", - "url": "https://github.com/symfony/polyfill" - } - }, - "autoload": { - "files": [ - "bootstrap.php" - ], - "psr-4": { - "Symfony\\Polyfill\\Intl\\Grapheme\\": "" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Nicolas Grekas", - "email": "p@tchwork.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Symfony polyfill for intl's grapheme_* functions", - "homepage": "https://symfony.com", - "keywords": [ - "compatibility", - "grapheme", - "intl", - "polyfill", - "portable", - "shim" - ], - "support": { - "source" : "https://github.com/symfony/polyfill-intl-grapheme/tree/v1.26.0" - }, - "funding": [ - { - "url": "https://symfony.com/sponsor", - "type": "custom" - }, - { - "url" : "https://github.com/fabpot", - "type" : "github" - }, - { - "url" : "https://tidelift.com/funding/github/packagist/symfony/symfony", - "type" : "tidelift" - } - ], - "time" : "2022-05-24T11:49:31+00:00" - }, - { - "name" : "symfony/polyfill-intl-normalizer", - "version" : "v1.26.0", - "source" : { - "type" : "git", - "url" : "https://github.com/symfony/polyfill-intl-normalizer.git", - "reference" : "219aa369ceff116e673852dce47c3a41794c14bd" - }, - "dist" : { - "type" : "zip", - "url" : "https://api.github.com/repos/symfony/polyfill-intl-normalizer/zipball/219aa369ceff116e673852dce47c3a41794c14bd", - "reference" : "219aa369ceff116e673852dce47c3a41794c14bd", - "shasum" : "" - }, - "require" : { - "php" : ">=7.1" - }, - "suggest" : { - "ext-intl" : "For best performance" - }, - "type" : "library", - "extra" : { - "branch-alias" : { - "dev-main" : "1.26-dev" - }, - "thanks": { - "name": "symfony/polyfill", - "url": "https://github.com/symfony/polyfill" - } - }, - "autoload": { - "files": [ - "bootstrap.php" - ], - "psr-4": { - "Symfony\\Polyfill\\Intl\\Normalizer\\": "" - }, - "classmap": [ - "Resources/stubs" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Nicolas Grekas", - "email": "p@tchwork.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Symfony polyfill for intl's Normalizer class and related functions", - "homepage": "https://symfony.com", - "keywords": [ - "compatibility", - "intl", - "normalizer", - "polyfill", - "portable", - "shim" - ], - "support": { - "source" : "https://github.com/symfony/polyfill-intl-normalizer/tree/v1.26.0" - }, - "funding": [ - { - "url": "https://symfony.com/sponsor", - "type": "custom" - }, - { - "url" : "https://github.com/fabpot", - "type" : "github" - }, - { - "url" : "https://tidelift.com/funding/github/packagist/symfony/symfony", - "type" : "tidelift" - } - ], - "time" : "2022-05-24T11:49:31+00:00" - }, - { - "name" : "symfony/polyfill-mbstring", - "version" : "v1.26.0", - "source" : { - "type" : "git", - "url" : "https://github.com/symfony/polyfill-mbstring.git", - "reference" : "9344f9cb97f3b19424af1a21a3b0e75b0a7d8d7e" - }, - "dist" : { - "type" : "zip", - "url" : "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/9344f9cb97f3b19424af1a21a3b0e75b0a7d8d7e", - "reference" : "9344f9cb97f3b19424af1a21a3b0e75b0a7d8d7e", - "shasum" : "" - }, - "require" : { - "php" : ">=7.1" - }, - "provide" : { - "ext-mbstring" : "*" - }, - "suggest" : { - "ext-mbstring" : "For best performance" - }, - "type" : "library", - "extra": { - "branch-alias": { - "dev-main" : "1.26-dev" - }, - "thanks": { - "name": "symfony/polyfill", - "url": "https://github.com/symfony/polyfill" - } - }, - "autoload": { - "files": [ - "bootstrap.php" - ], - "psr-4": { - "Symfony\\Polyfill\\Mbstring\\": "" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Nicolas Grekas", - "email": "p@tchwork.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Symfony polyfill for the Mbstring extension", - "homepage": "https://symfony.com", - "keywords": [ - "compatibility", - "mbstring", - "polyfill", - "portable", - "shim" - ], - "support": { - "source" : "https://github.com/symfony/polyfill-mbstring/tree/v1.26.0" - }, - "funding": [ - { - "url": "https://symfony.com/sponsor", - "type": "custom" - }, - { - "url" : "https://github.com/fabpot", - "type" : "github" - }, - { - "url" : "https://tidelift.com/funding/github/packagist/symfony/symfony", - "type" : "tidelift" - } - ], - "time" : "2022-05-24T11:49:31+00:00" - }, - { - "name" : "symfony/service-contracts", - "version" : "v3.1.1", - "source" : { - "type" : "git", - "url" : "https://github.com/symfony/service-contracts.git", - "reference" : "925e713fe8fcacf6bc05e936edd8dd5441a21239" - }, - "dist" : { - "type" : "zip", - "url" : "https://api.github.com/repos/symfony/service-contracts/zipball/925e713fe8fcacf6bc05e936edd8dd5441a21239", - "reference" : "925e713fe8fcacf6bc05e936edd8dd5441a21239", - "shasum" : "" - }, - "require" : { - "php" : ">=8.1", - "psr/container" : "^2.0" - }, - "conflict" : { - "ext-psr" : "<1.1|>=2" - }, - "suggest" : { - "symfony/service-implementation" : "" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-main" : "3.1-dev" - }, - "thanks": { - "name": "symfony/contracts", - "url": "https://github.com/symfony/contracts" - } - }, - "autoload": { - "psr-4" : { - "Symfony\\Contracts\\Service\\" : "" - }, - "exclude-from-classmap" : [ - "/Test/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Nicolas Grekas", - "email": "p@tchwork.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Generic abstractions related to writing services", - "homepage": "https://symfony.com", - "keywords": [ - "abstractions", - "contracts", - "decoupling", - "interfaces", - "interoperability", - "standards" - ], - "support": { - "source" : "https://github.com/symfony/service-contracts/tree/v3.1.1" - }, - "funding": [ - { - "url": "https://symfony.com/sponsor", - "type": "custom" - }, - { - "url" : "https://github.com/fabpot", - "type" : "github" - }, - { - "url" : "https://tidelift.com/funding/github/packagist/symfony/symfony", - "type" : "tidelift" - } - ], - "time" : "2022-05-30T19:18:58+00:00" - }, - { - "name" : "symfony/string", - "version" : "v6.1.4", - "source" : { - "type" : "git", - "url" : "https://github.com/symfony/string.git", - "reference" : "290972cad7b364e3befaa74ba0ec729800fb161c" - }, - "dist" : { - "type" : "zip", - "url" : "https://api.github.com/repos/symfony/string/zipball/290972cad7b364e3befaa74ba0ec729800fb161c", - "reference" : "290972cad7b364e3befaa74ba0ec729800fb161c", - "shasum" : "" - }, - "require" : { - "php" : ">=8.1", - "symfony/polyfill-ctype" : "~1.8", - "symfony/polyfill-intl-grapheme" : "~1.0", - "symfony/polyfill-intl-normalizer" : "~1.0", - "symfony/polyfill-mbstring" : "~1.0" - }, - "conflict" : { - "symfony/translation-contracts" : "<2.0" - }, - "require-dev": { - "symfony/error-handler": "^5.4|^6.0", - "symfony/http-client": "^5.4|^6.0", - "symfony/translation-contracts": "^2.0|^3.0", - "symfony/var-exporter": "^5.4|^6.0" - }, - "type": "library", - "autoload": { - "files": [ - "Resources/functions.php" - ], - "psr-4": { - "Symfony\\Component\\String\\": "" - }, - "exclude-from-classmap": [ - "/Tests/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Nicolas Grekas", - "email": "p@tchwork.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Provides an object-oriented API to strings and deals with bytes, UTF-8 code points and grapheme clusters in a unified way", - "homepage": "https://symfony.com", - "keywords": [ - "grapheme", - "i18n", - "string", - "unicode", - "utf-8", - "utf8" - ], - "support": { - "source" : "https://github.com/symfony/string/tree/v6.1.4" - }, - "funding": [ - { - "url": "https://symfony.com/sponsor", - "type": "custom" - }, - { - "url": "https://github.com/fabpot", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", - "type": "tidelift" - } - ], - "time" : "2022-08-12T18:05:43+00:00" - }, - { - "name": "theseer/tokenizer", - "version": "1.2.1", - "source": { - "type": "git", - "url": "https://github.com/theseer/tokenizer.git", - "reference": "34a41e998c2183e22995f158c581e7b5e755ab9e" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/theseer/tokenizer/zipball/34a41e998c2183e22995f158c581e7b5e755ab9e", - "reference": "34a41e998c2183e22995f158c581e7b5e755ab9e", - "shasum": "" - }, - "require": { - "ext-dom": "*", - "ext-tokenizer": "*", - "ext-xmlwriter": "*", - "php": "^7.2 || ^8.0" - }, - "type": "library", - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Arne Blankerts", - "email": "arne@blankerts.de", - "role": "Developer" - } - ], - "description": "A small library for converting tokenized PHP source code into XML and potentially other formats", - "support": { - "issues": "https://github.com/theseer/tokenizer/issues", - "source": "https://github.com/theseer/tokenizer/tree/1.2.1" - }, - "funding": [ - { - "url": "https://github.com/theseer", - "type": "github" - } - ], - "time": "2021-07-28T10:34:58+00:00" - } - ], - "aliases": [], - "minimum-stability": "stable", - "stability-flags": [], - "prefer-stable": false, - "prefer-lowest": false, - "platform": { - "php": ">=8.0", - "ext-json": "*", - "ext-mbstring": "*" - }, - "platform-dev": [], - "plugin-api-version" : "2.3.0" +{ + "_readme": [ + "This file locks the dependencies of your project to a known state", + "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", + "This file is @generated automatically" + ], + "content-hash": "dd66f76a8b680d6fe1cb8729ac66d299", + "packages": [], + "packages-dev": [ + { + "name": "doctrine/instantiator", + "version": "1.4.1", + "source": { + "type": "git", + "url": "https://github.com/doctrine/instantiator.git", + "reference": "10dcfce151b967d20fde1b34ae6640712c3891bc" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/doctrine/instantiator/zipball/10dcfce151b967d20fde1b34ae6640712c3891bc", + "reference": "10dcfce151b967d20fde1b34ae6640712c3891bc", + "shasum": "" + }, + "require": { + "php": "^7.1 || ^8.0" + }, + "require-dev": { + "doctrine/coding-standard": "^9", + "ext-pdo": "*", + "ext-phar": "*", + "phpbench/phpbench": "^0.16 || ^1", + "phpstan/phpstan": "^1.4", + "phpstan/phpstan-phpunit": "^1", + "phpunit/phpunit": "^7.5 || ^8.5 || ^9.5", + "vimeo/psalm": "^4.22" + }, + "type": "library", + "autoload": { + "psr-4": { + "Doctrine\\Instantiator\\": "src/Doctrine/Instantiator/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Marco Pivetta", + "email": "ocramius@gmail.com", + "homepage": "https://ocramius.github.io/" + } + ], + "description": "A small, lightweight utility to instantiate objects in PHP without invoking their constructors", + "homepage": "https://www.doctrine-project.org/projects/instantiator.html", + "keywords": [ + "constructor", + "instantiate" + ], + "support": { + "issues": "https://github.com/doctrine/instantiator/issues", + "source": "https://github.com/doctrine/instantiator/tree/1.4.1" + }, + "funding": [ + { + "url": "https://www.doctrine-project.org/sponsorship.html", + "type": "custom" + }, + { + "url": "https://www.patreon.com/phpdoctrine", + "type": "patreon" + }, + { + "url": "https://tidelift.com/funding/github/packagist/doctrine%2Finstantiator", + "type": "tidelift" + } + ], + "time": "2022-03-03T08:28:38+00:00" + }, + { + "name": "filp/whoops", + "version": "2.14.5", + "source": { + "type": "git", + "url": "https://github.com/filp/whoops.git", + "reference": "a63e5e8f26ebbebf8ed3c5c691637325512eb0dc" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/filp/whoops/zipball/a63e5e8f26ebbebf8ed3c5c691637325512eb0dc", + "reference": "a63e5e8f26ebbebf8ed3c5c691637325512eb0dc", + "shasum": "" + }, + "require": { + "php": "^5.5.9 || ^7.0 || ^8.0", + "psr/log": "^1.0.1 || ^2.0 || ^3.0" + }, + "require-dev": { + "mockery/mockery": "^0.9 || ^1.0", + "phpunit/phpunit": "^4.8.36 || ^5.7.27 || ^6.5.14 || ^7.5.20 || ^8.5.8 || ^9.3.3", + "symfony/var-dumper": "^2.6 || ^3.0 || ^4.0 || ^5.0" + }, + "suggest": { + "symfony/var-dumper": "Pretty print complex values better with var-dumper available", + "whoops/soap": "Formats errors as SOAP responses" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.7-dev" + } + }, + "autoload": { + "psr-4": { + "Whoops\\": "src/Whoops/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Filipe Dobreira", + "homepage": "https://github.com/filp", + "role": "Developer" + } + ], + "description": "php error handling for cool kids", + "homepage": "https://filp.github.io/whoops/", + "keywords": [ + "error", + "exception", + "handling", + "library", + "throwable", + "whoops" + ], + "support": { + "issues": "https://github.com/filp/whoops/issues", + "source": "https://github.com/filp/whoops/tree/2.14.5" + }, + "funding": [ + { + "url": "https://github.com/denis-sokolov", + "type": "github" + } + ], + "time": "2022-01-07T12:00:00+00:00" + }, + { + "name": "myclabs/deep-copy", + "version": "1.11.0", + "source": { + "type": "git", + "url": "https://github.com/myclabs/DeepCopy.git", + "reference": "14daed4296fae74d9e3201d2c4925d1acb7aa614" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/14daed4296fae74d9e3201d2c4925d1acb7aa614", + "reference": "14daed4296fae74d9e3201d2c4925d1acb7aa614", + "shasum": "" + }, + "require": { + "php": "^7.1 || ^8.0" + }, + "conflict": { + "doctrine/collections": "<1.6.8", + "doctrine/common": "<2.13.3 || >=3,<3.2.2" + }, + "require-dev": { + "doctrine/collections": "^1.6.8", + "doctrine/common": "^2.13.3 || ^3.2.2", + "phpunit/phpunit": "^7.5.20 || ^8.5.23 || ^9.5.13" + }, + "type": "library", + "autoload": { + "files": [ + "src/DeepCopy/deep_copy.php" + ], + "psr-4": { + "DeepCopy\\": "src/DeepCopy/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "Create deep copies (clones) of your objects", + "keywords": [ + "clone", + "copy", + "duplicate", + "object", + "object graph" + ], + "support": { + "issues": "https://github.com/myclabs/DeepCopy/issues", + "source": "https://github.com/myclabs/DeepCopy/tree/1.11.0" + }, + "funding": [ + { + "url": "https://tidelift.com/funding/github/packagist/myclabs/deep-copy", + "type": "tidelift" + } + ], + "time": "2022-03-03T13:19:32+00:00" + }, + { + "name" : "nikic/php-parser", + "version" : "v4.15.1", + "source" : { + "type" : "git", + "url" : "https://github.com/nikic/PHP-Parser.git", + "reference" : "0ef6c55a3f47f89d7a374e6f835197a0b5fcf900" + }, + "dist" : { + "type" : "zip", + "url" : "https://api.github.com/repos/nikic/PHP-Parser/zipball/0ef6c55a3f47f89d7a374e6f835197a0b5fcf900", + "reference" : "0ef6c55a3f47f89d7a374e6f835197a0b5fcf900", + "shasum" : "" + }, + "require" : { + "ext-tokenizer" : "*", + "php" : ">=7.0" + }, + "require-dev" : { + "ircmaxell/php-yacc" : "^0.0.7", + "phpunit/phpunit" : "^6.5 || ^7.0 || ^8.0 || ^9.0" + }, + "bin" : [ + "bin/php-parse" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.9-dev" + } + }, + "autoload": { + "psr-4": { + "PhpParser\\": "lib/PhpParser" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Nikita Popov" + } + ], + "description": "A PHP parser written in PHP", + "keywords" : [ + "parser", + "php" + ], + "support" : { + "issues" : "https://github.com/nikic/PHP-Parser/issues", + "source" : "https://github.com/nikic/PHP-Parser/tree/v4.15.1" + }, + "time" : "2022-09-04T07:30:47+00:00" + }, + { + "name" : "nunomaduro/collision", + "version" : "v6.3.0", + "source" : { + "type" : "git", + "url" : "https://github.com/nunomaduro/collision.git", + "reference" : "17f600e2e8872856ff2846243efb74ad4b6da531" + }, + "dist" : { + "type" : "zip", + "url" : "https://api.github.com/repos/nunomaduro/collision/zipball/17f600e2e8872856ff2846243efb74ad4b6da531", + "reference" : "17f600e2e8872856ff2846243efb74ad4b6da531", + "shasum" : "" + }, + "require" : { + "filp/whoops" : "^2.14.5", + "php" : "^8.0.0", + "symfony/console" : "^6.0.2" + }, + "require-dev" : { + "brianium/paratest" : "^6.4.1", + "laravel/framework" : "^9.26.1", + "laravel/pint" : "^1.1.1", + "nunomaduro/larastan" : "^1.0.3", + "nunomaduro/mock-final-classes" : "^1.1.0", + "orchestra/testbench" : "^7.7", + "phpunit/phpunit" : "^9.5.23", + "spatie/ignition" : "^1.4.1" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-develop": "6.x-dev" + }, + "laravel": { + "providers": [ + "NunoMaduro\\Collision\\Adapters\\Laravel\\CollisionServiceProvider" + ] + } + }, + "autoload": { + "psr-4": { + "NunoMaduro\\Collision\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nuno Maduro", + "email": "enunomaduro@gmail.com" + } + ], + "description": "Cli error handling for console/command-line PHP applications.", + "keywords": [ + "artisan", + "cli", + "command-line", + "console", + "error", + "handling", + "laravel", + "laravel-zero", + "php", + "symfony" + ], + "support": { + "issues": "https://github.com/nunomaduro/collision/issues", + "source": "https://github.com/nunomaduro/collision" + }, + "funding": [ + { + "url": "https://www.paypal.com/paypalme/enunomaduro", + "type": "custom" + }, + { + "url" : "https://github.com/nunomaduro", + "type" : "github" + }, + { + "url" : "https://www.patreon.com/nunomaduro", + "type" : "patreon" + } + ], + "time" : "2022-08-29T09:11:20+00:00" + }, + { + "name" : "pestphp/pest", + "version" : "v1.22.1", + "source" : { + "type" : "git", + "url" : "https://github.com/pestphp/pest.git", + "reference" : "af6240b4eed8b049ac43c91184141ee337305df7" + }, + "dist" : { + "type" : "zip", + "url" : "https://api.github.com/repos/pestphp/pest/zipball/af6240b4eed8b049ac43c91184141ee337305df7", + "reference" : "af6240b4eed8b049ac43c91184141ee337305df7", + "shasum" : "" + }, + "require" : { + "nunomaduro/collision" : "^5.10.0|^6.0", + "pestphp/pest-plugin" : "^1.0.0", + "php" : "^7.3 || ^8.0", + "phpunit/phpunit" : "^9.5.5" + }, + "require-dev" : { + "illuminate/console" : "^8.47.0", + "illuminate/support" : "^8.47.0", + "laravel/dusk" : "^6.15.0", + "pestphp/pest-dev-tools" : "dev-master", + "pestphp/pest-plugin-parallel" : "^1.0" + }, + "bin" : [ + "bin/pest" + ], + "type" : "library", + "extra" : { + "branch-alias" : { + "dev-1.x" : "1.x-dev" + }, + "pest": { + "plugins": [ + "Pest\\Plugins\\Coverage", + "Pest\\Plugins\\Init", + "Pest\\Plugins\\Version", + "Pest\\Plugins\\Environment" + ] + }, + "laravel": { + "providers": [ + "Pest\\Laravel\\PestServiceProvider" + ] + } + }, + "autoload": { + "files": [ + "src/Functions.php", + "src/Pest.php" + ], + "psr-4": { + "Pest\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nuno Maduro", + "email": "enunomaduro@gmail.com" + } + ], + "description": "An elegant PHP Testing Framework.", + "keywords": [ + "framework", + "pest", + "php", + "test", + "testing", + "unit" + ], + "support": { + "issues": "https://github.com/pestphp/pest/issues", + "source" : "https://github.com/pestphp/pest/tree/v1.22.1" + }, + "funding": [ + { + "url": "https://www.paypal.com/paypalme/enunomaduro", + "type": "custom" + }, + { + "url": "https://github.com/lukeraymonddowning", + "type": "github" + }, + { + "url": "https://github.com/nunomaduro", + "type": "github" + }, + { + "url": "https://github.com/octoper", + "type": "github" + }, + { + "url": "https://github.com/olivernybroe", + "type": "github" + }, + { + "url": "https://github.com/owenvoke", + "type": "github" + }, + { + "url": "https://www.patreon.com/nunomaduro", + "type": "patreon" + } + ], + "time" : "2022-08-29T10:42:13+00:00" + }, + { + "name": "pestphp/pest-plugin", + "version": "v1.0.0", + "source": { + "type": "git", + "url": "https://github.com/pestphp/pest-plugin.git", + "reference": "fc8519de148699fe612d9c669be60554cd2db4fa" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/pestphp/pest-plugin/zipball/fc8519de148699fe612d9c669be60554cd2db4fa", + "reference": "fc8519de148699fe612d9c669be60554cd2db4fa", + "shasum": "" + }, + "require": { + "composer-plugin-api": "^1.1 || ^2.0", + "php": "^7.3 || ^8.0" + }, + "conflict": { + "pestphp/pest": "<1.0" + }, + "require-dev": { + "composer/composer": "^1.10.19", + "pestphp/pest": "^1.0", + "pestphp/pest-dev-tools": "dev-master" + }, + "type": "composer-plugin", + "extra": { + "branch-alias": { + "dev-master": "1.x-dev" + }, + "class": "Pest\\Plugin\\Manager" + }, + "autoload": { + "psr-4": { + "Pest\\Plugin\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "The Pest plugin manager", + "keywords": [ + "framework", + "manager", + "pest", + "php", + "plugin", + "test", + "testing", + "unit" + ], + "support": { + "source": "https://github.com/pestphp/pest-plugin/tree/v1.0.0" + }, + "funding": [ + { + "url": "https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=66BYDWAT92N6L", + "type": "custom" + }, + { + "url": "https://github.com/nunomaduro", + "type": "github" + }, + { + "url": "https://www.patreon.com/nunomaduro", + "type": "patreon" + } + ], + "time": "2021-01-03T15:53:42+00:00" + }, + { + "name": "phar-io/manifest", + "version": "2.0.3", + "source": { + "type": "git", + "url": "https://github.com/phar-io/manifest.git", + "reference": "97803eca37d319dfa7826cc2437fc020857acb53" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phar-io/manifest/zipball/97803eca37d319dfa7826cc2437fc020857acb53", + "reference": "97803eca37d319dfa7826cc2437fc020857acb53", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "ext-phar": "*", + "ext-xmlwriter": "*", + "phar-io/version": "^3.0.1", + "php": "^7.2 || ^8.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Arne Blankerts", + "email": "arne@blankerts.de", + "role": "Developer" + }, + { + "name": "Sebastian Heuer", + "email": "sebastian@phpeople.de", + "role": "Developer" + }, + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "Developer" + } + ], + "description": "Component for reading phar.io manifest information from a PHP Archive (PHAR)", + "support": { + "issues": "https://github.com/phar-io/manifest/issues", + "source": "https://github.com/phar-io/manifest/tree/2.0.3" + }, + "time": "2021-07-20T11:28:43+00:00" + }, + { + "name": "phar-io/version", + "version": "3.2.1", + "source": { + "type": "git", + "url": "https://github.com/phar-io/version.git", + "reference": "4f7fd7836c6f332bb2933569e566a0d6c4cbed74" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phar-io/version/zipball/4f7fd7836c6f332bb2933569e566a0d6c4cbed74", + "reference": "4f7fd7836c6f332bb2933569e566a0d6c4cbed74", + "shasum": "" + }, + "require": { + "php": "^7.2 || ^8.0" + }, + "type": "library", + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Arne Blankerts", + "email": "arne@blankerts.de", + "role": "Developer" + }, + { + "name": "Sebastian Heuer", + "email": "sebastian@phpeople.de", + "role": "Developer" + }, + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role" : "Developer" + } + ], + "description" : "Library for handling version information and constraints", + "support" : { + "issues" : "https://github.com/phar-io/version/issues", + "source" : "https://github.com/phar-io/version/tree/3.2.1" + }, + "time" : "2022-02-21T01:04:05+00:00" + }, + { + "name" : "phpunit/php-code-coverage", + "version" : "9.2.17", + "source" : { + "type" : "git", + "url" : "https://github.com/sebastianbergmann/php-code-coverage.git", + "reference" : "aa94dc41e8661fe90c7316849907cba3007b10d8" + }, + "dist" : { + "type" : "zip", + "url" : "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/aa94dc41e8661fe90c7316849907cba3007b10d8", + "reference" : "aa94dc41e8661fe90c7316849907cba3007b10d8", + "shasum" : "" + }, + "require" : { + "ext-dom" : "*", + "ext-libxml" : "*", + "ext-xmlwriter" : "*", + "nikic/php-parser" : "^4.14", + "php" : ">=7.3", + "phpunit/php-file-iterator" : "^3.0.3", + "phpunit/php-text-template" : "^2.0.2", + "sebastian/code-unit-reverse-lookup" : "^2.0.2", + "sebastian/complexity" : "^2.0", + "sebastian/environment" : "^5.1.2", + "sebastian/lines-of-code" : "^1.0.3", + "sebastian/version" : "^3.0.1", + "theseer/tokenizer" : "^1.2.0" + }, + "require-dev": { + "phpunit/phpunit": "^9.3" + }, + "suggest": { + "ext-pcov": "*", + "ext-xdebug": "*" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "9.2-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Library that provides collection, processing, and rendering functionality for PHP code coverage information.", + "homepage": "https://github.com/sebastianbergmann/php-code-coverage", + "keywords": [ + "coverage", + "testing", + "xunit" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/php-code-coverage/issues", + "source" : "https://github.com/sebastianbergmann/php-code-coverage/tree/9.2.17" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time" : "2022-08-30T12:24:04+00:00" + }, + { + "name": "phpunit/php-file-iterator", + "version": "3.0.6", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-file-iterator.git", + "reference": "cf1c2e7c203ac650e352f4cc675a7021e7d1b3cf" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/cf1c2e7c203ac650e352f4cc675a7021e7d1b3cf", + "reference": "cf1c2e7c203ac650e352f4cc675a7021e7d1b3cf", + "shasum": "" + }, + "require": { + "php": ">=7.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "FilterIterator implementation that filters files based on a list of suffixes.", + "homepage": "https://github.com/sebastianbergmann/php-file-iterator/", + "keywords": [ + "filesystem", + "iterator" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/php-file-iterator/issues", + "source": "https://github.com/sebastianbergmann/php-file-iterator/tree/3.0.6" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2021-12-02T12:48:52+00:00" + }, + { + "name": "phpunit/php-invoker", + "version": "3.1.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-invoker.git", + "reference": "5a10147d0aaf65b58940a0b72f71c9ac0423cc67" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-invoker/zipball/5a10147d0aaf65b58940a0b72f71c9ac0423cc67", + "reference": "5a10147d0aaf65b58940a0b72f71c9ac0423cc67", + "shasum": "" + }, + "require": { + "php": ">=7.3" + }, + "require-dev": { + "ext-pcntl": "*", + "phpunit/phpunit": "^9.3" + }, + "suggest": { + "ext-pcntl": "*" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.1-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Invoke callables with a timeout", + "homepage": "https://github.com/sebastianbergmann/php-invoker/", + "keywords": [ + "process" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/php-invoker/issues", + "source": "https://github.com/sebastianbergmann/php-invoker/tree/3.1.1" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-09-28T05:58:55+00:00" + }, + { + "name": "phpunit/php-text-template", + "version": "2.0.4", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-text-template.git", + "reference": "5da5f67fc95621df9ff4c4e5a84d6a8a2acf7c28" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-text-template/zipball/5da5f67fc95621df9ff4c4e5a84d6a8a2acf7c28", + "reference": "5da5f67fc95621df9ff4c4e5a84d6a8a2acf7c28", + "shasum": "" + }, + "require": { + "php": ">=7.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Simple template engine.", + "homepage": "https://github.com/sebastianbergmann/php-text-template/", + "keywords": [ + "template" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/php-text-template/issues", + "source": "https://github.com/sebastianbergmann/php-text-template/tree/2.0.4" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-10-26T05:33:50+00:00" + }, + { + "name": "phpunit/php-timer", + "version": "5.0.3", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-timer.git", + "reference": "5a63ce20ed1b5bf577850e2c4e87f4aa902afbd2" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/5a63ce20ed1b5bf577850e2c4e87f4aa902afbd2", + "reference": "5a63ce20ed1b5bf577850e2c4e87f4aa902afbd2", + "shasum": "" + }, + "require": { + "php": ">=7.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "5.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Utility class for timing", + "homepage": "https://github.com/sebastianbergmann/php-timer/", + "keywords": [ + "timer" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/php-timer/issues", + "source" : "https://github.com/sebastianbergmann/php-timer/tree/5.0.3" + }, + "funding" : [ + { + "url" : "https://github.com/sebastianbergmann", + "type" : "github" + } + ], + "time" : "2020-10-26T13:16:10+00:00" + }, + { + "name" : "phpunit/phpunit", + "version" : "9.5.24", + "source" : { + "type" : "git", + "url" : "https://github.com/sebastianbergmann/phpunit.git", + "reference" : "d0aa6097bef9fd42458a9b3c49da32c6ce6129c5" + }, + "dist" : { + "type" : "zip", + "url" : "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/d0aa6097bef9fd42458a9b3c49da32c6ce6129c5", + "reference" : "d0aa6097bef9fd42458a9b3c49da32c6ce6129c5", + "shasum" : "" + }, + "require" : { + "doctrine/instantiator" : "^1.3.1", + "ext-dom" : "*", + "ext-json" : "*", + "ext-libxml" : "*", + "ext-mbstring" : "*", + "ext-xml" : "*", + "ext-xmlwriter" : "*", + "myclabs/deep-copy" : "^1.10.1", + "phar-io/manifest" : "^2.0.3", + "phar-io/version" : "^3.0.2", + "php" : ">=7.3", + "phpunit/php-code-coverage" : "^9.2.13", + "phpunit/php-file-iterator" : "^3.0.5", + "phpunit/php-invoker" : "^3.1.1", + "phpunit/php-text-template" : "^2.0.3", + "phpunit/php-timer" : "^5.0.2", + "sebastian/cli-parser" : "^1.0.1", + "sebastian/code-unit" : "^1.0.6", + "sebastian/comparator" : "^4.0.5", + "sebastian/diff" : "^4.0.3", + "sebastian/environment" : "^5.1.3", + "sebastian/exporter" : "^4.0.3", + "sebastian/global-state" : "^5.0.1", + "sebastian/object-enumerator" : "^4.0.3", + "sebastian/resource-operations" : "^3.0.3", + "sebastian/type" : "^3.1", + "sebastian/version" : "^3.0.2" + }, + "suggest": { + "ext-soap": "*", + "ext-xdebug": "*" + }, + "bin": [ + "phpunit" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "9.5-dev" + } + }, + "autoload": { + "files": [ + "src/Framework/Assert/Functions.php" + ], + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "The PHP Unit Testing framework.", + "homepage": "https://phpunit.de/", + "keywords": [ + "phpunit", + "testing", + "xunit" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/phpunit/issues", + "source" : "https://github.com/sebastianbergmann/phpunit/tree/9.5.24" + }, + "funding": [ + { + "url": "https://phpunit.de/sponsors.html", + "type": "custom" + }, + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time" : "2022-08-30T07:42:16+00:00" + }, + { + "name": "psr/container", + "version": "2.0.2", + "source": { + "type": "git", + "url": "https://github.com/php-fig/container.git", + "reference": "c71ecc56dfe541dbd90c5360474fbc405f8d5963" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/container/zipball/c71ecc56dfe541dbd90c5360474fbc405f8d5963", + "reference": "c71ecc56dfe541dbd90c5360474fbc405f8d5963", + "shasum": "" + }, + "require": { + "php": ">=7.4.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Container\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "https://www.php-fig.org/" + } + ], + "description": "Common Container Interface (PHP FIG PSR-11)", + "homepage": "https://github.com/php-fig/container", + "keywords": [ + "PSR-11", + "container", + "container-interface", + "container-interop", + "psr" + ], + "support": { + "issues": "https://github.com/php-fig/container/issues", + "source": "https://github.com/php-fig/container/tree/2.0.2" + }, + "time": "2021-11-05T16:47:00+00:00" + }, + { + "name": "psr/log", + "version": "3.0.0", + "source": { + "type": "git", + "url": "https://github.com/php-fig/log.git", + "reference": "fe5ea303b0887d5caefd3d431c3e61ad47037001" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/log/zipball/fe5ea303b0887d5caefd3d431c3e61ad47037001", + "reference": "fe5ea303b0887d5caefd3d431c3e61ad47037001", + "shasum": "" + }, + "require": { + "php": ">=8.0.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Log\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "https://www.php-fig.org/" + } + ], + "description": "Common interface for logging libraries", + "homepage": "https://github.com/php-fig/log", + "keywords": [ + "log", + "psr", + "psr-3" + ], + "support": { + "source": "https://github.com/php-fig/log/tree/3.0.0" + }, + "time": "2021-07-14T16:46:02+00:00" + }, + { + "name": "sebastian/cli-parser", + "version": "1.0.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/cli-parser.git", + "reference": "442e7c7e687e42adc03470c7b668bc4b2402c0b2" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/cli-parser/zipball/442e7c7e687e42adc03470c7b668bc4b2402c0b2", + "reference": "442e7c7e687e42adc03470c7b668bc4b2402c0b2", + "shasum": "" + }, + "require": { + "php": ">=7.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Library for parsing CLI options", + "homepage": "https://github.com/sebastianbergmann/cli-parser", + "support": { + "issues": "https://github.com/sebastianbergmann/cli-parser/issues", + "source": "https://github.com/sebastianbergmann/cli-parser/tree/1.0.1" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-09-28T06:08:49+00:00" + }, + { + "name": "sebastian/code-unit", + "version": "1.0.8", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/code-unit.git", + "reference": "1fc9f64c0927627ef78ba436c9b17d967e68e120" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/code-unit/zipball/1fc9f64c0927627ef78ba436c9b17d967e68e120", + "reference": "1fc9f64c0927627ef78ba436c9b17d967e68e120", + "shasum": "" + }, + "require": { + "php": ">=7.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Collection of value objects that represent the PHP code units", + "homepage": "https://github.com/sebastianbergmann/code-unit", + "support": { + "issues": "https://github.com/sebastianbergmann/code-unit/issues", + "source": "https://github.com/sebastianbergmann/code-unit/tree/1.0.8" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-10-26T13:08:54+00:00" + }, + { + "name": "sebastian/code-unit-reverse-lookup", + "version": "2.0.3", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/code-unit-reverse-lookup.git", + "reference": "ac91f01ccec49fb77bdc6fd1e548bc70f7faa3e5" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/code-unit-reverse-lookup/zipball/ac91f01ccec49fb77bdc6fd1e548bc70f7faa3e5", + "reference": "ac91f01ccec49fb77bdc6fd1e548bc70f7faa3e5", + "shasum": "" + }, + "require": { + "php": ">=7.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Looks up which function or method a line of code belongs to", + "homepage": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/", + "support": { + "issues": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/issues", + "source" : "https://github.com/sebastianbergmann/code-unit-reverse-lookup/tree/2.0.3" + }, + "funding" : [ + { + "url" : "https://github.com/sebastianbergmann", + "type" : "github" + } + ], + "time" : "2020-09-28T05:30:19+00:00" + }, + { + "name" : "sebastian/comparator", + "version" : "4.0.8", + "source" : { + "type" : "git", + "url" : "https://github.com/sebastianbergmann/comparator.git", + "reference" : "fa0f136dd2334583309d32b62544682ee972b51a" + }, + "dist" : { + "type" : "zip", + "url" : "https://api.github.com/repos/sebastianbergmann/comparator/zipball/fa0f136dd2334583309d32b62544682ee972b51a", + "reference" : "fa0f136dd2334583309d32b62544682ee972b51a", + "shasum" : "" + }, + "require" : { + "php" : ">=7.3", + "sebastian/diff" : "^4.0", + "sebastian/exporter" : "^4.0" + }, + "require-dev" : { + "phpunit/phpunit" : "^9.3" + }, + "type" : "library", + "extra" : { + "branch-alias": { + "dev-master": "4.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + }, + { + "name": "Jeff Welch", + "email": "whatthejeff@gmail.com" + }, + { + "name": "Volker Dusch", + "email": "github@wallbash.com" + }, + { + "name": "Bernhard Schussek", + "email": "bschussek@2bepublished.at" + } + ], + "description": "Provides the functionality to compare PHP values for equality", + "homepage": "https://github.com/sebastianbergmann/comparator", + "keywords": [ + "comparator", + "compare", + "equality" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/comparator/issues", + "source" : "https://github.com/sebastianbergmann/comparator/tree/4.0.8" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time" : "2022-09-14T12:41:17+00:00" + }, + { + "name": "sebastian/complexity", + "version": "2.0.2", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/complexity.git", + "reference": "739b35e53379900cc9ac327b2147867b8b6efd88" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/complexity/zipball/739b35e53379900cc9ac327b2147867b8b6efd88", + "reference": "739b35e53379900cc9ac327b2147867b8b6efd88", + "shasum": "" + }, + "require": { + "nikic/php-parser": "^4.7", + "php": ">=7.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Library for calculating the complexity of PHP code units", + "homepage": "https://github.com/sebastianbergmann/complexity", + "support": { + "issues": "https://github.com/sebastianbergmann/complexity/issues", + "source": "https://github.com/sebastianbergmann/complexity/tree/2.0.2" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-10-26T15:52:27+00:00" + }, + { + "name": "sebastian/diff", + "version": "4.0.4", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/diff.git", + "reference": "3461e3fccc7cfdfc2720be910d3bd73c69be590d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/3461e3fccc7cfdfc2720be910d3bd73c69be590d", + "reference": "3461e3fccc7cfdfc2720be910d3bd73c69be590d", + "shasum": "" + }, + "require": { + "php": ">=7.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.3", + "symfony/process": "^4.2 || ^5" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + }, + { + "name": "Kore Nordmann", + "email": "mail@kore-nordmann.de" + } + ], + "description": "Diff implementation", + "homepage": "https://github.com/sebastianbergmann/diff", + "keywords": [ + "diff", + "udiff", + "unidiff", + "unified diff" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/diff/issues", + "source": "https://github.com/sebastianbergmann/diff/tree/4.0.4" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-10-26T13:10:38+00:00" + }, + { + "name": "sebastian/environment", + "version": "5.1.4", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/environment.git", + "reference": "1b5dff7bb151a4db11d49d90e5408e4e938270f7" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/1b5dff7bb151a4db11d49d90e5408e4e938270f7", + "reference": "1b5dff7bb151a4db11d49d90e5408e4e938270f7", + "shasum": "" + }, + "require": { + "php": ">=7.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.3" + }, + "suggest": { + "ext-posix": "*" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "5.1-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Provides functionality to handle HHVM/PHP environments", + "homepage": "http://www.github.com/sebastianbergmann/environment", + "keywords": [ + "Xdebug", + "environment", + "hhvm" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/environment/issues", + "source" : "https://github.com/sebastianbergmann/environment/tree/5.1.4" + }, + "funding" : [ + { + "url" : "https://github.com/sebastianbergmann", + "type" : "github" + } + ], + "time" : "2022-04-03T09:37:03+00:00" + }, + { + "name" : "sebastian/exporter", + "version" : "4.0.5", + "source" : { + "type" : "git", + "url" : "https://github.com/sebastianbergmann/exporter.git", + "reference" : "ac230ed27f0f98f597c8a2b6eb7ac563af5e5b9d" + }, + "dist" : { + "type" : "zip", + "url" : "https://api.github.com/repos/sebastianbergmann/exporter/zipball/ac230ed27f0f98f597c8a2b6eb7ac563af5e5b9d", + "reference" : "ac230ed27f0f98f597c8a2b6eb7ac563af5e5b9d", + "shasum" : "" + }, + "require" : { + "php" : ">=7.3", + "sebastian/recursion-context" : "^4.0" + }, + "require-dev" : { + "ext-mbstring" : "*", + "phpunit/phpunit" : "^9.3" + }, + "type" : "library", + "extra" : { + "branch-alias": { + "dev-master": "4.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + }, + { + "name": "Jeff Welch", + "email": "whatthejeff@gmail.com" + }, + { + "name": "Volker Dusch", + "email": "github@wallbash.com" + }, + { + "name": "Adam Harvey", + "email": "aharvey@php.net" + }, + { + "name": "Bernhard Schussek", + "email": "bschussek@gmail.com" + } + ], + "description": "Provides the functionality to export PHP variables for visualization", + "homepage": "https://www.github.com/sebastianbergmann/exporter", + "keywords": [ + "export", + "exporter" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/exporter/issues", + "source" : "https://github.com/sebastianbergmann/exporter/tree/4.0.5" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time" : "2022-09-14T06:03:37+00:00" + }, + { + "name": "sebastian/global-state", + "version": "5.0.5", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/global-state.git", + "reference": "0ca8db5a5fc9c8646244e629625ac486fa286bf2" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/0ca8db5a5fc9c8646244e629625ac486fa286bf2", + "reference": "0ca8db5a5fc9c8646244e629625ac486fa286bf2", + "shasum": "" + }, + "require": { + "php": ">=7.3", + "sebastian/object-reflector": "^2.0", + "sebastian/recursion-context": "^4.0" + }, + "require-dev": { + "ext-dom": "*", + "phpunit/phpunit": "^9.3" + }, + "suggest": { + "ext-uopz": "*" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "5.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Snapshotting of global state", + "homepage": "http://www.github.com/sebastianbergmann/global-state", + "keywords": [ + "global state" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/global-state/issues", + "source": "https://github.com/sebastianbergmann/global-state/tree/5.0.5" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2022-02-14T08:28:10+00:00" + }, + { + "name": "sebastian/lines-of-code", + "version": "1.0.3", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/lines-of-code.git", + "reference": "c1c2e997aa3146983ed888ad08b15470a2e22ecc" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/lines-of-code/zipball/c1c2e997aa3146983ed888ad08b15470a2e22ecc", + "reference": "c1c2e997aa3146983ed888ad08b15470a2e22ecc", + "shasum": "" + }, + "require": { + "nikic/php-parser": "^4.6", + "php": ">=7.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Library for counting the lines of code in PHP source code", + "homepage": "https://github.com/sebastianbergmann/lines-of-code", + "support": { + "issues": "https://github.com/sebastianbergmann/lines-of-code/issues", + "source": "https://github.com/sebastianbergmann/lines-of-code/tree/1.0.3" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-11-28T06:42:11+00:00" + }, + { + "name": "sebastian/object-enumerator", + "version": "4.0.4", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/object-enumerator.git", + "reference": "5c9eeac41b290a3712d88851518825ad78f45c71" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/object-enumerator/zipball/5c9eeac41b290a3712d88851518825ad78f45c71", + "reference": "5c9eeac41b290a3712d88851518825ad78f45c71", + "shasum": "" + }, + "require": { + "php": ">=7.3", + "sebastian/object-reflector": "^2.0", + "sebastian/recursion-context": "^4.0" + }, + "require-dev": { + "phpunit/phpunit": "^9.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Traverses array structures and object graphs to enumerate all referenced objects", + "homepage": "https://github.com/sebastianbergmann/object-enumerator/", + "support": { + "issues": "https://github.com/sebastianbergmann/object-enumerator/issues", + "source": "https://github.com/sebastianbergmann/object-enumerator/tree/4.0.4" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-10-26T13:12:34+00:00" + }, + { + "name": "sebastian/object-reflector", + "version": "2.0.4", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/object-reflector.git", + "reference": "b4f479ebdbf63ac605d183ece17d8d7fe49c15c7" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/object-reflector/zipball/b4f479ebdbf63ac605d183ece17d8d7fe49c15c7", + "reference": "b4f479ebdbf63ac605d183ece17d8d7fe49c15c7", + "shasum": "" + }, + "require": { + "php": ">=7.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Allows reflection of object attributes, including inherited and non-public ones", + "homepage": "https://github.com/sebastianbergmann/object-reflector/", + "support": { + "issues": "https://github.com/sebastianbergmann/object-reflector/issues", + "source": "https://github.com/sebastianbergmann/object-reflector/tree/2.0.4" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-10-26T13:14:26+00:00" + }, + { + "name": "sebastian/recursion-context", + "version": "4.0.4", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/recursion-context.git", + "reference": "cd9d8cf3c5804de4341c283ed787f099f5506172" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/cd9d8cf3c5804de4341c283ed787f099f5506172", + "reference": "cd9d8cf3c5804de4341c283ed787f099f5506172", + "shasum": "" + }, + "require": { + "php": ">=7.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + }, + { + "name": "Jeff Welch", + "email": "whatthejeff@gmail.com" + }, + { + "name": "Adam Harvey", + "email": "aharvey@php.net" + } + ], + "description": "Provides functionality to recursively process PHP variables", + "homepage": "http://www.github.com/sebastianbergmann/recursion-context", + "support": { + "issues": "https://github.com/sebastianbergmann/recursion-context/issues", + "source": "https://github.com/sebastianbergmann/recursion-context/tree/4.0.4" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-10-26T13:17:30+00:00" + }, + { + "name": "sebastian/resource-operations", + "version": "3.0.3", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/resource-operations.git", + "reference": "0f4443cb3a1d92ce809899753bc0d5d5a8dd19a8" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/resource-operations/zipball/0f4443cb3a1d92ce809899753bc0d5d5a8dd19a8", + "reference": "0f4443cb3a1d92ce809899753bc0d5d5a8dd19a8", + "shasum": "" + }, + "require": { + "php": ">=7.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Provides a list of PHP built-in functions that operate on resources", + "homepage": "https://www.github.com/sebastianbergmann/resource-operations", + "support": { + "issues": "https://github.com/sebastianbergmann/resource-operations/issues", + "source" : "https://github.com/sebastianbergmann/resource-operations/tree/3.0.3" + }, + "funding" : [ + { + "url" : "https://github.com/sebastianbergmann", + "type" : "github" + } + ], + "time" : "2020-09-28T06:45:17+00:00" + }, + { + "name" : "sebastian/type", + "version" : "3.2.0", + "source" : { + "type" : "git", + "url" : "https://github.com/sebastianbergmann/type.git", + "reference" : "fb3fe09c5f0bae6bc27ef3ce933a1e0ed9464b6e" + }, + "dist" : { + "type" : "zip", + "url" : "https://api.github.com/repos/sebastianbergmann/type/zipball/fb3fe09c5f0bae6bc27ef3ce933a1e0ed9464b6e", + "reference" : "fb3fe09c5f0bae6bc27ef3ce933a1e0ed9464b6e", + "shasum" : "" + }, + "require" : { + "php" : ">=7.3" + }, + "require-dev" : { + "phpunit/phpunit" : "^9.5" + }, + "type" : "library", + "extra" : { + "branch-alias" : { + "dev-master" : "3.2-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Collection of value objects that represent the types of the PHP type system", + "homepage": "https://github.com/sebastianbergmann/type", + "support": { + "issues": "https://github.com/sebastianbergmann/type/issues", + "source" : "https://github.com/sebastianbergmann/type/tree/3.2.0" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time" : "2022-09-12T14:47:03+00:00" + }, + { + "name": "sebastian/version", + "version": "3.0.2", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/version.git", + "reference": "c6c1022351a901512170118436c764e473f6de8c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/c6c1022351a901512170118436c764e473f6de8c", + "reference": "c6c1022351a901512170118436c764e473f6de8c", + "shasum": "" + }, + "require": { + "php": ">=7.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Library that helps with managing the version number of Git-hosted PHP projects", + "homepage": "https://github.com/sebastianbergmann/version", + "support": { + "issues": "https://github.com/sebastianbergmann/version/issues", + "source" : "https://github.com/sebastianbergmann/version/tree/3.0.2" + }, + "funding" : [ + { + "url" : "https://github.com/sebastianbergmann", + "type" : "github" + } + ], + "time" : "2020-09-28T06:39:44+00:00" + }, + { + "name" : "symfony/console", + "version" : "v6.1.4", + "source" : { + "type" : "git", + "url" : "https://github.com/symfony/console.git", + "reference" : "7fccea8728aa2d431a6725b02b3ce759049fc84d" + }, + "dist" : { + "type" : "zip", + "url" : "https://api.github.com/repos/symfony/console/zipball/7fccea8728aa2d431a6725b02b3ce759049fc84d", + "reference" : "7fccea8728aa2d431a6725b02b3ce759049fc84d", + "shasum" : "" + }, + "require" : { + "php" : ">=8.1", + "symfony/deprecation-contracts" : "^2.1|^3", + "symfony/polyfill-mbstring" : "~1.0", + "symfony/service-contracts" : "^1.1|^2|^3", + "symfony/string" : "^5.4|^6.0" + }, + "conflict" : { + "symfony/dependency-injection" : "<5.4", + "symfony/dotenv" : "<5.4", + "symfony/event-dispatcher": "<5.4", + "symfony/lock": "<5.4", + "symfony/process": "<5.4" + }, + "provide": { + "psr/log-implementation": "1.0|2.0|3.0" + }, + "require-dev": { + "psr/log": "^1|^2|^3", + "symfony/config": "^5.4|^6.0", + "symfony/dependency-injection": "^5.4|^6.0", + "symfony/event-dispatcher": "^5.4|^6.0", + "symfony/lock": "^5.4|^6.0", + "symfony/process": "^5.4|^6.0", + "symfony/var-dumper": "^5.4|^6.0" + }, + "suggest": { + "psr/log": "For using the console logger", + "symfony/event-dispatcher": "", + "symfony/lock": "", + "symfony/process": "" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\Console\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors" : [ + { + "name" : "Fabien Potencier", + "email" : "fabien@symfony.com" + }, + { + "name" : "Symfony Community", + "homepage" : "https://symfony.com/contributors" + } + ], + "description" : "Eases the creation of beautiful and testable command line interfaces", + "homepage" : "https://symfony.com", + "keywords" : [ + "cli", + "command line", + "console", + "terminal" + ], + "support" : { + "source" : "https://github.com/symfony/console/tree/v6.1.4" + }, + "funding" : [ + { + "url" : "https://symfony.com/sponsor", + "type" : "custom" + }, + { + "url" : "https://github.com/fabpot", + "type" : "github" + }, + { + "url" : "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type" : "tidelift" + } + ], + "time" : "2022-08-26T10:32:31+00:00" + }, + { + "name" : "symfony/deprecation-contracts", + "version" : "v3.1.1", + "source" : { + "type" : "git", + "url" : "https://github.com/symfony/deprecation-contracts.git", + "reference" : "07f1b9cc2ffee6aaafcf4b710fbc38ff736bd918" + }, + "dist" : { + "type" : "zip", + "url" : "https://api.github.com/repos/symfony/deprecation-contracts/zipball/07f1b9cc2ffee6aaafcf4b710fbc38ff736bd918", + "reference" : "07f1b9cc2ffee6aaafcf4b710fbc38ff736bd918", + "shasum" : "" + }, + "require" : { + "php" : ">=8.1" + }, + "type" : "library", + "extra" : { + "branch-alias" : { + "dev-main" : "3.1-dev" + }, + "thanks" : { + "name" : "symfony/contracts", + "url" : "https://github.com/symfony/contracts" + } + }, + "autoload" : { + "files" : [ + "function.php" + ] + }, + "notification-url" : "https://packagist.org/downloads/", + "license" : [ + "MIT" + ], + "authors" : [ + { + "name" : "Nicolas Grekas", + "email" : "p@tchwork.com" + }, + { + "name" : "Symfony Community", + "homepage" : "https://symfony.com/contributors" + } + ], + "description" : "A generic function and convention to trigger deprecation notices", + "homepage" : "https://symfony.com", + "support" : { + "source" : "https://github.com/symfony/deprecation-contracts/tree/v3.1.1" + }, + "funding" : [ + { + "url" : "https://symfony.com/sponsor", + "type" : "custom" + }, + { + "url" : "https://github.com/fabpot", + "type" : "github" + }, + { + "url" : "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type" : "tidelift" + } + ], + "time" : "2022-02-25T11:15:52+00:00" + }, + { + "name" : "symfony/polyfill-ctype", + "version" : "v1.26.0", + "source" : { + "type" : "git", + "url" : "https://github.com/symfony/polyfill-ctype.git", + "reference" : "6fd1b9a79f6e3cf65f9e679b23af304cd9e010d4" + }, + "dist" : { + "type" : "zip", + "url" : "https://api.github.com/repos/symfony/polyfill-ctype/zipball/6fd1b9a79f6e3cf65f9e679b23af304cd9e010d4", + "reference" : "6fd1b9a79f6e3cf65f9e679b23af304cd9e010d4", + "shasum" : "" + }, + "require" : { + "php" : ">=7.1" + }, + "provide" : { + "ext-ctype" : "*" + }, + "suggest" : { + "ext-ctype" : "For best performance" + }, + "type" : "library", + "extra": { + "branch-alias": { + "dev-main" : "1.26-dev" + }, + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Ctype\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Gert de Pagter", + "email": "BackEndTea@gmail.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill for ctype functions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "ctype", + "polyfill", + "portable" + ], + "support": { + "source" : "https://github.com/symfony/polyfill-ctype/tree/v1.26.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url" : "https://github.com/fabpot", + "type" : "github" + }, + { + "url" : "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type" : "tidelift" + } + ], + "time" : "2022-05-24T11:49:31+00:00" + }, + { + "name" : "symfony/polyfill-intl-grapheme", + "version" : "v1.26.0", + "source" : { + "type" : "git", + "url" : "https://github.com/symfony/polyfill-intl-grapheme.git", + "reference" : "433d05519ce6990bf3530fba6957499d327395c2" + }, + "dist" : { + "type" : "zip", + "url" : "https://api.github.com/repos/symfony/polyfill-intl-grapheme/zipball/433d05519ce6990bf3530fba6957499d327395c2", + "reference" : "433d05519ce6990bf3530fba6957499d327395c2", + "shasum" : "" + }, + "require" : { + "php" : ">=7.1" + }, + "suggest" : { + "ext-intl" : "For best performance" + }, + "type" : "library", + "extra" : { + "branch-alias" : { + "dev-main" : "1.26-dev" + }, + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Intl\\Grapheme\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill for intl's grapheme_* functions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "grapheme", + "intl", + "polyfill", + "portable", + "shim" + ], + "support": { + "source" : "https://github.com/symfony/polyfill-intl-grapheme/tree/v1.26.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url" : "https://github.com/fabpot", + "type" : "github" + }, + { + "url" : "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type" : "tidelift" + } + ], + "time" : "2022-05-24T11:49:31+00:00" + }, + { + "name" : "symfony/polyfill-intl-normalizer", + "version" : "v1.26.0", + "source" : { + "type" : "git", + "url" : "https://github.com/symfony/polyfill-intl-normalizer.git", + "reference" : "219aa369ceff116e673852dce47c3a41794c14bd" + }, + "dist" : { + "type" : "zip", + "url" : "https://api.github.com/repos/symfony/polyfill-intl-normalizer/zipball/219aa369ceff116e673852dce47c3a41794c14bd", + "reference" : "219aa369ceff116e673852dce47c3a41794c14bd", + "shasum" : "" + }, + "require" : { + "php" : ">=7.1" + }, + "suggest" : { + "ext-intl" : "For best performance" + }, + "type" : "library", + "extra" : { + "branch-alias" : { + "dev-main" : "1.26-dev" + }, + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Intl\\Normalizer\\": "" + }, + "classmap": [ + "Resources/stubs" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill for intl's Normalizer class and related functions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "intl", + "normalizer", + "polyfill", + "portable", + "shim" + ], + "support": { + "source" : "https://github.com/symfony/polyfill-intl-normalizer/tree/v1.26.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url" : "https://github.com/fabpot", + "type" : "github" + }, + { + "url" : "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type" : "tidelift" + } + ], + "time" : "2022-05-24T11:49:31+00:00" + }, + { + "name" : "symfony/polyfill-mbstring", + "version" : "v1.26.0", + "source" : { + "type" : "git", + "url" : "https://github.com/symfony/polyfill-mbstring.git", + "reference" : "9344f9cb97f3b19424af1a21a3b0e75b0a7d8d7e" + }, + "dist" : { + "type" : "zip", + "url" : "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/9344f9cb97f3b19424af1a21a3b0e75b0a7d8d7e", + "reference" : "9344f9cb97f3b19424af1a21a3b0e75b0a7d8d7e", + "shasum" : "" + }, + "require" : { + "php" : ">=7.1" + }, + "provide" : { + "ext-mbstring" : "*" + }, + "suggest" : { + "ext-mbstring" : "For best performance" + }, + "type" : "library", + "extra": { + "branch-alias": { + "dev-main" : "1.26-dev" + }, + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Mbstring\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill for the Mbstring extension", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "mbstring", + "polyfill", + "portable", + "shim" + ], + "support": { + "source" : "https://github.com/symfony/polyfill-mbstring/tree/v1.26.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url" : "https://github.com/fabpot", + "type" : "github" + }, + { + "url" : "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type" : "tidelift" + } + ], + "time" : "2022-05-24T11:49:31+00:00" + }, + { + "name" : "symfony/service-contracts", + "version" : "v3.1.1", + "source" : { + "type" : "git", + "url" : "https://github.com/symfony/service-contracts.git", + "reference" : "925e713fe8fcacf6bc05e936edd8dd5441a21239" + }, + "dist" : { + "type" : "zip", + "url" : "https://api.github.com/repos/symfony/service-contracts/zipball/925e713fe8fcacf6bc05e936edd8dd5441a21239", + "reference" : "925e713fe8fcacf6bc05e936edd8dd5441a21239", + "shasum" : "" + }, + "require" : { + "php" : ">=8.1", + "psr/container" : "^2.0" + }, + "conflict" : { + "ext-psr" : "<1.1|>=2" + }, + "suggest" : { + "symfony/service-implementation" : "" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main" : "3.1-dev" + }, + "thanks": { + "name": "symfony/contracts", + "url": "https://github.com/symfony/contracts" + } + }, + "autoload": { + "psr-4" : { + "Symfony\\Contracts\\Service\\" : "" + }, + "exclude-from-classmap" : [ + "/Test/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Generic abstractions related to writing services", + "homepage": "https://symfony.com", + "keywords": [ + "abstractions", + "contracts", + "decoupling", + "interfaces", + "interoperability", + "standards" + ], + "support": { + "source" : "https://github.com/symfony/service-contracts/tree/v3.1.1" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url" : "https://github.com/fabpot", + "type" : "github" + }, + { + "url" : "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type" : "tidelift" + } + ], + "time" : "2022-05-30T19:18:58+00:00" + }, + { + "name" : "symfony/string", + "version" : "v6.1.4", + "source" : { + "type" : "git", + "url" : "https://github.com/symfony/string.git", + "reference" : "290972cad7b364e3befaa74ba0ec729800fb161c" + }, + "dist" : { + "type" : "zip", + "url" : "https://api.github.com/repos/symfony/string/zipball/290972cad7b364e3befaa74ba0ec729800fb161c", + "reference" : "290972cad7b364e3befaa74ba0ec729800fb161c", + "shasum" : "" + }, + "require" : { + "php" : ">=8.1", + "symfony/polyfill-ctype" : "~1.8", + "symfony/polyfill-intl-grapheme" : "~1.0", + "symfony/polyfill-intl-normalizer" : "~1.0", + "symfony/polyfill-mbstring" : "~1.0" + }, + "conflict" : { + "symfony/translation-contracts" : "<2.0" + }, + "require-dev": { + "symfony/error-handler": "^5.4|^6.0", + "symfony/http-client": "^5.4|^6.0", + "symfony/translation-contracts": "^2.0|^3.0", + "symfony/var-exporter": "^5.4|^6.0" + }, + "type": "library", + "autoload": { + "files": [ + "Resources/functions.php" + ], + "psr-4": { + "Symfony\\Component\\String\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Provides an object-oriented API to strings and deals with bytes, UTF-8 code points and grapheme clusters in a unified way", + "homepage": "https://symfony.com", + "keywords": [ + "grapheme", + "i18n", + "string", + "unicode", + "utf-8", + "utf8" + ], + "support": { + "source" : "https://github.com/symfony/string/tree/v6.1.4" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time" : "2022-08-12T18:05:43+00:00" + }, + { + "name": "theseer/tokenizer", + "version": "1.2.1", + "source": { + "type": "git", + "url": "https://github.com/theseer/tokenizer.git", + "reference": "34a41e998c2183e22995f158c581e7b5e755ab9e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/theseer/tokenizer/zipball/34a41e998c2183e22995f158c581e7b5e755ab9e", + "reference": "34a41e998c2183e22995f158c581e7b5e755ab9e", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "ext-tokenizer": "*", + "ext-xmlwriter": "*", + "php": "^7.2 || ^8.0" + }, + "type": "library", + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Arne Blankerts", + "email": "arne@blankerts.de", + "role": "Developer" + } + ], + "description": "A small library for converting tokenized PHP source code into XML and potentially other formats", + "support": { + "issues": "https://github.com/theseer/tokenizer/issues", + "source": "https://github.com/theseer/tokenizer/tree/1.2.1" + }, + "funding": [ + { + "url": "https://github.com/theseer", + "type": "github" + } + ], + "time": "2021-07-28T10:34:58+00:00" + } + ], + "aliases": [], + "minimum-stability": "stable", + "stability-flags": [], + "prefer-stable": false, + "prefer-lowest": false, + "platform": { + "php": ">=8.0", + "ext-json": "*", + "ext-mbstring": "*" + }, + "platform-dev": [], + "plugin-api-version" : "2.3.0" } \ No newline at end of file diff --git a/sample/HomeController.php b/sample/HomeController.php index 01cc6eb..28db1a5 100644 --- a/sample/HomeController.php +++ b/sample/HomeController.php @@ -1,48 +1,48 @@ -send([ "message" => "Hello from controller::home" ]); - } - - public function getUsers(Request $request) : void { - $request->send([ "message" => "Hello from controller::home", "ses" => $_SESSION ]); - } - - public function addUser(Request $request) : void { - $request->send([ "message" => "Hello from controller::home" ]); - } - - public function updateUser(Request $request) : void { - $request->send([ "message" => "Hello from controller::home" ]); - } - - public function replaceUser(Request $request) : void { - $request->send([ "message" => "Hello from controller::home" ]); - } - - public function deleteUser(Request $request) : void { - $request->send([ "message" => "Hello from controller::home" ]); - } - - public function test(Request $request, int $userID, string $username, float $amount, bool $valid) : void { - var_dump($this->injected); - echo "Dynamic route here"; - } - - public function dependency_injection_test(Request $request) : string { - //$request->send([ "isInstanceOf" => $this->injected instanceof InjectedClass ]); - return json_encode([ 'isInstanceOf' => $this->injected instanceof InjectedClass ]); - } +send([ "message" => "Hello from controller::home" ]); + } + + public function getUsers(Request $request) : void { + $request->send([ "message" => "Hello from controller::home", "ses" => $_SESSION ]); + } + + public function addUser(Request $request) : void { + $request->send([ "message" => "Hello from controller::home" ]); + } + + public function updateUser(Request $request) : void { + $request->send([ "message" => "Hello from controller::home" ]); + } + + public function replaceUser(Request $request) : void { + $request->send([ "message" => "Hello from controller::home" ]); + } + + public function deleteUser(Request $request) : void { + $request->send([ "message" => "Hello from controller::home" ]); + } + + public function test(Request $request, int $userID, string $username, float $amount, bool $valid) : void { + var_dump($this->injected); + echo "Dynamic route here"; + } + + public function dependency_injection_test(Request $request) : string { + //$request->send([ "isInstanceOf" => $this->injected instanceof InjectedClass ]); + return json_encode([ 'isInstanceOf' => $this->injected instanceof InjectedClass ]); + } } \ No newline at end of file diff --git a/sample/InjectController.php b/sample/InjectController.php index 26a43ff..5935faf 100644 --- a/sample/InjectController.php +++ b/sample/InjectController.php @@ -1,17 +1,17 @@ - - * Date: 2022-06-04 - * Project: PHP-routing - */ - class InjectController - { - public function __construct(protected InjectedClass $injectedClass) { } - - public function __invoke() : void { - echo "Hello"; - } + + * Date: 2022-06-04 + * Project: PHP-routing + */ + class InjectController + { + public function __construct(protected InjectedClass $injectedClass) { } + + public function __invoke() : void { + echo "Hello"; + } } \ No newline at end of file diff --git a/sample/InjectedClass.php b/sample/InjectedClass.php index 076bfa9..152ac8f 100644 --- a/sample/InjectedClass.php +++ b/sample/InjectedClass.php @@ -1,15 +1,15 @@ - - * Date: 2022-06-03 - * Project: PHP-routing - */ - class InjectedClass - { - public function test() : void { - echo "Test method from the injected class called"; - } + + * Date: 2022-06-03 + * Project: PHP-routing + */ + class InjectedClass + { + public function test() : void { + echo "Test method from the injected class called"; + } } \ No newline at end of file diff --git a/sample/Middleware.php b/sample/Middleware.php index c1102a4..b7cef78 100644 --- a/sample/Middleware.php +++ b/sample/Middleware.php @@ -1,30 +1,30 @@ -headers("Host") ]); - echo "
"; - } - - //The $request argument can also be emitted if it is not needed - public function test_method() : void { - echo 'RolesMiddleware test method' . PHP_EOL; - } +headers("Host") ]); + echo "
"; + } + + //The $request argument can also be emitted if it is not needed + public function test_method() : void { + echo 'RolesMiddleware test method' . PHP_EOL; + } } \ No newline at end of file diff --git a/sample/index.php b/sample/index.php index 3996fc7..40882dc 100644 --- a/sample/index.php +++ b/sample/index.php @@ -1,213 +1,213 @@ -add('/', function (Request $request) { - echo json_encode([ 'message' => 'Hello World' ]); - }); - - // When using chained method calls either use `save()` or `add()` method at the end to indicate an end of a chain - // save() method can still be chained onto if needed, but add() can not - $routes - ->prefix("/test") - ->middleware([ 'decode_token' ]) - ->get("/t1", function () { }) - ->get("/t2", function () { }) - ->get("/t3", function () { }) - ->save(false) // by passing the false argument here, we keep all the previous shared data from the chain (previous prefix(es) and middlewares) - ->prefix("/test2") - ->middleware([ "verify_token" ]) - ->get("/t4", function () { }) - ->get("/t5", function () { }) - ->get("/t6", function () { }) - ->save() // by not passing the false argument here, we are removing all shared data from the previous chains (previous prefix(es) and middlewares) - ->prefix("/test3") - ->middleware([ "verify_token" ]) - ->get("/t7", function () { }) - ->get("/t8", function () { }) - ->get("/t9", function () { }) - ->add(); //using save or add at the end makes the chaining stop and allows for other independent routes to be added - - $routes->add("/routes", function (Request $request) { - global $routes; - $request->send($routes->get_routes()); - }); - - $routes->add('/test', function (Request $request) { - $request - ->status(200, 'OK') - ->send([ 'message' => 'Welcome' ]); - }); - - $routes - ->prefix('/user') - ->middleware([ 'verify_token' ]) - ->route('/', [ HomeController::class, 'getUsers' ], Routes::GET) - ->route('/', [ HomeController::class, 'addUser' ], Routes::POST) - ->route('/', [ HomeController::class, 'updateUser' ], Routes::PATCH) - ->route('/', [ HomeController::class, 'replaceUser' ], Routes::PUT) - ->add('/test', [ HomeController::class, 'deleteUser' ], Routes::DELETE); - - $routes->add('/test', function () { - }, [ Routes::PATCH, Routes::POST ]); - - $routes->get("/test-get", function () { - echo "Hello from test-get"; - }); - - $routes->post("/test-post", function () { - echo "Hello from test-post"; - }); - - $routes->put("/test-put", function () { - echo "Hello from test-put"; - }); - - $routes->patch("/test-patch", function () { - echo "Hello from test-patch"; - }); - - $routes->delete("/test-delete", function () { - echo "Hello from test-delete"; - }); - - $routes->add('/test/{int:userID}-{username}/{float:amount}/{bool:valid}', function ( - Request $request, - int $userID, - string $username, - float $amount, - bool $valid - ) { - echo 'Dynamic route here'; - }); - - $routes->add( - '/test/{int:userID}-{username}/{float:amount}/{bool:valid}', - [ HomeController::class, 'test' ], - [ Routes::PUT ] - ); # It works like this also - - $routes - ->middleware([ - [ Middleware::class, 'verify_token' ], - [ Middleware::class, 'test' ], - 'verify_token', - ]) - ->add('/test-hello', function (Request $request) { - $request->send([ 'message' => 'Hello' ]); - }); - - - $routes - ->middleware([ - 'test_middleware', - 'has_roles' => 'admin,user', - [ Middleware::class, 'test_method' ], - [ Middleware::class, 'has_role', 'Admin', 'Moderator', [ 'User', 'Bot' ] ], - ]) - ->add('/testing', function (Request $request) { - $request->send([ 'msg' => 'testing' ]); - }); - - - $routes->add('/', function (Request $request) { - echo "
";
-			print_r([ $_REQUEST, $_FILES ]);
-		}, [ Routes::PATCH ]);
-
-		$routes->add('/', function (Request $request) {
-			echo "
";
-			print_r([ $_REQUEST, $_FILES ]);
-		}, [ Routes::PUT ]);
-
-
-		//This $otherRoutes variable could be defined in a different file and included here only via require or include
-		$otherRoutes = new Routes();
-		$otherRoutes->prefix("/sample")
-					->get("/", function (Request $request) { })
-					->get("/sample1", function (Request $request) { })
-					->get("/sample2", function (Request $request) { })
-					->save();
-
-		$routes->append($otherRoutes->get_routes());
-
-
-		$routes->add("/headers", function (Request $request) {
-			$request->header("Content-type", "text/plain")
-					->header([ "foo" => "bar", "best" => "test" ])
-					->header((object) [ "X-Auth" => "Token {token-123}" ])
-					->status(201)
-					->send([ "message" => "hello" ]);
-		}, Routes::GET);
-
-		$routes->add(
-			'/demo',
-			[ HomeController::class, 'dependency_injection_test', [ new InjectedClass() ] ],
-			Routes::GET
-		);
-
-		$routes->add(
-			"/inject",
-			[ InjectController::class ]
-		);
-
-		$routes->handle();
-	} catch ( RouteNotFoundException $ex ) {
-		$routes->request->status(404, 'Route not found')->send([ 'error' => [ 'message' => $ex->getMessage() ] ]);
-	} catch ( CallbackNotFound $ex ) {
-		$routes->request->status(404, 'Callback method not found')
-						->send([ 'error' => [ 'message' => $ex->getMessage() ] ]);
-	} catch ( Exception $ex ) {
-		$code = $ex->getCode() ?? 500;
-		$routes->request->status($code)->send([ 'error' => [ 'message' => $ex->getMessage() ] ]);
-	}
-
-	function test_route_function() : void {
-		echo json_encode([ 'message' => 'Welcome from test route' ]);
-	}
-
-	function verify_token() : void {
-		//Do something
-	}
-
-	function has_roles(string $allowedRoles) : void {
-		//Do something
-	}
-
-	function test_middleware() : void {
-
+add('/', function (Request $request) {
+			echo json_encode([ 'message' => 'Hello World' ]);
+		});
+
+		// When using chained method calls either use `save()` or `add()` method at the end to indicate an end of a chain
+		// save() method can still be chained onto if needed, but add() can not
+		$routes
+			->prefix("/test")
+			->middleware([ 'decode_token' ])
+			->get("/t1", function () { })
+			->get("/t2", function () { })
+			->get("/t3", function () { })
+			->save(false) // by passing the false argument here, we keep all the previous shared data from the chain (previous prefix(es) and middlewares)
+			->prefix("/test2")
+			->middleware([ "verify_token" ])
+			->get("/t4", function () { })
+			->get("/t5", function () { })
+			->get("/t6", function () { })
+			->save() // by not passing the false argument here, we are removing all shared data from the previous chains (previous prefix(es) and middlewares)
+			->prefix("/test3")
+			->middleware([ "verify_token" ])
+			->get("/t7", function () { })
+			->get("/t8", function () { })
+			->get("/t9", function () { })
+			->add(); //using save or add at the end makes the chaining stop and allows for other independent routes to be added
+
+		$routes->add("/routes", function (Request $request) {
+			global $routes;
+			$request->send($routes->get_routes());
+		});
+
+		$routes->add('/test', function (Request $request) {
+			$request
+				->status(200, 'OK')
+				->send([ 'message' => 'Welcome' ]);
+		});
+
+		$routes
+			->prefix('/user')
+			->middleware([ 'verify_token' ])
+			->route('/', [ HomeController::class, 'getUsers' ], Routes::GET)
+			->route('/', [ HomeController::class, 'addUser' ], Routes::POST)
+			->route('/', [ HomeController::class, 'updateUser' ], Routes::PATCH)
+			->route('/', [ HomeController::class, 'replaceUser' ], Routes::PUT)
+			->add('/test', [ HomeController::class, 'deleteUser' ], Routes::DELETE);
+
+		$routes->add('/test', function () {
+		}, [ Routes::PATCH, Routes::POST ]);
+
+		$routes->get("/test-get", function () {
+			echo "Hello from test-get";
+		});
+
+		$routes->post("/test-post", function () {
+			echo "Hello from test-post";
+		});
+
+		$routes->put("/test-put", function () {
+			echo "Hello from test-put";
+		});
+
+		$routes->patch("/test-patch", function () {
+			echo "Hello from test-patch";
+		});
+
+		$routes->delete("/test-delete", function () {
+			echo "Hello from test-delete";
+		});
+
+		$routes->add('/test/{int:userID}-{username}/{float:amount}/{bool:valid}', function (
+			Request $request,
+			int     $userID,
+			string  $username,
+			float   $amount,
+			bool    $valid
+		) {
+			echo 'Dynamic route here';
+		});
+
+		$routes->add(
+			'/test/{int:userID}-{username}/{float:amount}/{bool:valid}',
+			[ HomeController::class, 'test' ],
+			[ Routes::PUT ]
+		); # It works like this also
+
+		$routes
+			->middleware([
+				[ Middleware::class, 'verify_token' ],
+				[ Middleware::class, 'test' ],
+				'verify_token',
+			])
+			->add('/test-hello', function (Request $request) {
+				$request->send([ 'message' => 'Hello' ]);
+			});
+
+
+		$routes
+			->middleware([
+				'test_middleware',
+				'has_roles' => 'admin,user',
+				[ Middleware::class, 'test_method' ],
+				[ Middleware::class, 'has_role', 'Admin', 'Moderator', [ 'User', 'Bot' ] ],
+			])
+			->add('/testing', function (Request $request) {
+				$request->send([ 'msg' => 'testing' ]);
+			});
+
+
+		$routes->add('/', function (Request $request) {
+			echo "
";
+			print_r([ $_REQUEST, $_FILES ]);
+		}, [ Routes::PATCH ]);
+
+		$routes->add('/', function (Request $request) {
+			echo "
";
+			print_r([ $_REQUEST, $_FILES ]);
+		}, [ Routes::PUT ]);
+
+
+		//This $otherRoutes variable could be defined in a different file and included here only via require or include
+		$otherRoutes = new Routes();
+		$otherRoutes->prefix("/sample")
+					->get("/", function (Request $request) { })
+					->get("/sample1", function (Request $request) { })
+					->get("/sample2", function (Request $request) { })
+					->save();
+
+		$routes->append($otherRoutes->get_routes());
+
+
+		$routes->add("/headers", function (Request $request) {
+			$request->header("Content-type", "text/plain")
+					->header([ "foo" => "bar", "best" => "test" ])
+					->header((object) [ "X-Auth" => "Token {token-123}" ])
+					->status(201)
+					->send([ "message" => "hello" ]);
+		}, Routes::GET);
+
+		$routes->add(
+			'/demo',
+			[ HomeController::class, 'dependency_injection_test', [ new InjectedClass() ] ],
+			Routes::GET
+		);
+
+		$routes->add(
+			"/inject",
+			[ InjectController::class ]
+		);
+
+		$routes->handle();
+	} catch ( RouteNotFoundException $ex ) {
+		$routes->request->status(404, 'Route not found')->send([ 'error' => [ 'message' => $ex->getMessage() ] ]);
+	} catch ( CallbackNotFound $ex ) {
+		$routes->request->status(404, 'Callback method not found')
+						->send([ 'error' => [ 'message' => $ex->getMessage() ] ]);
+	} catch ( Exception $ex ) {
+		$code = $ex->getCode() ?? 500;
+		$routes->request->status($code)->send([ 'error' => [ 'message' => $ex->getMessage() ] ]);
+	}
+
+	function test_route_function() : void {
+		echo json_encode([ 'message' => 'Welcome from test route' ]);
+	}
+
+	function verify_token() : void {
+		//Do something
+	}
+
+	function has_roles(string $allowedRoles) : void {
+		//Do something
+	}
+
+	function test_middleware() : void {
+
 	}
\ No newline at end of file
diff --git a/sample/nestedClasses.php b/sample/nestedClasses.php
index 61f468f..7910eae 100644
--- a/sample/nestedClasses.php
+++ b/sample/nestedClasses.php
@@ -1,24 +1,24 @@
-
-	 * Date: 2022-06-05
-	 * Project: PHP-routing
-	 */
-	declare( strict_types=1 );
-
-	namespace Gac\Routing\sample;
-
-	class A
-	{
-		public function __construct(protected B $b, protected C $c, protected bool $test) { }
-	}
-
-	class B
-	{
-		public function __construct(protected C $c) { }
-	}
-
-	class C
-	{
-		public function __construct() { }
+
+	 * Date: 2022-06-05
+	 * Project: PHP-routing
+	 */
+	declare( strict_types=1 );
+
+	namespace Gac\Routing\sample;
+
+	class A
+	{
+		public function __construct(protected B $b, protected C $c, protected bool $test) { }
+	}
+
+	class B
+	{
+		public function __construct(protected C $c) { }
+	}
+
+	class C
+	{
+		public function __construct() { }
 	}
\ No newline at end of file
diff --git a/src/DIContainer.php b/src/DIContainer.php
index 2873812..e2479cb 100644
--- a/src/DIContainer.php
+++ b/src/DIContainer.php
@@ -1,127 +1,127 @@
-
-	 * Date: 2022-06-05
-	 * Project: PHP-routing
-	 */
-
-	namespace Gac\Routing;
-
-	use ReflectionClass;
-	use ReflectionException;
-	use ReflectionUnionType;
-
-	/**
-	 * Class used for handling dependency injection for the library
-	 */
-	class DIContainer
-	{
-
-		/**
-		 * Method used for handling dependency injection
-		 *
-		 * It receives the class name that will be checked if it has any parameters that need to be injected
-		 * and a list of already defined/created arguments to be injected. It will than use the Reflection class API
-		 * to check if the provided class has any injectable parameters and if those parameters also require
-		 * any others to be injected as well using a recursion.
-		 *
-		 * @param string $class Name of the class for which to auto-inject arguments
-		 * @param array $arguments List of arguments that will be passed alongside of auto-injected ones
-		 *
-		 * @return array Return a new list of arguments that holds manually provided and auto-injected arguments
-		 */
-		public static function get(string $class, array $arguments = []) : array {
-
-			if ( !class_exists($class) ) {
-				return $arguments;
-			}
-
-			try {
-				$reflection = new ReflectionClass($class);
-
-				if ( !$reflection->isInstantiable() ) {
-					$arguments["err"][] = 1;
-					return $arguments;
-				}
-
-				$constructor = $reflection->getConstructor();
-
-				if ( !$constructor ) {
-					return $arguments;
-				}
-
-				$parameters = $constructor->getParameters();
-
-				if ( is_null($parameters) || count($parameters) === 0 ) {
-					return $arguments;
-				}
-
-				foreach ( $parameters as $parameter ) {
-					if ( isset($arguments[$parameter->name]) ) {
-						continue;
-					}
-
-					if ( $parameter->isDefaultValueAvailable() ) {
-						continue;
-					}
-
-					$type = $parameter->getType();
-
-					if ( $type === NULL ) {
-						continue;
-					}
-
-					if ( $type instanceof ReflectionUnionType ) {
-						continue;
-					}
-
-					if ( $type->isBuiltin() ) {
-						$arguments[$parameter->getName()] = $arguments[$parameter->getName()] ?? match ( $type->getName() ) {
-							'int' => 0,
-							'float', 'double' => 0.0,
-							'bool' => false,
-							default => "",
-						};
-						continue;
-					}
-
-					if ( !class_exists($type->getName()) ) {
-						continue;
-					}
-
-					if ( $type->allowsNull() ) {
-						continue;
-					}
-
-					/*
-					 * Removed: It was causing DI to fail when mixing manually defined arguments and auto-detected ones
-					 * if ( count($arguments) > 0 && in_array(new ( $type->getName() ), $arguments) ) {
-					 * 	continue;
-					 * }
-					*/
-
-					$injectedClass = new ReflectionClass($type->getName());
-					if ( !$injectedClass->isInstantiable() ) {
-						continue;
-					}
-
-					/**
-					 * NOTE:
-					 * In a scenario like this:
-					 *    class A { public function __construct(protected B $b){} }
-					 *    class B { public function __construct(protected A $a){} }
-					 * this could lead to an infinite loop
-					 */
-					$injectedClassArguments = self::get($injectedClass->getName());
-					if ( count($injectedClassArguments) > 0 ) {
-						$arguments[$parameter->getName()] = $injectedClass->newInstance(...$injectedClassArguments);
-					} else {
-						$arguments[$parameter->getName()] = $injectedClass->newInstance();
-					}
-				}
-			} catch ( ReflectionException ) {
-			} finally {
-				return $arguments;
-			}
-		}
+
+	 * Date: 2022-06-05
+	 * Project: PHP-routing
+	 */
+
+	namespace Gac\Routing;
+
+	use ReflectionClass;
+	use ReflectionException;
+	use ReflectionUnionType;
+
+	/**
+	 * Class used for handling dependency injection for the library
+	 */
+	class DIContainer
+	{
+
+		/**
+		 * Method used for handling dependency injection
+		 *
+		 * It receives the class name that will be checked if it has any parameters that need to be injected
+		 * and a list of already defined/created arguments to be injected. It will than use the Reflection class API
+		 * to check if the provided class has any injectable parameters and if those parameters also require
+		 * any others to be injected as well using a recursion.
+		 *
+		 * @param string $class Name of the class for which to auto-inject arguments
+		 * @param array $arguments List of arguments that will be passed alongside of auto-injected ones
+		 *
+		 * @return array Return a new list of arguments that holds manually provided and auto-injected arguments
+		 */
+		public static function get(string $class, array $arguments = []) : array {
+
+			if ( !class_exists($class) ) {
+				return $arguments;
+			}
+
+			try {
+				$reflection = new ReflectionClass($class);
+
+				if ( !$reflection->isInstantiable() ) {
+					$arguments["err"][] = 1;
+					return $arguments;
+				}
+
+				$constructor = $reflection->getConstructor();
+
+				if ( !$constructor ) {
+					return $arguments;
+				}
+
+				$parameters = $constructor->getParameters();
+
+				if ( is_null($parameters) || count($parameters) === 0 ) {
+					return $arguments;
+				}
+
+				foreach ( $parameters as $parameter ) {
+					if ( isset($arguments[$parameter->name]) ) {
+						continue;
+					}
+
+					if ( $parameter->isDefaultValueAvailable() ) {
+						continue;
+					}
+
+					$type = $parameter->getType();
+
+					if ( $type === NULL ) {
+						continue;
+					}
+
+					if ( $type instanceof ReflectionUnionType ) {
+						continue;
+					}
+
+					if ( $type->isBuiltin() ) {
+						$arguments[$parameter->getName()] = $arguments[$parameter->getName()] ?? match ( $type->getName() ) {
+							'int' => 0,
+							'float', 'double' => 0.0,
+							'bool' => false,
+							default => "",
+						};
+						continue;
+					}
+
+					if ( !class_exists($type->getName()) ) {
+						continue;
+					}
+
+					if ( $type->allowsNull() ) {
+						continue;
+					}
+
+					/*
+					 * Removed: It was causing DI to fail when mixing manually defined arguments and auto-detected ones
+					 * if ( count($arguments) > 0 && in_array(new ( $type->getName() ), $arguments) ) {
+					 * 	continue;
+					 * }
+					*/
+
+					$injectedClass = new ReflectionClass($type->getName());
+					if ( !$injectedClass->isInstantiable() ) {
+						continue;
+					}
+
+					/**
+					 * NOTE:
+					 * In a scenario like this:
+					 *    class A { public function __construct(protected B $b){} }
+					 *    class B { public function __construct(protected A $a){} }
+					 * this could lead to an infinite loop
+					 */
+					$injectedClassArguments = self::get($injectedClass->getName());
+					if ( count($injectedClassArguments) > 0 ) {
+						$arguments[$parameter->getName()] = $injectedClass->newInstance(...$injectedClassArguments);
+					} else {
+						$arguments[$parameter->getName()] = $injectedClass->newInstance();
+					}
+				}
+			} catch ( ReflectionException ) {
+			} finally {
+				return $arguments;
+			}
+		}
 	}
\ No newline at end of file
diff --git a/src/Request.php b/src/Request.php
index 8fdbcc6..3cd565f 100644
--- a/src/Request.php
+++ b/src/Request.php
@@ -1,192 +1,192 @@
-parse_patch_and_put_request_data();
-			} else {
-				$rawInput = file_get_contents('php://input');
-
-				$input = json_decode($rawInput) ?? [];
-				if ( is_array($input) && count($input) == 0 ) {
-					mb_parse_str($rawInput, $input);
-				}
-			}
-
-			$_REQUEST = array_merge($_REQUEST, (array) $input);
-			$this->data = $_REQUEST;
-		}
-
-		/**
-		 * Returns a value for a specified body argument
-		 *
-		 * @param string $key Which request body argument to be returned
-		 *
-		 * @return mixed Body argument value or NULL if the argument doesn't exist
-		 */
-		public function get(string $key = '') : mixed {
-			return $this->data[$key] ?? NULL;
-		}
-
-		/**
-		 * Returns list of all the header items or a value of a specific item
-		 *
-		 * @param string $key Name of a specific item in the header list to return the value for
-		 *
-		 * @return array|string|null List of header values or a value of a single item
-		 */
-		public function headers(string $key = '') : array|string|null {
-			$headers = getallheaders();
-			return empty($key) ? $headers : $headers[$key] ?? NULL;
-		}
-
-		/**
-		 * Sets the header status code for the response
-		 *
-		 * @param int $statusCode Status code to be set for the response
-		 * @param string $message Message to be sent int the header alongside the status code
-		 *
-		 * @return Request Returns an instance of the Request class so that it can be chained on
-		 */
-		public function status(int $statusCode = 200, string $message = '') : self {
-			header("HTTP/1.1 $statusCode $message");
-			return $this;
-		}
-
-		/**
-		 * Method used for setting custom header properties
-		 *
-		 * @param string|array|object $key Header key value
-		 * @param mixed $value Header value
-		 *
-		 * @return Request Returns an instance of the Request class so that it can be chained on
-		 */
-		public function header(string|array|object $key, mixed $value = NULL) : self {
-			if ( is_string($key) ) {
-				header("$key: $value");
-			} elseif ( is_array($key) || is_object($key) ) {
-				$keys = $key;
-				foreach ( $keys as $key => $value ) {
-					header("$key: $value");
-				}
-			}
-			return $this;
-		}
-
-		/**
-		 * Send response back
-		 *
-		 * @param string|array|object $output Value to be outputted as part of the response
-		 * @param array|object|null $headers Optional list of custom header properties to be sent with the response
-		 */
-		public function send(string|array|object $output, array|object|null $headers = NULL) : void {
-			if ( !is_null($headers) ) {
-				$this->header($headers);
-			}
-			echo json_encode($output);
-		}
-
-		/**
-		 * Private method used for parsing request body data for PUT and PATCH requests
-		 *
-		 * @return array Return an array of request body data
-		 */
-		private function parse_patch_and_put_request_data() : array {
-
-			/* PUT data comes in on the stdin stream */
-			$putData = fopen('php://input', 'r');
-
-			$raw_data = '';
-
-			/* Read the data 1 KB at a time and write to the file */
-			while ( $chunk = fread($putData, 1024) )
-				$raw_data .= $chunk;
-
-			/* Close the streams */
-			fclose($putData);
-
-			// Fetch content and determine boundary
-			$boundary = substr($raw_data, 0, strpos($raw_data, "\r\n"));
-
-			if ( empty($boundary) ) {
-				parse_str($raw_data, $data);
-				return $data ?? [];
-			}
-
-			// Fetch each part
-			$parts = array_slice(explode($boundary, $raw_data), 1);
-			$data = [];
-
-			foreach ( $parts as $part ) {
-				// If this is the last part, break
-				if ( $part == "--\r\n" ) break;
-
-				// Separate content from headers
-				$part = ltrim($part, "\r\n");
-				[ $raw_headers, $body ] = explode("\r\n\r\n", $part, 2);
-
-				// Parse the headers list
-				$raw_headers = explode("\r\n", $raw_headers);
-				$headers = [];
-				foreach ( $raw_headers as $header ) {
-					[ $name, $value ] = explode(':', $header);
-					$headers[strtolower($name)] = ltrim($value, ' ');
-				}
-
-				// Parse the Content-Disposition to get the field name, etc.
-				if ( isset($headers['content-disposition']) ) {
-					$filename = NULL;
-					preg_match(
-						'/^(.+); *name="([^"]+)"(; *filename="([^"]+)")?/',
-						$headers['content-disposition'],
-						$matches
-					);
-					[ , $type, $name ] = $matches;
-
-					//Parse File
-					if ( isset($matches[4]) ) {
-						//if labeled the same as previous, skip
-						if ( isset($_FILES[$matches[2]]) ) {
-							continue;
-						}
-
-						//get filename
-						$filename = $matches[4];
-
-						//get tmp name
-						$filename_parts = pathinfo($filename);
-						$tmp_name = tempnam(ini_get('upload_tmp_dir'), $filename_parts['filename']);
-
-						//populate $_FILES with information, size may be off in multibyte situation
-						$_FILES[$matches[2]] = [
-							'error' => 0,
-							'name' => $filename,
-							'tmp_name' => $tmp_name,
-							'size' => strlen($body),
-							'type' => $type,
-						];
-
-						//place in temporary directory
-						file_put_contents($tmp_name, $body);
-					} else { //Parse Field
-						$data[$name] = substr($body, 0, strlen($body) - 2);
-					}
-				}
-			}
-			return $data ?? [];
-		}
-	}
+parse_patch_and_put_request_data();
+			} else {
+				$rawInput = file_get_contents('php://input');
+
+				$input = json_decode($rawInput) ?? [];
+				if ( is_array($input) && count($input) == 0 ) {
+					mb_parse_str($rawInput, $input);
+				}
+			}
+
+			$_REQUEST = array_merge($_REQUEST, (array) $input);
+			$this->data = $_REQUEST;
+		}
+
+		/**
+		 * Returns a value for a specified body argument
+		 *
+		 * @param string $key Which request body argument to be returned
+		 *
+		 * @return mixed Body argument value or NULL if the argument doesn't exist
+		 */
+		public function get(string $key = '') : mixed {
+			return $this->data[$key] ?? NULL;
+		}
+
+		/**
+		 * Returns list of all the header items or a value of a specific item
+		 *
+		 * @param string $key Name of a specific item in the header list to return the value for
+		 *
+		 * @return array|string|null List of header values or a value of a single item
+		 */
+		public function headers(string $key = '') : array|string|null {
+			$headers = getallheaders();
+			return empty($key) ? $headers : $headers[$key] ?? NULL;
+		}
+
+		/**
+		 * Sets the header status code for the response
+		 *
+		 * @param int $statusCode Status code to be set for the response
+		 * @param string $message Message to be sent int the header alongside the status code
+		 *
+		 * @return Request Returns an instance of the Request class so that it can be chained on
+		 */
+		public function status(int $statusCode = 200, string $message = '') : self {
+			header("HTTP/1.1 $statusCode $message");
+			return $this;
+		}
+
+		/**
+		 * Method used for setting custom header properties
+		 *
+		 * @param string|array|object $key Header key value
+		 * @param mixed $value Header value
+		 *
+		 * @return Request Returns an instance of the Request class so that it can be chained on
+		 */
+		public function header(string|array|object $key, mixed $value = NULL) : self {
+			if ( is_string($key) ) {
+				header("$key: $value");
+			} elseif ( is_array($key) || is_object($key) ) {
+				$keys = $key;
+				foreach ( $keys as $key => $value ) {
+					header("$key: $value");
+				}
+			}
+			return $this;
+		}
+
+		/**
+		 * Send response back
+		 *
+		 * @param string|array|object $output Value to be outputted as part of the response
+		 * @param array|object|null $headers Optional list of custom header properties to be sent with the response
+		 */
+		public function send(string|array|object $output, array|object|null $headers = NULL) : void {
+			if ( !is_null($headers) ) {
+				$this->header($headers);
+			}
+			echo json_encode($output);
+		}
+
+		/**
+		 * Private method used for parsing request body data for PUT and PATCH requests
+		 *
+		 * @return array Return an array of request body data
+		 */
+		private function parse_patch_and_put_request_data() : array {
+
+			/* PUT data comes in on the stdin stream */
+			$putData = fopen('php://input', 'r');
+
+			$raw_data = '';
+
+			/* Read the data 1 KB at a time and write to the file */
+			while ( $chunk = fread($putData, 1024) )
+				$raw_data .= $chunk;
+
+			/* Close the streams */
+			fclose($putData);
+
+			// Fetch content and determine boundary
+			$boundary = substr($raw_data, 0, strpos($raw_data, "\r\n"));
+
+			if ( empty($boundary) ) {
+				parse_str($raw_data, $data);
+				return $data ?? [];
+			}
+
+			// Fetch each part
+			$parts = array_slice(explode($boundary, $raw_data), 1);
+			$data = [];
+
+			foreach ( $parts as $part ) {
+				// If this is the last part, break
+				if ( $part == "--\r\n" ) break;
+
+				// Separate content from headers
+				$part = ltrim($part, "\r\n");
+				[ $raw_headers, $body ] = explode("\r\n\r\n", $part, 2);
+
+				// Parse the headers list
+				$raw_headers = explode("\r\n", $raw_headers);
+				$headers = [];
+				foreach ( $raw_headers as $header ) {
+					[ $name, $value ] = explode(':', $header);
+					$headers[strtolower($name)] = ltrim($value, ' ');
+				}
+
+				// Parse the Content-Disposition to get the field name, etc.
+				if ( isset($headers['content-disposition']) ) {
+					$filename = NULL;
+					preg_match(
+						'/^(.+); *name="([^"]+)"(; *filename="([^"]+)")?/',
+						$headers['content-disposition'],
+						$matches
+					);
+					[ , $type, $name ] = $matches;
+
+					//Parse File
+					if ( isset($matches[4]) ) {
+						//if labeled the same as previous, skip
+						if ( isset($_FILES[$matches[2]]) ) {
+							continue;
+						}
+
+						//get filename
+						$filename = $matches[4];
+
+						//get tmp name
+						$filename_parts = pathinfo($filename);
+						$tmp_name = tempnam(ini_get('upload_tmp_dir'), $filename_parts['filename']);
+
+						//populate $_FILES with information, size may be off in multibyte situation
+						$_FILES[$matches[2]] = [
+							'error' => 0,
+							'name' => $filename,
+							'tmp_name' => $tmp_name,
+							'size' => strlen($body),
+							'type' => $type,
+						];
+
+						//place in temporary directory
+						file_put_contents($tmp_name, $body);
+					} else { //Parse Field
+						$data[$name] = substr($body, 0, strlen($body) - 2);
+					}
+				}
+			}
+			return $data ?? [];
+		}
+	}
diff --git a/src/Routes.php b/src/Routes.php
index 04f7f3c..0bd90d2 100644
--- a/src/Routes.php
+++ b/src/Routes.php
@@ -1,530 +1,546 @@
-
-	 * @license   GNU General Public License v3.0
-	 * @copyright 2020-2022 Igor Ilić
-	 */
-
-	declare( strict_types=1 );
-
-	namespace Gac\Routing;
-
-
-	use Closure;
-	use Gac\Routing\Exceptions\CallbackNotFound;
-	use Gac\Routing\Exceptions\RouteNotFoundException;
-	use ReflectionException;
-	use ReflectionFunction;
-	use ReflectionMethod;
-	use ReflectionNamedType;
-	use ReflectionUnionType;
-
-	class Routes
-	{
-		/**
-		 * @var string GET Constant representing a GET request method
-		 */
-		public const GET = 'GET';
-
-		/**
-		 * @var string POST Constant representing a POST request method
-		 */
-		public const POST = 'POST';
-
-		/**
-		 * @var string PUT Constant representing a PUT request method
-		 */
-		public const PUT = 'PUT';
-
-		/**
-		 * @var string PATCH Constant representing a PATCH request method
-		 */
-		public const PATCH = 'PATCH';
-
-		/**
-		 * @var string DELETE Constant representing a DELETE request method
-		 */
-		public const DELETE = 'DELETE';
-
-		/**
-		 * @var Request $request Instance of a Request class to be passed as an argument to routes callback
-		 */
-		public Request $request;
-		/**
-		 * @var string $prefix Routes prefix
-		 */
-		private string $prefix = '';
-		/**
-		 * @var array $middlewares List of middlewares to be executed before the routes
-		 */
-		private array $middlewares = [];
-		/**
-		 * @var array $routes List of available routes
-		 */
-		private array $routes = [];
-		/**
-		 * @var array $routes Temporary holder of route information until it all gets stored in the primary $routes array
-		 */
-		private array $tmpRoutes = [];
-
-		/**
-		 * @var array|null Array of the current route being processed for eas of access in other methods
-		 */
-		private ?array $currentRoute = NULL;
-
-		/**
-		 * Routes constructor
-		 */
-		public function __construct() {
-			$this->request = new Request;
-		}
-
-		/**
-		 * Method used for adding new routes
-		 *
-		 * @param string $path Path for the route
-		 * @param callable|array|string|null $callback Callback method, an anonymous function or a class and method name to be executed
-		 * @param string|array|null $methods Allowed request method(s) (GET, POST, PUT, PATCH, DELETE)
-		 */
-		public function add(
-			string                     $path = '',
-			callable|array|string|null $callback = NULL,
-			string|array|null          $methods = self::GET
-		) : void {
-			$this->route($path, $callback, $methods);
-			$this->save();
-		}
-
-		/**
-		 * Method used for adding new routes into the temporary list when using chained method approach
-		 *
-		 * @param string $path Path for the route
-		 * @param callable|array|string|null $callback Callback method, an anonymous function or a class and method name to be executed
-		 * @param string|array $methods Allowed request method(s) (GET, POST, PUT, PATCH, DELETE)
-		 *
-		 * @return Routes Returns an instance of itself so that other methods could be chained onto it
-		 */
-		public function route(
-			string                     $path,
-			callable|array|string|null $callback,
-			string|array               $methods = self::GET
-		) : self {
-			if ( is_string($methods) ) $methods = [ $methods ];
-
-			if ( !empty($this->prefix) ) $path = $this->prefix . $path; // Prepend prefix to routes
-
-			if ( $path !== '/' ) $path = rtrim($path, '/');
-
-			$regex = NULL;
-			$arguments = NULL;
-			if ( str_contains($path, '{') ) {
-				$regex = preg_replace('/{.+?}/', '(.+?)', $path);
-				$regex = str_replace('/', '\/', $regex);
-				$regex = "^$regex$";
-				preg_match_all('/{(.+?)}/', $path, $matches);
-				if ( isset($matches[1]) && count($matches) > 0 ) $arguments = $matches[1];
-			}
-
-			foreach ( $methods as $method ) {
-				$this->tmpRoutes[$method][$path] = [
-					'callback' => $callback,
-					'middlewares' => $this->middlewares,
-				];
-
-				if ( !is_null($regex) ) {
-					$this->tmpRoutes[$method][$path]['regex'] = $regex;
-					if ( !is_null($arguments) ) {
-						$this->tmpRoutes[$method][$path]['arguments'] = $arguments;
-					}
-				}
-			}
-
-			$this->save(false);
-			return $this;
-		}
-
-		/**
-		 * Method used for saving routing information into the global $routes array
-		 *
-		 * @param bool $cleanData should the data from the tmpRoutes be cleared or not when this method runs
-		 */
-		public function save(bool $cleanData = true) : self {
-			foreach ( $this->tmpRoutes as $method => $route ) {
-				if ( !isset($this->routes[$method]) ) $this->routes[$method] = [];
-				$path = array_key_first($route);
-
-				if ( count($this->middlewares) > 0 && count($route[$path]['middlewares']) === 0 ) {
-					$route[$path]['middlewares'] = $this->middlewares;
-				}
-
-				if ( !empty($this->prefix) && !str_starts_with($path, $this->prefix) ) {
-					$newPath = rtrim("$this->prefix$path", '/');
-					$route[$newPath] = $route[$path];
-					unset($route[$path]);
-				}
-
-				$this->routes[$method] = array_merge($this->routes[$method], $route);
-			}
-
-			if ( $cleanData ) {
-				$this->prefix = '';
-				$this->middlewares = [];
-			}
-
-			$this->tmpRoutes = [];
-			return $this;
-		}
-
-		/**
-		 * Method used to handle execution of routes and middlewares
-		 *
-		 * @throws RouteNotFoundException When the route was not found
-		 * @throws CallbackNotFound When the callback for the route was not found
-		 */
-		public function handle() : void {
-			$path = $this->get_path();
-			$method = $_SERVER['REQUEST_METHOD'] ?? 'GET';
-
-			if ( !isset($this->routes[$method]) ) {
-				throw new RouteNotFoundException("Route $path not found", 404);
-			}
-
-			$route = $this->routes[$method][$path] ?? false;
-
-			$arguments = [];
-			if ( $route === false ) {
-				$dynamic_routes = array_filter($this->routes[$method], fn($route) => !is_null($route['regex'] ?? NULL));
-				foreach ( $dynamic_routes as $routePath => $dynamic_route ) {
-					$countRouteSlashes = count(explode("/", $routePath));
-					$countPathSlashes = count(explode('/', $path));
-
-					//TODO: Find a way to not check the number of / as it seems a bit hacky
-					if ( $countPathSlashes !== $countRouteSlashes ) continue;
-
-					if ( preg_match("/{$dynamic_route['regex']}/", $path) ) {
-						$route = $dynamic_route;
-						$arguments = $this->get_route_arguments($dynamic_route, $path);
-						break;
-					}
-				}
-			}
-
-			if ( $route === false ) throw new RouteNotFoundException("Route $path not found", 404);
-			$this->currentRoute = $route;
-
-			$middlewares = $route['middlewares'] ?? [];
-			$this->execute_middleware($middlewares);
-
-			$callback = $route['callback'] ?? false;
-			if ( $callback === false ) throw new CallbackNotFound("No callback specified for $path", 404);
-
-			$callback = $this->setup_callback($callback);
-
-			if ( !is_callable($callback) ) throw new CallbackNotFound("Unable to execute callback for $path", 404);
-
-			$parameters = $this->get_all_arguments($callback);
-
-			$callbackArguments = [];
-			foreach ( $parameters as $name => $type ) {
-				if ( strtolower($type) === strtolower('Gac\Routing\Request') ) {
-					$callbackArguments[$name] = $this->request;
-					continue;
-				}
-				$callbackArguments[$name] = $arguments[$name] ?? NULL;
-			}
-
-			$this->currentRoute = NULL;
-			call_user_func_array($callback, $callbackArguments);
-		}
-
-		private function get_route_arguments(array $route, string $path) : array {
-			$arguments = [];
-			if ( !isset($route["regex"]) ) return $arguments;
-
-			preg_match_all("/{$route['regex']}/", $path, $matches);
-			if ( count($matches) > 1 ) array_shift($matches);
-			$matches = array_map(fn($m) => $m[0], $matches);
-
-			$args = $route['arguments'] ?? [];
-			foreach ( $args as $index => $argumentName ) {
-				$type = 'string';
-				if ( str_contains($argumentName, ':') ) {
-					$colonIndex = strpos($argumentName, ':');
-					$type = substr($argumentName, 0, $colonIndex);
-					$argumentName = substr($argumentName, $colonIndex + 1, strlen($argumentName));
-				}
-
-				$value = $matches[$index] ?? NULL;
-				$value = match ( $type ) {
-					'int' => intval($value),
-					'float' => floatval($value),
-					'double' => doubleval($value),
-					'bool' => is_numeric($value) ? boolval($value) : ( $value === 'true' ),
-					default => (string) $value,
-				};
-
-				$arguments[$argumentName] = $value;
-			}
-
-			return $arguments;
-		}
-
-		/**
-		 * Method used to set up callback properties for routes
-		 *
-		 * @param Closure|string|array $callback Callback data of a route
-		 *
-		 * @return mixed Return data needed to execute callback
-		 */
-		private function setup_callback(Closure|string|array $callback) : mixed {
-			if ( ( is_string($callback) && class_exists($callback) ) || is_array($callback) ) {
-				if ( is_string($callback) ) {
-					return new $callback;
-				}
-
-				if ( is_array($callback) ) {
-					//There is no method provided so relay on __invoke to be used
-					if ( isset($callback[1]) && is_array($callback[1]) ) {
-						$callback[1] = DIContainer::get($callback[0], $callback[1]);
-						return new $callback[0](...$callback[1]);
-					}
-
-					//There is a method provided but also any other arguments
-					if ( isset($callback[1]) && is_string($callback[1]) ) {
-						//There dependencies that need to be injected
-						if ( isset($callback[2]) ) {
-							$callback[2] = DIContainer::get($callback[0], $callback[2]);
-							return [ new $callback[0](...$callback[2]), $callback[1] ];
-						}
-						return [ new $callback[0], $callback[1] ];
-					}
-
-					$args = DIContainer::get($callback[0]);
-					return [ new $callback[0](...$args), "__invoke" ];
-				}
-			}
-
-			return $callback;
-		}
-
-		/**
-		 * Method which returns the current path the user is trying to access
-		 *
-		 * @return string Returns the current path
-		 */
-		private function get_path() : string {
-			$path = $_SERVER['REQUEST_URI'] ?? '/';
-			$position = strpos($path, '?');
-
-			$path = ( $path !== '/' ) ? rtrim($path, '/') : $path;
-			return ( $position === false ) ? $path : substr($path, 0, $position);
-		}
-
-		/**
-		 * Method which executes each specified middleware before the route's callback is executed
-		 *
-		 * @param array $data List of middlewares to be executed before accessing the endpoint
-		 *
-		 * @throws CallbackNotFound When the specified middleware method is not found
-		 */
-		private function execute_middleware(array $data) : void {
-			$namedArguments = match ( is_null($this->currentRoute) ) {
-				false => $this->get_route_arguments($this->currentRoute, $this->get_path()),
-				default => []
-			};
-
-			foreach ( $data as $key => $function ) {
-				$arguments = [];
-				$tmpArguments = [];
-
-				if ( is_integer($key) && is_array($function) ) {
-					$class = $function[0];
-					$method = $function[1];
-					array_shift($function);
-					array_shift($function);
-					$tmpArguments = $function;
-					$function = [ new $class, $method ];
-				}
-
-				if ( is_string($key) ) {
-					$tmpArguments = [ $function ];
-					$function = $key;
-				}
-
-				$parameters = $this->get_all_arguments($function);
-				$requestClassIndex = array_search(Request::class, array_values($parameters));
-
-				$paramNames = array_keys($parameters);
-				for ( $index = 0; $index < count($parameters); $index++ ) {
-					if ( $index === $requestClassIndex ) {
-						$arguments[$index] = $this->request;
-						continue;
-					}
-					$arguments[$index] = $tmpArguments[$index] ?? $namedArguments[$paramNames[$index]] ?? NULL;
-				}
-
-				if ( !is_callable($function) ) throw new CallbackNotFound("Middleware method $function not found", 404);
-				call_user_func($function, ...$arguments);
-			}
-		}
-
-		/**
-		 * Private method used to fetch the arguments of the route's callback methods
-		 *
-		 * @param object|array|string $function
-		 *
-		 * @return array|null Returns a list of arguments for a method or null on error
-		 */
-		private function get_all_arguments(object|array|string $function) : array|null {
-			$function_get_args = [];
-			try {
-				if ( ( is_string($function) && function_exists($function) ) || $function instanceof Closure ) {
-					$ref = new ReflectionFunction($function);
-				} elseif (
-					is_string($function) &&
-					( str_contains($function, "::") && !method_exists(...explode("::", $function)) )
-				) {
-					return $function_get_args;
-				} elseif ( is_object($function) || is_array($function) ) {
-					$class = ( (array) $function )[0];
-					$method = ( (array) $function )[1];
-					$ref = new ReflectionMethod($class, $method);
-				} else {
-					return $function_get_args;
-				}
-
-				foreach ( $ref->getParameters() as $param ) {
-					if ( !isset($function_get_args[$param->name]) ) {
-						$type = $param->getType();
-						if ( is_null($type) ) {
-							$function_get_args[$param->name] = 'nothing';
-						} else {
-							if ( $type instanceof ReflectionNamedType ) {
-								$function_get_args[$param->name] = $type->getName() ?? 'string';
-							} elseif ( $type instanceof ReflectionUnionType ) {
-								# $function_get_args[$param->name] = implode("|", $type->getTypes());
-								$function_get_args[$param->name] = "mixed";
-							}
-						}
-					}
-				}
-				return $function_get_args;
-			} catch ( ReflectionException $ex ) {
-				error_log($ex->getMessage());
-				return NULL;
-			}
-		}
-
-		/**
-		 * Method used for fetching a list of all the created routes
-		 *
-		 * @return array Return the list of defined routes
-		 */
-		public function get_routes() : array {
-			return $this->routes;
-		}
-
-		/**
-		 * Wrapper method used for adding new GET routes
-		 *
-		 * @param string $path Path for the route
-		 * @param callable|array|string|null $callback Callback method, an anonymous function or a class and method name to be executed
-		 *
-		 * @return Routes Returns an instance of itself so that other methods could be chained onto it
-		 */
-		public function get(string $path, callable|array|string|null $callback = NULL) : self {
-			$this->route($path, $callback, [ self::GET ]);
-			return $this;
-		}
-
-		/**
-		 * Wrapper method used for adding new POST routes
-		 *
-		 * @param string $path Path for the route
-		 * @param callable|array|string|null $callback Callback method, an anonymous function or a class and method name to be executed
-		 *
-		 * @return Routes Returns an instance of itself so that other methods could be chained onto it
-		 */
-		public function post(string $path, callable|array|string|null $callback = NULL) : self {
-			$this->route($path, $callback, [ self::POST ]);
-			return $this;
-		}
-
-		/**
-		 * Wrapper method used for adding new POST routes
-		 *
-		 * @param string $path Path for the route
-		 * @param callable|array|string|null $callback Callback method, an anonymous function or a class and method name to be executed
-		 *
-		 * @return Routes Returns an instance of itself so that other methods could be chained onto it
-		 */
-		public function put(string $path, callable|array|string|null $callback = NULL) : self {
-			$this->route($path, $callback, [ self::PUT ]);
-			return $this;
-		}
-
-		/**
-		 * Wrapper method used for adding new POS routes
-		 *
-		 * @param string $path Path for the route
-		 * @param callable|array|string|null $callback Callback method, an anonymous function or a class and method name to be executed
-		 *
-		 * @return Routes Returns an instance of itself so that other methods could be chained onto it
-		 */
-		public function patch(string $path, callable|array|string|null $callback = NULL) : self {
-			$this->route($path, $callback, [ self::PATCH ]);
-			return $this;
-		}
-
-		/**
-		 * Wrapper method used for adding new POST routes
-		 *
-		 * @param string $path Path for the route
-		 * @param callable|array|string|null $callback Callback method, an anonymous function or a class and method name to be executed
-		 *
-		 * @return Routes Returns an instance of itself so that other methods could be chained onto it
-		 */
-		public function delete(string $path, callable|array|string|null $callback = NULL) : self {
-			$this->route($path, $callback, [ self::DELETE ]);
-			return $this;
-		}
-
-		/**
-		 * Method used to set the prefix for routes
-		 *
-		 * @param string $prefix Prefix to be added to all the routes in the chain.
-		 *
-		 * @return Routes Returns an instance of itself so that other methods could be chained onto it
-		 */
-		public function prefix(string $prefix = '') : self {
-			$this->prefix .= $prefix;
-			return $this;
-		}
-
-		/**
-		 * Method used to set the middlewares for routes
-		 *
-		 * @param array $data List of middlewares to be executed before the routes
-		 *
-		 * @return Routes Returns an instance of itself so that other methods could be chained onto it
-		 */
-		public function middleware(array $data) : self {
-			$this->middlewares = array_merge($this->middlewares, $data);
-			return $this;
-		}
-
-		/**
-		 * Method used to append more routes to the main route handler
-		 *
-		 * @param array $routes List of routes from other route classes
-		 *
-		 * @return Routes Returns an instance of itself so that other methods could be chained onto it
-		 */
-		public function append(array $routes) : self {
-			$this->routes = array_merge_recursive($routes, $this->routes);
-			return $this;
-		}
+
+	 * @license   GNU General Public License v3.0
+	 * @copyright 2020-2022 Igor Ilić
+	 */
+
+	declare( strict_types=1 );
+
+	namespace Gac\Routing;
+
+
+	use Closure;
+	use Gac\Routing\Exceptions\CallbackNotFound;
+	use Gac\Routing\Exceptions\RouteNotFoundException;
+	use ReflectionException;
+	use ReflectionFunction;
+	use ReflectionMethod;
+	use ReflectionNamedType;
+	use ReflectionUnionType;
+
+	class Routes
+	{
+		/**
+		 * @var string GET Constant representing a GET request method
+		 */
+		public const GET = 'GET';
+
+		/**
+		 * @var string POST Constant representing a POST request method
+		 */
+		public const POST = 'POST';
+
+		/**
+		 * @var string PUT Constant representing a PUT request method
+		 */
+		public const PUT = 'PUT';
+
+		/**
+		 * @var string PATCH Constant representing a PATCH request method
+		 */
+		public const PATCH = 'PATCH';
+
+		/**
+		 * @var string DELETE Constant representing a DELETE request method
+		 */
+		public const DELETE = 'DELETE';
+
+		/**
+		 * @var Request $request Instance of a Request class to be passed as an argument to routes callback
+		 */
+		public Request $request;
+		/**
+		 * @var string $prefix Routes prefix
+		 */
+		private string $prefix = '';
+		/**
+		 * @var array $middlewares List of middlewares to be executed before the routes
+		 */
+		private array $middlewares = [];
+		/**
+		 * @var array $routes List of available routes
+		 */
+		private array $routes = [];
+		/**
+		 * @var array $routes Temporary holder of route information until it all gets stored in the primary $routes array
+		 */
+		private array $tmpRoutes = [];
+
+		/**
+		 * @var array|null Array of the current route being processed for eas of access in other methods
+		 */
+		private ?array $currentRoute = NULL;
+
+		/**
+		 * Routes constructor
+		 */
+		public function __construct() {
+			$this->request = new Request;
+		}
+
+		/**
+		 * Method used for adding new routes
+		 *
+		 * @param string $path Path for the route
+		 * @param callable|array|string|null $callback Callback method, an anonymous function or a class and method name to be executed
+		 * @param string|array|null $methods Allowed request method(s) (GET, POST, PUT, PATCH, DELETE)
+		 */
+		public function add(
+			string                     $path = '',
+			callable|array|string|null $callback = NULL,
+			string|array|null          $methods = self::GET
+		) : void {
+			$this->route($path, $callback, $methods);
+			$this->save();
+		}
+
+		/**
+		 * Method used for adding new routes into the temporary list when using chained method approach
+		 *
+		 * @param string $path Path for the route
+		 * @param callable|array|string|null $callback Callback method, an anonymous function or a class and method name to be executed
+		 * @param string|array $methods Allowed request method(s) (GET, POST, PUT, PATCH, DELETE)
+		 *
+		 * @return Routes Returns an instance of itself so that other methods could be chained onto it
+		 */
+		public function route(
+			string                     $path,
+			callable|array|string|null $callback,
+			string|array               $methods = self::GET
+		) : self {
+			if ( is_string($methods) ) $methods = [ $methods ];
+
+			if ( !empty($this->prefix) ) $path = $this->prefix . $path; // Prepend prefix to routes
+
+			if ( $path !== '/' ) $path = rtrim($path, '/');
+
+			$regex = NULL;
+			$arguments = NULL;
+			if ( str_contains($path, '{') ) {
+				$regex = preg_replace('/{.+?}/', '(.+?)', $path);
+				$regex = str_replace('/', '\/', $regex);
+				$regex = "^$regex$";
+				preg_match_all('/{(.+?)}/', $path, $matches);
+				if ( isset($matches[1]) && count($matches) > 0 ) $arguments = $matches[1];
+			}
+
+			foreach ( $methods as $method ) {
+				$this->tmpRoutes[$method][$path] = [
+					'callback' => $callback,
+					'middlewares' => $this->middlewares,
+				];
+
+				if ( !is_null($regex) ) {
+					$this->tmpRoutes[$method][$path]['regex'] = $regex;
+					if ( !is_null($arguments) ) {
+						$this->tmpRoutes[$method][$path]['arguments'] = $arguments;
+					}
+				}
+			}
+
+			$this->save(false);
+			return $this;
+		}
+
+		/**
+		 * Method used for saving routing information into the global $routes array
+		 *
+		 * @param bool $cleanData should the data from the tmpRoutes be cleared or not when this method runs
+		 */
+		public function save(bool $cleanData = true) : self {
+			foreach ( $this->tmpRoutes as $method => $route ) {
+				if ( !isset($this->routes[$method]) ) $this->routes[$method] = [];
+				$path = array_key_first($route);
+
+				if ( count($this->middlewares) > 0 && count($route[$path]['middlewares']) === 0 ) {
+					$route[$path]['middlewares'] = $this->middlewares;
+				}
+
+				$route[$path]["di"] = [];
+				if ( is_array($route[$path]["callback"]) && count($route[$path]["callback"]) > 2 ) {
+					//store manual entries for dependency injection
+					while ( count($route[$path]["callback"]) > 2 ) {
+						$route[$path]["di"][] = array_pop($route[$path]["callback"]);
+					}
+				}
+
+				if ( !empty($this->prefix) && !str_starts_with($path, $this->prefix) ) {
+					$newPath = rtrim("$this->prefix$path", '/');
+					$route[$newPath] = $route[$path];
+					unset($route[$path]);
+				}
+
+				$this->routes[$method] = array_merge($this->routes[$method], $route);
+			}
+
+			if ( $cleanData ) {
+				$this->prefix = '';
+				$this->middlewares = [];
+			}
+
+			$this->tmpRoutes = [];
+			return $this;
+		}
+
+		/**
+		 * Method used to handle execution of routes and middlewares
+		 *
+		 * @throws RouteNotFoundException When the route was not found
+		 * @throws CallbackNotFound When the callback for the route was not found
+		 */
+		public function handle() : void {
+			$path = $this->get_path();
+			$method = $_SERVER['REQUEST_METHOD'] ?? 'GET';
+
+			if ( !isset($this->routes[$method]) ) {
+				throw new RouteNotFoundException("Route $path not found", 404);
+			}
+
+			$route = $this->routes[$method][$path] ?? false;
+
+			$arguments = [];
+			if ( $route === false ) {
+				$dynamic_routes = array_filter($this->routes[$method], fn($route) => !is_null($route['regex'] ?? NULL));
+				foreach ( $dynamic_routes as $routePath => $dynamic_route ) {
+					$countRouteSlashes = count(explode("/", $routePath));
+					$countPathSlashes = count(explode('/', $path));
+
+					//TODO: Find a way to not check the number of / as it seems a bit hacky
+					if ( $countPathSlashes !== $countRouteSlashes ) continue;
+
+					if ( preg_match("/{$dynamic_route['regex']}/", $path) ) {
+						$route = $dynamic_route;
+						$arguments = $this->get_route_arguments($dynamic_route, $path);
+						break;
+					}
+				}
+			}
+
+			if ( $route === false ) throw new RouteNotFoundException("Route $path not found", 404);
+			$this->currentRoute = $route;
+
+			$middlewares = $route['middlewares'] ?? [];
+			$this->execute_middleware($middlewares);
+
+			$callback = $route['callback'] ?? false;
+			if ( $callback === false ) throw new CallbackNotFound("No callback specified for $path", 404);
+
+			$callback = $this->setup_callback($callback);
+
+			if ( !is_callable($callback) ) throw new CallbackNotFound("Unable to execute callback for $path", 404);
+
+			$parameters = $this->get_all_arguments($callback);
+
+			$callbackArguments = [];
+			foreach ( $parameters as $name => $type ) {
+				if ( strtolower($type) === strtolower('Gac\Routing\Request') ) {
+					$callbackArguments[$name] = $this->request;
+					continue;
+				}
+				$callbackArguments[$name] = $arguments[$name] ?? NULL;
+			}
+
+			foreach ( $this->currentRoute["di"] as $argument ) {
+				$name = array_key_first($argument);
+				$value = $argument[$name];
+				if ( !isset($callbackArguments[$name]) ) {
+					$callbackArguments[$name] = $value;
+				}
+			}
+
+			$this->currentRoute = NULL;
+			call_user_func_array($callback, $callbackArguments);
+		}
+
+		private function get_route_arguments(array $route, string $path) : array {
+			$arguments = [];
+			if ( !isset($route["regex"]) ) return $arguments;
+
+			preg_match_all("/{$route['regex']}/", $path, $matches);
+			if ( count($matches) > 1 ) array_shift($matches);
+			$matches = array_map(fn($m) => $m[0], $matches);
+
+			$args = $route['arguments'] ?? [];
+			foreach ( $args as $index => $argumentName ) {
+				$type = 'string';
+				if ( str_contains($argumentName, ':') ) {
+					$colonIndex = strpos($argumentName, ':');
+					$type = substr($argumentName, 0, $colonIndex);
+					$argumentName = substr($argumentName, $colonIndex + 1, strlen($argumentName));
+				}
+
+				$value = $matches[$index] ?? NULL;
+				$value = match ( $type ) {
+					'int' => intval($value),
+					'float' => floatval($value),
+					'double' => doubleval($value),
+					'bool' => is_numeric($value) ? boolval($value) : ( $value === 'true' ),
+					default => (string) $value,
+				};
+
+				$arguments[$argumentName] = $value;
+			}
+
+			return $arguments;
+		}
+
+		/**
+		 * Method used to set up callback properties for routes
+		 *
+		 * @param Closure|string|array $callback Callback data of a route
+		 *
+		 * @return mixed Return data needed to execute callback
+		 */
+		private function setup_callback(Closure|string|array $callback) : mixed {
+			if ( ( is_string($callback) && class_exists($callback) ) || is_array($callback) ) {
+				if ( is_string($callback) ) {
+					return new $callback;
+				}
+
+				if ( is_array($callback) ) {
+					//There is no method provided so relay on __invoke to be used
+					if ( isset($callback[1]) && is_array($callback[1]) ) {
+						$callback[1] = DIContainer::get($callback[0], $callback[1]);
+						return new $callback[0](...$callback[1]);
+					}
+
+					//There is a method provided but also any other arguments
+					if ( isset($callback[1]) && is_string($callback[1]) ) {
+						//There dependencies that need to be injected
+						if ( isset($callback[2]) ) {
+							$callback[2] = DIContainer::get($callback[0], $callback[2]);
+							return [ new $callback[0](...$callback[2]), $callback[1] ];
+						}
+						return [ new $callback[0], $callback[1] ];
+					}
+
+					$args = DIContainer::get($callback[0]);
+					return [ new $callback[0](...$args), "__invoke" ];
+				}
+			}
+
+			return $callback;
+		}
+
+		/**
+		 * Method which returns the current path the user is trying to access
+		 *
+		 * @return string Returns the current path
+		 */
+		private function get_path() : string {
+			$path = $_SERVER['REQUEST_URI'] ?? '/';
+			$position = strpos($path, '?');
+
+			$path = ( $path !== '/' ) ? rtrim($path, '/') : $path;
+			return ( $position === false ) ? $path : substr($path, 0, $position);
+		}
+
+		/**
+		 * Method which executes each specified middleware before the route's callback is executed
+		 *
+		 * @param array $data List of middlewares to be executed before accessing the endpoint
+		 *
+		 * @throws CallbackNotFound When the specified middleware method is not found
+		 */
+		private function execute_middleware(array $data) : void {
+			$namedArguments = match ( is_null($this->currentRoute) ) {
+				false => $this->get_route_arguments($this->currentRoute, $this->get_path()),
+				default => []
+			};
+
+			foreach ( $data as $key => $function ) {
+				$arguments = [];
+				$tmpArguments = [];
+
+				if ( is_integer($key) && is_array($function) ) {
+					$class = $function[0];
+					$method = $function[1];
+					array_shift($function);
+					array_shift($function);
+					$tmpArguments = $function;
+					$function = [ new $class, $method ];
+				}
+
+				if ( is_string($key) ) {
+					$tmpArguments = [ $function ];
+					$function = $key;
+				}
+
+				$parameters = $this->get_all_arguments($function);
+				$requestClassIndex = array_search(Request::class, array_values($parameters));
+
+				$paramNames = array_keys($parameters);
+				for ( $index = 0; $index < count($parameters); $index++ ) {
+					if ( $index === $requestClassIndex ) {
+						$arguments[$index] = $this->request;
+						continue;
+					}
+					$arguments[$index] = $tmpArguments[$index] ?? $namedArguments[$paramNames[$index]] ?? NULL;
+				}
+
+				if ( !is_callable($function) ) throw new CallbackNotFound("Middleware method $function not found", 404);
+				call_user_func($function, ...$arguments);
+			}
+		}
+
+		/**
+		 * Private method used to fetch the arguments of the route's callback methods
+		 *
+		 * @param object|array|string $function
+		 *
+		 * @return array|null Returns a list of arguments for a method or null on error
+		 */
+		private function get_all_arguments(object|array|string $function) : array|null {
+			$function_get_args = [];
+			try {
+				if ( ( is_string($function) && function_exists($function) ) || $function instanceof Closure ) {
+					$ref = new ReflectionFunction($function);
+				} elseif (
+					is_string($function) &&
+					( str_contains($function, "::") && !method_exists(...explode("::", $function)) )
+				) {
+					return $function_get_args;
+				} elseif ( is_object($function) || is_array($function) ) {
+					$class = ( (array) $function )[0];
+					$method = ( (array) $function )[1];
+					$ref = new ReflectionMethod($class, $method);
+				} else {
+					return $function_get_args;
+				}
+
+				foreach ( $ref->getParameters() as $param ) {
+					if ( !isset($function_get_args[$param->name]) ) {
+						$type = $param->getType();
+						if ( is_null($type) ) {
+							$function_get_args[$param->name] = 'nothing';
+						} else {
+							if ( $type instanceof ReflectionNamedType ) {
+								$function_get_args[$param->name] = $type->getName() ?? 'string';
+							} elseif ( $type instanceof ReflectionUnionType ) {
+								# $function_get_args[$param->name] = implode("|", $type->getTypes());
+								$function_get_args[$param->name] = "mixed";
+							}
+						}
+					}
+				}
+				return $function_get_args;
+			} catch ( ReflectionException $ex ) {
+				error_log($ex->getMessage());
+				return NULL;
+			}
+		}
+
+		/**
+		 * Method used for fetching a list of all the created routes
+		 *
+		 * @return array Return the list of defined routes
+		 */
+		public function get_routes() : array {
+			return $this->routes;
+		}
+
+		/**
+		 * Wrapper method used for adding new GET routes
+		 *
+		 * @param string $path Path for the route
+		 * @param callable|array|string|null $callback Callback method, an anonymous function or a class and method name to be executed
+		 *
+		 * @return Routes Returns an instance of itself so that other methods could be chained onto it
+		 */
+		public function get(string $path, callable|array|string|null $callback = NULL) : self {
+			$this->route($path, $callback, [ self::GET ]);
+			return $this;
+		}
+
+		/**
+		 * Wrapper method used for adding new POST routes
+		 *
+		 * @param string $path Path for the route
+		 * @param callable|array|string|null $callback Callback method, an anonymous function or a class and method name to be executed
+		 *
+		 * @return Routes Returns an instance of itself so that other methods could be chained onto it
+		 */
+		public function post(string $path, callable|array|string|null $callback = NULL) : self {
+			$this->route($path, $callback, [ self::POST ]);
+			return $this;
+		}
+
+		/**
+		 * Wrapper method used for adding new POST routes
+		 *
+		 * @param string $path Path for the route
+		 * @param callable|array|string|null $callback Callback method, an anonymous function or a class and method name to be executed
+		 *
+		 * @return Routes Returns an instance of itself so that other methods could be chained onto it
+		 */
+		public function put(string $path, callable|array|string|null $callback = NULL) : self {
+			$this->route($path, $callback, [ self::PUT ]);
+			return $this;
+		}
+
+		/**
+		 * Wrapper method used for adding new POS routes
+		 *
+		 * @param string $path Path for the route
+		 * @param callable|array|string|null $callback Callback method, an anonymous function or a class and method name to be executed
+		 *
+		 * @return Routes Returns an instance of itself so that other methods could be chained onto it
+		 */
+		public function patch(string $path, callable|array|string|null $callback = NULL) : self {
+			$this->route($path, $callback, [ self::PATCH ]);
+			return $this;
+		}
+
+		/**
+		 * Wrapper method used for adding new POST routes
+		 *
+		 * @param string $path Path for the route
+		 * @param callable|array|string|null $callback Callback method, an anonymous function or a class and method name to be executed
+		 *
+		 * @return Routes Returns an instance of itself so that other methods could be chained onto it
+		 */
+		public function delete(string $path, callable|array|string|null $callback = NULL) : self {
+			$this->route($path, $callback, [ self::DELETE ]);
+			return $this;
+		}
+
+		/**
+		 * Method used to set the prefix for routes
+		 *
+		 * @param string $prefix Prefix to be added to all the routes in the chain.
+		 *
+		 * @return Routes Returns an instance of itself so that other methods could be chained onto it
+		 */
+		public function prefix(string $prefix = '') : self {
+			$this->prefix .= $prefix;
+			return $this;
+		}
+
+		/**
+		 * Method used to set the middlewares for routes
+		 *
+		 * @param array $data List of middlewares to be executed before the routes
+		 *
+		 * @return Routes Returns an instance of itself so that other methods could be chained onto it
+		 */
+		public function middleware(array $data) : self {
+			$this->middlewares = array_merge($this->middlewares, $data);
+			return $this;
+		}
+
+		/**
+		 * Method used to append more routes to the main route handler
+		 *
+		 * @param array $routes List of routes from other route classes
+		 *
+		 * @return Routes Returns an instance of itself so that other methods could be chained onto it
+		 */
+		public function append(array $routes) : self {
+			$this->routes = array_merge_recursive($routes, $this->routes);
+			return $this;
+		}
 	}
\ No newline at end of file
diff --git a/tests/DIContainerTest.php b/tests/DIContainerTest.php
index 7c5d2e1..a7129a8 100644
--- a/tests/DIContainerTest.php
+++ b/tests/DIContainerTest.php
@@ -1,47 +1,47 @@
-
-	 * Date: 2022-06-05
-	 * Project: PHP-routing
-	 */
-
-	use Gac\Routing\DIContainer;
-	use Gac\Routing\sample\A;
-	use Gac\Routing\sample\B;
-	use Gac\Routing\sample\C;
-	use Gac\Routing\sample\InjectController;
-	use Gac\Routing\sample\InjectedClass;
-
-	it("can resolve dependencies", function () {
-		if ( !class_exists("InjectController") ) {
-			include_once __DIR__ . "/../sample/InjectController.php";
-		}
-
-		if ( !class_exists("InjectedClass") ) {
-			include_once __DIR__ . "/../sample/InjectedClass.php";
-		}
-
-		$data = DIContainer::get(InjectController::class, []);
-
-		expect($data)
-			->toBeArray()
-			->toHaveCount(1)
-			->and($data["injectedClass"])
-			->toBeInstanceOf(InjectedClass::class);
-	});
-
-	it("can handle nested dependency injection", function () {
-		include_once __DIR__ . '/../sample/nestedClasses.php';
-
-		$data = DIContainer::get(A::class, [ "test" => true, new C ]);
-
-		expect($data)
-			->toBeArray()
-			->toHaveCount(4)
-			->and($data['b'])
-			->toBeInstanceOf(B::class)
-			->and($data['c'])
-			->toBeInstanceOf(C::class)
-			->and($data["test"])
-			->toEqual(true);
+
+	 * Date: 2022-06-05
+	 * Project: PHP-routing
+	 */
+
+	use Gac\Routing\DIContainer;
+	use Gac\Routing\sample\A;
+	use Gac\Routing\sample\B;
+	use Gac\Routing\sample\C;
+	use Gac\Routing\sample\InjectController;
+	use Gac\Routing\sample\InjectedClass;
+
+	it("can resolve dependencies", function () {
+		if ( !class_exists("InjectController") ) {
+			include_once __DIR__ . "/../sample/InjectController.php";
+		}
+
+		if ( !class_exists("InjectedClass") ) {
+			include_once __DIR__ . "/../sample/InjectedClass.php";
+		}
+
+		$data = DIContainer::get(InjectController::class, []);
+
+		expect($data)
+			->toBeArray()
+			->toHaveCount(1)
+			->and($data["injectedClass"])
+			->toBeInstanceOf(InjectedClass::class);
+	});
+
+	it("can handle nested dependency injection", function () {
+		include_once __DIR__ . '/../sample/nestedClasses.php';
+
+		$data = DIContainer::get(A::class, [ "test" => true, new C ]);
+
+		expect($data)
+			->toBeArray()
+			->toHaveCount(4)
+			->and($data['b'])
+			->toBeInstanceOf(B::class)
+			->and($data['c'])
+			->toBeInstanceOf(C::class)
+			->and($data["test"])
+			->toEqual(true);
 	});
\ No newline at end of file
diff --git a/tests/RoutesTest.php b/tests/RoutesTest.php
index 6b54ad4..77e26ea 100644
--- a/tests/RoutesTest.php
+++ b/tests/RoutesTest.php
@@ -1,89 +1,90 @@
-add('/', []);
-		expect($routes->get_routes()["GET"]["/"])->toBeArray();
-	});
-
-	it("can add multiple request type routes", function () {
-		$routes = new Routes;
-
-		$routes->add('/test', [], [ Routes::GET, Routes::POST ]);
-
-		$issetGet = isset($routes->get_routes()['GET']['/test']);
-		$issetPost = isset($routes->get_routes()['POST']['/test']);
-		expect($issetGet)
-			->toBeTrue()
-			->and($issetPost)
-			->toBeTrue();
-	});
-
-	it("can add middleware", function () {
-		$routes = new Routes;
-		$routes->middleware([ "test" ])->add("/middleware", []);
-		expect($routes->get_routes()['GET']['/middleware']['middlewares'][0])->toBe("test");
-	});
-
-	it("can add prefix to routes", function () {
-		$routes = new Routes;
-		$routes->prefix('/testing')->add('/test', []);
-		expect(isset($routes->get_routes()['GET']['/testing/test']))->toBeTrue();
-	});
-
-	it("can use the save method to add a new route", function () {
-		$routes = new Routes;
-		$routes->prefix('/testing')->get('/test', [])->save();
-		expect($routes->get_routes()["GET"])->toHaveCount(1);
-	});
-
-	it('can use the add method to add a new route', function () {
-		$routes = new Routes;
-		$routes->prefix('/testing')->add('/test', []);
-		expect($routes->get_routes()['GET'])->toHaveCount(1);
-	});
-
-	it("can append new routes", function () {
-		$routes = new Routes;
-		$routes->add('/', []);
-
-		$appendedRoutes = new Routes;
-		$appendedRoutes->prefix('/test')
-					   ->get('/appended', function () { })
-					   ->get('/appended_sample', function () { })
-					   ->save();
-
-		$newRoutes = $appendedRoutes->get_routes();
-		$routes->append($newRoutes);
-
-		expect($routes->get_routes()["GET"])->toHaveCount(3);
-	});
-
-	it("can do dependency injection", function () {
-		if ( !class_exists('InjectedClass') ) {
-			require_once './sample/InjectedClass.php';
-		}
-
-		if ( !class_exists('HomeController') ) {
-			require_once './sample/HomeController.php';
-		}
-
-		$route = new Routes;
-		$route->add("/demo", [
-			\Gac\Routing\sample\HomeController::class,
-			"dependency_injection_test",
-			[ new \Gac\Routing\sample\InjectedClass ],
-		]);
-
-		$callback = $route->get_routes()["GET"]["/demo"]["callback"];
-		$setup = [ new $callback[0](...$callback[2]), $callback[1] ];
-
-		expect($callback)
-			->toHaveCount(3)
-			->and(call_user_func($setup, $route->request))
-			->json()
-			->isInstanceOf
-			->toBe(true);
-	});
+add('/', []);
+		expect($routes->get_routes()["GET"]["/"])->toBeArray();
+	});
+
+	it("can add multiple request type routes", function () {
+		$routes = new Routes;
+
+		$routes->add('/test', [], [ Routes::GET, Routes::POST ]);
+
+		$issetGet = isset($routes->get_routes()['GET']['/test']);
+		$issetPost = isset($routes->get_routes()['POST']['/test']);
+		expect($issetGet)
+			->toBeTrue()
+			->and($issetPost)
+			->toBeTrue();
+	});
+
+	it("can add middleware", function () {
+		$routes = new Routes;
+		$routes->middleware([ "test" ])->add("/middleware", []);
+		expect($routes->get_routes()['GET']['/middleware']['middlewares'][0])->toBe("test");
+	});
+
+	it("can add prefix to routes", function () {
+		$routes = new Routes;
+		$routes->prefix('/testing')->add('/test', []);
+		expect(isset($routes->get_routes()['GET']['/testing/test']))->toBeTrue();
+	});
+
+	it("can use the save method to add a new route", function () {
+		$routes = new Routes;
+		$routes->prefix('/testing')->get('/test', [])->save();
+		expect($routes->get_routes()["GET"])->toHaveCount(1);
+	});
+
+	it('can use the add method to add a new route', function () {
+		$routes = new Routes;
+		$routes->prefix('/testing')->add('/test', []);
+		expect($routes->get_routes()['GET'])->toHaveCount(1);
+	});
+
+	it("can append new routes", function () {
+		$routes = new Routes;
+		$routes->add('/', []);
+
+		$appendedRoutes = new Routes;
+		$appendedRoutes->prefix('/test')
+					   ->get('/appended', function () { })
+					   ->get('/appended_sample', function () { })
+					   ->save();
+
+		$newRoutes = $appendedRoutes->get_routes();
+		$routes->append($newRoutes);
+
+		expect($routes->get_routes()["GET"])->toHaveCount(3);
+	});
+
+	it("can do dependency injection", function () {
+		if ( !class_exists('InjectedClass') ) {
+			require_once './sample/InjectedClass.php';
+		}
+
+		if ( !class_exists('HomeController') ) {
+			require_once './sample/HomeController.php';
+		}
+
+		$route = new Routes;
+		$route->add("/demo", [
+			\Gac\Routing\sample\HomeController::class,
+			"dependency_injection_test",
+			[ new \Gac\Routing\sample\InjectedClass ],
+		]);
+
+		$callback = $route->get_routes()["GET"]["/demo"]["callback"];
+		$di = $route->get_routes()["GET"]["/demo"]["di"];
+		$setup = [ new $callback[0](...$di[0]), $callback[1] ];
+
+		expect($callback)
+			->toHaveCount(2)
+			->and(call_user_func($setup, $route->request))
+			->json()
+			->isInstanceOf
+			->toBe(true);
+	});
\ No newline at end of file