From a3ef3caefc85c091109d255368f6d3dc4f757413 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Joan=20Fabr=C3=A9gat?= Date: Thu, 22 Feb 2024 13:23:39 -0800 Subject: [PATCH] first version :+1: --- .gitignore | 2 + .idea/.gitignore | 8 + .idea/modules.xml | 8 + .idea/pdf2text-php-client.iml | 64 + .idea/php.xml | 81 + .idea/phpunit.xml | 10 + .idea/symfony2.xml | 6 + .idea/vcs.xml | 6 + LICENSE | 22 +- README.md | 71 +- composer.json | 46 + composer.lock | 3413 +++++++++++++++++++++++++++++++++ docker-compose.yaml | 5 + src/ConvertOptions.php | 29 + src/Exception.php | 21 + src/Format.php | 11 + src/Pdf2TextClient.php | 150 ++ tests/Pdf2TextClientTest.php | 96 + tests/assets/file.json | 1 + tests/assets/file.pdf | Bin 0 -> 65931 bytes tests/assets/file.txt | 1 + 21 files changed, 4031 insertions(+), 20 deletions(-) create mode 100644 .gitignore create mode 100644 .idea/.gitignore create mode 100644 .idea/modules.xml create mode 100644 .idea/pdf2text-php-client.iml create mode 100644 .idea/php.xml create mode 100644 .idea/phpunit.xml create mode 100644 .idea/symfony2.xml create mode 100644 .idea/vcs.xml create mode 100644 composer.json create mode 100644 composer.lock create mode 100644 docker-compose.yaml create mode 100644 src/ConvertOptions.php create mode 100644 src/Exception.php create mode 100644 src/Format.php create mode 100644 src/Pdf2TextClient.php create mode 100644 tests/Pdf2TextClientTest.php create mode 100644 tests/assets/file.json create mode 100644 tests/assets/file.pdf create mode 100644 tests/assets/file.txt diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..d8b2ded --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +.DS_Store +/vendor \ No newline at end of file diff --git a/.idea/.gitignore b/.idea/.gitignore new file mode 100644 index 0000000..13566b8 --- /dev/null +++ b/.idea/.gitignore @@ -0,0 +1,8 @@ +# Default ignored files +/shelf/ +/workspace.xml +# Editor-based HTTP Client requests +/httpRequests/ +# Datasource local storage ignored files +/dataSources/ +/dataSources.local.xml diff --git a/.idea/modules.xml b/.idea/modules.xml new file mode 100644 index 0000000..f7c0b20 --- /dev/null +++ b/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/pdf2text-php-client.iml b/.idea/pdf2text-php-client.iml new file mode 100644 index 0000000..421d364 --- /dev/null +++ b/.idea/pdf2text-php-client.iml @@ -0,0 +1,64 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/php.xml b/.idea/php.xml new file mode 100644 index 0000000..199f1f1 --- /dev/null +++ b/.idea/php.xml @@ -0,0 +1,81 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/phpunit.xml b/.idea/phpunit.xml new file mode 100644 index 0000000..4f8104c --- /dev/null +++ b/.idea/phpunit.xml @@ -0,0 +1,10 @@ + + + + + + \ No newline at end of file diff --git a/.idea/symfony2.xml b/.idea/symfony2.xml new file mode 100644 index 0000000..632dba4 --- /dev/null +++ b/.idea/symfony2.xml @@ -0,0 +1,6 @@ + + + + + \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 0000000..35eb1dd --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/LICENSE b/LICENSE index d99315e..770b4b0 100644 --- a/LICENSE +++ b/LICENSE @@ -1,21 +1,7 @@ -MIT License +Copyright 2024 Code Inc. / Joan Fabrégat -Copyright (c) 2024 Joan Fabrégat +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. +THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. \ No newline at end of file diff --git a/README.md b/README.md index 84f2a50..70a64e2 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,69 @@ -# pdf2text-php-client -PHP client for the pdf2text API +# pdf2txt PHP client + +This repository contains a PHP 8.2+ library for converting PDF files to images using the [pdf2txt](https://github.com/codeinchq/pdf2txt) service. + +## Installation + +The recommended way to install the library is through [Composer](http://getcomposer.org): + +```bash +composer require codeinc/pdf2txt-client +``` + +## Usage + +This client requires a running instance of the [pdf2text](https://github.com/codeinchq/pdf2text) service. The service can be run locally [using Docker](https://hub.docker.com/r/codeinchq/pdf2text) or deployed to a server. + +Base example: +```php +use CodeInc\Pdf2TextClient\Pdf2TextClient; +use CodeInc\Pdf2TextClient\Exception; + +$apiBaseUri = 'http://localhost:3000/'; +$localPdfPath = '/path/to/local/file.pdf'; + +try { + // convert + $client = new Pdf2TextClient($apiBaseUri); + $stream = $client->convertLocalFile($localPdfPath); + + // display the text + echo (string)$stream; +} +catch (Exception $e) { + // handle exception +} +``` + +With options: + +```php +use CodeInc\Pdf2TextClient\Pdf2TextClient; +use CodeInc\Pdf2TextClient\ConvertOptions; +use CodeInc\Pdf2TextClient\Format; + +$apiBaseUri = 'http://localhost:3000/'; +$localPdfPath = '/path/to/local/file.pdf'; +$convertOption = new ConvertOptions( + firstPage: 2, + lastPage: 3, + format: Format::json +); + +try { + // convert + $client = new Pdf2TextClient($apiBaseUri); + $jsonResponse = $client->convertLocalFile($localPdfPath, $convertOption); + $decodedJson = $client->processJsonResponse($jsonResponse); + + // display the text in a JSON format + var_dump($decodedJson); +} +catch (Exception $e) { + // handle exception +} +``` + +## License + +The library is published under the MIT license (see [`LICENSE`](LICENSE) file). \ No newline at end of file diff --git a/composer.json b/composer.json new file mode 100644 index 0000000..986febd --- /dev/null +++ b/composer.json @@ -0,0 +1,46 @@ +{ + "name": "codeinc/pdf2text-client", + "version": "v1.0", + "description": "A PHP client for the pdf2text service", + "homepage": "https://github.com/codeinchq/pdf2text-php-client", + "type": "library", + "license": "MIT", + "require": { + "php": ">=8.3", + "php-http/discovery": "^1.19", + "psr/http-client": "^1.0", + "php-http/multipart-stream-builder": "^1.3", + "nyholm/psr7": "^1.8" + }, + "autoload": { + "psr-4": { + "CodeInc\\Pdf2TextClient\\": "src" + } + }, + "autoload-dev": { + "psr-4": { + "CodeInc\\Pdf2TextClient\\Tests\\": "tests/" + } + }, + "authors": [ + { + "name": "Joan Fabrégat", + "email": "joan@codeinc.co", + "homepage": "https://www.codeinc.co", + "role": "developer" + } + ], + "config": { + "preferred-install": { + "*": "dist" + }, + "allow-plugins": { + "php-http/discovery": true + } + }, + "require-dev": { + "phpunit/phpunit": "^11", + "spatie/ray": "^1.41", + "php-http/guzzle7-adapter": "^1.0" + } +} diff --git a/composer.lock b/composer.lock new file mode 100644 index 0000000..7be2ff0 --- /dev/null +++ b/composer.lock @@ -0,0 +1,3413 @@ +{ + "_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": "2d589f3cc49f5f5edaed578061ed80ff", + "packages": [ + { + "name": "nyholm/psr7", + "version": "1.8.1", + "source": { + "type": "git", + "url": "https://github.com/Nyholm/psr7.git", + "reference": "aa5fc277a4f5508013d571341ade0c3886d4d00e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/Nyholm/psr7/zipball/aa5fc277a4f5508013d571341ade0c3886d4d00e", + "reference": "aa5fc277a4f5508013d571341ade0c3886d4d00e", + "shasum": "" + }, + "require": { + "php": ">=7.2", + "psr/http-factory": "^1.0", + "psr/http-message": "^1.1 || ^2.0" + }, + "provide": { + "php-http/message-factory-implementation": "1.0", + "psr/http-factory-implementation": "1.0", + "psr/http-message-implementation": "1.0" + }, + "require-dev": { + "http-interop/http-factory-tests": "^0.9", + "php-http/message-factory": "^1.0", + "php-http/psr7-integration-tests": "^1.0", + "phpunit/phpunit": "^7.5 || ^8.5 || ^9.4", + "symfony/error-handler": "^4.4" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.8-dev" + } + }, + "autoload": { + "psr-4": { + "Nyholm\\Psr7\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Tobias Nyholm", + "email": "tobias.nyholm@gmail.com" + }, + { + "name": "Martijn van der Ven", + "email": "martijn@vanderven.se" + } + ], + "description": "A fast PHP7 implementation of PSR-7", + "homepage": "https://tnyholm.se", + "keywords": [ + "psr-17", + "psr-7" + ], + "support": { + "issues": "https://github.com/Nyholm/psr7/issues", + "source": "https://github.com/Nyholm/psr7/tree/1.8.1" + }, + "funding": [ + { + "url": "https://github.com/Zegnat", + "type": "github" + }, + { + "url": "https://github.com/nyholm", + "type": "github" + } + ], + "time": "2023-11-13T09:31:12+00:00" + }, + { + "name": "php-http/discovery", + "version": "1.19.2", + "source": { + "type": "git", + "url": "https://github.com/php-http/discovery.git", + "reference": "61e1a1eb69c92741f5896d9e05fb8e9d7e8bb0cb" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-http/discovery/zipball/61e1a1eb69c92741f5896d9e05fb8e9d7e8bb0cb", + "reference": "61e1a1eb69c92741f5896d9e05fb8e9d7e8bb0cb", + "shasum": "" + }, + "require": { + "composer-plugin-api": "^1.0|^2.0", + "php": "^7.1 || ^8.0" + }, + "conflict": { + "nyholm/psr7": "<1.0", + "zendframework/zend-diactoros": "*" + }, + "provide": { + "php-http/async-client-implementation": "*", + "php-http/client-implementation": "*", + "psr/http-client-implementation": "*", + "psr/http-factory-implementation": "*", + "psr/http-message-implementation": "*" + }, + "require-dev": { + "composer/composer": "^1.0.2|^2.0", + "graham-campbell/phpspec-skip-example-extension": "^5.0", + "php-http/httplug": "^1.0 || ^2.0", + "php-http/message-factory": "^1.0", + "phpspec/phpspec": "^5.1 || ^6.1 || ^7.3", + "symfony/phpunit-bridge": "^6.2" + }, + "type": "composer-plugin", + "extra": { + "class": "Http\\Discovery\\Composer\\Plugin", + "plugin-optional": true + }, + "autoload": { + "psr-4": { + "Http\\Discovery\\": "src/" + }, + "exclude-from-classmap": [ + "src/Composer/Plugin.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Márk Sági-Kazár", + "email": "mark.sagikazar@gmail.com" + } + ], + "description": "Finds and installs PSR-7, PSR-17, PSR-18 and HTTPlug implementations", + "homepage": "http://php-http.org", + "keywords": [ + "adapter", + "client", + "discovery", + "factory", + "http", + "message", + "psr17", + "psr7" + ], + "support": { + "issues": "https://github.com/php-http/discovery/issues", + "source": "https://github.com/php-http/discovery/tree/1.19.2" + }, + "time": "2023-11-30T16:49:05+00:00" + }, + { + "name": "php-http/multipart-stream-builder", + "version": "1.3.0", + "source": { + "type": "git", + "url": "https://github.com/php-http/multipart-stream-builder.git", + "reference": "f5938fd135d9fa442cc297dc98481805acfe2b6a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-http/multipart-stream-builder/zipball/f5938fd135d9fa442cc297dc98481805acfe2b6a", + "reference": "f5938fd135d9fa442cc297dc98481805acfe2b6a", + "shasum": "" + }, + "require": { + "php": "^7.1 || ^8.0", + "php-http/discovery": "^1.15", + "psr/http-factory-implementation": "^1.0" + }, + "require-dev": { + "nyholm/psr7": "^1.0", + "php-http/message": "^1.5", + "php-http/message-factory": "^1.0.2", + "phpunit/phpunit": "^7.5.15 || ^8.5 || ^9.3" + }, + "type": "library", + "autoload": { + "psr-4": { + "Http\\Message\\MultipartStream\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Tobias Nyholm", + "email": "tobias.nyholm@gmail.com" + } + ], + "description": "A builder class that help you create a multipart stream", + "homepage": "http://php-http.org", + "keywords": [ + "factory", + "http", + "message", + "multipart stream", + "stream" + ], + "support": { + "issues": "https://github.com/php-http/multipart-stream-builder/issues", + "source": "https://github.com/php-http/multipart-stream-builder/tree/1.3.0" + }, + "time": "2023-04-28T14:10:22+00:00" + }, + { + "name": "psr/http-client", + "version": "1.0.3", + "source": { + "type": "git", + "url": "https://github.com/php-fig/http-client.git", + "reference": "bb5906edc1c324c9a05aa0873d40117941e5fa90" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/http-client/zipball/bb5906edc1c324c9a05aa0873d40117941e5fa90", + "reference": "bb5906edc1c324c9a05aa0873d40117941e5fa90", + "shasum": "" + }, + "require": { + "php": "^7.0 || ^8.0", + "psr/http-message": "^1.0 || ^2.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Http\\Client\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "https://www.php-fig.org/" + } + ], + "description": "Common interface for HTTP clients", + "homepage": "https://github.com/php-fig/http-client", + "keywords": [ + "http", + "http-client", + "psr", + "psr-18" + ], + "support": { + "source": "https://github.com/php-fig/http-client" + }, + "time": "2023-09-23T14:17:50+00:00" + }, + { + "name": "psr/http-factory", + "version": "1.0.2", + "source": { + "type": "git", + "url": "https://github.com/php-fig/http-factory.git", + "reference": "e616d01114759c4c489f93b099585439f795fe35" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/http-factory/zipball/e616d01114759c4c489f93b099585439f795fe35", + "reference": "e616d01114759c4c489f93b099585439f795fe35", + "shasum": "" + }, + "require": { + "php": ">=7.0.0", + "psr/http-message": "^1.0 || ^2.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Http\\Message\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "https://www.php-fig.org/" + } + ], + "description": "Common interfaces for PSR-7 HTTP message factories", + "keywords": [ + "factory", + "http", + "message", + "psr", + "psr-17", + "psr-7", + "request", + "response" + ], + "support": { + "source": "https://github.com/php-fig/http-factory/tree/1.0.2" + }, + "time": "2023-04-10T20:10:41+00:00" + }, + { + "name": "psr/http-message", + "version": "2.0", + "source": { + "type": "git", + "url": "https://github.com/php-fig/http-message.git", + "reference": "402d35bcb92c70c026d1a6a9883f06b2ead23d71" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/http-message/zipball/402d35bcb92c70c026d1a6a9883f06b2ead23d71", + "reference": "402d35bcb92c70c026d1a6a9883f06b2ead23d71", + "shasum": "" + }, + "require": { + "php": "^7.2 || ^8.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Http\\Message\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "https://www.php-fig.org/" + } + ], + "description": "Common interface for HTTP messages", + "homepage": "https://github.com/php-fig/http-message", + "keywords": [ + "http", + "http-message", + "psr", + "psr-7", + "request", + "response" + ], + "support": { + "source": "https://github.com/php-fig/http-message/tree/2.0" + }, + "time": "2023-04-04T09:54:51+00:00" + } + ], + "packages-dev": [ + { + "name": "brick/math", + "version": "0.11.0", + "source": { + "type": "git", + "url": "https://github.com/brick/math.git", + "reference": "0ad82ce168c82ba30d1c01ec86116ab52f589478" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/brick/math/zipball/0ad82ce168c82ba30d1c01ec86116ab52f589478", + "reference": "0ad82ce168c82ba30d1c01ec86116ab52f589478", + "shasum": "" + }, + "require": { + "php": "^8.0" + }, + "require-dev": { + "php-coveralls/php-coveralls": "^2.2", + "phpunit/phpunit": "^9.0", + "vimeo/psalm": "5.0.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Brick\\Math\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "Arbitrary-precision arithmetic library", + "keywords": [ + "Arbitrary-precision", + "BigInteger", + "BigRational", + "arithmetic", + "bigdecimal", + "bignum", + "brick", + "math" + ], + "support": { + "issues": "https://github.com/brick/math/issues", + "source": "https://github.com/brick/math/tree/0.11.0" + }, + "funding": [ + { + "url": "https://github.com/BenMorel", + "type": "github" + } + ], + "time": "2023-01-15T23:15:59+00:00" + }, + { + "name": "guzzlehttp/guzzle", + "version": "7.8.1", + "source": { + "type": "git", + "url": "https://github.com/guzzle/guzzle.git", + "reference": "41042bc7ab002487b876a0683fc8dce04ddce104" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/guzzle/guzzle/zipball/41042bc7ab002487b876a0683fc8dce04ddce104", + "reference": "41042bc7ab002487b876a0683fc8dce04ddce104", + "shasum": "" + }, + "require": { + "ext-json": "*", + "guzzlehttp/promises": "^1.5.3 || ^2.0.1", + "guzzlehttp/psr7": "^1.9.1 || ^2.5.1", + "php": "^7.2.5 || ^8.0", + "psr/http-client": "^1.0", + "symfony/deprecation-contracts": "^2.2 || ^3.0" + }, + "provide": { + "psr/http-client-implementation": "1.0" + }, + "require-dev": { + "bamarni/composer-bin-plugin": "^1.8.2", + "ext-curl": "*", + "php-http/client-integration-tests": "dev-master#2c025848417c1135031fdf9c728ee53d0a7ceaee as 3.0.999", + "php-http/message-factory": "^1.1", + "phpunit/phpunit": "^8.5.36 || ^9.6.15", + "psr/log": "^1.1 || ^2.0 || ^3.0" + }, + "suggest": { + "ext-curl": "Required for CURL handler support", + "ext-intl": "Required for Internationalized Domain Name (IDN) support", + "psr/log": "Required for using the Log middleware" + }, + "type": "library", + "extra": { + "bamarni-bin": { + "bin-links": true, + "forward-command": false + } + }, + "autoload": { + "files": [ + "src/functions_include.php" + ], + "psr-4": { + "GuzzleHttp\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Graham Campbell", + "email": "hello@gjcampbell.co.uk", + "homepage": "https://github.com/GrahamCampbell" + }, + { + "name": "Michael Dowling", + "email": "mtdowling@gmail.com", + "homepage": "https://github.com/mtdowling" + }, + { + "name": "Jeremy Lindblom", + "email": "jeremeamia@gmail.com", + "homepage": "https://github.com/jeremeamia" + }, + { + "name": "George Mponos", + "email": "gmponos@gmail.com", + "homepage": "https://github.com/gmponos" + }, + { + "name": "Tobias Nyholm", + "email": "tobias.nyholm@gmail.com", + "homepage": "https://github.com/Nyholm" + }, + { + "name": "Márk Sági-Kazár", + "email": "mark.sagikazar@gmail.com", + "homepage": "https://github.com/sagikazarmark" + }, + { + "name": "Tobias Schultze", + "email": "webmaster@tubo-world.de", + "homepage": "https://github.com/Tobion" + } + ], + "description": "Guzzle is a PHP HTTP client library", + "keywords": [ + "client", + "curl", + "framework", + "http", + "http client", + "psr-18", + "psr-7", + "rest", + "web service" + ], + "support": { + "issues": "https://github.com/guzzle/guzzle/issues", + "source": "https://github.com/guzzle/guzzle/tree/7.8.1" + }, + "funding": [ + { + "url": "https://github.com/GrahamCampbell", + "type": "github" + }, + { + "url": "https://github.com/Nyholm", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/guzzlehttp/guzzle", + "type": "tidelift" + } + ], + "time": "2023-12-03T20:35:24+00:00" + }, + { + "name": "guzzlehttp/promises", + "version": "2.0.2", + "source": { + "type": "git", + "url": "https://github.com/guzzle/promises.git", + "reference": "bbff78d96034045e58e13dedd6ad91b5d1253223" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/guzzle/promises/zipball/bbff78d96034045e58e13dedd6ad91b5d1253223", + "reference": "bbff78d96034045e58e13dedd6ad91b5d1253223", + "shasum": "" + }, + "require": { + "php": "^7.2.5 || ^8.0" + }, + "require-dev": { + "bamarni/composer-bin-plugin": "^1.8.2", + "phpunit/phpunit": "^8.5.36 || ^9.6.15" + }, + "type": "library", + "extra": { + "bamarni-bin": { + "bin-links": true, + "forward-command": false + } + }, + "autoload": { + "psr-4": { + "GuzzleHttp\\Promise\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Graham Campbell", + "email": "hello@gjcampbell.co.uk", + "homepage": "https://github.com/GrahamCampbell" + }, + { + "name": "Michael Dowling", + "email": "mtdowling@gmail.com", + "homepage": "https://github.com/mtdowling" + }, + { + "name": "Tobias Nyholm", + "email": "tobias.nyholm@gmail.com", + "homepage": "https://github.com/Nyholm" + }, + { + "name": "Tobias Schultze", + "email": "webmaster@tubo-world.de", + "homepage": "https://github.com/Tobion" + } + ], + "description": "Guzzle promises library", + "keywords": [ + "promise" + ], + "support": { + "issues": "https://github.com/guzzle/promises/issues", + "source": "https://github.com/guzzle/promises/tree/2.0.2" + }, + "funding": [ + { + "url": "https://github.com/GrahamCampbell", + "type": "github" + }, + { + "url": "https://github.com/Nyholm", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/guzzlehttp/promises", + "type": "tidelift" + } + ], + "time": "2023-12-03T20:19:20+00:00" + }, + { + "name": "guzzlehttp/psr7", + "version": "2.6.2", + "source": { + "type": "git", + "url": "https://github.com/guzzle/psr7.git", + "reference": "45b30f99ac27b5ca93cb4831afe16285f57b8221" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/guzzle/psr7/zipball/45b30f99ac27b5ca93cb4831afe16285f57b8221", + "reference": "45b30f99ac27b5ca93cb4831afe16285f57b8221", + "shasum": "" + }, + "require": { + "php": "^7.2.5 || ^8.0", + "psr/http-factory": "^1.0", + "psr/http-message": "^1.1 || ^2.0", + "ralouphie/getallheaders": "^3.0" + }, + "provide": { + "psr/http-factory-implementation": "1.0", + "psr/http-message-implementation": "1.0" + }, + "require-dev": { + "bamarni/composer-bin-plugin": "^1.8.2", + "http-interop/http-factory-tests": "^0.9", + "phpunit/phpunit": "^8.5.36 || ^9.6.15" + }, + "suggest": { + "laminas/laminas-httphandlerrunner": "Emit PSR-7 responses" + }, + "type": "library", + "extra": { + "bamarni-bin": { + "bin-links": true, + "forward-command": false + } + }, + "autoload": { + "psr-4": { + "GuzzleHttp\\Psr7\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Graham Campbell", + "email": "hello@gjcampbell.co.uk", + "homepage": "https://github.com/GrahamCampbell" + }, + { + "name": "Michael Dowling", + "email": "mtdowling@gmail.com", + "homepage": "https://github.com/mtdowling" + }, + { + "name": "George Mponos", + "email": "gmponos@gmail.com", + "homepage": "https://github.com/gmponos" + }, + { + "name": "Tobias Nyholm", + "email": "tobias.nyholm@gmail.com", + "homepage": "https://github.com/Nyholm" + }, + { + "name": "Márk Sági-Kazár", + "email": "mark.sagikazar@gmail.com", + "homepage": "https://github.com/sagikazarmark" + }, + { + "name": "Tobias Schultze", + "email": "webmaster@tubo-world.de", + "homepage": "https://github.com/Tobion" + }, + { + "name": "Márk Sági-Kazár", + "email": "mark.sagikazar@gmail.com", + "homepage": "https://sagikazarmark.hu" + } + ], + "description": "PSR-7 message implementation that also provides common utility methods", + "keywords": [ + "http", + "message", + "psr-7", + "request", + "response", + "stream", + "uri", + "url" + ], + "support": { + "issues": "https://github.com/guzzle/psr7/issues", + "source": "https://github.com/guzzle/psr7/tree/2.6.2" + }, + "funding": [ + { + "url": "https://github.com/GrahamCampbell", + "type": "github" + }, + { + "url": "https://github.com/Nyholm", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/guzzlehttp/psr7", + "type": "tidelift" + } + ], + "time": "2023-12-03T20:05:35+00:00" + }, + { + "name": "myclabs/deep-copy", + "version": "1.11.1", + "source": { + "type": "git", + "url": "https://github.com/myclabs/DeepCopy.git", + "reference": "7284c22080590fb39f2ffa3e9057f10a4ddd0e0c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/7284c22080590fb39f2ffa3e9057f10a4ddd0e0c", + "reference": "7284c22080590fb39f2ffa3e9057f10a4ddd0e0c", + "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.1" + }, + "funding": [ + { + "url": "https://tidelift.com/funding/github/packagist/myclabs/deep-copy", + "type": "tidelift" + } + ], + "time": "2023-03-08T13:26:56+00:00" + }, + { + "name": "nikic/php-parser", + "version": "v5.0.1", + "source": { + "type": "git", + "url": "https://github.com/nikic/PHP-Parser.git", + "reference": "2218c2252c874a4624ab2f613d86ac32d227bc69" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/2218c2252c874a4624ab2f613d86ac32d227bc69", + "reference": "2218c2252c874a4624ab2f613d86ac32d227bc69", + "shasum": "" + }, + "require": { + "ext-ctype": "*", + "ext-json": "*", + "ext-tokenizer": "*", + "php": ">=7.4" + }, + "require-dev": { + "ircmaxell/php-yacc": "^0.0.7", + "phpunit/phpunit": "^7.0 || ^8.0 || ^9.0" + }, + "bin": [ + "bin/php-parse" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "5.0-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/v5.0.1" + }, + "time": "2024-02-21T19:24:10+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": "php-http/guzzle7-adapter", + "version": "1.0.0", + "source": { + "type": "git", + "url": "https://github.com/php-http/guzzle7-adapter.git", + "reference": "fb075a71dbfa4847cf0c2938c4e5a9c478ef8b01" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-http/guzzle7-adapter/zipball/fb075a71dbfa4847cf0c2938c4e5a9c478ef8b01", + "reference": "fb075a71dbfa4847cf0c2938c4e5a9c478ef8b01", + "shasum": "" + }, + "require": { + "guzzlehttp/guzzle": "^7.0", + "php": "^7.2 | ^8.0", + "php-http/httplug": "^2.0", + "psr/http-client": "^1.0" + }, + "provide": { + "php-http/async-client-implementation": "1.0", + "php-http/client-implementation": "1.0", + "psr/http-client-implementation": "1.0" + }, + "require-dev": { + "php-http/client-integration-tests": "^3.0", + "phpunit/phpunit": "^8.0|^9.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "0.2.x-dev" + } + }, + "autoload": { + "psr-4": { + "Http\\Adapter\\Guzzle7\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Tobias Nyholm", + "email": "tobias.nyholm@gmail.com" + } + ], + "description": "Guzzle 7 HTTP Adapter", + "homepage": "http://httplug.io", + "keywords": [ + "Guzzle", + "http" + ], + "support": { + "issues": "https://github.com/php-http/guzzle7-adapter/issues", + "source": "https://github.com/php-http/guzzle7-adapter/tree/1.0.0" + }, + "time": "2021-03-09T07:35:15+00:00" + }, + { + "name": "php-http/httplug", + "version": "2.4.0", + "source": { + "type": "git", + "url": "https://github.com/php-http/httplug.git", + "reference": "625ad742c360c8ac580fcc647a1541d29e257f67" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-http/httplug/zipball/625ad742c360c8ac580fcc647a1541d29e257f67", + "reference": "625ad742c360c8ac580fcc647a1541d29e257f67", + "shasum": "" + }, + "require": { + "php": "^7.1 || ^8.0", + "php-http/promise": "^1.1", + "psr/http-client": "^1.0", + "psr/http-message": "^1.0 || ^2.0" + }, + "require-dev": { + "friends-of-phpspec/phpspec-code-coverage": "^4.1 || ^5.0 || ^6.0", + "phpspec/phpspec": "^5.1 || ^6.0 || ^7.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Http\\Client\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Eric GELOEN", + "email": "geloen.eric@gmail.com" + }, + { + "name": "Márk Sági-Kazár", + "email": "mark.sagikazar@gmail.com", + "homepage": "https://sagikazarmark.hu" + } + ], + "description": "HTTPlug, the HTTP client abstraction for PHP", + "homepage": "http://httplug.io", + "keywords": [ + "client", + "http" + ], + "support": { + "issues": "https://github.com/php-http/httplug/issues", + "source": "https://github.com/php-http/httplug/tree/2.4.0" + }, + "time": "2023-04-14T15:10:03+00:00" + }, + { + "name": "php-http/promise", + "version": "1.3.0", + "source": { + "type": "git", + "url": "https://github.com/php-http/promise.git", + "reference": "2916a606d3b390f4e9e8e2b8dd68581508be0f07" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-http/promise/zipball/2916a606d3b390f4e9e8e2b8dd68581508be0f07", + "reference": "2916a606d3b390f4e9e8e2b8dd68581508be0f07", + "shasum": "" + }, + "require": { + "php": "^7.1 || ^8.0" + }, + "require-dev": { + "friends-of-phpspec/phpspec-code-coverage": "^4.3.2 || ^6.3", + "phpspec/phpspec": "^5.1.2 || ^6.2 || ^7.4" + }, + "type": "library", + "autoload": { + "psr-4": { + "Http\\Promise\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Joel Wurtz", + "email": "joel.wurtz@gmail.com" + }, + { + "name": "Márk Sági-Kazár", + "email": "mark.sagikazar@gmail.com" + } + ], + "description": "Promise used for asynchronous HTTP requests", + "homepage": "http://httplug.io", + "keywords": [ + "promise" + ], + "support": { + "issues": "https://github.com/php-http/promise/issues", + "source": "https://github.com/php-http/promise/tree/1.3.0" + }, + "time": "2024-01-04T18:49:48+00:00" + }, + { + "name": "phpunit/php-code-coverage", + "version": "11.0.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-code-coverage.git", + "reference": "5e238e4b982cb272bf9faeee6f33af83d465d0e2" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/5e238e4b982cb272bf9faeee6f33af83d465d0e2", + "reference": "5e238e4b982cb272bf9faeee6f33af83d465d0e2", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "ext-libxml": "*", + "ext-xmlwriter": "*", + "nikic/php-parser": "^5.0", + "php": ">=8.2", + "phpunit/php-file-iterator": "^5.0", + "phpunit/php-text-template": "^4.0", + "sebastian/code-unit-reverse-lookup": "^4.0", + "sebastian/complexity": "^4.0", + "sebastian/environment": "^7.0", + "sebastian/lines-of-code": "^3.0", + "sebastian/version": "^5.0", + "theseer/tokenizer": "^1.2.0" + }, + "require-dev": { + "phpunit/phpunit": "^11.0" + }, + "suggest": { + "ext-pcov": "PHP extension that provides line coverage", + "ext-xdebug": "PHP extension that provides line coverage as well as branch and path coverage" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "11.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 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", + "security": "https://github.com/sebastianbergmann/php-code-coverage/security/policy", + "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/11.0.0" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2024-02-02T06:03:46+00:00" + }, + { + "name": "phpunit/php-file-iterator", + "version": "5.0.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-file-iterator.git", + "reference": "99e95c94ad9500daca992354fa09d7b99abe2210" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/99e95c94ad9500daca992354fa09d7b99abe2210", + "reference": "99e95c94ad9500daca992354fa09d7b99abe2210", + "shasum": "" + }, + "require": { + "php": ">=8.2" + }, + "require-dev": { + "phpunit/phpunit": "^11.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "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": "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", + "security": "https://github.com/sebastianbergmann/php-file-iterator/security/policy", + "source": "https://github.com/sebastianbergmann/php-file-iterator/tree/5.0.0" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2024-02-02T06:05:04+00:00" + }, + { + "name": "phpunit/php-invoker", + "version": "5.0.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-invoker.git", + "reference": "5d8d9355a16d8cc5a1305b0a85342cfa420612be" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-invoker/zipball/5d8d9355a16d8cc5a1305b0a85342cfa420612be", + "reference": "5d8d9355a16d8cc5a1305b0a85342cfa420612be", + "shasum": "" + }, + "require": { + "php": ">=8.2" + }, + "require-dev": { + "ext-pcntl": "*", + "phpunit/phpunit": "^11.0" + }, + "suggest": { + "ext-pcntl": "*" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "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": "Invoke callables with a timeout", + "homepage": "https://github.com/sebastianbergmann/php-invoker/", + "keywords": [ + "process" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/php-invoker/issues", + "security": "https://github.com/sebastianbergmann/php-invoker/security/policy", + "source": "https://github.com/sebastianbergmann/php-invoker/tree/5.0.0" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2024-02-02T06:05:50+00:00" + }, + { + "name": "phpunit/php-text-template", + "version": "4.0.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-text-template.git", + "reference": "d38f6cbff1cdb6f40b03c9811421561668cc133e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-text-template/zipball/d38f6cbff1cdb6f40b03c9811421561668cc133e", + "reference": "d38f6cbff1cdb6f40b03c9811421561668cc133e", + "shasum": "" + }, + "require": { + "php": ">=8.2" + }, + "require-dev": { + "phpunit/phpunit": "^11.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "4.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", + "security": "https://github.com/sebastianbergmann/php-text-template/security/policy", + "source": "https://github.com/sebastianbergmann/php-text-template/tree/4.0.0" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2024-02-02T06:06:56+00:00" + }, + { + "name": "phpunit/php-timer", + "version": "7.0.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-timer.git", + "reference": "8a59d9e25720482ee7fcdf296595e08795b84dc5" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/8a59d9e25720482ee7fcdf296595e08795b84dc5", + "reference": "8a59d9e25720482ee7fcdf296595e08795b84dc5", + "shasum": "" + }, + "require": { + "php": ">=8.2" + }, + "require-dev": { + "phpunit/phpunit": "^11.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "7.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", + "security": "https://github.com/sebastianbergmann/php-timer/security/policy", + "source": "https://github.com/sebastianbergmann/php-timer/tree/7.0.0" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2024-02-02T06:08:01+00:00" + }, + { + "name": "phpunit/phpunit", + "version": "11.0.3", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/phpunit.git", + "reference": "de24e7e7c67fbf437f7b6cd7bc919f2dc6fd89d4" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/de24e7e7c67fbf437f7b6cd7bc919f2dc6fd89d4", + "reference": "de24e7e7c67fbf437f7b6cd7bc919f2dc6fd89d4", + "shasum": "" + }, + "require": { + "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": ">=8.2", + "phpunit/php-code-coverage": "^11.0", + "phpunit/php-file-iterator": "^5.0", + "phpunit/php-invoker": "^5.0", + "phpunit/php-text-template": "^4.0", + "phpunit/php-timer": "^7.0", + "sebastian/cli-parser": "^3.0", + "sebastian/code-unit": "^3.0", + "sebastian/comparator": "^6.0", + "sebastian/diff": "^6.0", + "sebastian/environment": "^7.0", + "sebastian/exporter": "^6.0", + "sebastian/global-state": "^7.0", + "sebastian/object-enumerator": "^6.0", + "sebastian/type": "^5.0", + "sebastian/version": "^5.0" + }, + "suggest": { + "ext-soap": "To be able to generate mocks based on WSDL files" + }, + "bin": [ + "phpunit" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "11.0-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", + "security": "https://github.com/sebastianbergmann/phpunit/security/policy", + "source": "https://github.com/sebastianbergmann/phpunit/tree/11.0.3" + }, + "funding": [ + { + "url": "https://phpunit.de/sponsors.html", + "type": "custom" + }, + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/phpunit/phpunit", + "type": "tidelift" + } + ], + "time": "2024-02-10T06:31: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": "ralouphie/getallheaders", + "version": "3.0.3", + "source": { + "type": "git", + "url": "https://github.com/ralouphie/getallheaders.git", + "reference": "120b605dfeb996808c31b6477290a714d356e822" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/ralouphie/getallheaders/zipball/120b605dfeb996808c31b6477290a714d356e822", + "reference": "120b605dfeb996808c31b6477290a714d356e822", + "shasum": "" + }, + "require": { + "php": ">=5.6" + }, + "require-dev": { + "php-coveralls/php-coveralls": "^2.1", + "phpunit/phpunit": "^5 || ^6.5" + }, + "type": "library", + "autoload": { + "files": [ + "src/getallheaders.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Ralph Khattar", + "email": "ralph.khattar@gmail.com" + } + ], + "description": "A polyfill for getallheaders.", + "support": { + "issues": "https://github.com/ralouphie/getallheaders/issues", + "source": "https://github.com/ralouphie/getallheaders/tree/develop" + }, + "time": "2019-03-08T08:55:37+00:00" + }, + { + "name": "ramsey/collection", + "version": "2.0.0", + "source": { + "type": "git", + "url": "https://github.com/ramsey/collection.git", + "reference": "a4b48764bfbb8f3a6a4d1aeb1a35bb5e9ecac4a5" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/ramsey/collection/zipball/a4b48764bfbb8f3a6a4d1aeb1a35bb5e9ecac4a5", + "reference": "a4b48764bfbb8f3a6a4d1aeb1a35bb5e9ecac4a5", + "shasum": "" + }, + "require": { + "php": "^8.1" + }, + "require-dev": { + "captainhook/plugin-composer": "^5.3", + "ergebnis/composer-normalize": "^2.28.3", + "fakerphp/faker": "^1.21", + "hamcrest/hamcrest-php": "^2.0", + "jangregor/phpstan-prophecy": "^1.0", + "mockery/mockery": "^1.5", + "php-parallel-lint/php-console-highlighter": "^1.0", + "php-parallel-lint/php-parallel-lint": "^1.3", + "phpcsstandards/phpcsutils": "^1.0.0-rc1", + "phpspec/prophecy-phpunit": "^2.0", + "phpstan/extension-installer": "^1.2", + "phpstan/phpstan": "^1.9", + "phpstan/phpstan-mockery": "^1.1", + "phpstan/phpstan-phpunit": "^1.3", + "phpunit/phpunit": "^9.5", + "psalm/plugin-mockery": "^1.1", + "psalm/plugin-phpunit": "^0.18.4", + "ramsey/coding-standard": "^2.0.3", + "ramsey/conventional-commits": "^1.3", + "vimeo/psalm": "^5.4" + }, + "type": "library", + "extra": { + "captainhook": { + "force-install": true + }, + "ramsey/conventional-commits": { + "configFile": "conventional-commits.json" + } + }, + "autoload": { + "psr-4": { + "Ramsey\\Collection\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Ben Ramsey", + "email": "ben@benramsey.com", + "homepage": "https://benramsey.com" + } + ], + "description": "A PHP library for representing and manipulating collections.", + "keywords": [ + "array", + "collection", + "hash", + "map", + "queue", + "set" + ], + "support": { + "issues": "https://github.com/ramsey/collection/issues", + "source": "https://github.com/ramsey/collection/tree/2.0.0" + }, + "funding": [ + { + "url": "https://github.com/ramsey", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/ramsey/collection", + "type": "tidelift" + } + ], + "time": "2022-12-31T21:50:55+00:00" + }, + { + "name": "ramsey/uuid", + "version": "4.7.5", + "source": { + "type": "git", + "url": "https://github.com/ramsey/uuid.git", + "reference": "5f0df49ae5ad6efb7afa69e6bfab4e5b1e080d8e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/ramsey/uuid/zipball/5f0df49ae5ad6efb7afa69e6bfab4e5b1e080d8e", + "reference": "5f0df49ae5ad6efb7afa69e6bfab4e5b1e080d8e", + "shasum": "" + }, + "require": { + "brick/math": "^0.8.8 || ^0.9 || ^0.10 || ^0.11", + "ext-json": "*", + "php": "^8.0", + "ramsey/collection": "^1.2 || ^2.0" + }, + "replace": { + "rhumsaa/uuid": "self.version" + }, + "require-dev": { + "captainhook/captainhook": "^5.10", + "captainhook/plugin-composer": "^5.3", + "dealerdirect/phpcodesniffer-composer-installer": "^0.7.0", + "doctrine/annotations": "^1.8", + "ergebnis/composer-normalize": "^2.15", + "mockery/mockery": "^1.3", + "paragonie/random-lib": "^2", + "php-mock/php-mock": "^2.2", + "php-mock/php-mock-mockery": "^1.3", + "php-parallel-lint/php-parallel-lint": "^1.1", + "phpbench/phpbench": "^1.0", + "phpstan/extension-installer": "^1.1", + "phpstan/phpstan": "^1.8", + "phpstan/phpstan-mockery": "^1.1", + "phpstan/phpstan-phpunit": "^1.1", + "phpunit/phpunit": "^8.5 || ^9", + "ramsey/composer-repl": "^1.4", + "slevomat/coding-standard": "^8.4", + "squizlabs/php_codesniffer": "^3.5", + "vimeo/psalm": "^4.9" + }, + "suggest": { + "ext-bcmath": "Enables faster math with arbitrary-precision integers using BCMath.", + "ext-gmp": "Enables faster math with arbitrary-precision integers using GMP.", + "ext-uuid": "Enables the use of PeclUuidTimeGenerator and PeclUuidRandomGenerator.", + "paragonie/random-lib": "Provides RandomLib for use with the RandomLibAdapter", + "ramsey/uuid-doctrine": "Allows the use of Ramsey\\Uuid\\Uuid as Doctrine field type." + }, + "type": "library", + "extra": { + "captainhook": { + "force-install": true + } + }, + "autoload": { + "files": [ + "src/functions.php" + ], + "psr-4": { + "Ramsey\\Uuid\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "A PHP library for generating and working with universally unique identifiers (UUIDs).", + "keywords": [ + "guid", + "identifier", + "uuid" + ], + "support": { + "issues": "https://github.com/ramsey/uuid/issues", + "source": "https://github.com/ramsey/uuid/tree/4.7.5" + }, + "funding": [ + { + "url": "https://github.com/ramsey", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/ramsey/uuid", + "type": "tidelift" + } + ], + "time": "2023-11-08T05:53:05+00:00" + }, + { + "name": "sebastian/cli-parser", + "version": "3.0.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/cli-parser.git", + "reference": "efd6ce5bb8131fe981e2f879dbd47605fbe0cc6f" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/cli-parser/zipball/efd6ce5bb8131fe981e2f879dbd47605fbe0cc6f", + "reference": "efd6ce5bb8131fe981e2f879dbd47605fbe0cc6f", + "shasum": "" + }, + "require": { + "php": ">=8.2" + }, + "require-dev": { + "phpunit/phpunit": "^11.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "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 for parsing CLI options", + "homepage": "https://github.com/sebastianbergmann/cli-parser", + "support": { + "issues": "https://github.com/sebastianbergmann/cli-parser/issues", + "security": "https://github.com/sebastianbergmann/cli-parser/security/policy", + "source": "https://github.com/sebastianbergmann/cli-parser/tree/3.0.0" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2024-02-02T05:48:04+00:00" + }, + { + "name": "sebastian/code-unit", + "version": "3.0.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/code-unit.git", + "reference": "6634549cb8d702282a04a774e36a7477d2bd9015" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/code-unit/zipball/6634549cb8d702282a04a774e36a7477d2bd9015", + "reference": "6634549cb8d702282a04a774e36a7477d2bd9015", + "shasum": "" + }, + "require": { + "php": ">=8.2" + }, + "require-dev": { + "phpunit/phpunit": "^11.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "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": "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", + "security": "https://github.com/sebastianbergmann/code-unit/security/policy", + "source": "https://github.com/sebastianbergmann/code-unit/tree/3.0.0" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2024-02-02T05:50:41+00:00" + }, + { + "name": "sebastian/code-unit-reverse-lookup", + "version": "4.0.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/code-unit-reverse-lookup.git", + "reference": "df80c875d3e459b45c6039e4d9b71d4fbccae25d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/code-unit-reverse-lookup/zipball/df80c875d3e459b45c6039e4d9b71d4fbccae25d", + "reference": "df80c875d3e459b45c6039e4d9b71d4fbccae25d", + "shasum": "" + }, + "require": { + "php": ">=8.2" + }, + "require-dev": { + "phpunit/phpunit": "^11.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "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": "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", + "security": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/security/policy", + "source": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/tree/4.0.0" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2024-02-02T05:52:17+00:00" + }, + { + "name": "sebastian/comparator", + "version": "6.0.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/comparator.git", + "reference": "bd0f2fa5b9257c69903537b266ccb80fcf940db8" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/bd0f2fa5b9257c69903537b266ccb80fcf940db8", + "reference": "bd0f2fa5b9257c69903537b266ccb80fcf940db8", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "ext-mbstring": "*", + "php": ">=8.2", + "sebastian/diff": "^6.0", + "sebastian/exporter": "^6.0" + }, + "require-dev": { + "phpunit/phpunit": "^11.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "6.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", + "security": "https://github.com/sebastianbergmann/comparator/security/policy", + "source": "https://github.com/sebastianbergmann/comparator/tree/6.0.0" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2024-02-02T05:53:45+00:00" + }, + { + "name": "sebastian/complexity", + "version": "4.0.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/complexity.git", + "reference": "88a434ad86150e11a606ac4866b09130712671f0" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/complexity/zipball/88a434ad86150e11a606ac4866b09130712671f0", + "reference": "88a434ad86150e11a606ac4866b09130712671f0", + "shasum": "" + }, + "require": { + "nikic/php-parser": "^5.0", + "php": ">=8.2" + }, + "require-dev": { + "phpunit/phpunit": "^11.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "4.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", + "security": "https://github.com/sebastianbergmann/complexity/security/policy", + "source": "https://github.com/sebastianbergmann/complexity/tree/4.0.0" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2024-02-02T05:55:19+00:00" + }, + { + "name": "sebastian/diff", + "version": "6.0.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/diff.git", + "reference": "3e3f502419518897a923aa1c64d51f9def2e0aff" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/3e3f502419518897a923aa1c64d51f9def2e0aff", + "reference": "3e3f502419518897a923aa1c64d51f9def2e0aff", + "shasum": "" + }, + "require": { + "php": ">=8.2" + }, + "require-dev": { + "phpunit/phpunit": "^11.0", + "symfony/process": "^4.2 || ^5" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "6.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", + "security": "https://github.com/sebastianbergmann/diff/security/policy", + "source": "https://github.com/sebastianbergmann/diff/tree/6.0.0" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2024-02-02T05:56:35+00:00" + }, + { + "name": "sebastian/environment", + "version": "7.0.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/environment.git", + "reference": "100d8b855d7180f79f9a9a5c483f2d960581c3ea" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/100d8b855d7180f79f9a9a5c483f2d960581c3ea", + "reference": "100d8b855d7180f79f9a9a5c483f2d960581c3ea", + "shasum": "" + }, + "require": { + "php": ">=8.2" + }, + "require-dev": { + "phpunit/phpunit": "^11.0" + }, + "suggest": { + "ext-posix": "*" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "7.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 functionality to handle HHVM/PHP environments", + "homepage": "https://github.com/sebastianbergmann/environment", + "keywords": [ + "Xdebug", + "environment", + "hhvm" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/environment/issues", + "security": "https://github.com/sebastianbergmann/environment/security/policy", + "source": "https://github.com/sebastianbergmann/environment/tree/7.0.0" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2024-02-02T05:57:54+00:00" + }, + { + "name": "sebastian/exporter", + "version": "6.0.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/exporter.git", + "reference": "d0c0a93fc746b0c066037f1e7d09104129e868ff" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/d0c0a93fc746b0c066037f1e7d09104129e868ff", + "reference": "d0c0a93fc746b0c066037f1e7d09104129e868ff", + "shasum": "" + }, + "require": { + "ext-mbstring": "*", + "php": ">=8.2", + "sebastian/recursion-context": "^6.0" + }, + "require-dev": { + "phpunit/phpunit": "^11.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "6.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", + "security": "https://github.com/sebastianbergmann/exporter/security/policy", + "source": "https://github.com/sebastianbergmann/exporter/tree/6.0.0" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2024-02-02T05:58:52+00:00" + }, + { + "name": "sebastian/global-state", + "version": "7.0.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/global-state.git", + "reference": "590e7cbc6565fa2e26c3df4e629a34bb0bc00c17" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/590e7cbc6565fa2e26c3df4e629a34bb0bc00c17", + "reference": "590e7cbc6565fa2e26c3df4e629a34bb0bc00c17", + "shasum": "" + }, + "require": { + "php": ">=8.2", + "sebastian/object-reflector": "^4.0", + "sebastian/recursion-context": "^6.0" + }, + "require-dev": { + "ext-dom": "*", + "phpunit/phpunit": "^11.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "7.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": "https://www.github.com/sebastianbergmann/global-state", + "keywords": [ + "global state" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/global-state/issues", + "security": "https://github.com/sebastianbergmann/global-state/security/policy", + "source": "https://github.com/sebastianbergmann/global-state/tree/7.0.0" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2024-02-02T05:59:33+00:00" + }, + { + "name": "sebastian/lines-of-code", + "version": "3.0.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/lines-of-code.git", + "reference": "376c5b3f6b43c78fdc049740bca76a7c846706c0" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/lines-of-code/zipball/376c5b3f6b43c78fdc049740bca76a7c846706c0", + "reference": "376c5b3f6b43c78fdc049740bca76a7c846706c0", + "shasum": "" + }, + "require": { + "nikic/php-parser": "^5.0", + "php": ">=8.2" + }, + "require-dev": { + "phpunit/phpunit": "^11.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "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 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", + "security": "https://github.com/sebastianbergmann/lines-of-code/security/policy", + "source": "https://github.com/sebastianbergmann/lines-of-code/tree/3.0.0" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2024-02-02T06:00:36+00:00" + }, + { + "name": "sebastian/object-enumerator", + "version": "6.0.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/object-enumerator.git", + "reference": "f75f6c460da0bbd9668f43a3dde0ec0ba7faa678" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/object-enumerator/zipball/f75f6c460da0bbd9668f43a3dde0ec0ba7faa678", + "reference": "f75f6c460da0bbd9668f43a3dde0ec0ba7faa678", + "shasum": "" + }, + "require": { + "php": ">=8.2", + "sebastian/object-reflector": "^4.0", + "sebastian/recursion-context": "^6.0" + }, + "require-dev": { + "phpunit/phpunit": "^11.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "6.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", + "security": "https://github.com/sebastianbergmann/object-enumerator/security/policy", + "source": "https://github.com/sebastianbergmann/object-enumerator/tree/6.0.0" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2024-02-02T06:01:29+00:00" + }, + { + "name": "sebastian/object-reflector", + "version": "4.0.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/object-reflector.git", + "reference": "bb2a6255d30853425fd38f032eb64ced9f7f132d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/object-reflector/zipball/bb2a6255d30853425fd38f032eb64ced9f7f132d", + "reference": "bb2a6255d30853425fd38f032eb64ced9f7f132d", + "shasum": "" + }, + "require": { + "php": ">=8.2" + }, + "require-dev": { + "phpunit/phpunit": "^11.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "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": "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", + "security": "https://github.com/sebastianbergmann/object-reflector/security/policy", + "source": "https://github.com/sebastianbergmann/object-reflector/tree/4.0.0" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2024-02-02T06:02:18+00:00" + }, + { + "name": "sebastian/recursion-context", + "version": "6.0.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/recursion-context.git", + "reference": "b75224967b5a466925c6d54e68edd0edf8dd4ed4" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/b75224967b5a466925c6d54e68edd0edf8dd4ed4", + "reference": "b75224967b5a466925c6d54e68edd0edf8dd4ed4", + "shasum": "" + }, + "require": { + "php": ">=8.2" + }, + "require-dev": { + "phpunit/phpunit": "^11.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "6.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": "https://github.com/sebastianbergmann/recursion-context", + "support": { + "issues": "https://github.com/sebastianbergmann/recursion-context/issues", + "security": "https://github.com/sebastianbergmann/recursion-context/security/policy", + "source": "https://github.com/sebastianbergmann/recursion-context/tree/6.0.0" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2024-02-02T06:08:48+00:00" + }, + { + "name": "sebastian/type", + "version": "5.0.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/type.git", + "reference": "b8502785eb3523ca0dd4afe9ca62235590020f3f" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/type/zipball/b8502785eb3523ca0dd4afe9ca62235590020f3f", + "reference": "b8502785eb3523ca0dd4afe9ca62235590020f3f", + "shasum": "" + }, + "require": { + "php": ">=8.2" + }, + "require-dev": { + "phpunit/phpunit": "^11.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "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": "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", + "security": "https://github.com/sebastianbergmann/type/security/policy", + "source": "https://github.com/sebastianbergmann/type/tree/5.0.0" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2024-02-02T06:09:34+00:00" + }, + { + "name": "sebastian/version", + "version": "5.0.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/version.git", + "reference": "13999475d2cb1ab33cb73403ba356a814fdbb001" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/13999475d2cb1ab33cb73403ba356a814fdbb001", + "reference": "13999475d2cb1ab33cb73403ba356a814fdbb001", + "shasum": "" + }, + "require": { + "php": ">=8.2" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "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": "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", + "security": "https://github.com/sebastianbergmann/version/security/policy", + "source": "https://github.com/sebastianbergmann/version/tree/5.0.0" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2024-02-02T06:10:47+00:00" + }, + { + "name": "spatie/backtrace", + "version": "1.5.3", + "source": { + "type": "git", + "url": "https://github.com/spatie/backtrace.git", + "reference": "483f76a82964a0431aa836b6ed0edde0c248e3ab" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/spatie/backtrace/zipball/483f76a82964a0431aa836b6ed0edde0c248e3ab", + "reference": "483f76a82964a0431aa836b6ed0edde0c248e3ab", + "shasum": "" + }, + "require": { + "php": "^7.3|^8.0" + }, + "require-dev": { + "ext-json": "*", + "phpunit/phpunit": "^9.3", + "spatie/phpunit-snapshot-assertions": "^4.2", + "symfony/var-dumper": "^5.1" + }, + "type": "library", + "autoload": { + "psr-4": { + "Spatie\\Backtrace\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Freek Van de Herten", + "email": "freek@spatie.be", + "homepage": "https://spatie.be", + "role": "Developer" + } + ], + "description": "A better backtrace", + "homepage": "https://github.com/spatie/backtrace", + "keywords": [ + "Backtrace", + "spatie" + ], + "support": { + "source": "https://github.com/spatie/backtrace/tree/1.5.3" + }, + "funding": [ + { + "url": "https://github.com/sponsors/spatie", + "type": "github" + }, + { + "url": "https://spatie.be/open-source/support-us", + "type": "other" + } + ], + "time": "2023-06-28T12:59:17+00:00" + }, + { + "name": "spatie/macroable", + "version": "2.0.0", + "source": { + "type": "git", + "url": "https://github.com/spatie/macroable.git", + "reference": "ec2c320f932e730607aff8052c44183cf3ecb072" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/spatie/macroable/zipball/ec2c320f932e730607aff8052c44183cf3ecb072", + "reference": "ec2c320f932e730607aff8052c44183cf3ecb072", + "shasum": "" + }, + "require": { + "php": "^8.0" + }, + "require-dev": { + "phpunit/phpunit": "^8.0|^9.3" + }, + "type": "library", + "autoload": { + "psr-4": { + "Spatie\\Macroable\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Freek Van der Herten", + "email": "freek@spatie.be", + "homepage": "https://spatie.be", + "role": "Developer" + } + ], + "description": "A trait to dynamically add methods to a class", + "homepage": "https://github.com/spatie/macroable", + "keywords": [ + "macroable", + "spatie" + ], + "support": { + "issues": "https://github.com/spatie/macroable/issues", + "source": "https://github.com/spatie/macroable/tree/2.0.0" + }, + "time": "2021-03-26T22:39:02+00:00" + }, + { + "name": "spatie/ray", + "version": "1.41.1", + "source": { + "type": "git", + "url": "https://github.com/spatie/ray.git", + "reference": "051a0facb1d2462fafef87ff77eb74d6f2d12944" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/spatie/ray/zipball/051a0facb1d2462fafef87ff77eb74d6f2d12944", + "reference": "051a0facb1d2462fafef87ff77eb74d6f2d12944", + "shasum": "" + }, + "require": { + "ext-curl": "*", + "ext-json": "*", + "php": "^7.3|^8.0", + "ramsey/uuid": "^3.0|^4.1", + "spatie/backtrace": "^1.1", + "spatie/macroable": "^1.0|^2.0", + "symfony/stopwatch": "^4.0|^5.1|^6.0|^7.0", + "symfony/var-dumper": "^4.2|^5.1|^6.0|^7.0" + }, + "require-dev": { + "illuminate/support": "6.x|^8.18|^9.0", + "nesbot/carbon": "^2.63", + "pestphp/pest": "^1.22", + "phpstan/phpstan": "^1.10", + "phpunit/phpunit": "^9.5", + "rector/rector": "^0.19.2", + "spatie/phpunit-snapshot-assertions": "^4.2", + "spatie/test-time": "^1.2" + }, + "bin": [ + "bin/remove-ray.sh" + ], + "type": "library", + "autoload": { + "files": [ + "src/helpers.php" + ], + "psr-4": { + "Spatie\\Ray\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Freek Van der Herten", + "email": "freek@spatie.be", + "homepage": "https://spatie.be", + "role": "Developer" + } + ], + "description": "Debug with Ray to fix problems faster", + "homepage": "https://github.com/spatie/ray", + "keywords": [ + "ray", + "spatie" + ], + "support": { + "issues": "https://github.com/spatie/ray/issues", + "source": "https://github.com/spatie/ray/tree/1.41.1" + }, + "funding": [ + { + "url": "https://github.com/sponsors/spatie", + "type": "github" + }, + { + "url": "https://spatie.be/open-source/support-us", + "type": "other" + } + ], + "time": "2024-01-25T10:15:50+00:00" + }, + { + "name": "symfony/deprecation-contracts", + "version": "v3.4.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/deprecation-contracts.git", + "reference": "7c3aff79d10325257a001fcf92d991f24fc967cf" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/7c3aff79d10325257a001fcf92d991f24fc967cf", + "reference": "7c3aff79d10325257a001fcf92d991f24fc967cf", + "shasum": "" + }, + "require": { + "php": ">=8.1" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "3.4-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.4.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": "2023-05-23T14:45:45+00:00" + }, + { + "name": "symfony/polyfill-mbstring", + "version": "v1.29.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-mbstring.git", + "reference": "9773676c8a1bb1f8d4340a62efe641cf76eda7ec" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/9773676c8a1bb1f8d4340a62efe641cf76eda7ec", + "reference": "9773676c8a1bb1f8d4340a62efe641cf76eda7ec", + "shasum": "" + }, + "require": { + "php": ">=7.1" + }, + "provide": { + "ext-mbstring": "*" + }, + "suggest": { + "ext-mbstring": "For best performance" + }, + "type": "library", + "extra": { + "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.29.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": "2024-01-29T20:11:03+00:00" + }, + { + "name": "symfony/service-contracts", + "version": "v3.4.1", + "source": { + "type": "git", + "url": "https://github.com/symfony/service-contracts.git", + "reference": "fe07cbc8d837f60caf7018068e350cc5163681a0" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/service-contracts/zipball/fe07cbc8d837f60caf7018068e350cc5163681a0", + "reference": "fe07cbc8d837f60caf7018068e350cc5163681a0", + "shasum": "" + }, + "require": { + "php": ">=8.1", + "psr/container": "^1.1|^2.0" + }, + "conflict": { + "ext-psr": "<1.1|>=2" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "3.4-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.4.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": "2023-12-26T14:02:43+00:00" + }, + { + "name": "symfony/stopwatch", + "version": "v7.0.3", + "source": { + "type": "git", + "url": "https://github.com/symfony/stopwatch.git", + "reference": "983900d6fddf2b0cbaacacbbad07610854bd8112" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/stopwatch/zipball/983900d6fddf2b0cbaacacbbad07610854bd8112", + "reference": "983900d6fddf2b0cbaacacbbad07610854bd8112", + "shasum": "" + }, + "require": { + "php": ">=8.2", + "symfony/service-contracts": "^2.5|^3" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\Stopwatch\\": "" + }, + "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": "Provides a way to profile code", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/stopwatch/tree/v7.0.3" + }, + "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": "2024-01-23T15:02:46+00:00" + }, + { + "name": "symfony/var-dumper", + "version": "v7.0.3", + "source": { + "type": "git", + "url": "https://github.com/symfony/var-dumper.git", + "reference": "a7a061abbf6fe3d4a79032cbc5149a4d65a10234" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/var-dumper/zipball/a7a061abbf6fe3d4a79032cbc5149a4d65a10234", + "reference": "a7a061abbf6fe3d4a79032cbc5149a4d65a10234", + "shasum": "" + }, + "require": { + "php": ">=8.2", + "symfony/polyfill-mbstring": "~1.0" + }, + "conflict": { + "symfony/console": "<6.4" + }, + "require-dev": { + "ext-iconv": "*", + "symfony/console": "^6.4|^7.0", + "symfony/http-kernel": "^6.4|^7.0", + "symfony/process": "^6.4|^7.0", + "symfony/uid": "^6.4|^7.0", + "twig/twig": "^3.0.4" + }, + "bin": [ + "Resources/bin/var-dump-server" + ], + "type": "library", + "autoload": { + "files": [ + "Resources/functions/dump.php" + ], + "psr-4": { + "Symfony\\Component\\VarDumper\\": "" + }, + "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 mechanisms for walking through any arbitrary PHP variable", + "homepage": "https://symfony.com", + "keywords": [ + "debug", + "dump" + ], + "support": { + "source": "https://github.com/symfony/var-dumper/tree/v7.0.3" + }, + "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": "2024-01-23T15:02:46+00:00" + }, + { + "name": "theseer/tokenizer", + "version": "1.2.2", + "source": { + "type": "git", + "url": "https://github.com/theseer/tokenizer.git", + "reference": "b2ad5003ca10d4ee50a12da31de12a5774ba6b96" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/theseer/tokenizer/zipball/b2ad5003ca10d4ee50a12da31de12a5774ba6b96", + "reference": "b2ad5003ca10d4ee50a12da31de12a5774ba6b96", + "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.2" + }, + "funding": [ + { + "url": "https://github.com/theseer", + "type": "github" + } + ], + "time": "2023-11-20T00:12:19+00:00" + } + ], + "aliases": [], + "minimum-stability": "stable", + "stability-flags": [], + "prefer-stable": false, + "prefer-lowest": false, + "platform": { + "php": ">=8.3" + }, + "platform-dev": [], + "plugin-api-version": "2.6.0" +} diff --git a/docker-compose.yaml b/docker-compose.yaml new file mode 100644 index 0000000..b8420ff --- /dev/null +++ b/docker-compose.yaml @@ -0,0 +1,5 @@ +services: + pdf2txt: + image: codeinchq/pdf2txt:latest + ports: + - "3000:3000" diff --git a/src/ConvertOptions.php b/src/ConvertOptions.php new file mode 100644 index 0000000..666138c --- /dev/null +++ b/src/ConvertOptions.php @@ -0,0 +1,29 @@ + + * + * Use of this source code is governed by an MIT-style + * license that can be found in the LICENSE file or at + * https://opensource.org/licenses/MIT. + */ + +declare(strict_types=1); + +namespace CodeInc\Pdf2TextClient; + +/** + * pdf2text convert options. + * + * @see https://github.com/codeinchq/pdf2text?tab=readme-ov-file#usage + */ +final readonly class ConvertOptions +{ + public function __construct( + public int $firstPage = 1, + public int|null $lastPage = null, + public string|null $password = null, + public bool $normalizeWhitespace = true, + public Format $format = Format::text, + ) { + } +} \ No newline at end of file diff --git a/src/Exception.php b/src/Exception.php new file mode 100644 index 0000000..7ac09e1 --- /dev/null +++ b/src/Exception.php @@ -0,0 +1,21 @@ + + * + * Use of this source code is governed by an MIT-style + * license that can be found in the LICENSE file or at + * https://opensource.org/licenses/MIT. + */ + +declare(strict_types=1); + +namespace CodeInc\Pdf2TextClient; + +use Exception as BaseException; + +class Exception extends BaseException +{ + public const int ERROR_LOCAL_FILE = 100; + public const int ERROR_REQUEST = 200; + public const int ERROR_RESPONSE = 300; +} \ No newline at end of file diff --git a/src/Format.php b/src/Format.php new file mode 100644 index 0000000..d1ea474 --- /dev/null +++ b/src/Format.php @@ -0,0 +1,11 @@ + + * + * Use of this source code is governed by an MIT-style + * license that can be found in the LICENSE file or at + * https://opensource.org/licenses/MIT. + */ + +declare(strict_types=1); + +namespace CodeInc\Pdf2TextClient; + +use Http\Discovery\Psr17FactoryDiscovery; +use Http\Discovery\Psr18ClientDiscovery; +use Http\Message\MultipartStream\MultipartStreamBuilder; +use JsonException; +use Psr\Http\Client\ClientExceptionInterface; +use Psr\Http\Client\ClientInterface; +use Psr\Http\Message\RequestFactoryInterface; +use Psr\Http\Message\StreamFactoryInterface; +use Psr\Http\Message\StreamInterface; + +class Pdf2TextClient +{ + public function __construct( + private readonly string $baseUrl, + private ClientInterface|null $client = null, + private StreamFactoryInterface|null $streamFactory = null, + private RequestFactoryInterface|null $requestFactory = null, + ) { + $this->client ??= Psr18ClientDiscovery::find(); + $this->streamFactory ??= Psr17FactoryDiscovery::findStreamFactory(); + $this->requestFactory ??= Psr17FactoryDiscovery::findRequestFactory(); + } + + /** + * Converts a PDF to text using streams and the PDF2TEXT API. + * + * @param StreamInterface|resource|string $stream The PDF content. + * @param ConvertOptions $options The convert options. + * @return StreamInterface + * @throws Exception + */ + public function convert(mixed $stream, ConvertOptions $options = new ConvertOptions()): StreamInterface + { + try { + // building the multipart stream + $multipartStreamBuilder = (new MultipartStreamBuilder($this->streamFactory)) + ->addResource( + 'file', + $stream, + [ + 'filename' => 'file.pdf', + 'headers' => ['Content-Type' => 'application/pdf'] + ] + ) + ->addResource('firstPage', (string)$options->firstPage) + ->addResource('normalizeWhitespace', (string)$options->normalizeWhitespace) + ->addResource('raw', $options->format === Format::text ? 'true' : 'false'); + + if ($options->lastPage !== null) { + $multipartStreamBuilder->addResource('lastPage', (string)$options->lastPage); + } + if ($options->password !== null) { + $multipartStreamBuilder->addResource('password', (string)$options->password); + } + + // sending the request + $response = $this->client->sendRequest( + $this->requestFactory + ->createRequest("POST", $this->getConvertEndpointUri()) + ->withHeader( + "Content-Type", + "multipart/form-data; boundary={$multipartStreamBuilder->getBoundary()}" + ) + ->withBody($multipartStreamBuilder->build()) + ); + } catch (ClientExceptionInterface $e) { + throw new Exception( + message: "An error occurred while sending the request to the PDF2TEXT API", + code: Exception::ERROR_REQUEST, + previous: $e + ); + } + + // checking the response + if ($response->getStatusCode() !== 200) { + throw new Exception( + message: "The PDF2TEXT API returned an error {$response->getStatusCode()}", + code: Exception::ERROR_RESPONSE, + previous: new Exception((string)$response->getBody()) + ); + } + + // returning the response + return $response->getBody(); + } + + /** + * Processes a JSON response from the PDF2TEXT API. + * + * @param StreamInterface $response + * @return array + * @throws JsonException + */ + public function processJsonResponse(StreamInterface $response): array + { + return json_decode( + json: (string)$response, + associative: true, + flags: JSON_THROW_ON_ERROR + ); + } + + /** + * Converts a local PDF file to text using the PDF2TEXT API. + * + * @param string $pdfPath + * @param ConvertOptions $options + * @return StreamInterface + * @throws Exception|JsonException + */ + public function convertLocalFile(string $pdfPath, ConvertOptions $options = new ConvertOptions()): StreamInterface + { + $f = fopen($pdfPath, 'r'); + if ($f === false) { + throw new Exception( + message: "The file '$pdfPath' could not be opened", + code: Exception::ERROR_LOCAL_FILE + ); + } + + return $this->convert($f, $options); + } + + /** + * Returns the convert endpoint URI. + * + * @return string + */ + private function getConvertEndpointUri(): string + { + $url = $this->baseUrl; + if (!str_ends_with($url, '/')) { + $url .= '/'; + } + return "{$url}convert"; + } +} diff --git a/tests/Pdf2TextClientTest.php b/tests/Pdf2TextClientTest.php new file mode 100644 index 0000000..025f78b --- /dev/null +++ b/tests/Pdf2TextClientTest.php @@ -0,0 +1,96 @@ + + * + * Use of this source code is governed by an MIT-style + * license that can be found in the LICENSE file or at + * https://opensource.org/licenses/MIT. + */ + +declare(strict_types=1); + +namespace CodeInc\Pdf2TextClient\Tests; + +use CodeInc\Pdf2TextClient\ConvertOptions; +use CodeInc\Pdf2TextClient\Exception; +use CodeInc\Pdf2TextClient\Format; +use CodeInc\Pdf2TextClient\Pdf2TextClient; +use JsonException; +use PHPUnit\Framework\TestCase; +use Psr\Http\Message\StreamInterface; + +final class Pdf2TextClientTest extends TestCase +{ + private const string DEFAULT_PDF2TEXT_BASE_URL = 'http://localhost:3000'; + private const string TEST_PDF_PATH = __DIR__.'/assets/file.pdf'; + private const string TEST_PDF_RESULT_TXT = __DIR__.'/assets/file.txt'; + private const string TEST_PDF_RESULT_JSON = __DIR__.'/assets/file.json'; + + /** + * @throws Exception|JsonException + */ +// public function testConvertLocalFileToText(): void +// { +// $stream = $this->getClient()->convertLocalFile(self::TEST_PDF_PATH); +// $this->assertInstanceOf(StreamInterface::class, $stream, "The stream is not valid"); +// +// $text = (string)$stream; +// $this->assertNotEmpty($text, "The stream is empty"); +// $this->assertStringEqualsFile(self::TEST_PDF_RESULT_TXT, $text, "The text is not valid"); +// } + + /** + * @throws Exception|JsonException + */ + public function testConvertLocalFileToJson(): void + { + $client = $this->getNewClient(); + $stream = $client->convertLocalFile(self::TEST_PDF_PATH, new ConvertOptions(format: Format::json)); + $this->assertInstanceOf(StreamInterface::class, $stream, "The stream is not valid"); + + $json = $client->processJsonResponse($stream); + $this->assertIsArray($json, "The processed JSON is not valid"); + + + $expectedJson = json_decode(file_get_contents(self::TEST_PDF_RESULT_JSON), true); + ray($json); + ray($expectedJson); + + $this->assertArrayIsEqualToArrayOnlyConsideringListOfKeys( + $json, + $expectedJson, + ["meta", "pages"] + ); + } + +// /** +// * @throws Exception|JsonException +// */ +// public function testConvertLocalFileProcessedJson(): void +// { +// $client = $this->getClient(); +// $stream = $client->convertLocalFile( +// pdfPath: self::TEST_PDF_PATH, +// options: new ConvertOptions(format: Format::json) +// ); +// +// $this->assertInstanceOf(StreamInterface::class, $stream, "The stream is not valid"); +// $json = $client->processJsonResponse($stream); +// $this->assertIsArray($json, "The processed JSON is not valid"); +// $this->assertNotEmpty($json, "The processed JSON is empty"); +// $this->assertEquals( +// serialize($stream), +// serialize(json_decode(file_get_contents(self::TEST_PDF_RESULT_JSON), true)), +// "The processed JSON is not valid" +// ); +// } + + private function getNewClient(): Pdf2TextClient + { + $apiBaseUrl = self::DEFAULT_PDF2TEXT_BASE_URL; + if (defined('PDF2TEXT_BASE_URL')) { + $apiBaseUrl = constant('PDF2TEXT_BASE_URL'); + } + return new Pdf2TextClient($apiBaseUrl); + } +} \ No newline at end of file diff --git a/tests/assets/file.json b/tests/assets/file.json new file mode 100644 index 0000000..8bcd695 --- /dev/null +++ b/tests/assets/file.json @@ -0,0 +1 @@ +{"meta":{"info":{"PDFFormatVersion":"1.4","Language":null,"EncryptFilterName":null,"IsLinearized":false,"IsAcroFormPresent":false,"IsXFAPresent":false,"IsCollectionPresent":false,"IsSignaturesPresent":false,"Title":"Document de test","Producer":"Skia/PDF m123 Google Docs Renderer"},"metadata":null},"pages":[{"pageInfo":{"num":1,"scale":1,"rotation":0,"offsetX":0,"offsetY":0,"width":596,"height":842},"links":[],"content":[{"x":42.519684,"y":102.2099988,"str":"Document de test","dir":"ltr","width":203.71340028283205,"height":26.000001,"fontName":"g_d0_f1"},{"x":42.519684,"y":126.80999997749996,"str":"","dir":"ltr","width":0,"height":11.00000025,"fontName":"g_d0_f1"},{"x":42.519684,"y":126.80999997749996,"str":"Lorem ipsum dolor sit amet, consectetur adipiscing elit. Ut tristique purus ut tortor fringilla faucibus. Ut in","dir":"ltr","width":505.25314535403817,"height":11.00000025,"fontName":"g_d0_f1"},{"x":42.519684,"y":141.80999997749996,"str":"","dir":"ltr","width":0,"height":11.00000025,"fontName":"g_d0_f1"},{"x":42.519684,"y":141.80999997749996,"str":"ullamcorper orci. Cras lectus tellus, auctor vitae condimentum sed, eleifend eget velit. Vestibulum vel nisi","dir":"ltr","width":508.9320943005421,"height":11.00000025,"fontName":"g_d0_f1"},{"x":42.519684,"y":156.80999997749996,"str":"","dir":"ltr","width":0,"height":11.00000025,"fontName":"g_d0_f1"},{"x":42.519684,"y":156.80999997749996,"str":"ut odio lacinia iaculis. Mauris eleifend ante sapien, tempus dignissim quam lacinia ut. Vivamus faucibus","dir":"ltr","width":501.4310885249997,"height":11.00000025,"fontName":"g_d0_f1"},{"x":42.519684,"y":171.80999997749996,"str":"","dir":"ltr","width":0,"height":11.00000025,"fontName":"g_d0_f1"},{"x":42.519684,"y":171.80999997749996,"str":"quam nulla, et efficitur lacus bibendum et. Maecenas ullamcorper non neque ut auctor. Sed in viverra","dir":"ltr","width":490.4550074040382,"height":11.00000025,"fontName":"g_d0_f1"},{"x":42.519684,"y":186.80999997749996,"str":"","dir":"ltr","width":0,"height":11.00000025,"fontName":"g_d0_f1"},{"x":42.519684,"y":186.80999997749996,"str":"velit. Etiam consequat egestas dictum. Nam elementum dapibus nibh, id varius lorem accumsan eget.","dir":"ltr","width":494.8921117244579,"height":11.00000025,"fontName":"g_d0_f1"},{"x":42.519684,"y":201.80999997749996,"str":"","dir":"ltr","width":0,"height":11.00000025,"fontName":"g_d0_f1"},{"x":42.519684,"y":201.80999997749996,"str":"Curabitur placerat lectus non bibendum interdum.","dir":"ltr","width":240.74073949945807,"height":11.00000025,"fontName":"g_d0_f1"},{"x":42.519684,"y":231.80999997749996,"str":"","dir":"ltr","width":0,"height":11.00000025,"fontName":"g_d0_f1"},{"x":42.519684,"y":231.80999997749996,"str":"Donec velit nibh, sagittis ac ornare faucibus, placerat quis est. Duis in orci egestas, accumsan quam","dir":"ltr","width":486.9582761682517,"height":11.00000025,"fontName":"g_d0_f1"},{"x":42.519684,"y":246.80999997749996,"str":"","dir":"ltr","width":0,"height":11.00000025,"fontName":"g_d0_f1"},{"x":42.519684,"y":246.80999997749996,"str":"vitae, tincidunt risus. Donec sit amet convallis nibh. Curabitur accumsan ultrices laoreet. Nunc arcu","dir":"ltr","width":480.20942232903747,"height":11.00000025,"fontName":"g_d0_f1"},{"x":42.519684,"y":261.80999997749996,"str":"","dir":"ltr","width":0,"height":11.00000025,"fontName":"g_d0_f1"},{"x":42.519684,"y":261.80999997749996,"str":"tellus, finibus eu blandit vel, bibendum eget risus. Duis hendrerit, mauris a lobortis laoreet, risus massa","dir":"ltr","width":499.1666548290377,"height":11.00000025,"fontName":"g_d0_f1"},{"x":42.519684,"y":276.80999997749996,"str":"","dir":"ltr","width":0,"height":11.00000025,"fontName":"g_d0_f1"},{"x":42.519684,"y":276.80999997749996,"str":"maximus mi, id euismod lorem nibh ut lacus. Aenean sit amet ornare justo. Nam ultrices semper neque","dir":"ltr","width":500.368914279038,"height":11.00000025,"fontName":"g_d0_f1"},{"x":42.519684,"y":291.80999997749996,"str":"","dir":"ltr","width":0,"height":11.00000025,"fontName":"g_d0_f1"},{"x":42.519684,"y":291.80999997749996,"str":"at sodales. Sed rhoncus, metus convallis fermentum gravida, justo tellus sodales magna, nec auctor","dir":"ltr","width":486.9650990682517,"height":11.00000025,"fontName":"g_d0_f1"},{"x":42.519684,"y":306.80999997749996,"str":"","dir":"ltr","width":0,"height":11.00000025,"fontName":"g_d0_f1"},{"x":42.519684,"y":306.80999997749996,"str":"justo risus vitae diam. Integer nunc elit, sodales eu semper id, tincidunt tincidunt nulla.","dir":"ltr","width":417.9306988994575,"height":11.00000025,"fontName":"g_d0_f1"},{"x":42.519684,"y":336.8099999775,"str":"","dir":"ltr","width":0,"height":11.00000025,"fontName":"g_d0_f1"},{"x":42.519684,"y":336.8099999775,"str":"Fusce in egestas ligula, eu lobortis nibh. In hac habitasse platea dictumst. Aliquam feugiat aliquam","dir":"ltr","width":479.05225346825165,"height":11.00000025,"fontName":"g_d0_f1"},{"x":42.519684,"y":351.8099999775,"str":"","dir":"ltr","width":0,"height":11.00000025,"fontName":"g_d0_f1"},{"x":42.519684,"y":351.8099999775,"str":"neque sed vestibulum. Morbi blandit sem leo, sit amet ullamcorper orci aliquet sed. Ut in euismod quam.","dir":"ltr","width":506.4962055494577,"height":11.00000025,"fontName":"g_d0_f1"},{"x":42.519684,"y":366.8099999775,"str":"","dir":"ltr","width":0,"height":11.00000025,"fontName":"g_d0_f1"},{"x":42.519684,"y":366.8099999775,"str":"Etiam ut malesuada justo. Pellentesque habitant morbi tristique senectus et netus et malesuada fames","dir":"ltr","width":498.59731919999956,"height":11.00000025,"fontName":"g_d0_f1"},{"x":42.519684,"y":381.8099999775,"str":"","dir":"ltr","width":0,"height":11.00000025,"fontName":"g_d0_f1"},{"x":42.519684,"y":381.8099999775,"str":"ac turpis egestas. Phasellus placerat sed diam interdum efficitur. Nullam pulvinar quam eget est","dir":"ltr","width":464.75964949945796,"height":11.00000025,"fontName":"g_d0_f1"},{"x":42.519684,"y":396.8099999775,"str":"","dir":"ltr","width":0,"height":11.00000025,"fontName":"g_d0_f1"},{"x":42.519684,"y":396.8099999775,"str":"condimentum rutrum nec ac arcu. Sed ac enim feugiat, accumsan lacus eget, ornare libero. Sed tristique","dir":"ltr","width":508.34471067903837,"height":11.00000025,"fontName":"g_d0_f1"},{"x":42.519684,"y":411.8099999775,"str":"","dir":"ltr","width":0,"height":11.00000025,"fontName":"g_d0_f1"},{"x":42.519684,"y":411.8099999775,"str":"dui nec purus egestas blandit. Proin luctus sollicitudin leo, nec efficitur mauris sodales ut. Aliquam","dir":"ltr","width":475.16083826825206,"height":11.00000025,"fontName":"g_d0_f1"},{"x":42.519684,"y":426.8099999775,"str":"","dir":"ltr","width":0,"height":11.00000025,"fontName":"g_d0_f1"},{"x":42.519684,"y":426.8099999775,"str":"interdum imperdiet nisl vel iaculis. Aliquam erat volutpat. Mauris tempor mauris vitae elit viverra, vitae","dir":"ltr","width":491.7866542290381,"height":11.00000025,"fontName":"g_d0_f1"},{"x":42.519684,"y":441.8099999775,"str":"","dir":"ltr","width":0,"height":11.00000025,"fontName":"g_d0_f1"},{"x":42.519684,"y":441.8099999775,"str":"pulvinar nulla venenatis. Aenean nisi mi, aliquet et rhoncus sed, suscipit sed dolor.","dir":"ltr","width":400.22900134945814,"height":11.00000025,"fontName":"g_d0_f1"},{"x":42.519684,"y":471.8099999775,"str":"","dir":"ltr","width":0,"height":11.00000025,"fontName":"g_d0_f1"},{"x":42.519684,"y":471.8099999775,"str":"Suspendisse vitae elementum ex. Nam ac ligula tempus, vehicula neque sed, posuere mi. Aenean","dir":"ltr","width":478.4382574290379,"height":11.00000025,"fontName":"g_d0_f1"},{"x":42.519684,"y":486.8099999775,"str":"","dir":"ltr","width":0,"height":11.00000025,"fontName":"g_d0_f1"},{"x":42.519684,"y":486.8099999775,"str":"porttitor ornare orci, at porttitor orci pretium eu. In eu interdum sapien. Etiam in augue in nulla ornare","dir":"ltr","width":488.1852196290379,"height":11.00000025,"fontName":"g_d0_f1"},{"x":42.519684,"y":501.8099999775,"str":"","dir":"ltr","width":0,"height":11.00000025,"fontName":"g_d0_f1"},{"x":42.519684,"y":501.8099999775,"str":"porttitor sed nec dolor. Etiam tempus ultricies libero, ultrices tincidunt purus malesuada ut. Donec","dir":"ltr","width":471.6745733999999,"height":11.00000025,"fontName":"g_d0_f1"},{"x":42.519684,"y":516.8099999775,"str":"","dir":"ltr","width":0,"height":11.00000025,"fontName":"g_d0_f1"},{"x":42.519684,"y":516.8099999775,"str":"hendrerit elementum odio vitae cursus. Maecenas consectetur gravida consectetur. Integer iaculis justo","dir":"ltr","width":501.6351667290378,"height":11.00000025,"fontName":"g_d0_f1"},{"x":42.519684,"y":531.8099999775,"str":"","dir":"ltr","width":0,"height":11.00000025,"fontName":"g_d0_f1"},{"x":42.519684,"y":531.8099999775,"str":"quis purus lobortis, id blandit enim mollis. Integer vel vulputate ligula, a posuere eros. Ut commodo nec","dir":"ltr","width":499.7941943249996,"height":11.00000025,"fontName":"g_d0_f1"},{"x":42.519684,"y":546.8099999775,"str":"","dir":"ltr","width":0,"height":11.00000025,"fontName":"g_d0_f1"},{"x":42.519684,"y":546.8099999775,"str":"neque in malesuada. Praesent vel nulla mattis, faucibus nulla non, laoreet diam.","dir":"ltr","width":389.2372466744579,"height":11.00000025,"fontName":"g_d0_f1"},{"x":42.519684,"y":576.8099999775,"str":"","dir":"ltr","width":0,"height":11.00000025,"fontName":"g_d0_f1"},{"x":42.519684,"y":576.8099999775,"str":"Proin eget ipsum nec lacus vestibulum ullamcorper nec in nunc. Phasellus condimentum sit amet augue","dir":"ltr","width":505.2960992790381,"height":11.00000025,"fontName":"g_d0_f1"},{"x":42.519684,"y":591.8099999775,"str":"","dir":"ltr","width":0,"height":11.00000025,"fontName":"g_d0_f1"},{"x":42.519684,"y":591.8099999775,"str":"eu bibendum. Maecenas consectetur sit amet augue nec tempus. Vestibulum egestas feugiat volutpat.","dir":"ltr","width":497.392865074458,"height":11.00000025,"fontName":"g_d0_f1"},{"x":42.519684,"y":606.8099999775,"str":"","dir":"ltr","width":0,"height":11.00000025,"fontName":"g_d0_f1"},{"x":42.519684,"y":606.8099999775,"str":"Suspendisse vestibulum tristique nunc, non pharetra nunc tempor id. Nullam mollis pellentesque","dir":"ltr","width":468.036423804038,"height":11.00000025,"fontName":"g_d0_f1"},{"x":42.519684,"y":621.8099999775,"str":"","dir":"ltr","width":0,"height":11.00000025,"fontName":"g_d0_f1"},{"x":42.519684,"y":621.8099999775,"str":"pellentesque. Fusce scelerisque bibendum tristique. Vestibulum ante ipsum primis in faucibus orci luctus","dir":"ltr","width":507.1201118250001,"height":11.00000025,"fontName":"g_d0_f1"},{"x":42.519684,"y":636.8099999775,"str":"","dir":"ltr","width":0,"height":11.00000025,"fontName":"g_d0_f1"},{"x":42.519684,"y":636.8099999775,"str":"et ultrices posuere cubilia curae; Aenean gravida non tortor sed aliquet. Praesent pretium mattis sem,","dir":"ltr","width":493.0779850994579,"height":11.00000025,"fontName":"g_d0_f1"},{"x":42.519684,"y":651.8099999775,"str":"","dir":"ltr","width":0,"height":11.00000025,"fontName":"g_d0_f1"},{"x":42.519684,"y":651.8099999775,"str":"vitae ornare lectus hendrerit vel. Sed pharetra semper venenatis. Cras dapibus tempor enim eget","dir":"ltr","width":472.30663744945775,"height":11.00000025,"fontName":"g_d0_f1"},{"x":42.519684,"y":666.8099999775,"str":"","dir":"ltr","width":0,"height":11.00000025,"fontName":"g_d0_f1"},{"x":42.519684,"y":666.8099999775,"str":"condimentum. Nam semper sem vestibulum, hendrerit ipsum sit amet, fermentum tortor. Aenean ac enim","dir":"ltr","width":510.12840229325195,"height":11.00000025,"fontName":"g_d0_f1"},{"x":42.519684,"y":681.8099999775,"str":"","dir":"ltr","width":0,"height":11.00000025,"fontName":"g_d0_f1"},{"x":42.519684,"y":681.8099999775,"str":"ac lacus pharetra tincidunt eget sed massa.","dir":"ltr","width":212.02579219945784,"height":11.00000025,"fontName":"g_d0_f1"},{"x":42.519684,"y":799.6799998275,"str":"","dir":"ltr","width":0,"height":8.00000025,"fontName":"g_d0_f1"},{"x":42.519684,"y":799.6799998275,"str":"Code Inc. / SAS au capital de 10 000 € / RCS LYON 832757306 / SIRET 83275730600010 / TVA FR70832757306","dir":"ltr","width":404.91596273403843,"height":8.00000025,"fontName":"g_d0_f1"},{"x":42.519684,"y":810.9299998275,"str":"","dir":"ltr","width":0,"height":8.00000025,"fontName":"g_d0_f1"},{"x":42.519684,"y":810.9299998275,"str":"18 avenue Félix Faure 69007 Lyon, France / contact@codeinc.co / www.codeinc.co","dir":"ltr","width":295.2579776340383,"height":8.00000025,"fontName":"g_d0_f1"},{"x":507.4369214999999,"y":822.1799998275,"str":"","dir":"ltr","width":0,"height":8.00000025,"fontName":"g_d0_f1"},{"x":507.4369214999999,"y":822.1799998275,"str":"Page 1 sur 1","dir":"ltr","width":45.32334885903785,"height":8.00000025,"fontName":"g_d0_f1"}]}],"filename":"temp/27788aa345b8ff512a59dd5037bdc7d0"} \ No newline at end of file diff --git a/tests/assets/file.pdf b/tests/assets/file.pdf new file mode 100644 index 0000000000000000000000000000000000000000..bd5902ecfe77a676a03517ad5c8c1435c9fa7f18 GIT binary patch literal 65931 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 AZU6uP literal 0 HcmV?d00001 diff --git a/tests/assets/file.txt b/tests/assets/file.txt new file mode 100644 index 0000000..6804518 --- /dev/null +++ b/tests/assets/file.txt @@ -0,0 +1 @@ +Document de testLorem ipsum dolor sit amet, consectetur adipiscing elit. Ut tristique purus ut tortor fringilla faucibus. Ut inullamcorper orci. Cras lectus tellus, auctor vitae condimentum sed, eleifend eget velit. Vestibulum vel nisiut odio lacinia iaculis. Mauris eleifend ante sapien, tempus dignissim quam lacinia ut. Vivamus faucibusquam nulla, et efficitur lacus bibendum et. Maecenas ullamcorper non neque ut auctor. Sed in viverravelit. Etiam consequat egestas dictum. Nam elementum dapibus nibh, id varius lorem accumsan eget.Curabitur placerat lectus non bibendum interdum.Donec velit nibh, sagittis ac ornare faucibus, placerat quis est. Duis in orci egestas, accumsan quamvitae, tincidunt risus. Donec sit amet convallis nibh. Curabitur accumsan ultrices laoreet. Nunc arcutellus, finibus eu blandit vel, bibendum eget risus. Duis hendrerit, mauris a lobortis laoreet, risus massamaximus mi, id euismod lorem nibh ut lacus. Aenean sit amet ornare justo. Nam ultrices semper nequeat sodales. Sed rhoncus, metus convallis fermentum gravida, justo tellus sodales magna, nec auctorjusto risus vitae diam. Integer nunc elit, sodales eu semper id, tincidunt tincidunt nulla.Fusce in egestas ligula, eu lobortis nibh. In hac habitasse platea dictumst. Aliquam feugiat aliquamneque sed vestibulum. Morbi blandit sem leo, sit amet ullamcorper orci aliquet sed. Ut in euismod quam.Etiam ut malesuada justo. Pellentesque habitant morbi tristique senectus et netus et malesuada famesac turpis egestas. Phasellus placerat sed diam interdum efficitur. Nullam pulvinar quam eget estcondimentum rutrum nec ac arcu. Sed ac enim feugiat, accumsan lacus eget, ornare libero. Sed tristiquedui nec purus egestas blandit. Proin luctus sollicitudin leo, nec efficitur mauris sodales ut. Aliquaminterdum imperdiet nisl vel iaculis. Aliquam erat volutpat. Mauris tempor mauris vitae elit viverra, vitaepulvinar nulla venenatis. Aenean nisi mi, aliquet et rhoncus sed, suscipit sed dolor.Suspendisse vitae elementum ex. Nam ac ligula tempus, vehicula neque sed, posuere mi. Aeneanporttitor ornare orci, at porttitor orci pretium eu. In eu interdum sapien. Etiam in augue in nulla ornareporttitor sed nec dolor. Etiam tempus ultricies libero, ultrices tincidunt purus malesuada ut. Donechendrerit elementum odio vitae cursus. Maecenas consectetur gravida consectetur. Integer iaculis justoquis purus lobortis, id blandit enim mollis. Integer vel vulputate ligula, a posuere eros. Ut commodo necneque in malesuada. Praesent vel nulla mattis, faucibus nulla non, laoreet diam.Proin eget ipsum nec lacus vestibulum ullamcorper nec in nunc. Phasellus condimentum sit amet augueeu bibendum. Maecenas consectetur sit amet augue nec tempus. Vestibulum egestas feugiat volutpat.Suspendisse vestibulum tristique nunc, non pharetra nunc tempor id. Nullam mollis pellentesquepellentesque. Fusce scelerisque bibendum tristique. Vestibulum ante ipsum primis in faucibus orci luctuset ultrices posuere cubilia curae; Aenean gravida non tortor sed aliquet. Praesent pretium mattis sem,vitae ornare lectus hendrerit vel. Sed pharetra semper venenatis. Cras dapibus tempor enim egetcondimentum. Nam semper sem vestibulum, hendrerit ipsum sit amet, fermentum tortor. Aenean ac enimac lacus pharetra tincidunt eget sed massa.Code Inc. / SAS au capital de 10 000 € / RCS LYON 832757306 / SIRET 83275730600010 / TVA FR7083275730618 avenue Félix Faure 69007 Lyon, France / contact@codeinc.co / www.codeinc.coPage 1 sur 1 \ No newline at end of file