From 613e1a767c538eb0c95755859f2a785207c82ac6 Mon Sep 17 00:00:00 2001 From: James Date: Tue, 3 Dec 2024 21:27:44 +0100 Subject: [PATCH] Initial commit --- .editorconfig | 18 + .env.example | 66 + .env.testing | 3 + .gitattributes | 11 + .gitignore | 23 + README.md | 103 + app/Actions/PerformWalletTransaction.php | 61 + app/Actions/PerformWalletTransfer.php | 48 + app/Enums/WalletTransactionType.php | 21 + app/Exceptions/ApiException.php | 41 + app/Exceptions/InsufficientBalance.php | 15 + .../Controllers/Api/V1/AccountController.php | 16 + .../Controllers/Api/V1/LoginController.php | 33 + .../Api/V1/SendMoneyController.php | 26 + .../Auth/AuthenticatedSessionController.php | 39 + .../Auth/RegisteredUserController.php | 43 + app/Http/Controllers/DashboardController.php | 18 + app/Http/Controllers/SendMoneyController.php | 35 + app/Http/Middleware/ForceAcceptJson.php | 21 + app/Http/Requests/Api/V1/LoginRequest.php | 24 + app/Http/Requests/Api/V1/SendMoneyRequest.php | 43 + app/Http/Requests/LoginRequest.php | 72 + app/Http/Requests/SendMoneyRequest.php | 48 + app/Http/Resources/AccountResource.php | 25 + app/Models/User.php | 41 + app/Models/Wallet.php | 31 + app/Models/WalletTransaction.php | 43 + app/Models/WalletTransfer.php | 48 + app/Providers/AppServiceProvider.php | 41 + app/View/Components/AppLayout.php | 16 + app/View/Components/GuestLayout.php | 16 + artisan | 15 + bootstrap/app.php | 31 + bootstrap/cache/.gitignore | 2 + bootstrap/providers.php | 7 + composer.json | 74 + composer.lock | 8917 +++++++++++++++++ config/app.php | 128 + config/auth.php | 117 + config/cache.php | 110 + config/database.php | 175 + config/filesystems.php | 79 + config/logging.php | 134 + config/mail.php | 118 + config/queue.php | 114 + config/sanctum.php | 85 + config/services.php | 40 + config/session.php | 219 + database/.gitignore | 1 + database/factories/UserFactory.php | 26 + database/factories/WalletFactory.php | 44 + .../factories/WalletTransactionFactory.php | 59 + database/factories/WalletTransferFactory.php | 28 + .../0001_01_01_000000_create_users_table.php | 42 + .../0001_01_01_000001_create_cache_table.php | 37 + .../0001_01_01_000002_create_jobs_table.php | 59 + ...2024_12_02_153631_create_wallets_table.php | 33 + ...53635_create_wallet_transactions_table.php | 38 + ...2_153635_create_wallet_transfers_table.php | 35 + ...44_create_personal_access_tokens_table.php | 35 + database/seeders/DatabaseSeeder.php | 29 + mcd.png | Bin 0 -> 79764 bytes package-lock.json | 2966 ++++++ package.json | 19 + phpunit.xml | 33 + pint.json | 13 + postcss.config.js | 6 + public/.htaccess | 21 + public/favicon.ico | 0 public/index.php | 19 + public/robots.txt | 2 + resources/css/app.css | 3 + resources/js/app.js | 7 + resources/js/bootstrap.js | 4 + .../views/auth/confirm-password.blade.php | 27 + .../views/auth/forgot-password.blade.php | 25 + resources/views/auth/login.blade.php | 37 + resources/views/auth/register.blade.php | 52 + resources/views/auth/reset-password.blade.php | 39 + resources/views/auth/verify-email.blade.php | 31 + .../components/application-logo.blade.php | 3 + .../components/auth-session-status.blade.php | 7 + .../views/components/danger-button.blade.php | 3 + .../views/components/dropdown-link.blade.php | 1 + resources/views/components/dropdown.blade.php | 35 + .../views/components/input-error.blade.php | 9 + .../views/components/input-label.blade.php | 5 + resources/views/components/modal.blade.php | 78 + resources/views/components/nav-link.blade.php | 11 + .../views/components/primary-button.blade.php | 3 + .../components/responsive-nav-link.blade.php | 11 + .../components/secondary-button.blade.php | 3 + .../views/components/text-input.blade.php | 3 + resources/views/dashboard.blade.php | 133 + resources/views/layouts/app.blade.php | 36 + resources/views/layouts/guest.blade.php | 30 + resources/views/layouts/navigation.blade.php | 92 + routes/api.php | 15 + routes/auth.php | 24 + routes/console.php | 10 + routes/web.php | 14 + screenshot.png | Bin 0 -> 76139 bytes storage/app/.gitignore | 4 + storage/app/private/.gitignore | 2 + storage/app/public/.gitignore | 2 + storage/framework/.gitignore | 9 + storage/framework/cache/.gitignore | 3 + storage/framework/cache/data/.gitignore | 2 + storage/framework/sessions/.gitignore | 2 + storage/framework/testing/.gitignore | 2 + storage/framework/views/.gitignore | 2 + storage/logs/.gitignore | 2 + tailwind.config.js | 21 + .../Actions/PerformWalletTransactionTest.php | 90 + .../Actions/PerformWalletTransferTest.php | 66 + tests/Feature/Api/AccountControllerTest.php | 34 + tests/Feature/Api/LoginControllerTest.php | 34 + tests/Feature/Api/SendMoneyControllerTest.php | 66 + tests/Feature/Auth/AuthenticationTest.php | 49 + tests/Feature/Auth/RegistrationTest.php | 25 + tests/Feature/DashboardTest.php | 69 + tests/Pest.php | 18 + tests/TestCase.php | 12 + tests/Unit/Models/WalletTransactionTest.php | 23 + vite.config.js | 11 + 125 files changed, 16298 insertions(+) create mode 100644 .editorconfig create mode 100644 .env.example create mode 100644 .env.testing create mode 100644 .gitattributes create mode 100644 .gitignore create mode 100644 README.md create mode 100644 app/Actions/PerformWalletTransaction.php create mode 100644 app/Actions/PerformWalletTransfer.php create mode 100644 app/Enums/WalletTransactionType.php create mode 100644 app/Exceptions/ApiException.php create mode 100644 app/Exceptions/InsufficientBalance.php create mode 100644 app/Http/Controllers/Api/V1/AccountController.php create mode 100644 app/Http/Controllers/Api/V1/LoginController.php create mode 100644 app/Http/Controllers/Api/V1/SendMoneyController.php create mode 100644 app/Http/Controllers/Auth/AuthenticatedSessionController.php create mode 100644 app/Http/Controllers/Auth/RegisteredUserController.php create mode 100644 app/Http/Controllers/DashboardController.php create mode 100644 app/Http/Controllers/SendMoneyController.php create mode 100644 app/Http/Middleware/ForceAcceptJson.php create mode 100644 app/Http/Requests/Api/V1/LoginRequest.php create mode 100644 app/Http/Requests/Api/V1/SendMoneyRequest.php create mode 100644 app/Http/Requests/LoginRequest.php create mode 100644 app/Http/Requests/SendMoneyRequest.php create mode 100644 app/Http/Resources/AccountResource.php create mode 100644 app/Models/User.php create mode 100644 app/Models/Wallet.php create mode 100644 app/Models/WalletTransaction.php create mode 100644 app/Models/WalletTransfer.php create mode 100644 app/Providers/AppServiceProvider.php create mode 100644 app/View/Components/AppLayout.php create mode 100644 app/View/Components/GuestLayout.php create mode 100755 artisan create mode 100644 bootstrap/app.php create mode 100644 bootstrap/cache/.gitignore create mode 100644 bootstrap/providers.php create mode 100644 composer.json create mode 100644 composer.lock create mode 100644 config/app.php create mode 100644 config/auth.php create mode 100644 config/cache.php create mode 100644 config/database.php create mode 100644 config/filesystems.php create mode 100644 config/logging.php create mode 100644 config/mail.php create mode 100644 config/queue.php create mode 100644 config/sanctum.php create mode 100644 config/services.php create mode 100644 config/session.php create mode 100644 database/.gitignore create mode 100644 database/factories/UserFactory.php create mode 100644 database/factories/WalletFactory.php create mode 100644 database/factories/WalletTransactionFactory.php create mode 100644 database/factories/WalletTransferFactory.php create mode 100644 database/migrations/0001_01_01_000000_create_users_table.php create mode 100644 database/migrations/0001_01_01_000001_create_cache_table.php create mode 100644 database/migrations/0001_01_01_000002_create_jobs_table.php create mode 100644 database/migrations/2024_12_02_153631_create_wallets_table.php create mode 100644 database/migrations/2024_12_02_153635_create_wallet_transactions_table.php create mode 100644 database/migrations/2024_12_02_153635_create_wallet_transfers_table.php create mode 100644 database/migrations/2024_12_03_184444_create_personal_access_tokens_table.php create mode 100644 database/seeders/DatabaseSeeder.php create mode 100644 mcd.png create mode 100644 package-lock.json create mode 100644 package.json create mode 100644 phpunit.xml create mode 100644 pint.json create mode 100644 postcss.config.js create mode 100644 public/.htaccess create mode 100644 public/favicon.ico create mode 100644 public/index.php create mode 100644 public/robots.txt create mode 100644 resources/css/app.css create mode 100644 resources/js/app.js create mode 100644 resources/js/bootstrap.js create mode 100644 resources/views/auth/confirm-password.blade.php create mode 100644 resources/views/auth/forgot-password.blade.php create mode 100644 resources/views/auth/login.blade.php create mode 100644 resources/views/auth/register.blade.php create mode 100644 resources/views/auth/reset-password.blade.php create mode 100644 resources/views/auth/verify-email.blade.php create mode 100644 resources/views/components/application-logo.blade.php create mode 100644 resources/views/components/auth-session-status.blade.php create mode 100644 resources/views/components/danger-button.blade.php create mode 100644 resources/views/components/dropdown-link.blade.php create mode 100644 resources/views/components/dropdown.blade.php create mode 100644 resources/views/components/input-error.blade.php create mode 100644 resources/views/components/input-label.blade.php create mode 100644 resources/views/components/modal.blade.php create mode 100644 resources/views/components/nav-link.blade.php create mode 100644 resources/views/components/primary-button.blade.php create mode 100644 resources/views/components/responsive-nav-link.blade.php create mode 100644 resources/views/components/secondary-button.blade.php create mode 100644 resources/views/components/text-input.blade.php create mode 100644 resources/views/dashboard.blade.php create mode 100644 resources/views/layouts/app.blade.php create mode 100644 resources/views/layouts/guest.blade.php create mode 100644 resources/views/layouts/navigation.blade.php create mode 100644 routes/api.php create mode 100644 routes/auth.php create mode 100644 routes/console.php create mode 100644 routes/web.php create mode 100644 screenshot.png create mode 100644 storage/app/.gitignore create mode 100644 storage/app/private/.gitignore create mode 100644 storage/app/public/.gitignore create mode 100644 storage/framework/.gitignore create mode 100644 storage/framework/cache/.gitignore create mode 100644 storage/framework/cache/data/.gitignore create mode 100644 storage/framework/sessions/.gitignore create mode 100644 storage/framework/testing/.gitignore create mode 100644 storage/framework/views/.gitignore create mode 100644 storage/logs/.gitignore create mode 100644 tailwind.config.js create mode 100644 tests/Feature/Actions/PerformWalletTransactionTest.php create mode 100644 tests/Feature/Actions/PerformWalletTransferTest.php create mode 100644 tests/Feature/Api/AccountControllerTest.php create mode 100644 tests/Feature/Api/LoginControllerTest.php create mode 100644 tests/Feature/Api/SendMoneyControllerTest.php create mode 100644 tests/Feature/Auth/AuthenticationTest.php create mode 100644 tests/Feature/Auth/RegistrationTest.php create mode 100644 tests/Feature/DashboardTest.php create mode 100644 tests/Pest.php create mode 100644 tests/TestCase.php create mode 100644 tests/Unit/Models/WalletTransactionTest.php create mode 100644 vite.config.js diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..8f0de65 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,18 @@ +root = true + +[*] +charset = utf-8 +end_of_line = lf +indent_size = 4 +indent_style = space +insert_final_newline = true +trim_trailing_whitespace = true + +[*.md] +trim_trailing_whitespace = false + +[*.{yml,yaml}] +indent_size = 2 + +[docker-compose.yml] +indent_size = 4 diff --git a/.env.example b/.env.example new file mode 100644 index 0000000..a1b3de4 --- /dev/null +++ b/.env.example @@ -0,0 +1,66 @@ +APP_NAME=Laravel +APP_ENV=local +APP_KEY= +APP_DEBUG=true +APP_TIMEZONE=UTC +APP_URL=http://localhost + +APP_LOCALE=en +APP_FALLBACK_LOCALE=en +APP_FAKER_LOCALE=en_US + +APP_MAINTENANCE_DRIVER=file +# APP_MAINTENANCE_STORE=database + +PHP_CLI_SERVER_WORKERS=4 + +BCRYPT_ROUNDS=12 + +LOG_CHANNEL=stack +LOG_STACK=single +LOG_DEPRECATIONS_CHANNEL=null +LOG_LEVEL=debug + +DB_CONNECTION=sqlite +# DB_HOST=127.0.0.1 +# DB_PORT=3306 +# DB_DATABASE=laravel +# DB_USERNAME=root +# DB_PASSWORD= + +SESSION_DRIVER=database +SESSION_LIFETIME=120 +SESSION_ENCRYPT=false +SESSION_PATH=/ +SESSION_DOMAIN=null + +BROADCAST_CONNECTION=log +FILESYSTEM_DISK=local +QUEUE_CONNECTION=database + +CACHE_STORE=database +CACHE_PREFIX= + +MEMCACHED_HOST=127.0.0.1 + +REDIS_CLIENT=phpredis +REDIS_HOST=127.0.0.1 +REDIS_PASSWORD=null +REDIS_PORT=6379 + +MAIL_MAILER=log +MAIL_HOST=127.0.0.1 +MAIL_PORT=2525 +MAIL_USERNAME=null +MAIL_PASSWORD=null +MAIL_ENCRYPTION=null +MAIL_FROM_ADDRESS="hello@example.com" +MAIL_FROM_NAME="${APP_NAME}" + +AWS_ACCESS_KEY_ID= +AWS_SECRET_ACCESS_KEY= +AWS_DEFAULT_REGION=us-east-1 +AWS_BUCKET= +AWS_USE_PATH_STYLE_ENDPOINT=false + +VITE_APP_NAME="${APP_NAME}" diff --git a/.env.testing b/.env.testing new file mode 100644 index 0000000..9544371 --- /dev/null +++ b/.env.testing @@ -0,0 +1,3 @@ +APP_KEY=base64:OGtJT+U3xWWE5mge2a0NuK+vOHcfeq1Wyvupm25ZYCM= +DB_CONNECTION=sqlite +DB_DATABASE=":memory:" diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..fcb21d3 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,11 @@ +* text=auto eol=lf + +*.blade.php diff=html +*.css diff=css +*.html diff=html +*.md diff=markdown +*.php diff=php + +/.github export-ignore +CHANGELOG.md export-ignore +.styleci.yml export-ignore diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..bec2973 --- /dev/null +++ b/.gitignore @@ -0,0 +1,23 @@ +/.phpunit.cache +/node_modules +/public/build +/public/hot +/public/storage +/storage/*.key +/storage/pail +/vendor +.env +.env.backup +.env.production +.phpactor.json +.phpunit.result.cache +Homestead.json +Homestead.yaml +auth.json +npm-debug.log +yarn-error.log +/.fleet +/.idea +/.nova +/.vscode +/.zed diff --git a/README.md b/README.md new file mode 100644 index 0000000..b98a2aa --- /dev/null +++ b/README.md @@ -0,0 +1,103 @@ +# Test Technique - Laravel Wallet + +![Screenshot](screenshot.png) + +## Requirements + +- PHP 8.2+ +- Composer + +(i) No need database, just use sqlite. + +## Installation + +```bash +composer install +``` +c +```bash +composer install +``` + +## Running tests + +```bash +vendor/bin/pest +``` + +## Running formatter + +```bash +vendor/bin/pint +``` + +## Default Users + +Rich chill guy (1M€ balance): +- Email: rich.chill.guy@test.fr +- Password: password + +Another guy (0€ balance): +- Email: another.guy@test.fr +- Password: password + +## Database schema + +![Database schema](mcd.png) + +Amounts are saved in cents. + +Some Laravel tables are included : +- sessions +- cache +- cache_locks +- jobs +- job_batches +- failed_jobs + +## Tickets + +### Bugfix - Error on login + +On first login after registering, this error is thrown: +``` +Call to a member function transactions() on null +``` + +You need to write a test to ensure that this error does not occur again. + +### Feature - Notification when balance is low + +When a user balance is low (< 10€), he should be notified by email. + +You must write a test for this feature. + +### Feature - Recurring transfers + +As a user, I want to be able to create recurring transfers. + +I want to define : +- A start date +- An end date +- A frequency in days +- An amount +- A reason + +Of course, I want to be able to delete a recurring transfer. + +The transfer must be executed every X days (according to the periodicity defined by the user) at 2:00 a.m. +The transfer must also be executed immediately after its creation. + +If the user has a balance lower than the amount, the transfer should fail and the user should be notified by email. + +This feature must be available in the API and the front-end. + +You must write tests for this features. + +Don't forget to write seeders & factories. + +## BONUS - Feature - Sync wallet balance + +You need to write an action that reconstitutes the balance of a portfolio from its transaction history. + +You must write tests for this action. diff --git a/app/Actions/PerformWalletTransaction.php b/app/Actions/PerformWalletTransaction.php new file mode 100644 index 0000000..a834e6f --- /dev/null +++ b/app/Actions/PerformWalletTransaction.php @@ -0,0 +1,61 @@ +ensureWalletHasEnoughFunds($wallet, $amount); + } + + return DB::transaction(function () use ($wallet, $type, $amount, $reason, $transfer) { + $transaction = $wallet->transactions()->create([ + 'amount' => $amount, + 'type' => $type, + 'reason' => $reason, + 'transfer_id' => $transfer?->id, + ]); + + $this->updateWallet($wallet, $type, $amount); + + return $transaction; + }); + } + + /** + * @throws Throwable + */ + protected function updateWallet(Wallet $wallet, WalletTransactionType $type, int $amount): void + { + if ($type === WalletTransactionType::CREDIT) { + $wallet->increment('balance', $amount); + } else { + $wallet->decrement('balance', $amount); + } + } + + /** + * @throws InsufficientBalance + */ + protected function ensureWalletHasEnoughFunds(Wallet $wallet, int $amount): void + { + if ($wallet->balance < $amount) { + throw new InsufficientBalance($wallet, $amount); + } + } +} diff --git a/app/Actions/PerformWalletTransfer.php b/app/Actions/PerformWalletTransfer.php new file mode 100644 index 0000000..17415fd --- /dev/null +++ b/app/Actions/PerformWalletTransfer.php @@ -0,0 +1,48 @@ + $amount, + 'source_id' => $sender->wallet->id, + 'target_id' => $recipient->wallet->id, + ]); + + $this->performWalletTransaction->execute( + wallet: $sender->wallet, + type: WalletTransactionType::DEBIT, + amount: $amount, + reason: $reason, + transfer: $transfer + ); + + $this->performWalletTransaction->execute( + wallet: $recipient->wallet, + type: WalletTransactionType::CREDIT, + amount: $amount, + reason: $reason, + transfer: $transfer + ); + + return $transfer; + }); + } +} diff --git a/app/Enums/WalletTransactionType.php b/app/Enums/WalletTransactionType.php new file mode 100644 index 0000000..6bfd742 --- /dev/null +++ b/app/Enums/WalletTransactionType.php @@ -0,0 +1,21 @@ +silenced = $silenced; + $this->customCode = $code; + $this->status = $status ?? 400; + } + + public function toResponse($request): JsonResponse + { + return response()->json([ + 'code' => $this->customCode, + 'message' => $this->message, + ], $this->status); + } +} diff --git a/app/Exceptions/InsufficientBalance.php b/app/Exceptions/InsufficientBalance.php new file mode 100644 index 0000000..9eaf7d0 --- /dev/null +++ b/app/Exceptions/InsufficientBalance.php @@ -0,0 +1,15 @@ +user()); + } +} diff --git a/app/Http/Controllers/Api/V1/LoginController.php b/app/Http/Controllers/Api/V1/LoginController.php new file mode 100644 index 0000000..ec60a28 --- /dev/null +++ b/app/Http/Controllers/Api/V1/LoginController.php @@ -0,0 +1,33 @@ +where('email', $request->validated('email'))->first(); + + if (is_null($user)) { + return response()->json([ + 'message' => 'Invalid credentials.', + 'code' => 'BAD_LOGIN', + ], 400); + } + + $token = $user->createToken($request->validated('device_name'))->plainTextToken; + + return response()->json([ + 'data' => [ + 'token' => $token, + ], + ], 201); + } +} diff --git a/app/Http/Controllers/Api/V1/SendMoneyController.php b/app/Http/Controllers/Api/V1/SendMoneyController.php new file mode 100644 index 0000000..6a27922 --- /dev/null +++ b/app/Http/Controllers/Api/V1/SendMoneyController.php @@ -0,0 +1,26 @@ +getRecipient(); + + $performWalletTransfer->execute( + sender: $request->user(), + recipient: $recipient, + amount: $request->input('amount'), + reason: $request->input('reason'), + ); + + return response()->noContent(201); + } +} diff --git a/app/Http/Controllers/Auth/AuthenticatedSessionController.php b/app/Http/Controllers/Auth/AuthenticatedSessionController.php new file mode 100644 index 0000000..d07d0a6 --- /dev/null +++ b/app/Http/Controllers/Auth/AuthenticatedSessionController.php @@ -0,0 +1,39 @@ +authenticate(); + + $request->session()->regenerate(); + + return redirect()->intended(route('dashboard', absolute: false)); + } + + public function destroy(Request $request): RedirectResponse + { + Auth::guard('web')->logout(); + + $request->session()->invalidate(); + + $request->session()->regenerateToken(); + + return redirect('/'); + } +} diff --git a/app/Http/Controllers/Auth/RegisteredUserController.php b/app/Http/Controllers/Auth/RegisteredUserController.php new file mode 100644 index 0000000..18e9e88 --- /dev/null +++ b/app/Http/Controllers/Auth/RegisteredUserController.php @@ -0,0 +1,43 @@ +validate([ + 'name' => ['required', 'string', 'max:255'], + 'email' => ['required', 'string', 'email', 'max:255', 'unique:'.User::class], + 'password' => ['required', 'confirmed', Rules\Password::defaults()], + ]); + + $user = User::create([ + 'name' => $request->name, + 'email' => strtolower($request->email), + 'password' => Hash::make($request->password), + ]); + + event(new Registered($user)); + + Auth::login($user); + + return redirect(route('dashboard', absolute: false)); + } +} diff --git a/app/Http/Controllers/DashboardController.php b/app/Http/Controllers/DashboardController.php new file mode 100644 index 0000000..a1e6da0 --- /dev/null +++ b/app/Http/Controllers/DashboardController.php @@ -0,0 +1,18 @@ +user()->wallet->transactions()->with('transfer')->orderByDesc('id')->get(); + $balance = $request->user()->wallet->balance; + + return view('dashboard', compact('transactions', 'balance')); + } +} diff --git a/app/Http/Controllers/SendMoneyController.php b/app/Http/Controllers/SendMoneyController.php new file mode 100644 index 0000000..ffd9749 --- /dev/null +++ b/app/Http/Controllers/SendMoneyController.php @@ -0,0 +1,35 @@ +getRecipient(); + + try { + $performWalletTransfer->execute( + sender: $request->user(), + recipient: $recipient, + amount: $request->getAmountInCents(), + reason: $request->input('reason'), + ); + + return redirect()->back() + ->with('money-sent-status', 'success') + ->with('money-sent-recipient-name', $recipient->name) + ->with('money-sent-amount', $request->getAmountInCents()); + } catch (InsufficientBalance $exception) { + return redirect()->back()->with('money-sent-status', 'insufficient-balance') + ->with('money-sent-recipient-name', $recipient->name) + ->with('money-sent-amount', $request->getAmountInCents()); + } + } +} diff --git a/app/Http/Middleware/ForceAcceptJson.php b/app/Http/Middleware/ForceAcceptJson.php new file mode 100644 index 0000000..2774cd3 --- /dev/null +++ b/app/Http/Middleware/ForceAcceptJson.php @@ -0,0 +1,21 @@ +headers->set('Accept', 'application/json'); + + return $next($request); + } +} diff --git a/app/Http/Requests/Api/V1/LoginRequest.php b/app/Http/Requests/Api/V1/LoginRequest.php new file mode 100644 index 0000000..20b4cb3 --- /dev/null +++ b/app/Http/Requests/Api/V1/LoginRequest.php @@ -0,0 +1,24 @@ + 'required|email:rfc', + 'password' => 'required', + 'device_name' => 'required|string', + ]; + } +} diff --git a/app/Http/Requests/Api/V1/SendMoneyRequest.php b/app/Http/Requests/Api/V1/SendMoneyRequest.php new file mode 100644 index 0000000..9f2ff76 --- /dev/null +++ b/app/Http/Requests/Api/V1/SendMoneyRequest.php @@ -0,0 +1,43 @@ + [ + 'required', + 'email', + Rule::exists(User::class, 'email')->whereNot('id', $this->user()->id), + ], + 'amount' => [ + 'required', + 'integer', + 'min:1', + ], + 'reason' => [ + 'required', + 'string', + 'max:255', + ], + ]; + } + + public function getRecipient(): User + { + return User::where('email', '=', $this->input('recipient_email'))->firstOrFail(); + } +} diff --git a/app/Http/Requests/LoginRequest.php b/app/Http/Requests/LoginRequest.php new file mode 100644 index 0000000..23f7d46 --- /dev/null +++ b/app/Http/Requests/LoginRequest.php @@ -0,0 +1,72 @@ + ['required', 'string', 'email'], + 'password' => ['required', 'string'], + ]; + } + + public function authenticate(): void + { + $this->ensureIsNotRateLimited(); + + if (! Auth::attempt([ + 'email' => strtolower($this->email), + 'password' => $this->password, + ])) { + RateLimiter::hit($this->throttleKey()); + + throw ValidationException::withMessages([ + 'email' => trans('auth.failed'), + ]); + } + + RateLimiter::clear($this->throttleKey()); + } + + /** + * @throws \Illuminate\Validation\ValidationException + */ + public function ensureIsNotRateLimited(): void + { + if (! RateLimiter::tooManyAttempts($this->throttleKey(), 5)) { + return; + } + + event(new Lockout($this)); + + $seconds = RateLimiter::availableIn($this->throttleKey()); + + throw ValidationException::withMessages([ + 'email' => trans('auth.throttle', [ + 'seconds' => $seconds, + 'minutes' => ceil($seconds / 60), + ]), + ]); + } + + public function throttleKey(): string + { + return Str::transliterate(Str::lower($this->string('email')).'|'.$this->ip()); + } +} diff --git a/app/Http/Requests/SendMoneyRequest.php b/app/Http/Requests/SendMoneyRequest.php new file mode 100644 index 0000000..07e99d9 --- /dev/null +++ b/app/Http/Requests/SendMoneyRequest.php @@ -0,0 +1,48 @@ + [ + 'required', + 'email', + Rule::exists(User::class, 'email')->whereNot('id', $this->user()->id), + ], + 'amount' => [ + 'required', + 'numeric', + 'min:0.01', + ], + 'reason' => [ + 'required', + 'string', + 'max:255', + ], + ]; + } + + public function getRecipient(): User + { + return User::where('email', '=', $this->input('recipient_email'))->firstOrFail(); + } + + public function getAmountInCents(): int + { + return (int) ceil($this->float('amount') * 100); + } +} diff --git a/app/Http/Resources/AccountResource.php b/app/Http/Resources/AccountResource.php new file mode 100644 index 0000000..bee07a9 --- /dev/null +++ b/app/Http/Resources/AccountResource.php @@ -0,0 +1,25 @@ + $this->id, + 'name' => $this->name, + 'email' => $this->email, + 'balance' => $this->wallet->balance, + ]; + } +} diff --git a/app/Models/User.php b/app/Models/User.php new file mode 100644 index 0000000..3077e1b --- /dev/null +++ b/app/Models/User.php @@ -0,0 +1,41 @@ + 'hashed', + ]; + } + + /** + * @return HasOne + */ + public function wallet(): HasOne + { + return $this->hasOne(Wallet::class); + } +} diff --git a/app/Models/Wallet.php b/app/Models/Wallet.php new file mode 100644 index 0000000..53c810a --- /dev/null +++ b/app/Models/Wallet.php @@ -0,0 +1,31 @@ + + */ + public function user(): BelongsTo + { + return $this->belongsTo(User::class); + } + + /** + * @return HasMany + */ + public function transactions(): HasMany + { + return $this->hasMany(WalletTransaction::class); + } +} diff --git a/app/Models/WalletTransaction.php b/app/Models/WalletTransaction.php new file mode 100644 index 0000000..0339e15 --- /dev/null +++ b/app/Models/WalletTransaction.php @@ -0,0 +1,43 @@ + WalletTransactionType::class, + ]; + } + + protected function isTransfer(): Attribute + { + return Attribute::get(fn () => filled($this->transfer_id)); + } + + public function transfer(): BelongsTo + { + return $this->belongsTo(WalletTransfer::class, 'transfer_id'); + } + + /** + * @return BelongsTo + */ + public function wallet(): BelongsTo + { + return $this->belongsTo(Wallet::class); + } +} diff --git a/app/Models/WalletTransfer.php b/app/Models/WalletTransfer.php new file mode 100644 index 0000000..243de59 --- /dev/null +++ b/app/Models/WalletTransfer.php @@ -0,0 +1,48 @@ + + */ + public function source(): BelongsTo + { + return $this->belongsTo(Wallet::class, 'source_id'); + } + + /** + * @return BelongsTo + */ + public function target(): BelongsTo + { + return $this->belongsTo(Wallet::class, 'target_id'); + } + + /** + * @return BelongsTo + */ + public function credit(): BelongsTo + { + return $this->belongsTo(WalletTransaction::class, 'credit_id'); + } + + /** + * @return BelongsTo + */ + public function debit(): BelongsTo + { + return $this->belongsTo(WalletTransaction::class, 'debit_id'); + } +} diff --git a/app/Providers/AppServiceProvider.php b/app/Providers/AppServiceProvider.php new file mode 100644 index 0000000..a57ab2c --- /dev/null +++ b/app/Providers/AppServiceProvider.php @@ -0,0 +1,41 @@ +isProduction() ? Password::min(8) + ->numbers() + ->mixedCase() + ->uncompromised() : Password::min(6); + }); + + RateLimiter::for('api.login', function (Request $request) { + return Limit::perMinutes(5, 5)->by($request->ip()); + }); + + RateLimiter::for('api', function (Request $request) { + return Limit::perMinute(120)->by($request->user()?->id ?: $request->ip()); + }); + } +} diff --git a/app/View/Components/AppLayout.php b/app/View/Components/AppLayout.php new file mode 100644 index 0000000..c87d025 --- /dev/null +++ b/app/View/Components/AppLayout.php @@ -0,0 +1,16 @@ +handleCommand(new ArgvInput); + +exit($status); diff --git a/bootstrap/app.php b/bootstrap/app.php new file mode 100644 index 0000000..4602b88 --- /dev/null +++ b/bootstrap/app.php @@ -0,0 +1,31 @@ +withRouting( + web: __DIR__.'/../routes/web.php', + api: __DIR__.'/../routes/api.php', + commands: __DIR__.'/../routes/console.php', + health: '/up', + ) + ->withMiddleware(function (Middleware $middleware) { + $middleware->api(append: [ + ForceAcceptJson::class, + ]); + }) + ->withExceptions(function (Exceptions $exceptions) { + $exceptions->reportable(function (Throwable $e) { + if ($e instanceof ApiException) { + return ! $e->silenced; + } + + return true; + }); + })->create(); diff --git a/bootstrap/cache/.gitignore b/bootstrap/cache/.gitignore new file mode 100644 index 0000000..d6b7ef3 --- /dev/null +++ b/bootstrap/cache/.gitignore @@ -0,0 +1,2 @@ +* +!.gitignore diff --git a/bootstrap/providers.php b/bootstrap/providers.php new file mode 100644 index 0000000..84c7d4d --- /dev/null +++ b/bootstrap/providers.php @@ -0,0 +1,7 @@ +=5.0.0" + }, + "require-dev": { + "doctrine/dbal": "^4.0.0", + "nesbot/carbon": "^2.71.0 || ^3.0.0", + "phpunit/phpunit": "^10.3" + }, + "type": "library", + "autoload": { + "psr-4": { + "Carbon\\Doctrine\\": "src/Carbon/Doctrine/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "KyleKatarn", + "email": "kylekatarnls@gmail.com" + } + ], + "description": "Types to use Carbon in Doctrine", + "keywords": [ + "carbon", + "date", + "datetime", + "doctrine", + "time" + ], + "support": { + "issues": "https://github.com/CarbonPHP/carbon-doctrine-types/issues", + "source": "https://github.com/CarbonPHP/carbon-doctrine-types/tree/3.2.0" + }, + "funding": [ + { + "url": "https://github.com/kylekatarnls", + "type": "github" + }, + { + "url": "https://opencollective.com/Carbon", + "type": "open_collective" + }, + { + "url": "https://tidelift.com/funding/github/packagist/nesbot/carbon", + "type": "tidelift" + } + ], + "time": "2024-02-09T16:56:22+00:00" + }, + { + "name": "dflydev/dot-access-data", + "version": "v3.0.3", + "source": { + "type": "git", + "url": "https://github.com/dflydev/dflydev-dot-access-data.git", + "reference": "a23a2bf4f31d3518f3ecb38660c95715dfead60f" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/dflydev/dflydev-dot-access-data/zipball/a23a2bf4f31d3518f3ecb38660c95715dfead60f", + "reference": "a23a2bf4f31d3518f3ecb38660c95715dfead60f", + "shasum": "" + }, + "require": { + "php": "^7.1 || ^8.0" + }, + "require-dev": { + "phpstan/phpstan": "^0.12.42", + "phpunit/phpunit": "^7.5 || ^8.5 || ^9.3", + "scrutinizer/ocular": "1.6.0", + "squizlabs/php_codesniffer": "^3.5", + "vimeo/psalm": "^4.0.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "3.x-dev" + } + }, + "autoload": { + "psr-4": { + "Dflydev\\DotAccessData\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Dragonfly Development Inc.", + "email": "info@dflydev.com", + "homepage": "http://dflydev.com" + }, + { + "name": "Beau Simensen", + "email": "beau@dflydev.com", + "homepage": "http://beausimensen.com" + }, + { + "name": "Carlos Frutos", + "email": "carlos@kiwing.it", + "homepage": "https://github.com/cfrutos" + }, + { + "name": "Colin O'Dell", + "email": "colinodell@gmail.com", + "homepage": "https://www.colinodell.com" + } + ], + "description": "Given a deep data structure, access data by dot notation.", + "homepage": "https://github.com/dflydev/dflydev-dot-access-data", + "keywords": [ + "access", + "data", + "dot", + "notation" + ], + "support": { + "issues": "https://github.com/dflydev/dflydev-dot-access-data/issues", + "source": "https://github.com/dflydev/dflydev-dot-access-data/tree/v3.0.3" + }, + "time": "2024-07-08T12:26:09+00:00" + }, + { + "name": "doctrine/inflector", + "version": "2.0.10", + "source": { + "type": "git", + "url": "https://github.com/doctrine/inflector.git", + "reference": "5817d0659c5b50c9b950feb9af7b9668e2c436bc" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/doctrine/inflector/zipball/5817d0659c5b50c9b950feb9af7b9668e2c436bc", + "reference": "5817d0659c5b50c9b950feb9af7b9668e2c436bc", + "shasum": "" + }, + "require": { + "php": "^7.2 || ^8.0" + }, + "require-dev": { + "doctrine/coding-standard": "^11.0", + "phpstan/phpstan": "^1.8", + "phpstan/phpstan-phpunit": "^1.1", + "phpstan/phpstan-strict-rules": "^1.3", + "phpunit/phpunit": "^8.5 || ^9.5", + "vimeo/psalm": "^4.25 || ^5.4" + }, + "type": "library", + "autoload": { + "psr-4": { + "Doctrine\\Inflector\\": "lib/Doctrine/Inflector" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Guilherme Blanco", + "email": "guilhermeblanco@gmail.com" + }, + { + "name": "Roman Borschel", + "email": "roman@code-factory.org" + }, + { + "name": "Benjamin Eberlei", + "email": "kontakt@beberlei.de" + }, + { + "name": "Jonathan Wage", + "email": "jonwage@gmail.com" + }, + { + "name": "Johannes Schmitt", + "email": "schmittjoh@gmail.com" + } + ], + "description": "PHP Doctrine Inflector is a small library that can perform string manipulations with regard to upper/lowercase and singular/plural forms of words.", + "homepage": "https://www.doctrine-project.org/projects/inflector.html", + "keywords": [ + "inflection", + "inflector", + "lowercase", + "manipulation", + "php", + "plural", + "singular", + "strings", + "uppercase", + "words" + ], + "support": { + "issues": "https://github.com/doctrine/inflector/issues", + "source": "https://github.com/doctrine/inflector/tree/2.0.10" + }, + "funding": [ + { + "url": "https://www.doctrine-project.org/sponsorship.html", + "type": "custom" + }, + { + "url": "https://www.patreon.com/phpdoctrine", + "type": "patreon" + }, + { + "url": "https://tidelift.com/funding/github/packagist/doctrine%2Finflector", + "type": "tidelift" + } + ], + "time": "2024-02-18T20:23:39+00:00" + }, + { + "name": "doctrine/lexer", + "version": "3.0.1", + "source": { + "type": "git", + "url": "https://github.com/doctrine/lexer.git", + "reference": "31ad66abc0fc9e1a1f2d9bc6a42668d2fbbcd6dd" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/doctrine/lexer/zipball/31ad66abc0fc9e1a1f2d9bc6a42668d2fbbcd6dd", + "reference": "31ad66abc0fc9e1a1f2d9bc6a42668d2fbbcd6dd", + "shasum": "" + }, + "require": { + "php": "^8.1" + }, + "require-dev": { + "doctrine/coding-standard": "^12", + "phpstan/phpstan": "^1.10", + "phpunit/phpunit": "^10.5", + "psalm/plugin-phpunit": "^0.18.3", + "vimeo/psalm": "^5.21" + }, + "type": "library", + "autoload": { + "psr-4": { + "Doctrine\\Common\\Lexer\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Guilherme Blanco", + "email": "guilhermeblanco@gmail.com" + }, + { + "name": "Roman Borschel", + "email": "roman@code-factory.org" + }, + { + "name": "Johannes Schmitt", + "email": "schmittjoh@gmail.com" + } + ], + "description": "PHP Doctrine Lexer parser library that can be used in Top-Down, Recursive Descent Parsers.", + "homepage": "https://www.doctrine-project.org/projects/lexer.html", + "keywords": [ + "annotations", + "docblock", + "lexer", + "parser", + "php" + ], + "support": { + "issues": "https://github.com/doctrine/lexer/issues", + "source": "https://github.com/doctrine/lexer/tree/3.0.1" + }, + "funding": [ + { + "url": "https://www.doctrine-project.org/sponsorship.html", + "type": "custom" + }, + { + "url": "https://www.patreon.com/phpdoctrine", + "type": "patreon" + }, + { + "url": "https://tidelift.com/funding/github/packagist/doctrine%2Flexer", + "type": "tidelift" + } + ], + "time": "2024-02-05T11:56:58+00:00" + }, + { + "name": "dragonmantank/cron-expression", + "version": "v3.4.0", + "source": { + "type": "git", + "url": "https://github.com/dragonmantank/cron-expression.git", + "reference": "8c784d071debd117328803d86b2097615b457500" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/dragonmantank/cron-expression/zipball/8c784d071debd117328803d86b2097615b457500", + "reference": "8c784d071debd117328803d86b2097615b457500", + "shasum": "" + }, + "require": { + "php": "^7.2|^8.0", + "webmozart/assert": "^1.0" + }, + "replace": { + "mtdowling/cron-expression": "^1.0" + }, + "require-dev": { + "phpstan/extension-installer": "^1.0", + "phpstan/phpstan": "^1.0", + "phpunit/phpunit": "^7.0|^8.0|^9.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.x-dev" + } + }, + "autoload": { + "psr-4": { + "Cron\\": "src/Cron/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Chris Tankersley", + "email": "chris@ctankersley.com", + "homepage": "https://github.com/dragonmantank" + } + ], + "description": "CRON for PHP: Calculate the next or previous run date and determine if a CRON expression is due", + "keywords": [ + "cron", + "schedule" + ], + "support": { + "issues": "https://github.com/dragonmantank/cron-expression/issues", + "source": "https://github.com/dragonmantank/cron-expression/tree/v3.4.0" + }, + "funding": [ + { + "url": "https://github.com/dragonmantank", + "type": "github" + } + ], + "time": "2024-10-09T13:47:03+00:00" + }, + { + "name": "egulias/email-validator", + "version": "4.0.2", + "source": { + "type": "git", + "url": "https://github.com/egulias/EmailValidator.git", + "reference": "ebaaf5be6c0286928352e054f2d5125608e5405e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/egulias/EmailValidator/zipball/ebaaf5be6c0286928352e054f2d5125608e5405e", + "reference": "ebaaf5be6c0286928352e054f2d5125608e5405e", + "shasum": "" + }, + "require": { + "doctrine/lexer": "^2.0 || ^3.0", + "php": ">=8.1", + "symfony/polyfill-intl-idn": "^1.26" + }, + "require-dev": { + "phpunit/phpunit": "^10.2", + "vimeo/psalm": "^5.12" + }, + "suggest": { + "ext-intl": "PHP Internationalization Libraries are required to use the SpoofChecking validation" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Egulias\\EmailValidator\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Eduardo Gulias Davis" + } + ], + "description": "A library for validating emails against several RFCs", + "homepage": "https://github.com/egulias/EmailValidator", + "keywords": [ + "email", + "emailvalidation", + "emailvalidator", + "validation", + "validator" + ], + "support": { + "issues": "https://github.com/egulias/EmailValidator/issues", + "source": "https://github.com/egulias/EmailValidator/tree/4.0.2" + }, + "funding": [ + { + "url": "https://github.com/egulias", + "type": "github" + } + ], + "time": "2023-10-06T06:47:41+00:00" + }, + { + "name": "fruitcake/php-cors", + "version": "v1.3.0", + "source": { + "type": "git", + "url": "https://github.com/fruitcake/php-cors.git", + "reference": "3d158f36e7875e2f040f37bc0573956240a5a38b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/fruitcake/php-cors/zipball/3d158f36e7875e2f040f37bc0573956240a5a38b", + "reference": "3d158f36e7875e2f040f37bc0573956240a5a38b", + "shasum": "" + }, + "require": { + "php": "^7.4|^8.0", + "symfony/http-foundation": "^4.4|^5.4|^6|^7" + }, + "require-dev": { + "phpstan/phpstan": "^1.4", + "phpunit/phpunit": "^9", + "squizlabs/php_codesniffer": "^3.5" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.2-dev" + } + }, + "autoload": { + "psr-4": { + "Fruitcake\\Cors\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fruitcake", + "homepage": "https://fruitcake.nl" + }, + { + "name": "Barryvdh", + "email": "barryvdh@gmail.com" + } + ], + "description": "Cross-origin resource sharing library for the Symfony HttpFoundation", + "homepage": "https://github.com/fruitcake/php-cors", + "keywords": [ + "cors", + "laravel", + "symfony" + ], + "support": { + "issues": "https://github.com/fruitcake/php-cors/issues", + "source": "https://github.com/fruitcake/php-cors/tree/v1.3.0" + }, + "funding": [ + { + "url": "https://fruitcake.nl", + "type": "custom" + }, + { + "url": "https://github.com/barryvdh", + "type": "github" + } + ], + "time": "2023-10-12T05:21:21+00:00" + }, + { + "name": "graham-campbell/result-type", + "version": "v1.1.3", + "source": { + "type": "git", + "url": "https://github.com/GrahamCampbell/Result-Type.git", + "reference": "3ba905c11371512af9d9bdd27d99b782216b6945" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/GrahamCampbell/Result-Type/zipball/3ba905c11371512af9d9bdd27d99b782216b6945", + "reference": "3ba905c11371512af9d9bdd27d99b782216b6945", + "shasum": "" + }, + "require": { + "php": "^7.2.5 || ^8.0", + "phpoption/phpoption": "^1.9.3" + }, + "require-dev": { + "phpunit/phpunit": "^8.5.39 || ^9.6.20 || ^10.5.28" + }, + "type": "library", + "autoload": { + "psr-4": { + "GrahamCampbell\\ResultType\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Graham Campbell", + "email": "hello@gjcampbell.co.uk", + "homepage": "https://github.com/GrahamCampbell" + } + ], + "description": "An Implementation Of The Result Type", + "keywords": [ + "Graham Campbell", + "GrahamCampbell", + "Result Type", + "Result-Type", + "result" + ], + "support": { + "issues": "https://github.com/GrahamCampbell/Result-Type/issues", + "source": "https://github.com/GrahamCampbell/Result-Type/tree/v1.1.3" + }, + "funding": [ + { + "url": "https://github.com/GrahamCampbell", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/graham-campbell/result-type", + "type": "tidelift" + } + ], + "time": "2024-07-20T21:45:45+00:00" + }, + { + "name": "guzzlehttp/guzzle", + "version": "7.9.2", + "source": { + "type": "git", + "url": "https://github.com/guzzle/guzzle.git", + "reference": "d281ed313b989f213357e3be1a179f02196ac99b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/guzzle/guzzle/zipball/d281ed313b989f213357e3be1a179f02196ac99b", + "reference": "d281ed313b989f213357e3be1a179f02196ac99b", + "shasum": "" + }, + "require": { + "ext-json": "*", + "guzzlehttp/promises": "^1.5.3 || ^2.0.3", + "guzzlehttp/psr7": "^2.7.0", + "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": "*", + "guzzle/client-integration-tests": "3.0.2", + "php-http/message-factory": "^1.1", + "phpunit/phpunit": "^8.5.39 || ^9.6.20", + "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.9.2" + }, + "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": "2024-07-24T11:22:20+00:00" + }, + { + "name": "guzzlehttp/promises", + "version": "2.0.4", + "source": { + "type": "git", + "url": "https://github.com/guzzle/promises.git", + "reference": "f9c436286ab2892c7db7be8c8da4ef61ccf7b455" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/guzzle/promises/zipball/f9c436286ab2892c7db7be8c8da4ef61ccf7b455", + "reference": "f9c436286ab2892c7db7be8c8da4ef61ccf7b455", + "shasum": "" + }, + "require": { + "php": "^7.2.5 || ^8.0" + }, + "require-dev": { + "bamarni/composer-bin-plugin": "^1.8.2", + "phpunit/phpunit": "^8.5.39 || ^9.6.20" + }, + "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.4" + }, + "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": "2024-10-17T10:06:22+00:00" + }, + { + "name": "guzzlehttp/psr7", + "version": "2.7.0", + "source": { + "type": "git", + "url": "https://github.com/guzzle/psr7.git", + "reference": "a70f5c95fb43bc83f07c9c948baa0dc1829bf201" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/guzzle/psr7/zipball/a70f5c95fb43bc83f07c9c948baa0dc1829bf201", + "reference": "a70f5c95fb43bc83f07c9c948baa0dc1829bf201", + "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.0", + "phpunit/phpunit": "^8.5.39 || ^9.6.20" + }, + "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.7.0" + }, + "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": "2024-07-18T11:15:46+00:00" + }, + { + "name": "guzzlehttp/uri-template", + "version": "v1.0.3", + "source": { + "type": "git", + "url": "https://github.com/guzzle/uri-template.git", + "reference": "ecea8feef63bd4fef1f037ecb288386999ecc11c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/guzzle/uri-template/zipball/ecea8feef63bd4fef1f037ecb288386999ecc11c", + "reference": "ecea8feef63bd4fef1f037ecb288386999ecc11c", + "shasum": "" + }, + "require": { + "php": "^7.2.5 || ^8.0", + "symfony/polyfill-php80": "^1.24" + }, + "require-dev": { + "bamarni/composer-bin-plugin": "^1.8.2", + "phpunit/phpunit": "^8.5.36 || ^9.6.15", + "uri-template/tests": "1.0.0" + }, + "type": "library", + "extra": { + "bamarni-bin": { + "bin-links": true, + "forward-command": false + } + }, + "autoload": { + "psr-4": { + "GuzzleHttp\\UriTemplate\\": "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" + } + ], + "description": "A polyfill class for uri_template of PHP", + "keywords": [ + "guzzlehttp", + "uri-template" + ], + "support": { + "issues": "https://github.com/guzzle/uri-template/issues", + "source": "https://github.com/guzzle/uri-template/tree/v1.0.3" + }, + "funding": [ + { + "url": "https://github.com/GrahamCampbell", + "type": "github" + }, + { + "url": "https://github.com/Nyholm", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/guzzlehttp/uri-template", + "type": "tidelift" + } + ], + "time": "2023-12-03T19:50:20+00:00" + }, + { + "name": "laravel/framework", + "version": "v11.34.2", + "source": { + "type": "git", + "url": "https://github.com/laravel/framework.git", + "reference": "865da6d73dd353f07a7bcbd778c55966a620121f" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/laravel/framework/zipball/865da6d73dd353f07a7bcbd778c55966a620121f", + "reference": "865da6d73dd353f07a7bcbd778c55966a620121f", + "shasum": "" + }, + "require": { + "brick/math": "^0.9.3|^0.10.2|^0.11|^0.12", + "composer-runtime-api": "^2.2", + "doctrine/inflector": "^2.0.5", + "dragonmantank/cron-expression": "^3.4", + "egulias/email-validator": "^3.2.1|^4.0", + "ext-ctype": "*", + "ext-filter": "*", + "ext-hash": "*", + "ext-mbstring": "*", + "ext-openssl": "*", + "ext-session": "*", + "ext-tokenizer": "*", + "fruitcake/php-cors": "^1.3", + "guzzlehttp/guzzle": "^7.8.2", + "guzzlehttp/uri-template": "^1.0", + "laravel/prompts": "^0.1.18|^0.2.0|^0.3.0", + "laravel/serializable-closure": "^1.3|^2.0", + "league/commonmark": "^2.2.1", + "league/flysystem": "^3.25.1", + "league/flysystem-local": "^3.25.1", + "monolog/monolog": "^3.0", + "nesbot/carbon": "^2.72.2|^3.4", + "nunomaduro/termwind": "^2.0", + "php": "^8.2", + "psr/container": "^1.1.1|^2.0.1", + "psr/log": "^1.0|^2.0|^3.0", + "psr/simple-cache": "^1.0|^2.0|^3.0", + "ramsey/uuid": "^4.7", + "symfony/console": "^7.0.3", + "symfony/error-handler": "^7.0.3", + "symfony/finder": "^7.0.3", + "symfony/http-foundation": "^7.0.3", + "symfony/http-kernel": "^7.0.3", + "symfony/mailer": "^7.0.3", + "symfony/mime": "^7.0.3", + "symfony/polyfill-php83": "^1.31", + "symfony/process": "^7.0.3", + "symfony/routing": "^7.0.3", + "symfony/uid": "^7.0.3", + "symfony/var-dumper": "^7.0.3", + "tijsverkoyen/css-to-inline-styles": "^2.2.5", + "vlucas/phpdotenv": "^5.6.1", + "voku/portable-ascii": "^2.0.2" + }, + "conflict": { + "mockery/mockery": "1.6.8", + "tightenco/collect": "<5.5.33" + }, + "provide": { + "psr/container-implementation": "1.1|2.0", + "psr/log-implementation": "1.0|2.0|3.0", + "psr/simple-cache-implementation": "1.0|2.0|3.0" + }, + "replace": { + "illuminate/auth": "self.version", + "illuminate/broadcasting": "self.version", + "illuminate/bus": "self.version", + "illuminate/cache": "self.version", + "illuminate/collections": "self.version", + "illuminate/concurrency": "self.version", + "illuminate/conditionable": "self.version", + "illuminate/config": "self.version", + "illuminate/console": "self.version", + "illuminate/container": "self.version", + "illuminate/contracts": "self.version", + "illuminate/cookie": "self.version", + "illuminate/database": "self.version", + "illuminate/encryption": "self.version", + "illuminate/events": "self.version", + "illuminate/filesystem": "self.version", + "illuminate/hashing": "self.version", + "illuminate/http": "self.version", + "illuminate/log": "self.version", + "illuminate/macroable": "self.version", + "illuminate/mail": "self.version", + "illuminate/notifications": "self.version", + "illuminate/pagination": "self.version", + "illuminate/pipeline": "self.version", + "illuminate/process": "self.version", + "illuminate/queue": "self.version", + "illuminate/redis": "self.version", + "illuminate/routing": "self.version", + "illuminate/session": "self.version", + "illuminate/support": "self.version", + "illuminate/testing": "self.version", + "illuminate/translation": "self.version", + "illuminate/validation": "self.version", + "illuminate/view": "self.version", + "spatie/once": "*" + }, + "require-dev": { + "ably/ably-php": "^1.0", + "aws/aws-sdk-php": "^3.322.9", + "ext-gmp": "*", + "fakerphp/faker": "^1.24", + "guzzlehttp/promises": "^2.0.3", + "guzzlehttp/psr7": "^2.4", + "league/flysystem-aws-s3-v3": "^3.25.1", + "league/flysystem-ftp": "^3.25.1", + "league/flysystem-path-prefixing": "^3.25.1", + "league/flysystem-read-only": "^3.25.1", + "league/flysystem-sftp-v3": "^3.25.1", + "mockery/mockery": "^1.6.10", + "nyholm/psr7": "^1.2", + "orchestra/testbench-core": "^9.6", + "pda/pheanstalk": "^5.0.6", + "phpstan/phpstan": "^1.11.5", + "phpunit/phpunit": "^10.5.35|^11.3.6", + "predis/predis": "^2.3", + "resend/resend-php": "^0.10.0", + "symfony/cache": "^7.0.3", + "symfony/http-client": "^7.0.3", + "symfony/psr-http-message-bridge": "^7.0.3", + "symfony/translation": "^7.0.3" + }, + "suggest": { + "ably/ably-php": "Required to use the Ably broadcast driver (^1.0).", + "aws/aws-sdk-php": "Required to use the SQS queue driver, DynamoDb failed job storage, and SES mail driver (^3.322.9).", + "brianium/paratest": "Required to run tests in parallel (^7.0|^8.0).", + "ext-apcu": "Required to use the APC cache driver.", + "ext-fileinfo": "Required to use the Filesystem class.", + "ext-ftp": "Required to use the Flysystem FTP driver.", + "ext-gd": "Required to use Illuminate\\Http\\Testing\\FileFactory::image().", + "ext-memcached": "Required to use the memcache cache driver.", + "ext-pcntl": "Required to use all features of the queue worker and console signal trapping.", + "ext-pdo": "Required to use all database features.", + "ext-posix": "Required to use all features of the queue worker.", + "ext-redis": "Required to use the Redis cache and queue drivers (^4.0|^5.0|^6.0).", + "fakerphp/faker": "Required to use the eloquent factory builder (^1.9.1).", + "filp/whoops": "Required for friendly error pages in development (^2.14.3).", + "laravel/tinker": "Required to use the tinker console command (^2.0).", + "league/flysystem-aws-s3-v3": "Required to use the Flysystem S3 driver (^3.25.1).", + "league/flysystem-ftp": "Required to use the Flysystem FTP driver (^3.25.1).", + "league/flysystem-path-prefixing": "Required to use the scoped driver (^3.25.1).", + "league/flysystem-read-only": "Required to use read-only disks (^3.25.1)", + "league/flysystem-sftp-v3": "Required to use the Flysystem SFTP driver (^3.25.1).", + "mockery/mockery": "Required to use mocking (^1.6).", + "nyholm/psr7": "Required to use PSR-7 bridging features (^1.2).", + "pda/pheanstalk": "Required to use the beanstalk queue driver (^5.0).", + "phpunit/phpunit": "Required to use assertions and run tests (^10.5|^11.0).", + "predis/predis": "Required to use the predis connector (^2.3).", + "psr/http-message": "Required to allow Storage::put to accept a StreamInterface (^1.0).", + "pusher/pusher-php-server": "Required to use the Pusher broadcast driver (^6.0|^7.0).", + "resend/resend-php": "Required to enable support for the Resend mail transport (^0.10.0).", + "symfony/cache": "Required to PSR-6 cache bridge (^7.0).", + "symfony/filesystem": "Required to enable support for relative symbolic links (^7.0).", + "symfony/http-client": "Required to enable support for the Symfony API mail transports (^7.0).", + "symfony/mailgun-mailer": "Required to enable support for the Mailgun mail transport (^7.0).", + "symfony/postmark-mailer": "Required to enable support for the Postmark mail transport (^7.0).", + "symfony/psr-http-message-bridge": "Required to use PSR-7 bridging features (^7.0)." + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "11.x-dev" + } + }, + "autoload": { + "files": [ + "src/Illuminate/Collections/helpers.php", + "src/Illuminate/Events/functions.php", + "src/Illuminate/Filesystem/functions.php", + "src/Illuminate/Foundation/helpers.php", + "src/Illuminate/Log/functions.php", + "src/Illuminate/Support/functions.php", + "src/Illuminate/Support/helpers.php" + ], + "psr-4": { + "Illuminate\\": "src/Illuminate/", + "Illuminate\\Support\\": [ + "src/Illuminate/Macroable/", + "src/Illuminate/Collections/", + "src/Illuminate/Conditionable/" + ] + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Taylor Otwell", + "email": "taylor@laravel.com" + } + ], + "description": "The Laravel Framework.", + "homepage": "https://laravel.com", + "keywords": [ + "framework", + "laravel" + ], + "support": { + "issues": "https://github.com/laravel/framework/issues", + "source": "https://github.com/laravel/framework" + }, + "time": "2024-11-27T15:43:57+00:00" + }, + { + "name": "laravel/prompts", + "version": "v0.3.2", + "source": { + "type": "git", + "url": "https://github.com/laravel/prompts.git", + "reference": "0e0535747c6b8d6d10adca8b68293cf4517abb0f" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/laravel/prompts/zipball/0e0535747c6b8d6d10adca8b68293cf4517abb0f", + "reference": "0e0535747c6b8d6d10adca8b68293cf4517abb0f", + "shasum": "" + }, + "require": { + "composer-runtime-api": "^2.2", + "ext-mbstring": "*", + "php": "^8.1", + "symfony/console": "^6.2|^7.0" + }, + "conflict": { + "illuminate/console": ">=10.17.0 <10.25.0", + "laravel/framework": ">=10.17.0 <10.25.0" + }, + "require-dev": { + "illuminate/collections": "^10.0|^11.0", + "mockery/mockery": "^1.5", + "pestphp/pest": "^2.3|^3.4", + "phpstan/phpstan": "^1.11", + "phpstan/phpstan-mockery": "^1.1" + }, + "suggest": { + "ext-pcntl": "Required for the spinner to be animated." + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "0.3.x-dev" + } + }, + "autoload": { + "files": [ + "src/helpers.php" + ], + "psr-4": { + "Laravel\\Prompts\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "Add beautiful and user-friendly forms to your command-line applications.", + "support": { + "issues": "https://github.com/laravel/prompts/issues", + "source": "https://github.com/laravel/prompts/tree/v0.3.2" + }, + "time": "2024-11-12T14:59:47+00:00" + }, + { + "name": "laravel/sanctum", + "version": "v4.0.5", + "source": { + "type": "git", + "url": "https://github.com/laravel/sanctum.git", + "reference": "fe361b9a63407a228f884eb78d7217f680b50140" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/laravel/sanctum/zipball/fe361b9a63407a228f884eb78d7217f680b50140", + "reference": "fe361b9a63407a228f884eb78d7217f680b50140", + "shasum": "" + }, + "require": { + "ext-json": "*", + "illuminate/console": "^11.0", + "illuminate/contracts": "^11.0", + "illuminate/database": "^11.0", + "illuminate/support": "^11.0", + "php": "^8.2", + "symfony/console": "^7.0" + }, + "require-dev": { + "mockery/mockery": "^1.6", + "orchestra/testbench": "^9.0", + "phpstan/phpstan": "^1.10", + "phpunit/phpunit": "^10.5" + }, + "type": "library", + "extra": { + "laravel": { + "providers": [ + "Laravel\\Sanctum\\SanctumServiceProvider" + ] + } + }, + "autoload": { + "psr-4": { + "Laravel\\Sanctum\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Taylor Otwell", + "email": "taylor@laravel.com" + } + ], + "description": "Laravel Sanctum provides a featherweight authentication system for SPAs and simple APIs.", + "keywords": [ + "auth", + "laravel", + "sanctum" + ], + "support": { + "issues": "https://github.com/laravel/sanctum/issues", + "source": "https://github.com/laravel/sanctum" + }, + "time": "2024-11-26T14:36:23+00:00" + }, + { + "name": "laravel/serializable-closure", + "version": "v2.0.0", + "source": { + "type": "git", + "url": "https://github.com/laravel/serializable-closure.git", + "reference": "0d8d3d8086984996df86596a86dea60398093a81" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/laravel/serializable-closure/zipball/0d8d3d8086984996df86596a86dea60398093a81", + "reference": "0d8d3d8086984996df86596a86dea60398093a81", + "shasum": "" + }, + "require": { + "php": "^8.1" + }, + "require-dev": { + "illuminate/support": "^10.0|^11.0", + "nesbot/carbon": "^2.67|^3.0", + "pestphp/pest": "^2.36", + "phpstan/phpstan": "^2.0", + "symfony/var-dumper": "^6.2.0|^7.0.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.x-dev" + } + }, + "autoload": { + "psr-4": { + "Laravel\\SerializableClosure\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Taylor Otwell", + "email": "taylor@laravel.com" + }, + { + "name": "Nuno Maduro", + "email": "nuno@laravel.com" + } + ], + "description": "Laravel Serializable Closure provides an easy and secure way to serialize closures in PHP.", + "keywords": [ + "closure", + "laravel", + "serializable" + ], + "support": { + "issues": "https://github.com/laravel/serializable-closure/issues", + "source": "https://github.com/laravel/serializable-closure" + }, + "time": "2024-11-19T01:38:44+00:00" + }, + { + "name": "laravel/tinker", + "version": "v2.10.0", + "source": { + "type": "git", + "url": "https://github.com/laravel/tinker.git", + "reference": "ba4d51eb56de7711b3a37d63aa0643e99a339ae5" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/laravel/tinker/zipball/ba4d51eb56de7711b3a37d63aa0643e99a339ae5", + "reference": "ba4d51eb56de7711b3a37d63aa0643e99a339ae5", + "shasum": "" + }, + "require": { + "illuminate/console": "^6.0|^7.0|^8.0|^9.0|^10.0|^11.0", + "illuminate/contracts": "^6.0|^7.0|^8.0|^9.0|^10.0|^11.0", + "illuminate/support": "^6.0|^7.0|^8.0|^9.0|^10.0|^11.0", + "php": "^7.2.5|^8.0", + "psy/psysh": "^0.11.1|^0.12.0", + "symfony/var-dumper": "^4.3.4|^5.0|^6.0|^7.0" + }, + "require-dev": { + "mockery/mockery": "~1.3.3|^1.4.2", + "phpstan/phpstan": "^1.10", + "phpunit/phpunit": "^8.5.8|^9.3.3" + }, + "suggest": { + "illuminate/database": "The Illuminate Database package (^6.0|^7.0|^8.0|^9.0|^10.0|^11.0)." + }, + "type": "library", + "extra": { + "laravel": { + "providers": [ + "Laravel\\Tinker\\TinkerServiceProvider" + ] + } + }, + "autoload": { + "psr-4": { + "Laravel\\Tinker\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Taylor Otwell", + "email": "taylor@laravel.com" + } + ], + "description": "Powerful REPL for the Laravel framework.", + "keywords": [ + "REPL", + "Tinker", + "laravel", + "psysh" + ], + "support": { + "issues": "https://github.com/laravel/tinker/issues", + "source": "https://github.com/laravel/tinker/tree/v2.10.0" + }, + "time": "2024-09-23T13:32:56+00:00" + }, + { + "name": "league/commonmark", + "version": "2.5.3", + "source": { + "type": "git", + "url": "https://github.com/thephpleague/commonmark.git", + "reference": "b650144166dfa7703e62a22e493b853b58d874b0" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/thephpleague/commonmark/zipball/b650144166dfa7703e62a22e493b853b58d874b0", + "reference": "b650144166dfa7703e62a22e493b853b58d874b0", + "shasum": "" + }, + "require": { + "ext-mbstring": "*", + "league/config": "^1.1.1", + "php": "^7.4 || ^8.0", + "psr/event-dispatcher": "^1.0", + "symfony/deprecation-contracts": "^2.1 || ^3.0", + "symfony/polyfill-php80": "^1.16" + }, + "require-dev": { + "cebe/markdown": "^1.0", + "commonmark/cmark": "0.31.1", + "commonmark/commonmark.js": "0.31.1", + "composer/package-versions-deprecated": "^1.8", + "embed/embed": "^4.4", + "erusev/parsedown": "^1.0", + "ext-json": "*", + "github/gfm": "0.29.0", + "michelf/php-markdown": "^1.4 || ^2.0", + "nyholm/psr7": "^1.5", + "phpstan/phpstan": "^1.8.2", + "phpunit/phpunit": "^9.5.21 || ^10.5.9 || ^11.0.0", + "scrutinizer/ocular": "^1.8.1", + "symfony/finder": "^5.3 | ^6.0 || ^7.0", + "symfony/yaml": "^2.3 | ^3.0 | ^4.0 | ^5.0 | ^6.0 || ^7.0", + "unleashedtech/php-coding-standard": "^3.1.1", + "vimeo/psalm": "^4.24.0 || ^5.0.0" + }, + "suggest": { + "symfony/yaml": "v2.3+ required if using the Front Matter extension" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "2.6-dev" + } + }, + "autoload": { + "psr-4": { + "League\\CommonMark\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Colin O'Dell", + "email": "colinodell@gmail.com", + "homepage": "https://www.colinodell.com", + "role": "Lead Developer" + } + ], + "description": "Highly-extensible PHP Markdown parser which fully supports the CommonMark spec and GitHub-Flavored Markdown (GFM)", + "homepage": "https://commonmark.thephpleague.com", + "keywords": [ + "commonmark", + "flavored", + "gfm", + "github", + "github-flavored", + "markdown", + "md", + "parser" + ], + "support": { + "docs": "https://commonmark.thephpleague.com/", + "forum": "https://github.com/thephpleague/commonmark/discussions", + "issues": "https://github.com/thephpleague/commonmark/issues", + "rss": "https://github.com/thephpleague/commonmark/releases.atom", + "source": "https://github.com/thephpleague/commonmark" + }, + "funding": [ + { + "url": "https://www.colinodell.com/sponsor", + "type": "custom" + }, + { + "url": "https://www.paypal.me/colinpodell/10.00", + "type": "custom" + }, + { + "url": "https://github.com/colinodell", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/league/commonmark", + "type": "tidelift" + } + ], + "time": "2024-08-16T11:46:16+00:00" + }, + { + "name": "league/config", + "version": "v1.2.0", + "source": { + "type": "git", + "url": "https://github.com/thephpleague/config.git", + "reference": "754b3604fb2984c71f4af4a9cbe7b57f346ec1f3" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/thephpleague/config/zipball/754b3604fb2984c71f4af4a9cbe7b57f346ec1f3", + "reference": "754b3604fb2984c71f4af4a9cbe7b57f346ec1f3", + "shasum": "" + }, + "require": { + "dflydev/dot-access-data": "^3.0.1", + "nette/schema": "^1.2", + "php": "^7.4 || ^8.0" + }, + "require-dev": { + "phpstan/phpstan": "^1.8.2", + "phpunit/phpunit": "^9.5.5", + "scrutinizer/ocular": "^1.8.1", + "unleashedtech/php-coding-standard": "^3.1", + "vimeo/psalm": "^4.7.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "1.2-dev" + } + }, + "autoload": { + "psr-4": { + "League\\Config\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Colin O'Dell", + "email": "colinodell@gmail.com", + "homepage": "https://www.colinodell.com", + "role": "Lead Developer" + } + ], + "description": "Define configuration arrays with strict schemas and access values with dot notation", + "homepage": "https://config.thephpleague.com", + "keywords": [ + "array", + "config", + "configuration", + "dot", + "dot-access", + "nested", + "schema" + ], + "support": { + "docs": "https://config.thephpleague.com/", + "issues": "https://github.com/thephpleague/config/issues", + "rss": "https://github.com/thephpleague/config/releases.atom", + "source": "https://github.com/thephpleague/config" + }, + "funding": [ + { + "url": "https://www.colinodell.com/sponsor", + "type": "custom" + }, + { + "url": "https://www.paypal.me/colinpodell/10.00", + "type": "custom" + }, + { + "url": "https://github.com/colinodell", + "type": "github" + } + ], + "time": "2022-12-11T20:36:23+00:00" + }, + { + "name": "league/flysystem", + "version": "3.29.1", + "source": { + "type": "git", + "url": "https://github.com/thephpleague/flysystem.git", + "reference": "edc1bb7c86fab0776c3287dbd19b5fa278347319" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/thephpleague/flysystem/zipball/edc1bb7c86fab0776c3287dbd19b5fa278347319", + "reference": "edc1bb7c86fab0776c3287dbd19b5fa278347319", + "shasum": "" + }, + "require": { + "league/flysystem-local": "^3.0.0", + "league/mime-type-detection": "^1.0.0", + "php": "^8.0.2" + }, + "conflict": { + "async-aws/core": "<1.19.0", + "async-aws/s3": "<1.14.0", + "aws/aws-sdk-php": "3.209.31 || 3.210.0", + "guzzlehttp/guzzle": "<7.0", + "guzzlehttp/ringphp": "<1.1.1", + "phpseclib/phpseclib": "3.0.15", + "symfony/http-client": "<5.2" + }, + "require-dev": { + "async-aws/s3": "^1.5 || ^2.0", + "async-aws/simple-s3": "^1.1 || ^2.0", + "aws/aws-sdk-php": "^3.295.10", + "composer/semver": "^3.0", + "ext-fileinfo": "*", + "ext-ftp": "*", + "ext-mongodb": "^1.3", + "ext-zip": "*", + "friendsofphp/php-cs-fixer": "^3.5", + "google/cloud-storage": "^1.23", + "guzzlehttp/psr7": "^2.6", + "microsoft/azure-storage-blob": "^1.1", + "mongodb/mongodb": "^1.2", + "phpseclib/phpseclib": "^3.0.36", + "phpstan/phpstan": "^1.10", + "phpunit/phpunit": "^9.5.11|^10.0", + "sabre/dav": "^4.6.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "League\\Flysystem\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Frank de Jonge", + "email": "info@frankdejonge.nl" + } + ], + "description": "File storage abstraction for PHP", + "keywords": [ + "WebDAV", + "aws", + "cloud", + "file", + "files", + "filesystem", + "filesystems", + "ftp", + "s3", + "sftp", + "storage" + ], + "support": { + "issues": "https://github.com/thephpleague/flysystem/issues", + "source": "https://github.com/thephpleague/flysystem/tree/3.29.1" + }, + "time": "2024-10-08T08:58:34+00:00" + }, + { + "name": "league/flysystem-local", + "version": "3.29.0", + "source": { + "type": "git", + "url": "https://github.com/thephpleague/flysystem-local.git", + "reference": "e0e8d52ce4b2ed154148453d321e97c8e931bd27" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/thephpleague/flysystem-local/zipball/e0e8d52ce4b2ed154148453d321e97c8e931bd27", + "reference": "e0e8d52ce4b2ed154148453d321e97c8e931bd27", + "shasum": "" + }, + "require": { + "ext-fileinfo": "*", + "league/flysystem": "^3.0.0", + "league/mime-type-detection": "^1.0.0", + "php": "^8.0.2" + }, + "type": "library", + "autoload": { + "psr-4": { + "League\\Flysystem\\Local\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Frank de Jonge", + "email": "info@frankdejonge.nl" + } + ], + "description": "Local filesystem adapter for Flysystem.", + "keywords": [ + "Flysystem", + "file", + "files", + "filesystem", + "local" + ], + "support": { + "source": "https://github.com/thephpleague/flysystem-local/tree/3.29.0" + }, + "time": "2024-08-09T21:24:39+00:00" + }, + { + "name": "league/mime-type-detection", + "version": "1.16.0", + "source": { + "type": "git", + "url": "https://github.com/thephpleague/mime-type-detection.git", + "reference": "2d6702ff215bf922936ccc1ad31007edc76451b9" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/thephpleague/mime-type-detection/zipball/2d6702ff215bf922936ccc1ad31007edc76451b9", + "reference": "2d6702ff215bf922936ccc1ad31007edc76451b9", + "shasum": "" + }, + "require": { + "ext-fileinfo": "*", + "php": "^7.4 || ^8.0" + }, + "require-dev": { + "friendsofphp/php-cs-fixer": "^3.2", + "phpstan/phpstan": "^0.12.68", + "phpunit/phpunit": "^8.5.8 || ^9.3 || ^10.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "League\\MimeTypeDetection\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Frank de Jonge", + "email": "info@frankdejonge.nl" + } + ], + "description": "Mime-type detection for Flysystem", + "support": { + "issues": "https://github.com/thephpleague/mime-type-detection/issues", + "source": "https://github.com/thephpleague/mime-type-detection/tree/1.16.0" + }, + "funding": [ + { + "url": "https://github.com/frankdejonge", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/league/flysystem", + "type": "tidelift" + } + ], + "time": "2024-09-21T08:32:55+00:00" + }, + { + "name": "monolog/monolog", + "version": "3.8.0", + "source": { + "type": "git", + "url": "https://github.com/Seldaek/monolog.git", + "reference": "32e515fdc02cdafbe4593e30a9350d486b125b67" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/Seldaek/monolog/zipball/32e515fdc02cdafbe4593e30a9350d486b125b67", + "reference": "32e515fdc02cdafbe4593e30a9350d486b125b67", + "shasum": "" + }, + "require": { + "php": ">=8.1", + "psr/log": "^2.0 || ^3.0" + }, + "provide": { + "psr/log-implementation": "3.0.0" + }, + "require-dev": { + "aws/aws-sdk-php": "^3.0", + "doctrine/couchdb": "~1.0@dev", + "elasticsearch/elasticsearch": "^7 || ^8", + "ext-json": "*", + "graylog2/gelf-php": "^1.4.2 || ^2.0", + "guzzlehttp/guzzle": "^7.4.5", + "guzzlehttp/psr7": "^2.2", + "mongodb/mongodb": "^1.8", + "php-amqplib/php-amqplib": "~2.4 || ^3", + "php-console/php-console": "^3.1.8", + "phpstan/phpstan": "^2", + "phpstan/phpstan-deprecation-rules": "^2", + "phpstan/phpstan-strict-rules": "^2", + "phpunit/phpunit": "^10.5.17 || ^11.0.7", + "predis/predis": "^1.1 || ^2", + "rollbar/rollbar": "^4.0", + "ruflin/elastica": "^7 || ^8", + "symfony/mailer": "^5.4 || ^6", + "symfony/mime": "^5.4 || ^6" + }, + "suggest": { + "aws/aws-sdk-php": "Allow sending log messages to AWS services like DynamoDB", + "doctrine/couchdb": "Allow sending log messages to a CouchDB server", + "elasticsearch/elasticsearch": "Allow sending log messages to an Elasticsearch server via official client", + "ext-amqp": "Allow sending log messages to an AMQP server (1.0+ required)", + "ext-curl": "Required to send log messages using the IFTTTHandler, the LogglyHandler, the SendGridHandler, the SlackWebhookHandler or the TelegramBotHandler", + "ext-mbstring": "Allow to work properly with unicode symbols", + "ext-mongodb": "Allow sending log messages to a MongoDB server (via driver)", + "ext-openssl": "Required to send log messages using SSL", + "ext-sockets": "Allow sending log messages to a Syslog server (via UDP driver)", + "graylog2/gelf-php": "Allow sending log messages to a GrayLog2 server", + "mongodb/mongodb": "Allow sending log messages to a MongoDB server (via library)", + "php-amqplib/php-amqplib": "Allow sending log messages to an AMQP server using php-amqplib", + "rollbar/rollbar": "Allow sending log messages to Rollbar", + "ruflin/elastica": "Allow sending log messages to an Elastic Search server" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "3.x-dev" + } + }, + "autoload": { + "psr-4": { + "Monolog\\": "src/Monolog" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Jordi Boggiano", + "email": "j.boggiano@seld.be", + "homepage": "https://seld.be" + } + ], + "description": "Sends your logs to files, sockets, inboxes, databases and various web services", + "homepage": "https://github.com/Seldaek/monolog", + "keywords": [ + "log", + "logging", + "psr-3" + ], + "support": { + "issues": "https://github.com/Seldaek/monolog/issues", + "source": "https://github.com/Seldaek/monolog/tree/3.8.0" + }, + "funding": [ + { + "url": "https://github.com/Seldaek", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/monolog/monolog", + "type": "tidelift" + } + ], + "time": "2024-11-12T13:57:08+00:00" + }, + { + "name": "nesbot/carbon", + "version": "3.8.2", + "source": { + "type": "git", + "url": "https://github.com/briannesbitt/Carbon.git", + "reference": "e1268cdbc486d97ce23fef2c666dc3c6b6de9947" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/briannesbitt/Carbon/zipball/e1268cdbc486d97ce23fef2c666dc3c6b6de9947", + "reference": "e1268cdbc486d97ce23fef2c666dc3c6b6de9947", + "shasum": "" + }, + "require": { + "carbonphp/carbon-doctrine-types": "<100.0", + "ext-json": "*", + "php": "^8.1", + "psr/clock": "^1.0", + "symfony/clock": "^6.3 || ^7.0", + "symfony/polyfill-mbstring": "^1.0", + "symfony/translation": "^4.4.18 || ^5.2.1|| ^6.0 || ^7.0" + }, + "provide": { + "psr/clock-implementation": "1.0" + }, + "require-dev": { + "doctrine/dbal": "^3.6.3 || ^4.0", + "doctrine/orm": "^2.15.2 || ^3.0", + "friendsofphp/php-cs-fixer": "^3.57.2", + "kylekatarnls/multi-tester": "^2.5.3", + "ondrejmirtes/better-reflection": "^6.25.0.4", + "phpmd/phpmd": "^2.15.0", + "phpstan/extension-installer": "^1.3.1", + "phpstan/phpstan": "^1.11.2", + "phpunit/phpunit": "^10.5.20", + "squizlabs/php_codesniffer": "^3.9.0" + }, + "bin": [ + "bin/carbon" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.x-dev", + "dev-2.x": "2.x-dev" + }, + "laravel": { + "providers": [ + "Carbon\\Laravel\\ServiceProvider" + ] + }, + "phpstan": { + "includes": [ + "extension.neon" + ] + } + }, + "autoload": { + "psr-4": { + "Carbon\\": "src/Carbon/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Brian Nesbitt", + "email": "brian@nesbot.com", + "homepage": "https://markido.com" + }, + { + "name": "kylekatarnls", + "homepage": "https://github.com/kylekatarnls" + } + ], + "description": "An API extension for DateTime that supports 281 different languages.", + "homepage": "https://carbon.nesbot.com", + "keywords": [ + "date", + "datetime", + "time" + ], + "support": { + "docs": "https://carbon.nesbot.com/docs", + "issues": "https://github.com/briannesbitt/Carbon/issues", + "source": "https://github.com/briannesbitt/Carbon" + }, + "funding": [ + { + "url": "https://github.com/sponsors/kylekatarnls", + "type": "github" + }, + { + "url": "https://opencollective.com/Carbon#sponsor", + "type": "opencollective" + }, + { + "url": "https://tidelift.com/subscription/pkg/packagist-nesbot-carbon?utm_source=packagist-nesbot-carbon&utm_medium=referral&utm_campaign=readme", + "type": "tidelift" + } + ], + "time": "2024-11-07T17:46:48+00:00" + }, + { + "name": "nette/schema", + "version": "v1.3.2", + "source": { + "type": "git", + "url": "https://github.com/nette/schema.git", + "reference": "da801d52f0354f70a638673c4a0f04e16529431d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/nette/schema/zipball/da801d52f0354f70a638673c4a0f04e16529431d", + "reference": "da801d52f0354f70a638673c4a0f04e16529431d", + "shasum": "" + }, + "require": { + "nette/utils": "^4.0", + "php": "8.1 - 8.4" + }, + "require-dev": { + "nette/tester": "^2.5.2", + "phpstan/phpstan-nette": "^1.0", + "tracy/tracy": "^2.8" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.3-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause", + "GPL-2.0-only", + "GPL-3.0-only" + ], + "authors": [ + { + "name": "David Grudl", + "homepage": "https://davidgrudl.com" + }, + { + "name": "Nette Community", + "homepage": "https://nette.org/contributors" + } + ], + "description": "📐 Nette Schema: validating data structures against a given Schema.", + "homepage": "https://nette.org", + "keywords": [ + "config", + "nette" + ], + "support": { + "issues": "https://github.com/nette/schema/issues", + "source": "https://github.com/nette/schema/tree/v1.3.2" + }, + "time": "2024-10-06T23:10:23+00:00" + }, + { + "name": "nette/utils", + "version": "v4.0.5", + "source": { + "type": "git", + "url": "https://github.com/nette/utils.git", + "reference": "736c567e257dbe0fcf6ce81b4d6dbe05c6899f96" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/nette/utils/zipball/736c567e257dbe0fcf6ce81b4d6dbe05c6899f96", + "reference": "736c567e257dbe0fcf6ce81b4d6dbe05c6899f96", + "shasum": "" + }, + "require": { + "php": "8.0 - 8.4" + }, + "conflict": { + "nette/finder": "<3", + "nette/schema": "<1.2.2" + }, + "require-dev": { + "jetbrains/phpstorm-attributes": "dev-master", + "nette/tester": "^2.5", + "phpstan/phpstan": "^1.0", + "tracy/tracy": "^2.9" + }, + "suggest": { + "ext-gd": "to use Image", + "ext-iconv": "to use Strings::webalize(), toAscii(), chr() and reverse()", + "ext-intl": "to use Strings::webalize(), toAscii(), normalize() and compare()", + "ext-json": "to use Nette\\Utils\\Json", + "ext-mbstring": "to use Strings::lower() etc...", + "ext-tokenizer": "to use Nette\\Utils\\Reflection::getUseStatements()" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause", + "GPL-2.0-only", + "GPL-3.0-only" + ], + "authors": [ + { + "name": "David Grudl", + "homepage": "https://davidgrudl.com" + }, + { + "name": "Nette Community", + "homepage": "https://nette.org/contributors" + } + ], + "description": "🛠 Nette Utils: lightweight utilities for string & array manipulation, image handling, safe JSON encoding/decoding, validation, slug or strong password generating etc.", + "homepage": "https://nette.org", + "keywords": [ + "array", + "core", + "datetime", + "images", + "json", + "nette", + "paginator", + "password", + "slugify", + "string", + "unicode", + "utf-8", + "utility", + "validation" + ], + "support": { + "issues": "https://github.com/nette/utils/issues", + "source": "https://github.com/nette/utils/tree/v4.0.5" + }, + "time": "2024-08-07T15:39:19+00:00" + }, + { + "name": "nikic/php-parser", + "version": "v5.3.1", + "source": { + "type": "git", + "url": "https://github.com/nikic/PHP-Parser.git", + "reference": "8eea230464783aa9671db8eea6f8c6ac5285794b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/8eea230464783aa9671db8eea6f8c6ac5285794b", + "reference": "8eea230464783aa9671db8eea6f8c6ac5285794b", + "shasum": "" + }, + "require": { + "ext-ctype": "*", + "ext-json": "*", + "ext-tokenizer": "*", + "php": ">=7.4" + }, + "require-dev": { + "ircmaxell/php-yacc": "^0.0.7", + "phpunit/phpunit": "^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.3.1" + }, + "time": "2024-10-08T18:51:32+00:00" + }, + { + "name": "nunomaduro/termwind", + "version": "v2.3.0", + "source": { + "type": "git", + "url": "https://github.com/nunomaduro/termwind.git", + "reference": "52915afe6a1044e8b9cee1bcff836fb63acf9cda" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/nunomaduro/termwind/zipball/52915afe6a1044e8b9cee1bcff836fb63acf9cda", + "reference": "52915afe6a1044e8b9cee1bcff836fb63acf9cda", + "shasum": "" + }, + "require": { + "ext-mbstring": "*", + "php": "^8.2", + "symfony/console": "^7.1.8" + }, + "require-dev": { + "illuminate/console": "^11.33.2", + "laravel/pint": "^1.18.2", + "mockery/mockery": "^1.6.12", + "pestphp/pest": "^2.36.0", + "phpstan/phpstan": "^1.12.11", + "phpstan/phpstan-strict-rules": "^1.6.1", + "symfony/var-dumper": "^7.1.8", + "thecodingmachine/phpstan-strict-rules": "^1.0.0" + }, + "type": "library", + "extra": { + "laravel": { + "providers": [ + "Termwind\\Laravel\\TermwindServiceProvider" + ] + }, + "branch-alias": { + "dev-2.x": "2.x-dev" + } + }, + "autoload": { + "files": [ + "src/Functions.php" + ], + "psr-4": { + "Termwind\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nuno Maduro", + "email": "enunomaduro@gmail.com" + } + ], + "description": "Its like Tailwind CSS, but for the console.", + "keywords": [ + "cli", + "console", + "css", + "package", + "php", + "style" + ], + "support": { + "issues": "https://github.com/nunomaduro/termwind/issues", + "source": "https://github.com/nunomaduro/termwind/tree/v2.3.0" + }, + "funding": [ + { + "url": "https://www.paypal.com/paypalme/enunomaduro", + "type": "custom" + }, + { + "url": "https://github.com/nunomaduro", + "type": "github" + }, + { + "url": "https://github.com/xiCO2k", + "type": "github" + } + ], + "time": "2024-11-21T10:39:51+00:00" + }, + { + "name": "phpoption/phpoption", + "version": "1.9.3", + "source": { + "type": "git", + "url": "https://github.com/schmittjoh/php-option.git", + "reference": "e3fac8b24f56113f7cb96af14958c0dd16330f54" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/schmittjoh/php-option/zipball/e3fac8b24f56113f7cb96af14958c0dd16330f54", + "reference": "e3fac8b24f56113f7cb96af14958c0dd16330f54", + "shasum": "" + }, + "require": { + "php": "^7.2.5 || ^8.0" + }, + "require-dev": { + "bamarni/composer-bin-plugin": "^1.8.2", + "phpunit/phpunit": "^8.5.39 || ^9.6.20 || ^10.5.28" + }, + "type": "library", + "extra": { + "bamarni-bin": { + "bin-links": true, + "forward-command": false + }, + "branch-alias": { + "dev-master": "1.9-dev" + } + }, + "autoload": { + "psr-4": { + "PhpOption\\": "src/PhpOption/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "Apache-2.0" + ], + "authors": [ + { + "name": "Johannes M. Schmitt", + "email": "schmittjoh@gmail.com", + "homepage": "https://github.com/schmittjoh" + }, + { + "name": "Graham Campbell", + "email": "hello@gjcampbell.co.uk", + "homepage": "https://github.com/GrahamCampbell" + } + ], + "description": "Option Type for PHP", + "keywords": [ + "language", + "option", + "php", + "type" + ], + "support": { + "issues": "https://github.com/schmittjoh/php-option/issues", + "source": "https://github.com/schmittjoh/php-option/tree/1.9.3" + }, + "funding": [ + { + "url": "https://github.com/GrahamCampbell", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/phpoption/phpoption", + "type": "tidelift" + } + ], + "time": "2024-07-20T21:41:07+00:00" + }, + { + "name": "psr/clock", + "version": "1.0.0", + "source": { + "type": "git", + "url": "https://github.com/php-fig/clock.git", + "reference": "e41a24703d4560fd0acb709162f73b8adfc3aa0d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/clock/zipball/e41a24703d4560fd0acb709162f73b8adfc3aa0d", + "reference": "e41a24703d4560fd0acb709162f73b8adfc3aa0d", + "shasum": "" + }, + "require": { + "php": "^7.0 || ^8.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Psr\\Clock\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "https://www.php-fig.org/" + } + ], + "description": "Common interface for reading the clock.", + "homepage": "https://github.com/php-fig/clock", + "keywords": [ + "clock", + "now", + "psr", + "psr-20", + "time" + ], + "support": { + "issues": "https://github.com/php-fig/clock/issues", + "source": "https://github.com/php-fig/clock/tree/1.0.0" + }, + "time": "2022-11-25T14:36:26+00:00" + }, + { + "name": "psr/container", + "version": "2.0.2", + "source": { + "type": "git", + "url": "https://github.com/php-fig/container.git", + "reference": "c71ecc56dfe541dbd90c5360474fbc405f8d5963" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/container/zipball/c71ecc56dfe541dbd90c5360474fbc405f8d5963", + "reference": "c71ecc56dfe541dbd90c5360474fbc405f8d5963", + "shasum": "" + }, + "require": { + "php": ">=7.4.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Container\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "https://www.php-fig.org/" + } + ], + "description": "Common Container Interface (PHP FIG PSR-11)", + "homepage": "https://github.com/php-fig/container", + "keywords": [ + "PSR-11", + "container", + "container-interface", + "container-interop", + "psr" + ], + "support": { + "issues": "https://github.com/php-fig/container/issues", + "source": "https://github.com/php-fig/container/tree/2.0.2" + }, + "time": "2021-11-05T16:47:00+00:00" + }, + { + "name": "psr/event-dispatcher", + "version": "1.0.0", + "source": { + "type": "git", + "url": "https://github.com/php-fig/event-dispatcher.git", + "reference": "dbefd12671e8a14ec7f180cab83036ed26714bb0" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/event-dispatcher/zipball/dbefd12671e8a14ec7f180cab83036ed26714bb0", + "reference": "dbefd12671e8a14ec7f180cab83036ed26714bb0", + "shasum": "" + }, + "require": { + "php": ">=7.2.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\EventDispatcher\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "http://www.php-fig.org/" + } + ], + "description": "Standard interfaces for event handling.", + "keywords": [ + "events", + "psr", + "psr-14" + ], + "support": { + "issues": "https://github.com/php-fig/event-dispatcher/issues", + "source": "https://github.com/php-fig/event-dispatcher/tree/1.0.0" + }, + "time": "2019-01-08T18:20:26+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.1.0", + "source": { + "type": "git", + "url": "https://github.com/php-fig/http-factory.git", + "reference": "2b4765fddfe3b508ac62f829e852b1501d3f6e8a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/http-factory/zipball/2b4765fddfe3b508ac62f829e852b1501d3f6e8a", + "reference": "2b4765fddfe3b508ac62f829e852b1501d3f6e8a", + "shasum": "" + }, + "require": { + "php": ">=7.1", + "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": "PSR-17: 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" + }, + "time": "2024-04-15T12:06:14+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" + }, + { + "name": "psr/log", + "version": "3.0.2", + "source": { + "type": "git", + "url": "https://github.com/php-fig/log.git", + "reference": "f16e1d5863e37f8d8c2a01719f5b34baa2b714d3" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/log/zipball/f16e1d5863e37f8d8c2a01719f5b34baa2b714d3", + "reference": "f16e1d5863e37f8d8c2a01719f5b34baa2b714d3", + "shasum": "" + }, + "require": { + "php": ">=8.0.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Log\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "https://www.php-fig.org/" + } + ], + "description": "Common interface for logging libraries", + "homepage": "https://github.com/php-fig/log", + "keywords": [ + "log", + "psr", + "psr-3" + ], + "support": { + "source": "https://github.com/php-fig/log/tree/3.0.2" + }, + "time": "2024-09-11T13:17:53+00:00" + }, + { + "name": "psr/simple-cache", + "version": "3.0.0", + "source": { + "type": "git", + "url": "https://github.com/php-fig/simple-cache.git", + "reference": "764e0b3939f5ca87cb904f570ef9be2d78a07865" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/simple-cache/zipball/764e0b3939f5ca87cb904f570ef9be2d78a07865", + "reference": "764e0b3939f5ca87cb904f570ef9be2d78a07865", + "shasum": "" + }, + "require": { + "php": ">=8.0.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\SimpleCache\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "https://www.php-fig.org/" + } + ], + "description": "Common interfaces for simple caching", + "keywords": [ + "cache", + "caching", + "psr", + "psr-16", + "simple-cache" + ], + "support": { + "source": "https://github.com/php-fig/simple-cache/tree/3.0.0" + }, + "time": "2021-10-29T13:26:27+00:00" + }, + { + "name": "psy/psysh", + "version": "v0.12.5", + "source": { + "type": "git", + "url": "https://github.com/bobthecow/psysh.git", + "reference": "36a03ff27986682c22985e56aabaf840dd173cb5" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/bobthecow/psysh/zipball/36a03ff27986682c22985e56aabaf840dd173cb5", + "reference": "36a03ff27986682c22985e56aabaf840dd173cb5", + "shasum": "" + }, + "require": { + "ext-json": "*", + "ext-tokenizer": "*", + "nikic/php-parser": "^5.0 || ^4.0", + "php": "^8.0 || ^7.4", + "symfony/console": "^7.0 || ^6.0 || ^5.0 || ^4.0 || ^3.4", + "symfony/var-dumper": "^7.0 || ^6.0 || ^5.0 || ^4.0 || ^3.4" + }, + "conflict": { + "symfony/console": "4.4.37 || 5.3.14 || 5.3.15 || 5.4.3 || 5.4.4 || 6.0.3 || 6.0.4" + }, + "require-dev": { + "bamarni/composer-bin-plugin": "^1.2" + }, + "suggest": { + "ext-pcntl": "Enabling the PCNTL extension makes PsySH a lot happier :)", + "ext-pdo-sqlite": "The doc command requires SQLite to work.", + "ext-posix": "If you have PCNTL, you'll want the POSIX extension as well." + }, + "bin": [ + "bin/psysh" + ], + "type": "library", + "extra": { + "bamarni-bin": { + "bin-links": false, + "forward-command": false + }, + "branch-alias": { + "dev-main": "0.12.x-dev" + } + }, + "autoload": { + "files": [ + "src/functions.php" + ], + "psr-4": { + "Psy\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Justin Hileman", + "email": "justin@justinhileman.info", + "homepage": "http://justinhileman.com" + } + ], + "description": "An interactive shell for modern PHP.", + "homepage": "http://psysh.org", + "keywords": [ + "REPL", + "console", + "interactive", + "shell" + ], + "support": { + "issues": "https://github.com/bobthecow/psysh/issues", + "source": "https://github.com/bobthecow/psysh/tree/v0.12.5" + }, + "time": "2024-11-29T06:14:30+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.6", + "source": { + "type": "git", + "url": "https://github.com/ramsey/uuid.git", + "reference": "91039bc1faa45ba123c4328958e620d382ec7088" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/ramsey/uuid/zipball/91039bc1faa45ba123c4328958e620d382ec7088", + "reference": "91039bc1faa45ba123c4328958e620d382ec7088", + "shasum": "" + }, + "require": { + "brick/math": "^0.8.8 || ^0.9 || ^0.10 || ^0.11 || ^0.12", + "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.6" + }, + "funding": [ + { + "url": "https://github.com/ramsey", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/ramsey/uuid", + "type": "tidelift" + } + ], + "time": "2024-04-27T21:32:50+00:00" + }, + { + "name": "symfony/clock", + "version": "v7.2.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/clock.git", + "reference": "b81435fbd6648ea425d1ee96a2d8e68f4ceacd24" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/clock/zipball/b81435fbd6648ea425d1ee96a2d8e68f4ceacd24", + "reference": "b81435fbd6648ea425d1ee96a2d8e68f4ceacd24", + "shasum": "" + }, + "require": { + "php": ">=8.2", + "psr/clock": "^1.0", + "symfony/polyfill-php83": "^1.28" + }, + "provide": { + "psr/clock-implementation": "1.0" + }, + "type": "library", + "autoload": { + "files": [ + "Resources/now.php" + ], + "psr-4": { + "Symfony\\Component\\Clock\\": "" + }, + "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": "Decouples applications from the system clock", + "homepage": "https://symfony.com", + "keywords": [ + "clock", + "psr20", + "time" + ], + "support": { + "source": "https://github.com/symfony/clock/tree/v7.2.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-09-25T14:21:43+00:00" + }, + { + "name": "symfony/console", + "version": "v7.2.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/console.git", + "reference": "23c8aae6d764e2bae02d2a99f7532a7f6ed619cf" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/console/zipball/23c8aae6d764e2bae02d2a99f7532a7f6ed619cf", + "reference": "23c8aae6d764e2bae02d2a99f7532a7f6ed619cf", + "shasum": "" + }, + "require": { + "php": ">=8.2", + "symfony/polyfill-mbstring": "~1.0", + "symfony/service-contracts": "^2.5|^3", + "symfony/string": "^6.4|^7.0" + }, + "conflict": { + "symfony/dependency-injection": "<6.4", + "symfony/dotenv": "<6.4", + "symfony/event-dispatcher": "<6.4", + "symfony/lock": "<6.4", + "symfony/process": "<6.4" + }, + "provide": { + "psr/log-implementation": "1.0|2.0|3.0" + }, + "require-dev": { + "psr/log": "^1|^2|^3", + "symfony/config": "^6.4|^7.0", + "symfony/dependency-injection": "^6.4|^7.0", + "symfony/event-dispatcher": "^6.4|^7.0", + "symfony/http-foundation": "^6.4|^7.0", + "symfony/http-kernel": "^6.4|^7.0", + "symfony/lock": "^6.4|^7.0", + "symfony/messenger": "^6.4|^7.0", + "symfony/process": "^6.4|^7.0", + "symfony/stopwatch": "^6.4|^7.0", + "symfony/var-dumper": "^6.4|^7.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\Console\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Eases the creation of beautiful and testable command line interfaces", + "homepage": "https://symfony.com", + "keywords": [ + "cli", + "command-line", + "console", + "terminal" + ], + "support": { + "source": "https://github.com/symfony/console/tree/v7.2.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-11-06T14:24:19+00:00" + }, + { + "name": "symfony/css-selector", + "version": "v7.2.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/css-selector.git", + "reference": "601a5ce9aaad7bf10797e3663faefce9e26c24e2" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/css-selector/zipball/601a5ce9aaad7bf10797e3663faefce9e26c24e2", + "reference": "601a5ce9aaad7bf10797e3663faefce9e26c24e2", + "shasum": "" + }, + "require": { + "php": ">=8.2" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\CssSelector\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Jean-François Simon", + "email": "jeanfrancois.simon@sensiolabs.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Converts CSS selectors to XPath expressions", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/css-selector/tree/v7.2.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-09-25T14:21:43+00:00" + }, + { + "name": "symfony/deprecation-contracts", + "version": "v3.5.1", + "source": { + "type": "git", + "url": "https://github.com/symfony/deprecation-contracts.git", + "reference": "74c71c939a79f7d5bf3c1ce9f5ea37ba0114c6f6" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/74c71c939a79f7d5bf3c1ce9f5ea37ba0114c6f6", + "reference": "74c71c939a79f7d5bf3c1ce9f5ea37ba0114c6f6", + "shasum": "" + }, + "require": { + "php": ">=8.1" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "3.5-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.5.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": "2024-09-25T14:20:29+00:00" + }, + { + "name": "symfony/error-handler", + "version": "v7.2.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/error-handler.git", + "reference": "672b3dd1ef8b87119b446d67c58c106c43f965fe" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/error-handler/zipball/672b3dd1ef8b87119b446d67c58c106c43f965fe", + "reference": "672b3dd1ef8b87119b446d67c58c106c43f965fe", + "shasum": "" + }, + "require": { + "php": ">=8.2", + "psr/log": "^1|^2|^3", + "symfony/var-dumper": "^6.4|^7.0" + }, + "conflict": { + "symfony/deprecation-contracts": "<2.5", + "symfony/http-kernel": "<6.4" + }, + "require-dev": { + "symfony/deprecation-contracts": "^2.5|^3", + "symfony/http-kernel": "^6.4|^7.0", + "symfony/serializer": "^6.4|^7.0" + }, + "bin": [ + "Resources/bin/patch-type-declarations" + ], + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\ErrorHandler\\": "" + }, + "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 tools to manage errors and ease debugging PHP code", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/error-handler/tree/v7.2.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-11-05T15:35:02+00:00" + }, + { + "name": "symfony/event-dispatcher", + "version": "v7.2.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/event-dispatcher.git", + "reference": "910c5db85a5356d0fea57680defec4e99eb9c8c1" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/910c5db85a5356d0fea57680defec4e99eb9c8c1", + "reference": "910c5db85a5356d0fea57680defec4e99eb9c8c1", + "shasum": "" + }, + "require": { + "php": ">=8.2", + "symfony/event-dispatcher-contracts": "^2.5|^3" + }, + "conflict": { + "symfony/dependency-injection": "<6.4", + "symfony/service-contracts": "<2.5" + }, + "provide": { + "psr/event-dispatcher-implementation": "1.0", + "symfony/event-dispatcher-implementation": "2.0|3.0" + }, + "require-dev": { + "psr/log": "^1|^2|^3", + "symfony/config": "^6.4|^7.0", + "symfony/dependency-injection": "^6.4|^7.0", + "symfony/error-handler": "^6.4|^7.0", + "symfony/expression-language": "^6.4|^7.0", + "symfony/http-foundation": "^6.4|^7.0", + "symfony/service-contracts": "^2.5|^3", + "symfony/stopwatch": "^6.4|^7.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\EventDispatcher\\": "" + }, + "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 tools that allow your application components to communicate with each other by dispatching events and listening to them", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/event-dispatcher/tree/v7.2.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-09-25T14:21:43+00:00" + }, + { + "name": "symfony/event-dispatcher-contracts", + "version": "v3.5.1", + "source": { + "type": "git", + "url": "https://github.com/symfony/event-dispatcher-contracts.git", + "reference": "7642f5e970b672283b7823222ae8ef8bbc160b9f" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/event-dispatcher-contracts/zipball/7642f5e970b672283b7823222ae8ef8bbc160b9f", + "reference": "7642f5e970b672283b7823222ae8ef8bbc160b9f", + "shasum": "" + }, + "require": { + "php": ">=8.1", + "psr/event-dispatcher": "^1" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "3.5-dev" + }, + "thanks": { + "name": "symfony/contracts", + "url": "https://github.com/symfony/contracts" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Contracts\\EventDispatcher\\": "" + } + }, + "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 dispatching event", + "homepage": "https://symfony.com", + "keywords": [ + "abstractions", + "contracts", + "decoupling", + "interfaces", + "interoperability", + "standards" + ], + "support": { + "source": "https://github.com/symfony/event-dispatcher-contracts/tree/v3.5.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": "2024-09-25T14:20:29+00:00" + }, + { + "name": "symfony/finder", + "version": "v7.2.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/finder.git", + "reference": "6de263e5868b9a137602dd1e33e4d48bfae99c49" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/finder/zipball/6de263e5868b9a137602dd1e33e4d48bfae99c49", + "reference": "6de263e5868b9a137602dd1e33e4d48bfae99c49", + "shasum": "" + }, + "require": { + "php": ">=8.2" + }, + "require-dev": { + "symfony/filesystem": "^6.4|^7.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\Finder\\": "" + }, + "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": "Finds files and directories via an intuitive fluent interface", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/finder/tree/v7.2.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-10-23T06:56:12+00:00" + }, + { + "name": "symfony/http-foundation", + "version": "v7.2.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/http-foundation.git", + "reference": "e88a66c3997859532bc2ddd6dd8f35aba2711744" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/http-foundation/zipball/e88a66c3997859532bc2ddd6dd8f35aba2711744", + "reference": "e88a66c3997859532bc2ddd6dd8f35aba2711744", + "shasum": "" + }, + "require": { + "php": ">=8.2", + "symfony/deprecation-contracts": "^2.5|^3.0", + "symfony/polyfill-mbstring": "~1.1", + "symfony/polyfill-php83": "^1.27" + }, + "conflict": { + "doctrine/dbal": "<3.6", + "symfony/cache": "<6.4.12|>=7.0,<7.1.5" + }, + "require-dev": { + "doctrine/dbal": "^3.6|^4", + "predis/predis": "^1.1|^2.0", + "symfony/cache": "^6.4.12|^7.1.5", + "symfony/dependency-injection": "^6.4|^7.0", + "symfony/expression-language": "^6.4|^7.0", + "symfony/http-kernel": "^6.4|^7.0", + "symfony/mime": "^6.4|^7.0", + "symfony/rate-limiter": "^6.4|^7.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\HttpFoundation\\": "" + }, + "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": "Defines an object-oriented layer for the HTTP specification", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/http-foundation/tree/v7.2.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-11-13T18:58:46+00:00" + }, + { + "name": "symfony/http-kernel", + "version": "v7.2.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/http-kernel.git", + "reference": "6b4722a25e0aed1ccb4914b9bcbd493cc4676b4d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/http-kernel/zipball/6b4722a25e0aed1ccb4914b9bcbd493cc4676b4d", + "reference": "6b4722a25e0aed1ccb4914b9bcbd493cc4676b4d", + "shasum": "" + }, + "require": { + "php": ">=8.2", + "psr/log": "^1|^2|^3", + "symfony/deprecation-contracts": "^2.5|^3", + "symfony/error-handler": "^6.4|^7.0", + "symfony/event-dispatcher": "^6.4|^7.0", + "symfony/http-foundation": "^6.4|^7.0", + "symfony/polyfill-ctype": "^1.8" + }, + "conflict": { + "symfony/browser-kit": "<6.4", + "symfony/cache": "<6.4", + "symfony/config": "<6.4", + "symfony/console": "<6.4", + "symfony/dependency-injection": "<6.4", + "symfony/doctrine-bridge": "<6.4", + "symfony/form": "<6.4", + "symfony/http-client": "<6.4", + "symfony/http-client-contracts": "<2.5", + "symfony/mailer": "<6.4", + "symfony/messenger": "<6.4", + "symfony/translation": "<6.4", + "symfony/translation-contracts": "<2.5", + "symfony/twig-bridge": "<6.4", + "symfony/validator": "<6.4", + "symfony/var-dumper": "<6.4", + "twig/twig": "<3.12" + }, + "provide": { + "psr/log-implementation": "1.0|2.0|3.0" + }, + "require-dev": { + "psr/cache": "^1.0|^2.0|^3.0", + "symfony/browser-kit": "^6.4|^7.0", + "symfony/clock": "^6.4|^7.0", + "symfony/config": "^6.4|^7.0", + "symfony/console": "^6.4|^7.0", + "symfony/css-selector": "^6.4|^7.0", + "symfony/dependency-injection": "^6.4|^7.0", + "symfony/dom-crawler": "^6.4|^7.0", + "symfony/expression-language": "^6.4|^7.0", + "symfony/finder": "^6.4|^7.0", + "symfony/http-client-contracts": "^2.5|^3", + "symfony/process": "^6.4|^7.0", + "symfony/property-access": "^7.1", + "symfony/routing": "^6.4|^7.0", + "symfony/serializer": "^7.1", + "symfony/stopwatch": "^6.4|^7.0", + "symfony/translation": "^6.4|^7.0", + "symfony/translation-contracts": "^2.5|^3", + "symfony/uid": "^6.4|^7.0", + "symfony/validator": "^6.4|^7.0", + "symfony/var-dumper": "^6.4|^7.0", + "symfony/var-exporter": "^6.4|^7.0", + "twig/twig": "^3.12" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\HttpKernel\\": "" + }, + "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 structured process for converting a Request into a Response", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/http-kernel/tree/v7.2.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-11-29T08:42:40+00:00" + }, + { + "name": "symfony/mailer", + "version": "v7.2.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/mailer.git", + "reference": "e4d358702fb66e4c8a2af08e90e7271a62de39cc" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/mailer/zipball/e4d358702fb66e4c8a2af08e90e7271a62de39cc", + "reference": "e4d358702fb66e4c8a2af08e90e7271a62de39cc", + "shasum": "" + }, + "require": { + "egulias/email-validator": "^2.1.10|^3|^4", + "php": ">=8.2", + "psr/event-dispatcher": "^1", + "psr/log": "^1|^2|^3", + "symfony/event-dispatcher": "^6.4|^7.0", + "symfony/mime": "^7.2", + "symfony/service-contracts": "^2.5|^3" + }, + "conflict": { + "symfony/http-client-contracts": "<2.5", + "symfony/http-kernel": "<6.4", + "symfony/messenger": "<6.4", + "symfony/mime": "<6.4", + "symfony/twig-bridge": "<6.4" + }, + "require-dev": { + "symfony/console": "^6.4|^7.0", + "symfony/http-client": "^6.4|^7.0", + "symfony/messenger": "^6.4|^7.0", + "symfony/twig-bridge": "^6.4|^7.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\Mailer\\": "" + }, + "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": "Helps sending emails", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/mailer/tree/v7.2.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-11-25T15:21:05+00:00" + }, + { + "name": "symfony/mime", + "version": "v7.2.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/mime.git", + "reference": "cc84a4b81f62158c3846ac7ff10f696aae2b524d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/mime/zipball/cc84a4b81f62158c3846ac7ff10f696aae2b524d", + "reference": "cc84a4b81f62158c3846ac7ff10f696aae2b524d", + "shasum": "" + }, + "require": { + "php": ">=8.2", + "symfony/polyfill-intl-idn": "^1.10", + "symfony/polyfill-mbstring": "^1.0" + }, + "conflict": { + "egulias/email-validator": "~3.0.0", + "phpdocumentor/reflection-docblock": "<3.2.2", + "phpdocumentor/type-resolver": "<1.4.0", + "symfony/mailer": "<6.4", + "symfony/serializer": "<6.4.3|>7.0,<7.0.3" + }, + "require-dev": { + "egulias/email-validator": "^2.1.10|^3.1|^4", + "league/html-to-markdown": "^5.0", + "phpdocumentor/reflection-docblock": "^3.0|^4.0|^5.0", + "symfony/dependency-injection": "^6.4|^7.0", + "symfony/process": "^6.4|^7.0", + "symfony/property-access": "^6.4|^7.0", + "symfony/property-info": "^6.4|^7.0", + "symfony/serializer": "^6.4.3|^7.0.3" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\Mime\\": "" + }, + "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": "Allows manipulating MIME messages", + "homepage": "https://symfony.com", + "keywords": [ + "mime", + "mime-type" + ], + "support": { + "source": "https://github.com/symfony/mime/tree/v7.2.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-11-23T09:19:39+00:00" + }, + { + "name": "symfony/polyfill-ctype", + "version": "v1.31.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-ctype.git", + "reference": "a3cc8b044a6ea513310cbd48ef7333b384945638" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/a3cc8b044a6ea513310cbd48ef7333b384945638", + "reference": "a3cc8b044a6ea513310cbd48ef7333b384945638", + "shasum": "" + }, + "require": { + "php": ">=7.2" + }, + "provide": { + "ext-ctype": "*" + }, + "suggest": { + "ext-ctype": "For best performance" + }, + "type": "library", + "extra": { + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Ctype\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Gert de Pagter", + "email": "BackEndTea@gmail.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill for ctype functions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "ctype", + "polyfill", + "portable" + ], + "support": { + "source": "https://github.com/symfony/polyfill-ctype/tree/v1.31.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-09-09T11:45:10+00:00" + }, + { + "name": "symfony/polyfill-intl-grapheme", + "version": "v1.31.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-intl-grapheme.git", + "reference": "b9123926e3b7bc2f98c02ad54f6a4b02b91a8abe" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-intl-grapheme/zipball/b9123926e3b7bc2f98c02ad54f6a4b02b91a8abe", + "reference": "b9123926e3b7bc2f98c02ad54f6a4b02b91a8abe", + "shasum": "" + }, + "require": { + "php": ">=7.2" + }, + "suggest": { + "ext-intl": "For best performance" + }, + "type": "library", + "extra": { + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Intl\\Grapheme\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill for intl's grapheme_* functions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "grapheme", + "intl", + "polyfill", + "portable", + "shim" + ], + "support": { + "source": "https://github.com/symfony/polyfill-intl-grapheme/tree/v1.31.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-09-09T11:45:10+00:00" + }, + { + "name": "symfony/polyfill-intl-idn", + "version": "v1.31.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-intl-idn.git", + "reference": "c36586dcf89a12315939e00ec9b4474adcb1d773" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-intl-idn/zipball/c36586dcf89a12315939e00ec9b4474adcb1d773", + "reference": "c36586dcf89a12315939e00ec9b4474adcb1d773", + "shasum": "" + }, + "require": { + "php": ">=7.2", + "symfony/polyfill-intl-normalizer": "^1.10" + }, + "suggest": { + "ext-intl": "For best performance" + }, + "type": "library", + "extra": { + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Intl\\Idn\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Laurent Bassin", + "email": "laurent@bassin.info" + }, + { + "name": "Trevor Rowbotham", + "email": "trevor.rowbotham@pm.me" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill for intl's idn_to_ascii and idn_to_utf8 functions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "idn", + "intl", + "polyfill", + "portable", + "shim" + ], + "support": { + "source": "https://github.com/symfony/polyfill-intl-idn/tree/v1.31.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-09-09T11:45:10+00:00" + }, + { + "name": "symfony/polyfill-intl-normalizer", + "version": "v1.31.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-intl-normalizer.git", + "reference": "3833d7255cc303546435cb650316bff708a1c75c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-intl-normalizer/zipball/3833d7255cc303546435cb650316bff708a1c75c", + "reference": "3833d7255cc303546435cb650316bff708a1c75c", + "shasum": "" + }, + "require": { + "php": ">=7.2" + }, + "suggest": { + "ext-intl": "For best performance" + }, + "type": "library", + "extra": { + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Intl\\Normalizer\\": "" + }, + "classmap": [ + "Resources/stubs" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill for intl's Normalizer class and related functions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "intl", + "normalizer", + "polyfill", + "portable", + "shim" + ], + "support": { + "source": "https://github.com/symfony/polyfill-intl-normalizer/tree/v1.31.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-09-09T11:45:10+00:00" + }, + { + "name": "symfony/polyfill-mbstring", + "version": "v1.31.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-mbstring.git", + "reference": "85181ba99b2345b0ef10ce42ecac37612d9fd341" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/85181ba99b2345b0ef10ce42ecac37612d9fd341", + "reference": "85181ba99b2345b0ef10ce42ecac37612d9fd341", + "shasum": "" + }, + "require": { + "php": ">=7.2" + }, + "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.31.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-09-09T11:45:10+00:00" + }, + { + "name": "symfony/polyfill-php80", + "version": "v1.31.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-php80.git", + "reference": "60328e362d4c2c802a54fcbf04f9d3fb892b4cf8" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/60328e362d4c2c802a54fcbf04f9d3fb892b4cf8", + "reference": "60328e362d4c2c802a54fcbf04f9d3fb892b4cf8", + "shasum": "" + }, + "require": { + "php": ">=7.2" + }, + "type": "library", + "extra": { + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Php80\\": "" + }, + "classmap": [ + "Resources/stubs" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Ion Bazan", + "email": "ion.bazan@gmail.com" + }, + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill backporting some PHP 8.0+ features to lower PHP versions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "polyfill", + "portable", + "shim" + ], + "support": { + "source": "https://github.com/symfony/polyfill-php80/tree/v1.31.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-09-09T11:45:10+00:00" + }, + { + "name": "symfony/polyfill-php83", + "version": "v1.31.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-php83.git", + "reference": "2fb86d65e2d424369ad2905e83b236a8805ba491" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-php83/zipball/2fb86d65e2d424369ad2905e83b236a8805ba491", + "reference": "2fb86d65e2d424369ad2905e83b236a8805ba491", + "shasum": "" + }, + "require": { + "php": ">=7.2" + }, + "type": "library", + "extra": { + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Php83\\": "" + }, + "classmap": [ + "Resources/stubs" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill backporting some PHP 8.3+ features to lower PHP versions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "polyfill", + "portable", + "shim" + ], + "support": { + "source": "https://github.com/symfony/polyfill-php83/tree/v1.31.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-09-09T11:45:10+00:00" + }, + { + "name": "symfony/polyfill-uuid", + "version": "v1.31.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-uuid.git", + "reference": "21533be36c24be3f4b1669c4725c7d1d2bab4ae2" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-uuid/zipball/21533be36c24be3f4b1669c4725c7d1d2bab4ae2", + "reference": "21533be36c24be3f4b1669c4725c7d1d2bab4ae2", + "shasum": "" + }, + "require": { + "php": ">=7.2" + }, + "provide": { + "ext-uuid": "*" + }, + "suggest": { + "ext-uuid": "For best performance" + }, + "type": "library", + "extra": { + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Uuid\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Grégoire Pineau", + "email": "lyrixx@lyrixx.info" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill for uuid functions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "polyfill", + "portable", + "uuid" + ], + "support": { + "source": "https://github.com/symfony/polyfill-uuid/tree/v1.31.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-09-09T11:45:10+00:00" + }, + { + "name": "symfony/process", + "version": "v7.2.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/process.git", + "reference": "d34b22ba9390ec19d2dd966c40aa9e8462f27a7e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/process/zipball/d34b22ba9390ec19d2dd966c40aa9e8462f27a7e", + "reference": "d34b22ba9390ec19d2dd966c40aa9e8462f27a7e", + "shasum": "" + }, + "require": { + "php": ">=8.2" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\Process\\": "" + }, + "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": "Executes commands in sub-processes", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/process/tree/v7.2.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-11-06T14:24:19+00:00" + }, + { + "name": "symfony/routing", + "version": "v7.2.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/routing.git", + "reference": "e10a2450fa957af6c448b9b93c9010a4e4c0725e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/routing/zipball/e10a2450fa957af6c448b9b93c9010a4e4c0725e", + "reference": "e10a2450fa957af6c448b9b93c9010a4e4c0725e", + "shasum": "" + }, + "require": { + "php": ">=8.2", + "symfony/deprecation-contracts": "^2.5|^3" + }, + "conflict": { + "symfony/config": "<6.4", + "symfony/dependency-injection": "<6.4", + "symfony/yaml": "<6.4" + }, + "require-dev": { + "psr/log": "^1|^2|^3", + "symfony/config": "^6.4|^7.0", + "symfony/dependency-injection": "^6.4|^7.0", + "symfony/expression-language": "^6.4|^7.0", + "symfony/http-foundation": "^6.4|^7.0", + "symfony/yaml": "^6.4|^7.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\Routing\\": "" + }, + "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": "Maps an HTTP request to a set of configuration variables", + "homepage": "https://symfony.com", + "keywords": [ + "router", + "routing", + "uri", + "url" + ], + "support": { + "source": "https://github.com/symfony/routing/tree/v7.2.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-11-25T11:08:51+00:00" + }, + { + "name": "symfony/service-contracts", + "version": "v3.5.1", + "source": { + "type": "git", + "url": "https://github.com/symfony/service-contracts.git", + "reference": "e53260aabf78fb3d63f8d79d69ece59f80d5eda0" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/service-contracts/zipball/e53260aabf78fb3d63f8d79d69ece59f80d5eda0", + "reference": "e53260aabf78fb3d63f8d79d69ece59f80d5eda0", + "shasum": "" + }, + "require": { + "php": ">=8.1", + "psr/container": "^1.1|^2.0", + "symfony/deprecation-contracts": "^2.5|^3" + }, + "conflict": { + "ext-psr": "<1.1|>=2" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "3.5-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.5.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": "2024-09-25T14:20:29+00:00" + }, + { + "name": "symfony/string", + "version": "v7.2.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/string.git", + "reference": "446e0d146f991dde3e73f45f2c97a9faad773c82" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/string/zipball/446e0d146f991dde3e73f45f2c97a9faad773c82", + "reference": "446e0d146f991dde3e73f45f2c97a9faad773c82", + "shasum": "" + }, + "require": { + "php": ">=8.2", + "symfony/polyfill-ctype": "~1.8", + "symfony/polyfill-intl-grapheme": "~1.0", + "symfony/polyfill-intl-normalizer": "~1.0", + "symfony/polyfill-mbstring": "~1.0" + }, + "conflict": { + "symfony/translation-contracts": "<2.5" + }, + "require-dev": { + "symfony/emoji": "^7.1", + "symfony/error-handler": "^6.4|^7.0", + "symfony/http-client": "^6.4|^7.0", + "symfony/intl": "^6.4|^7.0", + "symfony/translation-contracts": "^2.5|^3.0", + "symfony/var-exporter": "^6.4|^7.0" + }, + "type": "library", + "autoload": { + "files": [ + "Resources/functions.php" + ], + "psr-4": { + "Symfony\\Component\\String\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Provides an object-oriented API to strings and deals with bytes, UTF-8 code points and grapheme clusters in a unified way", + "homepage": "https://symfony.com", + "keywords": [ + "grapheme", + "i18n", + "string", + "unicode", + "utf-8", + "utf8" + ], + "support": { + "source": "https://github.com/symfony/string/tree/v7.2.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-11-13T13:31:26+00:00" + }, + { + "name": "symfony/translation", + "version": "v7.2.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/translation.git", + "reference": "dc89e16b44048ceecc879054e5b7f38326ab6cc5" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/translation/zipball/dc89e16b44048ceecc879054e5b7f38326ab6cc5", + "reference": "dc89e16b44048ceecc879054e5b7f38326ab6cc5", + "shasum": "" + }, + "require": { + "php": ">=8.2", + "symfony/deprecation-contracts": "^2.5|^3", + "symfony/polyfill-mbstring": "~1.0", + "symfony/translation-contracts": "^2.5|^3.0" + }, + "conflict": { + "symfony/config": "<6.4", + "symfony/console": "<6.4", + "symfony/dependency-injection": "<6.4", + "symfony/http-client-contracts": "<2.5", + "symfony/http-kernel": "<6.4", + "symfony/service-contracts": "<2.5", + "symfony/twig-bundle": "<6.4", + "symfony/yaml": "<6.4" + }, + "provide": { + "symfony/translation-implementation": "2.3|3.0" + }, + "require-dev": { + "nikic/php-parser": "^4.18|^5.0", + "psr/log": "^1|^2|^3", + "symfony/config": "^6.4|^7.0", + "symfony/console": "^6.4|^7.0", + "symfony/dependency-injection": "^6.4|^7.0", + "symfony/finder": "^6.4|^7.0", + "symfony/http-client-contracts": "^2.5|^3.0", + "symfony/http-kernel": "^6.4|^7.0", + "symfony/intl": "^6.4|^7.0", + "symfony/polyfill-intl-icu": "^1.21", + "symfony/routing": "^6.4|^7.0", + "symfony/service-contracts": "^2.5|^3", + "symfony/yaml": "^6.4|^7.0" + }, + "type": "library", + "autoload": { + "files": [ + "Resources/functions.php" + ], + "psr-4": { + "Symfony\\Component\\Translation\\": "" + }, + "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 tools to internationalize your application", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/translation/tree/v7.2.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-11-12T20:47:56+00:00" + }, + { + "name": "symfony/translation-contracts", + "version": "v3.5.1", + "source": { + "type": "git", + "url": "https://github.com/symfony/translation-contracts.git", + "reference": "4667ff3bd513750603a09c8dedbea942487fb07c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/translation-contracts/zipball/4667ff3bd513750603a09c8dedbea942487fb07c", + "reference": "4667ff3bd513750603a09c8dedbea942487fb07c", + "shasum": "" + }, + "require": { + "php": ">=8.1" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "3.5-dev" + }, + "thanks": { + "name": "symfony/contracts", + "url": "https://github.com/symfony/contracts" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Contracts\\Translation\\": "" + }, + "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 translation", + "homepage": "https://symfony.com", + "keywords": [ + "abstractions", + "contracts", + "decoupling", + "interfaces", + "interoperability", + "standards" + ], + "support": { + "source": "https://github.com/symfony/translation-contracts/tree/v3.5.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": "2024-09-25T14:20:29+00:00" + }, + { + "name": "symfony/uid", + "version": "v7.2.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/uid.git", + "reference": "2d294d0c48df244c71c105a169d0190bfb080426" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/uid/zipball/2d294d0c48df244c71c105a169d0190bfb080426", + "reference": "2d294d0c48df244c71c105a169d0190bfb080426", + "shasum": "" + }, + "require": { + "php": ">=8.2", + "symfony/polyfill-uuid": "^1.15" + }, + "require-dev": { + "symfony/console": "^6.4|^7.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\Uid\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Grégoire Pineau", + "email": "lyrixx@lyrixx.info" + }, + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Provides an object-oriented API to generate and represent UIDs", + "homepage": "https://symfony.com", + "keywords": [ + "UID", + "ulid", + "uuid" + ], + "support": { + "source": "https://github.com/symfony/uid/tree/v7.2.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-09-25T14:21:43+00:00" + }, + { + "name": "symfony/var-dumper", + "version": "v7.2.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/var-dumper.git", + "reference": "c6a22929407dec8765d6e2b6ff85b800b245879c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/var-dumper/zipball/c6a22929407dec8765d6e2b6ff85b800b245879c", + "reference": "c6a22929407dec8765d6e2b6ff85b800b245879c", + "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.12" + }, + "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.2.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-11-08T15:48:14+00:00" + }, + { + "name": "tijsverkoyen/css-to-inline-styles", + "version": "v2.2.7", + "source": { + "type": "git", + "url": "https://github.com/tijsverkoyen/CssToInlineStyles.git", + "reference": "83ee6f38df0a63106a9e4536e3060458b74ccedb" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/tijsverkoyen/CssToInlineStyles/zipball/83ee6f38df0a63106a9e4536e3060458b74ccedb", + "reference": "83ee6f38df0a63106a9e4536e3060458b74ccedb", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "ext-libxml": "*", + "php": "^5.5 || ^7.0 || ^8.0", + "symfony/css-selector": "^2.7 || ^3.0 || ^4.0 || ^5.0 || ^6.0 || ^7.0" + }, + "require-dev": { + "phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.0 || ^7.5 || ^8.5.21 || ^9.5.10" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.2.x-dev" + } + }, + "autoload": { + "psr-4": { + "TijsVerkoyen\\CssToInlineStyles\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Tijs Verkoyen", + "email": "css_to_inline_styles@verkoyen.eu", + "role": "Developer" + } + ], + "description": "CssToInlineStyles is a class that enables you to convert HTML-pages/files into HTML-pages/files with inline styles. This is very useful when you're sending emails.", + "homepage": "https://github.com/tijsverkoyen/CssToInlineStyles", + "support": { + "issues": "https://github.com/tijsverkoyen/CssToInlineStyles/issues", + "source": "https://github.com/tijsverkoyen/CssToInlineStyles/tree/v2.2.7" + }, + "time": "2023-12-08T13:03:43+00:00" + }, + { + "name": "vlucas/phpdotenv", + "version": "v5.6.1", + "source": { + "type": "git", + "url": "https://github.com/vlucas/phpdotenv.git", + "reference": "a59a13791077fe3d44f90e7133eb68e7d22eaff2" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/vlucas/phpdotenv/zipball/a59a13791077fe3d44f90e7133eb68e7d22eaff2", + "reference": "a59a13791077fe3d44f90e7133eb68e7d22eaff2", + "shasum": "" + }, + "require": { + "ext-pcre": "*", + "graham-campbell/result-type": "^1.1.3", + "php": "^7.2.5 || ^8.0", + "phpoption/phpoption": "^1.9.3", + "symfony/polyfill-ctype": "^1.24", + "symfony/polyfill-mbstring": "^1.24", + "symfony/polyfill-php80": "^1.24" + }, + "require-dev": { + "bamarni/composer-bin-plugin": "^1.8.2", + "ext-filter": "*", + "phpunit/phpunit": "^8.5.34 || ^9.6.13 || ^10.4.2" + }, + "suggest": { + "ext-filter": "Required to use the boolean validator." + }, + "type": "library", + "extra": { + "bamarni-bin": { + "bin-links": true, + "forward-command": false + }, + "branch-alias": { + "dev-master": "5.6-dev" + } + }, + "autoload": { + "psr-4": { + "Dotenv\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Graham Campbell", + "email": "hello@gjcampbell.co.uk", + "homepage": "https://github.com/GrahamCampbell" + }, + { + "name": "Vance Lucas", + "email": "vance@vancelucas.com", + "homepage": "https://github.com/vlucas" + } + ], + "description": "Loads environment variables from `.env` to `getenv()`, `$_ENV` and `$_SERVER` automagically.", + "keywords": [ + "dotenv", + "env", + "environment" + ], + "support": { + "issues": "https://github.com/vlucas/phpdotenv/issues", + "source": "https://github.com/vlucas/phpdotenv/tree/v5.6.1" + }, + "funding": [ + { + "url": "https://github.com/GrahamCampbell", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/vlucas/phpdotenv", + "type": "tidelift" + } + ], + "time": "2024-07-20T21:52:34+00:00" + }, + { + "name": "voku/portable-ascii", + "version": "2.0.3", + "source": { + "type": "git", + "url": "https://github.com/voku/portable-ascii.git", + "reference": "b1d923f88091c6bf09699efcd7c8a1b1bfd7351d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/voku/portable-ascii/zipball/b1d923f88091c6bf09699efcd7c8a1b1bfd7351d", + "reference": "b1d923f88091c6bf09699efcd7c8a1b1bfd7351d", + "shasum": "" + }, + "require": { + "php": ">=7.0.0" + }, + "require-dev": { + "phpunit/phpunit": "~6.0 || ~7.0 || ~9.0" + }, + "suggest": { + "ext-intl": "Use Intl for transliterator_transliterate() support" + }, + "type": "library", + "autoload": { + "psr-4": { + "voku\\": "src/voku/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Lars Moelleken", + "homepage": "https://www.moelleken.org/" + } + ], + "description": "Portable ASCII library - performance optimized (ascii) string functions for php.", + "homepage": "https://github.com/voku/portable-ascii", + "keywords": [ + "ascii", + "clean", + "php" + ], + "support": { + "issues": "https://github.com/voku/portable-ascii/issues", + "source": "https://github.com/voku/portable-ascii/tree/2.0.3" + }, + "funding": [ + { + "url": "https://www.paypal.me/moelleken", + "type": "custom" + }, + { + "url": "https://github.com/voku", + "type": "github" + }, + { + "url": "https://opencollective.com/portable-ascii", + "type": "open_collective" + }, + { + "url": "https://www.patreon.com/voku", + "type": "patreon" + }, + { + "url": "https://tidelift.com/funding/github/packagist/voku/portable-ascii", + "type": "tidelift" + } + ], + "time": "2024-11-21T01:49:47+00:00" + }, + { + "name": "webmozart/assert", + "version": "1.11.0", + "source": { + "type": "git", + "url": "https://github.com/webmozarts/assert.git", + "reference": "11cb2199493b2f8a3b53e7f19068fc6aac760991" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/webmozarts/assert/zipball/11cb2199493b2f8a3b53e7f19068fc6aac760991", + "reference": "11cb2199493b2f8a3b53e7f19068fc6aac760991", + "shasum": "" + }, + "require": { + "ext-ctype": "*", + "php": "^7.2 || ^8.0" + }, + "conflict": { + "phpstan/phpstan": "<0.12.20", + "vimeo/psalm": "<4.6.1 || 4.6.2" + }, + "require-dev": { + "phpunit/phpunit": "^8.5.13" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.10-dev" + } + }, + "autoload": { + "psr-4": { + "Webmozart\\Assert\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Bernhard Schussek", + "email": "bschussek@gmail.com" + } + ], + "description": "Assertions to validate method input/output with nice error messages.", + "keywords": [ + "assert", + "check", + "validate" + ], + "support": { + "issues": "https://github.com/webmozarts/assert/issues", + "source": "https://github.com/webmozarts/assert/tree/1.11.0" + }, + "time": "2022-06-03T18:03:27+00:00" + } + ], + "packages-dev": [ + { + "name": "brianium/paratest", + "version": "v7.6.0", + "source": { + "type": "git", + "url": "https://github.com/paratestphp/paratest.git", + "reference": "68ff89a8de47d086588e391a516d2a5b5fde6254" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/paratestphp/paratest/zipball/68ff89a8de47d086588e391a516d2a5b5fde6254", + "reference": "68ff89a8de47d086588e391a516d2a5b5fde6254", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "ext-pcre": "*", + "ext-reflection": "*", + "ext-simplexml": "*", + "fidry/cpu-core-counter": "^1.2.0", + "jean85/pretty-package-versions": "^2.0.6", + "php": "~8.2.0 || ~8.3.0 || ~8.4.0", + "phpunit/php-code-coverage": "^11.0.7", + "phpunit/php-file-iterator": "^5.1.0", + "phpunit/php-timer": "^7.0.1", + "phpunit/phpunit": "^11.4.1", + "sebastian/environment": "^7.2.0", + "symfony/console": "^6.4.11 || ^7.1.5", + "symfony/process": "^6.4.8 || ^7.1.5" + }, + "require-dev": { + "doctrine/coding-standard": "^12.0.0", + "ext-pcov": "*", + "ext-posix": "*", + "phpstan/phpstan": "^1.12.6", + "phpstan/phpstan-deprecation-rules": "^1.2.1", + "phpstan/phpstan-phpunit": "^1.4.0", + "phpstan/phpstan-strict-rules": "^1.6.1", + "squizlabs/php_codesniffer": "^3.10.3", + "symfony/filesystem": "^6.4.9 || ^7.1.5" + }, + "bin": [ + "bin/paratest", + "bin/paratest_for_phpstorm" + ], + "type": "library", + "autoload": { + "psr-4": { + "ParaTest\\": [ + "src/" + ] + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Brian Scaturro", + "email": "scaturrob@gmail.com", + "role": "Developer" + }, + { + "name": "Filippo Tessarotto", + "email": "zoeslam@gmail.com", + "role": "Developer" + } + ], + "description": "Parallel testing for PHP", + "homepage": "https://github.com/paratestphp/paratest", + "keywords": [ + "concurrent", + "parallel", + "phpunit", + "testing" + ], + "support": { + "issues": "https://github.com/paratestphp/paratest/issues", + "source": "https://github.com/paratestphp/paratest/tree/v7.6.0" + }, + "funding": [ + { + "url": "https://github.com/sponsors/Slamdunk", + "type": "github" + }, + { + "url": "https://paypal.me/filippotessarotto", + "type": "paypal" + } + ], + "time": "2024-10-15T12:38:31+00:00" + }, + { + "name": "doctrine/deprecations", + "version": "1.1.3", + "source": { + "type": "git", + "url": "https://github.com/doctrine/deprecations.git", + "reference": "dfbaa3c2d2e9a9df1118213f3b8b0c597bb99fab" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/doctrine/deprecations/zipball/dfbaa3c2d2e9a9df1118213f3b8b0c597bb99fab", + "reference": "dfbaa3c2d2e9a9df1118213f3b8b0c597bb99fab", + "shasum": "" + }, + "require": { + "php": "^7.1 || ^8.0" + }, + "require-dev": { + "doctrine/coding-standard": "^9", + "phpstan/phpstan": "1.4.10 || 1.10.15", + "phpstan/phpstan-phpunit": "^1.0", + "phpunit/phpunit": "^7.5 || ^8.5 || ^9.5", + "psalm/plugin-phpunit": "0.18.4", + "psr/log": "^1 || ^2 || ^3", + "vimeo/psalm": "4.30.0 || 5.12.0" + }, + "suggest": { + "psr/log": "Allows logging deprecations via PSR-3 logger implementation" + }, + "type": "library", + "autoload": { + "psr-4": { + "Doctrine\\Deprecations\\": "lib/Doctrine/Deprecations" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "A small layer on top of trigger_error(E_USER_DEPRECATED) or PSR-3 logging with options to disable all deprecations or selectively for packages.", + "homepage": "https://www.doctrine-project.org/", + "support": { + "issues": "https://github.com/doctrine/deprecations/issues", + "source": "https://github.com/doctrine/deprecations/tree/1.1.3" + }, + "time": "2024-01-30T19:34:25+00:00" + }, + { + "name": "fakerphp/faker", + "version": "v1.24.1", + "source": { + "type": "git", + "url": "https://github.com/FakerPHP/Faker.git", + "reference": "e0ee18eb1e6dc3cda3ce9fd97e5a0689a88a64b5" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/FakerPHP/Faker/zipball/e0ee18eb1e6dc3cda3ce9fd97e5a0689a88a64b5", + "reference": "e0ee18eb1e6dc3cda3ce9fd97e5a0689a88a64b5", + "shasum": "" + }, + "require": { + "php": "^7.4 || ^8.0", + "psr/container": "^1.0 || ^2.0", + "symfony/deprecation-contracts": "^2.2 || ^3.0" + }, + "conflict": { + "fzaninotto/faker": "*" + }, + "require-dev": { + "bamarni/composer-bin-plugin": "^1.4.1", + "doctrine/persistence": "^1.3 || ^2.0", + "ext-intl": "*", + "phpunit/phpunit": "^9.5.26", + "symfony/phpunit-bridge": "^5.4.16" + }, + "suggest": { + "doctrine/orm": "Required to use Faker\\ORM\\Doctrine", + "ext-curl": "Required by Faker\\Provider\\Image to download images.", + "ext-dom": "Required by Faker\\Provider\\HtmlLorem for generating random HTML.", + "ext-iconv": "Required by Faker\\Provider\\ru_RU\\Text::realText() for generating real Russian text.", + "ext-mbstring": "Required for multibyte Unicode string functionality." + }, + "type": "library", + "autoload": { + "psr-4": { + "Faker\\": "src/Faker/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "François Zaninotto" + } + ], + "description": "Faker is a PHP library that generates fake data for you.", + "keywords": [ + "data", + "faker", + "fixtures" + ], + "support": { + "issues": "https://github.com/FakerPHP/Faker/issues", + "source": "https://github.com/FakerPHP/Faker/tree/v1.24.1" + }, + "time": "2024-11-21T13:46:39+00:00" + }, + { + "name": "fidry/cpu-core-counter", + "version": "1.2.0", + "source": { + "type": "git", + "url": "https://github.com/theofidry/cpu-core-counter.git", + "reference": "8520451a140d3f46ac33042715115e290cf5785f" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/theofidry/cpu-core-counter/zipball/8520451a140d3f46ac33042715115e290cf5785f", + "reference": "8520451a140d3f46ac33042715115e290cf5785f", + "shasum": "" + }, + "require": { + "php": "^7.2 || ^8.0" + }, + "require-dev": { + "fidry/makefile": "^0.2.0", + "fidry/php-cs-fixer-config": "^1.1.2", + "phpstan/extension-installer": "^1.2.0", + "phpstan/phpstan": "^1.9.2", + "phpstan/phpstan-deprecation-rules": "^1.0.0", + "phpstan/phpstan-phpunit": "^1.2.2", + "phpstan/phpstan-strict-rules": "^1.4.4", + "phpunit/phpunit": "^8.5.31 || ^9.5.26", + "webmozarts/strict-phpunit": "^7.5" + }, + "type": "library", + "autoload": { + "psr-4": { + "Fidry\\CpuCoreCounter\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Théo FIDRY", + "email": "theo.fidry@gmail.com" + } + ], + "description": "Tiny utility to get the number of CPU cores.", + "keywords": [ + "CPU", + "core" + ], + "support": { + "issues": "https://github.com/theofidry/cpu-core-counter/issues", + "source": "https://github.com/theofidry/cpu-core-counter/tree/1.2.0" + }, + "funding": [ + { + "url": "https://github.com/theofidry", + "type": "github" + } + ], + "time": "2024-08-06T10:04:20+00:00" + }, + { + "name": "filp/whoops", + "version": "2.16.0", + "source": { + "type": "git", + "url": "https://github.com/filp/whoops.git", + "reference": "befcdc0e5dce67252aa6322d82424be928214fa2" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/filp/whoops/zipball/befcdc0e5dce67252aa6322d82424be928214fa2", + "reference": "befcdc0e5dce67252aa6322d82424be928214fa2", + "shasum": "" + }, + "require": { + "php": "^7.1 || ^8.0", + "psr/log": "^1.0.1 || ^2.0 || ^3.0" + }, + "require-dev": { + "mockery/mockery": "^1.0", + "phpunit/phpunit": "^7.5.20 || ^8.5.8 || ^9.3.3", + "symfony/var-dumper": "^4.0 || ^5.0" + }, + "suggest": { + "symfony/var-dumper": "Pretty print complex values better with var-dumper available", + "whoops/soap": "Formats errors as SOAP responses" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.7-dev" + } + }, + "autoload": { + "psr-4": { + "Whoops\\": "src/Whoops/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Filipe Dobreira", + "homepage": "https://github.com/filp", + "role": "Developer" + } + ], + "description": "php error handling for cool kids", + "homepage": "https://filp.github.io/whoops/", + "keywords": [ + "error", + "exception", + "handling", + "library", + "throwable", + "whoops" + ], + "support": { + "issues": "https://github.com/filp/whoops/issues", + "source": "https://github.com/filp/whoops/tree/2.16.0" + }, + "funding": [ + { + "url": "https://github.com/denis-sokolov", + "type": "github" + } + ], + "time": "2024-09-25T12:00:00+00:00" + }, + { + "name": "hamcrest/hamcrest-php", + "version": "v2.0.1", + "source": { + "type": "git", + "url": "https://github.com/hamcrest/hamcrest-php.git", + "reference": "8c3d0a3f6af734494ad8f6fbbee0ba92422859f3" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/hamcrest/hamcrest-php/zipball/8c3d0a3f6af734494ad8f6fbbee0ba92422859f3", + "reference": "8c3d0a3f6af734494ad8f6fbbee0ba92422859f3", + "shasum": "" + }, + "require": { + "php": "^5.3|^7.0|^8.0" + }, + "replace": { + "cordoval/hamcrest-php": "*", + "davedevelopment/hamcrest-php": "*", + "kodova/hamcrest-php": "*" + }, + "require-dev": { + "phpunit/php-file-iterator": "^1.4 || ^2.0", + "phpunit/phpunit": "^4.8.36 || ^5.7 || ^6.5 || ^7.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.1-dev" + } + }, + "autoload": { + "classmap": [ + "hamcrest" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "description": "This is the PHP port of Hamcrest Matchers", + "keywords": [ + "test" + ], + "support": { + "issues": "https://github.com/hamcrest/hamcrest-php/issues", + "source": "https://github.com/hamcrest/hamcrest-php/tree/v2.0.1" + }, + "time": "2020-07-09T08:09:16+00:00" + }, + { + "name": "jean85/pretty-package-versions", + "version": "2.1.0", + "source": { + "type": "git", + "url": "https://github.com/Jean85/pretty-package-versions.git", + "reference": "3c4e5f62ba8d7de1734312e4fff32f67a8daaf10" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/Jean85/pretty-package-versions/zipball/3c4e5f62ba8d7de1734312e4fff32f67a8daaf10", + "reference": "3c4e5f62ba8d7de1734312e4fff32f67a8daaf10", + "shasum": "" + }, + "require": { + "composer-runtime-api": "^2.1.0", + "php": "^7.4|^8.0" + }, + "require-dev": { + "friendsofphp/php-cs-fixer": "^3.2", + "jean85/composer-provided-replaced-stub-package": "^1.0", + "phpstan/phpstan": "^1.4", + "phpunit/phpunit": "^7.5|^8.5|^9.6", + "vimeo/psalm": "^4.3 || ^5.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.x-dev" + } + }, + "autoload": { + "psr-4": { + "Jean85\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Alessandro Lai", + "email": "alessandro.lai85@gmail.com" + } + ], + "description": "A library to get pretty versions strings of installed dependencies", + "keywords": [ + "composer", + "package", + "release", + "versions" + ], + "support": { + "issues": "https://github.com/Jean85/pretty-package-versions/issues", + "source": "https://github.com/Jean85/pretty-package-versions/tree/2.1.0" + }, + "time": "2024-11-18T16:19:46+00:00" + }, + { + "name": "laravel/breeze", + "version": "v2.2.6", + "source": { + "type": "git", + "url": "https://github.com/laravel/breeze.git", + "reference": "907b12160d1b8b8213e7e2e011987fffb5567edc" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/laravel/breeze/zipball/907b12160d1b8b8213e7e2e011987fffb5567edc", + "reference": "907b12160d1b8b8213e7e2e011987fffb5567edc", + "shasum": "" + }, + "require": { + "illuminate/console": "^11.0", + "illuminate/filesystem": "^11.0", + "illuminate/support": "^11.0", + "illuminate/validation": "^11.0", + "php": "^8.2.0", + "symfony/console": "^7.0" + }, + "require-dev": { + "laravel/framework": "^11.0", + "orchestra/testbench-core": "^9.0", + "phpstan/phpstan": "^2.0" + }, + "type": "library", + "extra": { + "laravel": { + "providers": [ + "Laravel\\Breeze\\BreezeServiceProvider" + ] + } + }, + "autoload": { + "psr-4": { + "Laravel\\Breeze\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Taylor Otwell", + "email": "taylor@laravel.com" + } + ], + "description": "Minimal Laravel authentication scaffolding with Blade and Tailwind.", + "keywords": [ + "auth", + "laravel" + ], + "support": { + "issues": "https://github.com/laravel/breeze/issues", + "source": "https://github.com/laravel/breeze" + }, + "time": "2024-11-20T15:01:15+00:00" + }, + { + "name": "laravel/pail", + "version": "v1.2.1", + "source": { + "type": "git", + "url": "https://github.com/laravel/pail.git", + "reference": "353ac12134b98e2e7c3333d916bd3e523931e583" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/laravel/pail/zipball/353ac12134b98e2e7c3333d916bd3e523931e583", + "reference": "353ac12134b98e2e7c3333d916bd3e523931e583", + "shasum": "" + }, + "require": { + "ext-mbstring": "*", + "illuminate/console": "^10.24|^11.0", + "illuminate/contracts": "^10.24|^11.0", + "illuminate/log": "^10.24|^11.0", + "illuminate/process": "^10.24|^11.0", + "illuminate/support": "^10.24|^11.0", + "nunomaduro/termwind": "^1.15|^2.0", + "php": "^8.2", + "symfony/console": "^6.0|^7.0" + }, + "require-dev": { + "laravel/framework": "^10.24|^11.0", + "laravel/pint": "^1.13", + "orchestra/testbench-core": "^8.12|^9.0", + "pestphp/pest": "^2.20", + "pestphp/pest-plugin-type-coverage": "^2.3", + "phpstan/phpstan": "^1.10", + "symfony/var-dumper": "^6.3|^7.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "1.x-dev" + }, + "laravel": { + "providers": [ + "Laravel\\Pail\\PailServiceProvider" + ] + } + }, + "autoload": { + "psr-4": { + "Laravel\\Pail\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Taylor Otwell", + "email": "taylor@laravel.com" + }, + { + "name": "Nuno Maduro", + "email": "enunomaduro@gmail.com" + } + ], + "description": "Easily delve into your Laravel application's log files directly from the command line.", + "homepage": "https://github.com/laravel/pail", + "keywords": [ + "laravel", + "logs", + "php", + "tail" + ], + "support": { + "issues": "https://github.com/laravel/pail/issues", + "source": "https://github.com/laravel/pail" + }, + "time": "2024-10-23T12:56:23+00:00" + }, + { + "name": "laravel/pint", + "version": "v1.18.3", + "source": { + "type": "git", + "url": "https://github.com/laravel/pint.git", + "reference": "cef51821608239040ab841ad6e1c6ae502ae3026" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/laravel/pint/zipball/cef51821608239040ab841ad6e1c6ae502ae3026", + "reference": "cef51821608239040ab841ad6e1c6ae502ae3026", + "shasum": "" + }, + "require": { + "ext-json": "*", + "ext-mbstring": "*", + "ext-tokenizer": "*", + "ext-xml": "*", + "php": "^8.1.0" + }, + "require-dev": { + "friendsofphp/php-cs-fixer": "^3.65.0", + "illuminate/view": "^10.48.24", + "larastan/larastan": "^2.9.11", + "laravel-zero/framework": "^10.4.0", + "mockery/mockery": "^1.6.12", + "nunomaduro/termwind": "^1.17.0", + "pestphp/pest": "^2.36.0" + }, + "bin": [ + "builds/pint" + ], + "type": "project", + "autoload": { + "psr-4": { + "App\\": "app/", + "Database\\Seeders\\": "database/seeders/", + "Database\\Factories\\": "database/factories/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nuno Maduro", + "email": "enunomaduro@gmail.com" + } + ], + "description": "An opinionated code formatter for PHP.", + "homepage": "https://laravel.com", + "keywords": [ + "format", + "formatter", + "lint", + "linter", + "php" + ], + "support": { + "issues": "https://github.com/laravel/pint/issues", + "source": "https://github.com/laravel/pint" + }, + "time": "2024-11-26T15:34:00+00:00" + }, + { + "name": "laravel/sail", + "version": "v1.39.1", + "source": { + "type": "git", + "url": "https://github.com/laravel/sail.git", + "reference": "1a3c7291bc88de983b66688919a4d298d68ddec7" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/laravel/sail/zipball/1a3c7291bc88de983b66688919a4d298d68ddec7", + "reference": "1a3c7291bc88de983b66688919a4d298d68ddec7", + "shasum": "" + }, + "require": { + "illuminate/console": "^9.52.16|^10.0|^11.0", + "illuminate/contracts": "^9.52.16|^10.0|^11.0", + "illuminate/support": "^9.52.16|^10.0|^11.0", + "php": "^8.0", + "symfony/console": "^6.0|^7.0", + "symfony/yaml": "^6.0|^7.0" + }, + "require-dev": { + "orchestra/testbench": "^7.0|^8.0|^9.0", + "phpstan/phpstan": "^1.10" + }, + "bin": [ + "bin/sail" + ], + "type": "library", + "extra": { + "laravel": { + "providers": [ + "Laravel\\Sail\\SailServiceProvider" + ] + } + }, + "autoload": { + "psr-4": { + "Laravel\\Sail\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Taylor Otwell", + "email": "taylor@laravel.com" + } + ], + "description": "Docker files for running a basic Laravel application.", + "keywords": [ + "docker", + "laravel" + ], + "support": { + "issues": "https://github.com/laravel/sail/issues", + "source": "https://github.com/laravel/sail" + }, + "time": "2024-11-27T15:42:28+00:00" + }, + { + "name": "mockery/mockery", + "version": "1.6.12", + "source": { + "type": "git", + "url": "https://github.com/mockery/mockery.git", + "reference": "1f4efdd7d3beafe9807b08156dfcb176d18f1699" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/mockery/mockery/zipball/1f4efdd7d3beafe9807b08156dfcb176d18f1699", + "reference": "1f4efdd7d3beafe9807b08156dfcb176d18f1699", + "shasum": "" + }, + "require": { + "hamcrest/hamcrest-php": "^2.0.1", + "lib-pcre": ">=7.0", + "php": ">=7.3" + }, + "conflict": { + "phpunit/phpunit": "<8.0" + }, + "require-dev": { + "phpunit/phpunit": "^8.5 || ^9.6.17", + "symplify/easy-coding-standard": "^12.1.14" + }, + "type": "library", + "autoload": { + "files": [ + "library/helpers.php", + "library/Mockery.php" + ], + "psr-4": { + "Mockery\\": "library/Mockery" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Pádraic Brady", + "email": "padraic.brady@gmail.com", + "homepage": "https://github.com/padraic", + "role": "Author" + }, + { + "name": "Dave Marshall", + "email": "dave.marshall@atstsolutions.co.uk", + "homepage": "https://davedevelopment.co.uk", + "role": "Developer" + }, + { + "name": "Nathanael Esayeas", + "email": "nathanael.esayeas@protonmail.com", + "homepage": "https://github.com/ghostwriter", + "role": "Lead Developer" + } + ], + "description": "Mockery is a simple yet flexible PHP mock object framework", + "homepage": "https://github.com/mockery/mockery", + "keywords": [ + "BDD", + "TDD", + "library", + "mock", + "mock objects", + "mockery", + "stub", + "test", + "test double", + "testing" + ], + "support": { + "docs": "https://docs.mockery.io/", + "issues": "https://github.com/mockery/mockery/issues", + "rss": "https://github.com/mockery/mockery/releases.atom", + "security": "https://github.com/mockery/mockery/security/advisories", + "source": "https://github.com/mockery/mockery" + }, + "time": "2024-05-16T03:13:13+00:00" + }, + { + "name": "myclabs/deep-copy", + "version": "1.12.1", + "source": { + "type": "git", + "url": "https://github.com/myclabs/DeepCopy.git", + "reference": "123267b2c49fbf30d78a7b2d333f6be754b94845" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/123267b2c49fbf30d78a7b2d333f6be754b94845", + "reference": "123267b2c49fbf30d78a7b2d333f6be754b94845", + "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", + "phpspec/prophecy": "^1.10", + "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.12.1" + }, + "funding": [ + { + "url": "https://tidelift.com/funding/github/packagist/myclabs/deep-copy", + "type": "tidelift" + } + ], + "time": "2024-11-08T17:47:46+00:00" + }, + { + "name": "nunomaduro/collision", + "version": "v8.5.0", + "source": { + "type": "git", + "url": "https://github.com/nunomaduro/collision.git", + "reference": "f5c101b929c958e849a633283adff296ed5f38f5" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/nunomaduro/collision/zipball/f5c101b929c958e849a633283adff296ed5f38f5", + "reference": "f5c101b929c958e849a633283adff296ed5f38f5", + "shasum": "" + }, + "require": { + "filp/whoops": "^2.16.0", + "nunomaduro/termwind": "^2.1.0", + "php": "^8.2.0", + "symfony/console": "^7.1.5" + }, + "conflict": { + "laravel/framework": "<11.0.0 || >=12.0.0", + "phpunit/phpunit": "<10.5.1 || >=12.0.0" + }, + "require-dev": { + "larastan/larastan": "^2.9.8", + "laravel/framework": "^11.28.0", + "laravel/pint": "^1.18.1", + "laravel/sail": "^1.36.0", + "laravel/sanctum": "^4.0.3", + "laravel/tinker": "^2.10.0", + "orchestra/testbench-core": "^9.5.3", + "pestphp/pest": "^2.36.0 || ^3.4.0", + "sebastian/environment": "^6.1.0 || ^7.2.0" + }, + "type": "library", + "extra": { + "laravel": { + "providers": [ + "NunoMaduro\\Collision\\Adapters\\Laravel\\CollisionServiceProvider" + ] + }, + "branch-alias": { + "dev-8.x": "8.x-dev" + } + }, + "autoload": { + "files": [ + "./src/Adapters/Phpunit/Autoload.php" + ], + "psr-4": { + "NunoMaduro\\Collision\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nuno Maduro", + "email": "enunomaduro@gmail.com" + } + ], + "description": "Cli error handling for console/command-line PHP applications.", + "keywords": [ + "artisan", + "cli", + "command-line", + "console", + "error", + "handling", + "laravel", + "laravel-zero", + "php", + "symfony" + ], + "support": { + "issues": "https://github.com/nunomaduro/collision/issues", + "source": "https://github.com/nunomaduro/collision" + }, + "funding": [ + { + "url": "https://www.paypal.com/paypalme/enunomaduro", + "type": "custom" + }, + { + "url": "https://github.com/nunomaduro", + "type": "github" + }, + { + "url": "https://www.patreon.com/nunomaduro", + "type": "patreon" + } + ], + "time": "2024-10-15T16:06:32+00:00" + }, + { + "name": "pestphp/pest", + "version": "v3.6.0", + "source": { + "type": "git", + "url": "https://github.com/pestphp/pest.git", + "reference": "918a8fc16996849937e281482bd34f236881ce96" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/pestphp/pest/zipball/918a8fc16996849937e281482bd34f236881ce96", + "reference": "918a8fc16996849937e281482bd34f236881ce96", + "shasum": "" + }, + "require": { + "brianium/paratest": "^7.6.0", + "nunomaduro/collision": "^8.5.0", + "nunomaduro/termwind": "^2.3.0", + "pestphp/pest-plugin": "^3.0.0", + "pestphp/pest-plugin-arch": "^3.0.0", + "pestphp/pest-plugin-mutate": "^3.0.5", + "php": "^8.2.0", + "phpunit/phpunit": "^11.4.4" + }, + "conflict": { + "filp/whoops": "<2.16.0", + "phpunit/phpunit": ">11.4.4", + "sebastian/exporter": "<6.0.0", + "webmozart/assert": "<1.11.0" + }, + "require-dev": { + "pestphp/pest-dev-tools": "^3.3.0", + "pestphp/pest-plugin-type-coverage": "^3.2.0", + "symfony/process": "^7.1.8" + }, + "bin": [ + "bin/pest" + ], + "type": "library", + "extra": { + "pest": { + "plugins": [ + "Pest\\Mutate\\Plugins\\Mutate", + "Pest\\Plugins\\Configuration", + "Pest\\Plugins\\Bail", + "Pest\\Plugins\\Cache", + "Pest\\Plugins\\Coverage", + "Pest\\Plugins\\Init", + "Pest\\Plugins\\Environment", + "Pest\\Plugins\\Help", + "Pest\\Plugins\\Memory", + "Pest\\Plugins\\Only", + "Pest\\Plugins\\Printer", + "Pest\\Plugins\\ProcessIsolation", + "Pest\\Plugins\\Profile", + "Pest\\Plugins\\Retry", + "Pest\\Plugins\\Snapshot", + "Pest\\Plugins\\Verbose", + "Pest\\Plugins\\Version", + "Pest\\Plugins\\Parallel" + ] + }, + "phpstan": { + "includes": [ + "extension.neon" + ] + } + }, + "autoload": { + "files": [ + "src/Functions.php", + "src/Pest.php" + ], + "psr-4": { + "Pest\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nuno Maduro", + "email": "enunomaduro@gmail.com" + } + ], + "description": "The elegant PHP Testing Framework.", + "keywords": [ + "framework", + "pest", + "php", + "test", + "testing", + "unit" + ], + "support": { + "issues": "https://github.com/pestphp/pest/issues", + "source": "https://github.com/pestphp/pest/tree/v3.6.0" + }, + "funding": [ + { + "url": "https://www.paypal.com/paypalme/enunomaduro", + "type": "custom" + }, + { + "url": "https://github.com/nunomaduro", + "type": "github" + } + ], + "time": "2024-12-01T22:46:00+00:00" + }, + { + "name": "pestphp/pest-plugin", + "version": "v3.0.0", + "source": { + "type": "git", + "url": "https://github.com/pestphp/pest-plugin.git", + "reference": "e79b26c65bc11c41093b10150c1341cc5cdbea83" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/pestphp/pest-plugin/zipball/e79b26c65bc11c41093b10150c1341cc5cdbea83", + "reference": "e79b26c65bc11c41093b10150c1341cc5cdbea83", + "shasum": "" + }, + "require": { + "composer-plugin-api": "^2.0.0", + "composer-runtime-api": "^2.2.2", + "php": "^8.2" + }, + "conflict": { + "pestphp/pest": "<3.0.0" + }, + "require-dev": { + "composer/composer": "^2.7.9", + "pestphp/pest": "^3.0.0", + "pestphp/pest-dev-tools": "^3.0.0" + }, + "type": "composer-plugin", + "extra": { + "class": "Pest\\Plugin\\Manager" + }, + "autoload": { + "psr-4": { + "Pest\\Plugin\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "The Pest plugin manager", + "keywords": [ + "framework", + "manager", + "pest", + "php", + "plugin", + "test", + "testing", + "unit" + ], + "support": { + "source": "https://github.com/pestphp/pest-plugin/tree/v3.0.0" + }, + "funding": [ + { + "url": "https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=66BYDWAT92N6L", + "type": "custom" + }, + { + "url": "https://github.com/nunomaduro", + "type": "github" + }, + { + "url": "https://www.patreon.com/nunomaduro", + "type": "patreon" + } + ], + "time": "2024-09-08T23:21:41+00:00" + }, + { + "name": "pestphp/pest-plugin-arch", + "version": "v3.0.0", + "source": { + "type": "git", + "url": "https://github.com/pestphp/pest-plugin-arch.git", + "reference": "0a27e55a270cfe73d8cb70551b91002ee2cb64b0" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/pestphp/pest-plugin-arch/zipball/0a27e55a270cfe73d8cb70551b91002ee2cb64b0", + "reference": "0a27e55a270cfe73d8cb70551b91002ee2cb64b0", + "shasum": "" + }, + "require": { + "pestphp/pest-plugin": "^3.0.0", + "php": "^8.2", + "ta-tikoma/phpunit-architecture-test": "^0.8.4" + }, + "require-dev": { + "pestphp/pest": "^3.0.0", + "pestphp/pest-dev-tools": "^3.0.0" + }, + "type": "library", + "extra": { + "pest": { + "plugins": [ + "Pest\\Arch\\Plugin" + ] + } + }, + "autoload": { + "files": [ + "src/Autoload.php" + ], + "psr-4": { + "Pest\\Arch\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "The Arch plugin for Pest PHP.", + "keywords": [ + "arch", + "architecture", + "framework", + "pest", + "php", + "plugin", + "test", + "testing", + "unit" + ], + "support": { + "source": "https://github.com/pestphp/pest-plugin-arch/tree/v3.0.0" + }, + "funding": [ + { + "url": "https://www.paypal.com/paypalme/enunomaduro", + "type": "custom" + }, + { + "url": "https://github.com/nunomaduro", + "type": "github" + } + ], + "time": "2024-09-08T23:23:55+00:00" + }, + { + "name": "pestphp/pest-plugin-laravel", + "version": "v3.0.0", + "source": { + "type": "git", + "url": "https://github.com/pestphp/pest-plugin-laravel.git", + "reference": "7dd98c0c3b3542970ec21fce80ec5c88916ac469" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/pestphp/pest-plugin-laravel/zipball/7dd98c0c3b3542970ec21fce80ec5c88916ac469", + "reference": "7dd98c0c3b3542970ec21fce80ec5c88916ac469", + "shasum": "" + }, + "require": { + "laravel/framework": "^11.22.0", + "pestphp/pest": "^3.0.0", + "php": "^8.2.0" + }, + "require-dev": { + "laravel/dusk": "^8.2.5", + "orchestra/testbench": "^9.4.0", + "pestphp/pest-dev-tools": "^3.0.0" + }, + "type": "library", + "extra": { + "laravel": { + "providers": [ + "Pest\\Laravel\\PestServiceProvider" + ] + }, + "pest": { + "plugins": [ + "Pest\\Laravel\\Plugin" + ] + } + }, + "autoload": { + "files": [ + "src/Autoload.php" + ], + "psr-4": { + "Pest\\Laravel\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "The Pest Laravel Plugin", + "keywords": [ + "framework", + "laravel", + "pest", + "php", + "test", + "testing", + "unit" + ], + "support": { + "source": "https://github.com/pestphp/pest-plugin-laravel/tree/v3.0.0" + }, + "funding": [ + { + "url": "https://www.paypal.com/paypalme/enunomaduro", + "type": "custom" + }, + { + "url": "https://github.com/nunomaduro", + "type": "github" + } + ], + "time": "2024-09-08T23:32:52+00:00" + }, + { + "name": "pestphp/pest-plugin-mutate", + "version": "v3.0.5", + "source": { + "type": "git", + "url": "https://github.com/pestphp/pest-plugin-mutate.git", + "reference": "e10dbdc98c9e2f3890095b4fe2144f63a5717e08" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/pestphp/pest-plugin-mutate/zipball/e10dbdc98c9e2f3890095b4fe2144f63a5717e08", + "reference": "e10dbdc98c9e2f3890095b4fe2144f63a5717e08", + "shasum": "" + }, + "require": { + "nikic/php-parser": "^5.2.0", + "pestphp/pest-plugin": "^3.0.0", + "php": "^8.2", + "psr/simple-cache": "^3.0.0" + }, + "require-dev": { + "pestphp/pest": "^3.0.8", + "pestphp/pest-dev-tools": "^3.0.0", + "pestphp/pest-plugin-type-coverage": "^3.0.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Pest\\Mutate\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Sandro Gehri", + "email": "sandrogehri@gmail.com" + } + ], + "description": "Mutates your code to find untested cases", + "keywords": [ + "framework", + "mutate", + "mutation", + "pest", + "php", + "plugin", + "test", + "testing", + "unit" + ], + "support": { + "source": "https://github.com/pestphp/pest-plugin-mutate/tree/v3.0.5" + }, + "funding": [ + { + "url": "https://www.paypal.com/paypalme/enunomaduro", + "type": "custom" + }, + { + "url": "https://github.com/gehrisandro", + "type": "github" + }, + { + "url": "https://github.com/nunomaduro", + "type": "github" + } + ], + "time": "2024-09-22T07:54:40+00:00" + }, + { + "name": "phar-io/manifest", + "version": "2.0.4", + "source": { + "type": "git", + "url": "https://github.com/phar-io/manifest.git", + "reference": "54750ef60c58e43759730615a392c31c80e23176" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phar-io/manifest/zipball/54750ef60c58e43759730615a392c31c80e23176", + "reference": "54750ef60c58e43759730615a392c31c80e23176", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "ext-libxml": "*", + "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.4" + }, + "funding": [ + { + "url": "https://github.com/theseer", + "type": "github" + } + ], + "time": "2024-03-03T12:33:53+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": "phpdocumentor/reflection-common", + "version": "2.2.0", + "source": { + "type": "git", + "url": "https://github.com/phpDocumentor/ReflectionCommon.git", + "reference": "1d01c49d4ed62f25aa84a747ad35d5a16924662b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpDocumentor/ReflectionCommon/zipball/1d01c49d4ed62f25aa84a747ad35d5a16924662b", + "reference": "1d01c49d4ed62f25aa84a747ad35d5a16924662b", + "shasum": "" + }, + "require": { + "php": "^7.2 || ^8.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-2.x": "2.x-dev" + } + }, + "autoload": { + "psr-4": { + "phpDocumentor\\Reflection\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Jaap van Otterdijk", + "email": "opensource@ijaap.nl" + } + ], + "description": "Common reflection classes used by phpdocumentor to reflect the code structure", + "homepage": "http://www.phpdoc.org", + "keywords": [ + "FQSEN", + "phpDocumentor", + "phpdoc", + "reflection", + "static analysis" + ], + "support": { + "issues": "https://github.com/phpDocumentor/ReflectionCommon/issues", + "source": "https://github.com/phpDocumentor/ReflectionCommon/tree/2.x" + }, + "time": "2020-06-27T09:03:43+00:00" + }, + { + "name": "phpdocumentor/reflection-docblock", + "version": "5.6.0", + "source": { + "type": "git", + "url": "https://github.com/phpDocumentor/ReflectionDocBlock.git", + "reference": "f3558a4c23426d12bffeaab463f8a8d8b681193c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/f3558a4c23426d12bffeaab463f8a8d8b681193c", + "reference": "f3558a4c23426d12bffeaab463f8a8d8b681193c", + "shasum": "" + }, + "require": { + "doctrine/deprecations": "^1.1", + "ext-filter": "*", + "php": "^7.4 || ^8.0", + "phpdocumentor/reflection-common": "^2.2", + "phpdocumentor/type-resolver": "^1.7", + "phpstan/phpdoc-parser": "^1.7|^2.0", + "webmozart/assert": "^1.9.1" + }, + "require-dev": { + "mockery/mockery": "~1.3.5 || ~1.6.0", + "phpstan/extension-installer": "^1.1", + "phpstan/phpstan": "^1.8", + "phpstan/phpstan-mockery": "^1.1", + "phpstan/phpstan-webmozart-assert": "^1.2", + "phpunit/phpunit": "^9.5", + "psalm/phar": "^5.26" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "5.x-dev" + } + }, + "autoload": { + "psr-4": { + "phpDocumentor\\Reflection\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Mike van Riel", + "email": "me@mikevanriel.com" + }, + { + "name": "Jaap van Otterdijk", + "email": "opensource@ijaap.nl" + } + ], + "description": "With this component, a library can provide support for annotations via DocBlocks or otherwise retrieve information that is embedded in a DocBlock.", + "support": { + "issues": "https://github.com/phpDocumentor/ReflectionDocBlock/issues", + "source": "https://github.com/phpDocumentor/ReflectionDocBlock/tree/5.6.0" + }, + "time": "2024-11-12T11:25:25+00:00" + }, + { + "name": "phpdocumentor/type-resolver", + "version": "1.10.0", + "source": { + "type": "git", + "url": "https://github.com/phpDocumentor/TypeResolver.git", + "reference": "679e3ce485b99e84c775d28e2e96fade9a7fb50a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/679e3ce485b99e84c775d28e2e96fade9a7fb50a", + "reference": "679e3ce485b99e84c775d28e2e96fade9a7fb50a", + "shasum": "" + }, + "require": { + "doctrine/deprecations": "^1.0", + "php": "^7.3 || ^8.0", + "phpdocumentor/reflection-common": "^2.0", + "phpstan/phpdoc-parser": "^1.18|^2.0" + }, + "require-dev": { + "ext-tokenizer": "*", + "phpbench/phpbench": "^1.2", + "phpstan/extension-installer": "^1.1", + "phpstan/phpstan": "^1.8", + "phpstan/phpstan-phpunit": "^1.1", + "phpunit/phpunit": "^9.5", + "rector/rector": "^0.13.9", + "vimeo/psalm": "^4.25" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-1.x": "1.x-dev" + } + }, + "autoload": { + "psr-4": { + "phpDocumentor\\Reflection\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Mike van Riel", + "email": "me@mikevanriel.com" + } + ], + "description": "A PSR-5 based resolver of Class names, Types and Structural Element Names", + "support": { + "issues": "https://github.com/phpDocumentor/TypeResolver/issues", + "source": "https://github.com/phpDocumentor/TypeResolver/tree/1.10.0" + }, + "time": "2024-11-09T15:12:26+00:00" + }, + { + "name": "phpstan/phpdoc-parser", + "version": "2.0.0", + "source": { + "type": "git", + "url": "https://github.com/phpstan/phpdoc-parser.git", + "reference": "c00d78fb6b29658347f9d37ebe104bffadf36299" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpstan/phpdoc-parser/zipball/c00d78fb6b29658347f9d37ebe104bffadf36299", + "reference": "c00d78fb6b29658347f9d37ebe104bffadf36299", + "shasum": "" + }, + "require": { + "php": "^7.4 || ^8.0" + }, + "require-dev": { + "doctrine/annotations": "^2.0", + "nikic/php-parser": "^5.3.0", + "php-parallel-lint/php-parallel-lint": "^1.2", + "phpstan/extension-installer": "^1.0", + "phpstan/phpstan": "^2.0", + "phpstan/phpstan-phpunit": "^2.0", + "phpstan/phpstan-strict-rules": "^2.0", + "phpunit/phpunit": "^9.6", + "symfony/process": "^5.2" + }, + "type": "library", + "autoload": { + "psr-4": { + "PHPStan\\PhpDocParser\\": [ + "src/" + ] + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "PHPDoc parser with support for nullable, intersection and generic types", + "support": { + "issues": "https://github.com/phpstan/phpdoc-parser/issues", + "source": "https://github.com/phpstan/phpdoc-parser/tree/2.0.0" + }, + "time": "2024-10-13T11:29:49+00:00" + }, + { + "name": "phpunit/php-code-coverage", + "version": "11.0.7", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-code-coverage.git", + "reference": "f7f08030e8811582cc459871d28d6f5a1a4d35ca" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/f7f08030e8811582cc459871d28d6f5a1a4d35ca", + "reference": "f7f08030e8811582cc459871d28d6f5a1a4d35ca", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "ext-libxml": "*", + "ext-xmlwriter": "*", + "nikic/php-parser": "^5.3.1", + "php": ">=8.2", + "phpunit/php-file-iterator": "^5.1.0", + "phpunit/php-text-template": "^4.0.1", + "sebastian/code-unit-reverse-lookup": "^4.0.1", + "sebastian/complexity": "^4.0.1", + "sebastian/environment": "^7.2.0", + "sebastian/lines-of-code": "^3.0.1", + "sebastian/version": "^5.0.2", + "theseer/tokenizer": "^1.2.3" + }, + "require-dev": { + "phpunit/phpunit": "^11.4.1" + }, + "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.x-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.7" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2024-10-09T06:21:38+00:00" + }, + { + "name": "phpunit/php-file-iterator", + "version": "5.1.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-file-iterator.git", + "reference": "118cfaaa8bc5aef3287bf315b6060b1174754af6" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/118cfaaa8bc5aef3287bf315b6060b1174754af6", + "reference": "118cfaaa8bc5aef3287bf315b6060b1174754af6", + "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.1.0" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2024-08-27T05:02:59+00:00" + }, + { + "name": "phpunit/php-invoker", + "version": "5.0.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-invoker.git", + "reference": "c1ca3814734c07492b3d4c5f794f4b0995333da2" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-invoker/zipball/c1ca3814734c07492b3d4c5f794f4b0995333da2", + "reference": "c1ca3814734c07492b3d4c5f794f4b0995333da2", + "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.1" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2024-07-03T05:07:44+00:00" + }, + { + "name": "phpunit/php-text-template", + "version": "4.0.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-text-template.git", + "reference": "3e0404dc6b300e6bf56415467ebcb3fe4f33e964" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-text-template/zipball/3e0404dc6b300e6bf56415467ebcb3fe4f33e964", + "reference": "3e0404dc6b300e6bf56415467ebcb3fe4f33e964", + "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.1" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2024-07-03T05:08:43+00:00" + }, + { + "name": "phpunit/php-timer", + "version": "7.0.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-timer.git", + "reference": "3b415def83fbcb41f991d9ebf16ae4ad8b7837b3" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/3b415def83fbcb41f991d9ebf16ae4ad8b7837b3", + "reference": "3b415def83fbcb41f991d9ebf16ae4ad8b7837b3", + "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.1" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2024-07-03T05:09:35+00:00" + }, + { + "name": "phpunit/phpunit", + "version": "11.4.4", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/phpunit.git", + "reference": "f9ba7bd3c9f3ff54ec379d7a1c2e3f13fe0bbde4" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/f9ba7bd3c9f3ff54ec379d7a1c2e3f13fe0bbde4", + "reference": "f9ba7bd3c9f3ff54ec379d7a1c2e3f13fe0bbde4", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "ext-json": "*", + "ext-libxml": "*", + "ext-mbstring": "*", + "ext-xml": "*", + "ext-xmlwriter": "*", + "myclabs/deep-copy": "^1.12.1", + "phar-io/manifest": "^2.0.4", + "phar-io/version": "^3.2.1", + "php": ">=8.2", + "phpunit/php-code-coverage": "^11.0.7", + "phpunit/php-file-iterator": "^5.1.0", + "phpunit/php-invoker": "^5.0.1", + "phpunit/php-text-template": "^4.0.1", + "phpunit/php-timer": "^7.0.1", + "sebastian/cli-parser": "^3.0.2", + "sebastian/code-unit": "^3.0.1", + "sebastian/comparator": "^6.2.1", + "sebastian/diff": "^6.0.2", + "sebastian/environment": "^7.2.0", + "sebastian/exporter": "^6.1.3", + "sebastian/global-state": "^7.0.2", + "sebastian/object-enumerator": "^6.0.1", + "sebastian/type": "^5.1.0", + "sebastian/version": "^5.0.2" + }, + "suggest": { + "ext-soap": "To be able to generate mocks based on WSDL files" + }, + "bin": [ + "phpunit" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "11.4-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.4.4" + }, + "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-11-27T10:44:52+00:00" + }, + { + "name": "sebastian/cli-parser", + "version": "3.0.2", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/cli-parser.git", + "reference": "15c5dd40dc4f38794d383bb95465193f5e0ae180" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/cli-parser/zipball/15c5dd40dc4f38794d383bb95465193f5e0ae180", + "reference": "15c5dd40dc4f38794d383bb95465193f5e0ae180", + "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.2" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2024-07-03T04:41:36+00:00" + }, + { + "name": "sebastian/code-unit", + "version": "3.0.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/code-unit.git", + "reference": "6bb7d09d6623567178cf54126afa9c2310114268" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/code-unit/zipball/6bb7d09d6623567178cf54126afa9c2310114268", + "reference": "6bb7d09d6623567178cf54126afa9c2310114268", + "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.1" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2024-07-03T04:44:28+00:00" + }, + { + "name": "sebastian/code-unit-reverse-lookup", + "version": "4.0.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/code-unit-reverse-lookup.git", + "reference": "183a9b2632194febd219bb9246eee421dad8d45e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/code-unit-reverse-lookup/zipball/183a9b2632194febd219bb9246eee421dad8d45e", + "reference": "183a9b2632194febd219bb9246eee421dad8d45e", + "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.1" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2024-07-03T04:45:54+00:00" + }, + { + "name": "sebastian/comparator", + "version": "6.2.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/comparator.git", + "reference": "43d129d6a0f81c78bee378b46688293eb7ea3739" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/43d129d6a0f81c78bee378b46688293eb7ea3739", + "reference": "43d129d6a0f81c78bee378b46688293eb7ea3739", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "ext-mbstring": "*", + "php": ">=8.2", + "sebastian/diff": "^6.0", + "sebastian/exporter": "^6.0" + }, + "require-dev": { + "phpunit/phpunit": "^11.4" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "6.2-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.2.1" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2024-10-31T05:30:08+00:00" + }, + { + "name": "sebastian/complexity", + "version": "4.0.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/complexity.git", + "reference": "ee41d384ab1906c68852636b6de493846e13e5a0" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/complexity/zipball/ee41d384ab1906c68852636b6de493846e13e5a0", + "reference": "ee41d384ab1906c68852636b6de493846e13e5a0", + "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.1" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2024-07-03T04:49:50+00:00" + }, + { + "name": "sebastian/diff", + "version": "6.0.2", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/diff.git", + "reference": "b4ccd857127db5d41a5b676f24b51371d76d8544" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/b4ccd857127db5d41a5b676f24b51371d76d8544", + "reference": "b4ccd857127db5d41a5b676f24b51371d76d8544", + "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.2" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2024-07-03T04:53:05+00:00" + }, + { + "name": "sebastian/environment", + "version": "7.2.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/environment.git", + "reference": "855f3ae0ab316bbafe1ba4e16e9f3c078d24a0c5" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/855f3ae0ab316bbafe1ba4e16e9f3c078d24a0c5", + "reference": "855f3ae0ab316bbafe1ba4e16e9f3c078d24a0c5", + "shasum": "" + }, + "require": { + "php": ">=8.2" + }, + "require-dev": { + "phpunit/phpunit": "^11.0" + }, + "suggest": { + "ext-posix": "*" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "7.2-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.2.0" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2024-07-03T04:54:44+00:00" + }, + { + "name": "sebastian/exporter", + "version": "6.1.3", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/exporter.git", + "reference": "c414673eee9a8f9d51bbf8d61fc9e3ef1e85b20e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/c414673eee9a8f9d51bbf8d61fc9e3ef1e85b20e", + "reference": "c414673eee9a8f9d51bbf8d61fc9e3ef1e85b20e", + "shasum": "" + }, + "require": { + "ext-mbstring": "*", + "php": ">=8.2", + "sebastian/recursion-context": "^6.0" + }, + "require-dev": { + "phpunit/phpunit": "^11.2" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "6.1-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.1.3" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2024-07-03T04:56:19+00:00" + }, + { + "name": "sebastian/global-state", + "version": "7.0.2", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/global-state.git", + "reference": "3be331570a721f9a4b5917f4209773de17f747d7" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/3be331570a721f9a4b5917f4209773de17f747d7", + "reference": "3be331570a721f9a4b5917f4209773de17f747d7", + "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.2" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2024-07-03T04:57:36+00:00" + }, + { + "name": "sebastian/lines-of-code", + "version": "3.0.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/lines-of-code.git", + "reference": "d36ad0d782e5756913e42ad87cb2890f4ffe467a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/lines-of-code/zipball/d36ad0d782e5756913e42ad87cb2890f4ffe467a", + "reference": "d36ad0d782e5756913e42ad87cb2890f4ffe467a", + "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.1" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2024-07-03T04:58:38+00:00" + }, + { + "name": "sebastian/object-enumerator", + "version": "6.0.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/object-enumerator.git", + "reference": "f5b498e631a74204185071eb41f33f38d64608aa" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/object-enumerator/zipball/f5b498e631a74204185071eb41f33f38d64608aa", + "reference": "f5b498e631a74204185071eb41f33f38d64608aa", + "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.1" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2024-07-03T05:00:13+00:00" + }, + { + "name": "sebastian/object-reflector", + "version": "4.0.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/object-reflector.git", + "reference": "6e1a43b411b2ad34146dee7524cb13a068bb35f9" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/object-reflector/zipball/6e1a43b411b2ad34146dee7524cb13a068bb35f9", + "reference": "6e1a43b411b2ad34146dee7524cb13a068bb35f9", + "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.1" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2024-07-03T05:01:32+00:00" + }, + { + "name": "sebastian/recursion-context", + "version": "6.0.2", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/recursion-context.git", + "reference": "694d156164372abbd149a4b85ccda2e4670c0e16" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/694d156164372abbd149a4b85ccda2e4670c0e16", + "reference": "694d156164372abbd149a4b85ccda2e4670c0e16", + "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.2" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2024-07-03T05:10:34+00:00" + }, + { + "name": "sebastian/type", + "version": "5.1.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/type.git", + "reference": "461b9c5da241511a2a0e8f240814fb23ce5c0aac" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/type/zipball/461b9c5da241511a2a0e8f240814fb23ce5c0aac", + "reference": "461b9c5da241511a2a0e8f240814fb23ce5c0aac", + "shasum": "" + }, + "require": { + "php": ">=8.2" + }, + "require-dev": { + "phpunit/phpunit": "^11.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "5.1-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "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.1.0" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2024-09-17T13:12:04+00:00" + }, + { + "name": "sebastian/version", + "version": "5.0.2", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/version.git", + "reference": "c687e3387b99f5b03b6caa64c74b63e2936ff874" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/c687e3387b99f5b03b6caa64c74b63e2936ff874", + "reference": "c687e3387b99f5b03b6caa64c74b63e2936ff874", + "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.2" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2024-10-09T05:16:32+00:00" + }, + { + "name": "symfony/yaml", + "version": "v7.2.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/yaml.git", + "reference": "099581e99f557e9f16b43c5916c26380b54abb22" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/yaml/zipball/099581e99f557e9f16b43c5916c26380b54abb22", + "reference": "099581e99f557e9f16b43c5916c26380b54abb22", + "shasum": "" + }, + "require": { + "php": ">=8.2", + "symfony/deprecation-contracts": "^2.5|^3.0", + "symfony/polyfill-ctype": "^1.8" + }, + "conflict": { + "symfony/console": "<6.4" + }, + "require-dev": { + "symfony/console": "^6.4|^7.0" + }, + "bin": [ + "Resources/bin/yaml-lint" + ], + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\Yaml\\": "" + }, + "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": "Loads and dumps YAML files", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/yaml/tree/v7.2.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-10-23T06:56:12+00:00" + }, + { + "name": "ta-tikoma/phpunit-architecture-test", + "version": "0.8.4", + "source": { + "type": "git", + "url": "https://github.com/ta-tikoma/phpunit-architecture-test.git", + "reference": "89f0dea1cb0f0d5744d3ec1764a286af5e006636" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/ta-tikoma/phpunit-architecture-test/zipball/89f0dea1cb0f0d5744d3ec1764a286af5e006636", + "reference": "89f0dea1cb0f0d5744d3ec1764a286af5e006636", + "shasum": "" + }, + "require": { + "nikic/php-parser": "^4.18.0 || ^5.0.0", + "php": "^8.1.0", + "phpdocumentor/reflection-docblock": "^5.3.0", + "phpunit/phpunit": "^10.5.5 || ^11.0.0", + "symfony/finder": "^6.4.0 || ^7.0.0" + }, + "require-dev": { + "laravel/pint": "^1.13.7", + "phpstan/phpstan": "^1.10.52" + }, + "type": "library", + "autoload": { + "psr-4": { + "PHPUnit\\Architecture\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Ni Shi", + "email": "futik0ma011@gmail.com" + }, + { + "name": "Nuno Maduro", + "email": "enunomaduro@gmail.com" + } + ], + "description": "Methods for testing application architecture", + "keywords": [ + "architecture", + "phpunit", + "stucture", + "test", + "testing" + ], + "support": { + "issues": "https://github.com/ta-tikoma/phpunit-architecture-test/issues", + "source": "https://github.com/ta-tikoma/phpunit-architecture-test/tree/0.8.4" + }, + "time": "2024-01-05T14:10:56+00:00" + }, + { + "name": "theseer/tokenizer", + "version": "1.2.3", + "source": { + "type": "git", + "url": "https://github.com/theseer/tokenizer.git", + "reference": "737eda637ed5e28c3413cb1ebe8bb52cbf1ca7a2" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/theseer/tokenizer/zipball/737eda637ed5e28c3413cb1ebe8bb52cbf1ca7a2", + "reference": "737eda637ed5e28c3413cb1ebe8bb52cbf1ca7a2", + "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.3" + }, + "funding": [ + { + "url": "https://github.com/theseer", + "type": "github" + } + ], + "time": "2024-03-03T12:36:25+00:00" + } + ], + "aliases": [], + "minimum-stability": "stable", + "stability-flags": [], + "prefer-stable": true, + "prefer-lowest": false, + "platform": { + "php": "^8.2" + }, + "platform-dev": [], + "plugin-api-version": "2.6.0" +} diff --git a/config/app.php b/config/app.php new file mode 100644 index 0000000..706439d --- /dev/null +++ b/config/app.php @@ -0,0 +1,128 @@ + env('APP_NAME', 'Laravel'), + + /* + |-------------------------------------------------------------------------- + | Application Environment + |-------------------------------------------------------------------------- + | + | This value determines the "environment" your application is currently + | running in. This may determine how you prefer to configure various + | services the application utilizes. Set this in your ".env" file. + | + */ + + 'env' => env('APP_ENV', 'production'), + + /* + |-------------------------------------------------------------------------- + | Application Debug Mode + |-------------------------------------------------------------------------- + | + | When your application is in debug mode, detailed error messages with + | stack traces will be shown on every error that occurs within your + | application. If disabled, a simple generic error page is shown. + | + */ + + 'debug' => (bool) env('APP_DEBUG', false), + + /* + |-------------------------------------------------------------------------- + | Application URL + |-------------------------------------------------------------------------- + | + | This URL is used by the console to properly generate URLs when using + | the Artisan command line tool. You should set this to the root of + | the application so that it's available within Artisan commands. + | + */ + + 'url' => env('APP_URL', 'http://localhost'), + + /* + |-------------------------------------------------------------------------- + | Application Timezone + |-------------------------------------------------------------------------- + | + | Here you may specify the default timezone for your application, which + | will be used by the PHP date and date-time functions. The timezone + | is set to "UTC" by default as it is suitable for most use cases. + | + */ + + 'timezone' => env('APP_TIMEZONE', 'UTC'), + + /* + |-------------------------------------------------------------------------- + | Application Locale Configuration + |-------------------------------------------------------------------------- + | + | The application locale determines the default locale that will be used + | by Laravel's translation / localization methods. This option can be + | set to any locale for which you plan to have translation strings. + | + */ + + 'locale' => env('APP_LOCALE', 'en'), + + 'fallback_locale' => env('APP_FALLBACK_LOCALE', 'en'), + + 'faker_locale' => env('APP_FAKER_LOCALE', 'en_US'), + + /* + |-------------------------------------------------------------------------- + | Encryption Key + |-------------------------------------------------------------------------- + | + | This key is utilized by Laravel's encryption services and should be set + | to a random, 32 character string to ensure that all encrypted values + | are secure. You should do this prior to deploying the application. + | + */ + + 'cipher' => 'AES-256-CBC', + + 'key' => env('APP_KEY'), + + 'previous_keys' => [ + ...array_filter( + explode(',', env('APP_PREVIOUS_KEYS', '')) + ), + ], + + /* + |-------------------------------------------------------------------------- + | Maintenance Mode Driver + |-------------------------------------------------------------------------- + | + | These configuration options determine the driver used to determine and + | manage Laravel's "maintenance mode" status. The "cache" driver will + | allow maintenance mode to be controlled across multiple machines. + | + | Supported drivers: "file", "cache" + | + */ + + 'maintenance' => [ + 'driver' => env('APP_MAINTENANCE_DRIVER', 'file'), + 'store' => env('APP_MAINTENANCE_STORE', 'database'), + ], + +]; diff --git a/config/auth.php b/config/auth.php new file mode 100644 index 0000000..2ce066d --- /dev/null +++ b/config/auth.php @@ -0,0 +1,117 @@ + [ + 'guard' => env('AUTH_GUARD', 'web'), + 'passwords' => env('AUTH_PASSWORD_BROKER', 'users'), + ], + + /* + |-------------------------------------------------------------------------- + | Authentication Guards + |-------------------------------------------------------------------------- + | + | Next, you may define every authentication guard for your application. + | Of course, a great default configuration has been defined for you + | which utilizes session storage plus the Eloquent user provider. + | + | All authentication guards have a user provider, which defines how the + | users are actually retrieved out of your database or other storage + | system used by the application. Typically, Eloquent is utilized. + | + | Supported: "session" + | + */ + + 'guards' => [ + 'web' => [ + 'driver' => 'session', + 'provider' => 'users', + ], + ], + + /* + |-------------------------------------------------------------------------- + | User Providers + |-------------------------------------------------------------------------- + | + | All authentication guards have a user provider, which defines how the + | users are actually retrieved out of your database or other storage + | system used by the application. Typically, Eloquent is utilized. + | + | If you have multiple user tables or models you may configure multiple + | providers to represent the model / table. These providers may then + | be assigned to any extra authentication guards you have defined. + | + | Supported: "database", "eloquent" + | + */ + + 'providers' => [ + 'users' => [ + 'driver' => 'eloquent', + 'model' => env('AUTH_MODEL', App\Models\User::class), + ], + + // 'users' => [ + // 'driver' => 'database', + // 'table' => 'users', + // ], + ], + + /* + |-------------------------------------------------------------------------- + | Resetting Passwords + |-------------------------------------------------------------------------- + | + | These configuration options specify the behavior of Laravel's password + | reset functionality, including the table utilized for token storage + | and the user provider that is invoked to actually retrieve users. + | + | The expiry time is the number of minutes that each reset token will be + | considered valid. This security feature keeps tokens short-lived so + | they have less time to be guessed. You may change this as needed. + | + | The throttle setting is the number of seconds a user must wait before + | generating more password reset tokens. This prevents the user from + | quickly generating a very large amount of password reset tokens. + | + */ + + 'passwords' => [ + 'users' => [ + 'provider' => 'users', + 'table' => env('AUTH_PASSWORD_RESET_TOKEN_TABLE', 'password_reset_tokens'), + 'expire' => 60, + 'throttle' => 60, + ], + ], + + /* + |-------------------------------------------------------------------------- + | Password Confirmation Timeout + |-------------------------------------------------------------------------- + | + | Here you may define the amount of seconds before a password confirmation + | window expires and users are asked to re-enter their password via the + | confirmation screen. By default, the timeout lasts for three hours. + | + */ + + 'password_timeout' => env('AUTH_PASSWORD_TIMEOUT', 10800), + +]; diff --git a/config/cache.php b/config/cache.php new file mode 100644 index 0000000..9f39702 --- /dev/null +++ b/config/cache.php @@ -0,0 +1,110 @@ + env('CACHE_STORE', 'database'), + + /* + |-------------------------------------------------------------------------- + | Cache Stores + |-------------------------------------------------------------------------- + | + | Here you may define all of the cache "stores" for your application as + | well as their drivers. You may even define multiple stores for the + | same cache driver to group types of items stored in your caches. + | + | Supported drivers: "array", "database", "file", "memcached", + | "redis", "dynamodb", "octane", "null" + | + */ + + 'stores' => [ + + 'array' => [ + 'driver' => 'array', + 'serialize' => false, + ], + + 'database' => [ + 'driver' => 'database', + 'connection' => env('DB_CACHE_CONNECTION'), + 'table' => env('DB_CACHE_TABLE', 'cache'), + 'lock_connection' => env('DB_CACHE_LOCK_CONNECTION'), + 'lock_table' => env('DB_CACHE_LOCK_TABLE'), + ], + + 'file' => [ + 'driver' => 'file', + 'path' => storage_path('framework/cache/data'), + 'lock_path' => storage_path('framework/cache/data'), + ], + + 'memcached' => [ + 'driver' => 'memcached', + 'persistent_id' => env('MEMCACHED_PERSISTENT_ID'), + 'sasl' => [ + env('MEMCACHED_USERNAME'), + env('MEMCACHED_PASSWORD'), + ], + 'options' => [ + // Memcached::OPT_CONNECT_TIMEOUT => 2000, + ], + 'servers' => [ + [ + 'host' => env('MEMCACHED_HOST', '127.0.0.1'), + 'port' => env('MEMCACHED_PORT', 11211), + 'weight' => 100, + ], + ], + ], + + 'redis' => [ + 'driver' => 'redis', + 'connection' => env('REDIS_CACHE_CONNECTION', 'cache'), + 'lock_connection' => env('REDIS_CACHE_LOCK_CONNECTION', 'default'), + ], + + 'dynamodb' => [ + 'driver' => 'dynamodb', + 'key' => env('AWS_ACCESS_KEY_ID'), + 'secret' => env('AWS_SECRET_ACCESS_KEY'), + 'region' => env('AWS_DEFAULT_REGION', 'us-east-1'), + 'table' => env('DYNAMODB_CACHE_TABLE', 'cache'), + 'endpoint' => env('DYNAMODB_ENDPOINT'), + ], + + 'octane' => [ + 'driver' => 'octane', + ], + + ], + + /* + |-------------------------------------------------------------------------- + | Cache Key Prefix + |-------------------------------------------------------------------------- + | + | When utilizing the APC, database, memcached, Redis, and DynamoDB cache + | stores, there might be other applications using the same cache. For + | that reason, you may prefix every cache key to avoid collisions. + | + */ + + 'prefix' => env('CACHE_PREFIX', Str::slug(env('APP_NAME', 'laravel'), '_').'_cache_'), + +]; diff --git a/config/database.php b/config/database.php new file mode 100644 index 0000000..dcab623 --- /dev/null +++ b/config/database.php @@ -0,0 +1,175 @@ + env('DB_CONNECTION', 'sqlite'), + + /* + |-------------------------------------------------------------------------- + | Database Connections + |-------------------------------------------------------------------------- + | + | Below are all of the database connections defined for your application. + | An example configuration is provided for each database system which + | is supported by Laravel. You're free to add / remove connections. + | + */ + + 'connections' => [ + + 'sqlite' => [ + 'driver' => 'sqlite', + 'url' => env('DB_URL'), + 'database' => env('DB_DATABASE', database_path('database.sqlite')), + 'prefix' => '', + 'foreign_key_constraints' => env('DB_FOREIGN_KEYS', true), + 'busy_timeout' => null, + 'journal_mode' => null, + 'synchronous' => null, + ], + + 'mysql' => [ + 'driver' => 'mysql', + 'url' => env('DB_URL'), + 'host' => env('DB_HOST', '127.0.0.1'), + 'port' => env('DB_PORT', '3306'), + 'database' => env('DB_DATABASE', 'laravel'), + 'username' => env('DB_USERNAME', 'root'), + 'password' => env('DB_PASSWORD', ''), + 'unix_socket' => env('DB_SOCKET', ''), + 'charset' => env('DB_CHARSET', 'utf8mb4'), + 'collation' => env('DB_COLLATION', 'utf8mb4_unicode_ci'), + 'prefix' => '', + 'prefix_indexes' => true, + 'strict' => true, + 'engine' => null, + 'options' => extension_loaded('pdo_mysql') ? array_filter([ + PDO::MYSQL_ATTR_SSL_CA => env('MYSQL_ATTR_SSL_CA'), + ]) : [], + ], + + 'mariadb' => [ + 'driver' => 'mariadb', + 'url' => env('DB_URL'), + 'host' => env('DB_HOST', '127.0.0.1'), + 'port' => env('DB_PORT', '3306'), + 'database' => env('DB_DATABASE', 'laravel'), + 'username' => env('DB_USERNAME', 'root'), + 'password' => env('DB_PASSWORD', ''), + 'unix_socket' => env('DB_SOCKET', ''), + 'charset' => env('DB_CHARSET', 'utf8mb4'), + 'collation' => env('DB_COLLATION', 'utf8mb4_unicode_ci'), + 'prefix' => '', + 'prefix_indexes' => true, + 'strict' => true, + 'engine' => null, + 'options' => extension_loaded('pdo_mysql') ? array_filter([ + PDO::MYSQL_ATTR_SSL_CA => env('MYSQL_ATTR_SSL_CA'), + ]) : [], + ], + + 'pgsql' => [ + 'driver' => 'pgsql', + 'url' => env('DB_URL'), + 'host' => env('DB_HOST', '127.0.0.1'), + 'port' => env('DB_PORT', '5432'), + 'database' => env('DB_DATABASE', 'laravel'), + 'username' => env('DB_USERNAME', 'root'), + 'password' => env('DB_PASSWORD', ''), + 'charset' => env('DB_CHARSET', 'utf8'), + 'prefix' => '', + 'prefix_indexes' => true, + 'search_path' => 'public', + 'sslmode' => 'prefer', + ], + + 'sqlsrv' => [ + 'driver' => 'sqlsrv', + 'url' => env('DB_URL'), + 'host' => env('DB_HOST', 'localhost'), + 'port' => env('DB_PORT', '1433'), + 'database' => env('DB_DATABASE', 'laravel'), + 'username' => env('DB_USERNAME', 'root'), + 'password' => env('DB_PASSWORD', ''), + 'charset' => env('DB_CHARSET', 'utf8'), + 'prefix' => '', + 'prefix_indexes' => true, + // 'encrypt' => env('DB_ENCRYPT', 'yes'), + // 'trust_server_certificate' => env('DB_TRUST_SERVER_CERTIFICATE', 'false'), + ], + + ], + + /* + |-------------------------------------------------------------------------- + | Migration Repository Table + |-------------------------------------------------------------------------- + | + | This table keeps track of all the migrations that have already run for + | your application. Using this information, we can determine which of + | the migrations on disk haven't actually been run on the database. + | + */ + + 'migrations' => [ + 'table' => 'migrations', + 'update_date_on_publish' => true, + ], + + /* + |-------------------------------------------------------------------------- + | Redis Databases + |-------------------------------------------------------------------------- + | + | Redis is an open source, fast, and advanced key-value store that also + | provides a richer body of commands than a typical key-value system + | such as Memcached. You may define your connection settings here. + | + */ + + 'redis' => [ + + 'client' => env('REDIS_CLIENT', 'phpredis'), + + 'options' => [ + 'cluster' => env('REDIS_CLUSTER', 'redis'), + 'prefix' => env('REDIS_PREFIX', Str::slug(env('APP_NAME', 'laravel'), '_').'_database_'), + ], + + 'default' => [ + 'url' => env('REDIS_URL'), + 'host' => env('REDIS_HOST', '127.0.0.1'), + 'username' => env('REDIS_USERNAME'), + 'password' => env('REDIS_PASSWORD'), + 'port' => env('REDIS_PORT', '6379'), + 'database' => env('REDIS_DB', '0'), + ], + + 'cache' => [ + 'url' => env('REDIS_URL'), + 'host' => env('REDIS_HOST', '127.0.0.1'), + 'username' => env('REDIS_USERNAME'), + 'password' => env('REDIS_PASSWORD'), + 'port' => env('REDIS_PORT', '6379'), + 'database' => env('REDIS_CACHE_DB', '1'), + ], + + ], + +]; diff --git a/config/filesystems.php b/config/filesystems.php new file mode 100644 index 0000000..7728e0a --- /dev/null +++ b/config/filesystems.php @@ -0,0 +1,79 @@ + env('FILESYSTEM_DISK', 'local'), + + /* + |-------------------------------------------------------------------------- + | Filesystem Disks + |-------------------------------------------------------------------------- + | + | Below you may configure as many filesystem disks as necessary, and you + | may even configure multiple disks for the same driver. Examples for + | most supported storage drivers are configured here for reference. + | + | Supported drivers: "local", "ftp", "sftp", "s3" + | + */ + + 'disks' => [ + + 'local' => [ + 'driver' => 'local', + 'root' => storage_path('app/private'), + 'serve' => true, + 'throw' => false, + ], + + 'public' => [ + 'driver' => 'local', + 'root' => storage_path('app/public'), + 'url' => env('APP_URL').'/storage', + 'visibility' => 'public', + 'throw' => false, + ], + + 's3' => [ + 'driver' => 's3', + 'key' => env('AWS_ACCESS_KEY_ID'), + 'secret' => env('AWS_SECRET_ACCESS_KEY'), + 'region' => env('AWS_DEFAULT_REGION'), + 'bucket' => env('AWS_BUCKET'), + 'url' => env('AWS_URL'), + 'endpoint' => env('AWS_ENDPOINT'), + 'use_path_style_endpoint' => env('AWS_USE_PATH_STYLE_ENDPOINT', false), + 'throw' => false, + ], + + ], + + /* + |-------------------------------------------------------------------------- + | Symbolic Links + |-------------------------------------------------------------------------- + | + | Here you may configure the symbolic links that will be created when the + | `storage:link` Artisan command is executed. The array keys should be + | the locations of the links and the values should be their targets. + | + */ + + 'links' => [ + public_path('storage') => storage_path('app/public'), + ], + +]; diff --git a/config/logging.php b/config/logging.php new file mode 100644 index 0000000..9453a2d --- /dev/null +++ b/config/logging.php @@ -0,0 +1,134 @@ + env('LOG_CHANNEL', 'stack'), + + /* + |-------------------------------------------------------------------------- + | Deprecations Log Channel + |-------------------------------------------------------------------------- + | + | This option controls the log channel that should be used to log warnings + | regarding deprecated PHP and library features. This allows you to get + | your application ready for upcoming major versions of dependencies. + | + */ + + 'deprecations' => [ + 'channel' => env('LOG_DEPRECATIONS_CHANNEL', 'null'), + 'trace' => env('LOG_DEPRECATIONS_TRACE', false), + ], + + /* + |-------------------------------------------------------------------------- + | Log Channels + |-------------------------------------------------------------------------- + | + | Here you may configure the log channels for your application. Laravel + | utilizes the Monolog PHP logging library, which includes a variety + | of powerful log handlers and formatters that you're free to use. + | + | Available drivers: "single", "daily", "slack", "syslog", + | "errorlog", "monolog", "custom", "stack" + | + */ + + 'channels' => [ + + 'stack' => [ + 'driver' => 'stack', + 'channels' => explode(',', env('LOG_STACK', 'single')), + 'ignore_exceptions' => false, + ], + + 'single' => [ + 'driver' => 'single', + 'path' => storage_path('logs/laravel.log'), + 'level' => env('LOG_LEVEL', 'debug'), + 'replace_placeholders' => true, + ], + + 'daily' => [ + 'driver' => 'daily', + 'path' => storage_path('logs/laravel.log'), + 'level' => env('LOG_LEVEL', 'debug'), + 'days' => env('LOG_DAILY_DAYS', 14), + 'replace_placeholders' => true, + ], + + 'slack' => [ + 'driver' => 'slack', + 'url' => env('LOG_SLACK_WEBHOOK_URL'), + 'username' => env('LOG_SLACK_USERNAME', 'Laravel Log'), + 'emoji' => env('LOG_SLACK_EMOJI', ':boom:'), + 'level' => env('LOG_LEVEL', 'critical'), + 'replace_placeholders' => true, + ], + + 'papertrail' => [ + 'driver' => 'monolog', + 'level' => env('LOG_LEVEL', 'debug'), + 'handler' => env('LOG_PAPERTRAIL_HANDLER', SyslogUdpHandler::class), + 'handler_with' => [ + 'host' => env('PAPERTRAIL_URL'), + 'port' => env('PAPERTRAIL_PORT'), + 'connectionString' => 'tls://'.env('PAPERTRAIL_URL').':'.env('PAPERTRAIL_PORT'), + ], + 'processors' => [PsrLogMessageProcessor::class], + ], + + 'stderr' => [ + 'driver' => 'monolog', + 'level' => env('LOG_LEVEL', 'debug'), + 'handler' => StreamHandler::class, + 'formatter' => env('LOG_STDERR_FORMATTER'), + 'with' => [ + 'stream' => 'php://stderr', + ], + 'processors' => [PsrLogMessageProcessor::class], + ], + + 'syslog' => [ + 'driver' => 'syslog', + 'level' => env('LOG_LEVEL', 'debug'), + 'facility' => env('LOG_SYSLOG_FACILITY', LOG_USER), + 'replace_placeholders' => true, + ], + + 'errorlog' => [ + 'driver' => 'errorlog', + 'level' => env('LOG_LEVEL', 'debug'), + 'replace_placeholders' => true, + ], + + 'null' => [ + 'driver' => 'monolog', + 'handler' => NullHandler::class, + ], + + 'emergency' => [ + 'path' => storage_path('logs/laravel.log'), + ], + + ], + +]; diff --git a/config/mail.php b/config/mail.php new file mode 100644 index 0000000..15f0cca --- /dev/null +++ b/config/mail.php @@ -0,0 +1,118 @@ + env('MAIL_MAILER', 'log'), + + /* + |-------------------------------------------------------------------------- + | Mailer Configurations + |-------------------------------------------------------------------------- + | + | Here you may configure all of the mailers used by your application plus + | their respective settings. Several examples have been configured for + | you and you are free to add your own as your application requires. + | + | Laravel supports a variety of mail "transport" drivers that can be used + | when delivering an email. You may specify which one you're using for + | your mailers below. You may also add additional mailers if needed. + | + | Supported: "smtp", "sendmail", "mailgun", "ses", "ses-v2", + | "postmark", "resend", "log", "array", + | "failover", "roundrobin" + | + */ + + 'mailers' => [ + + 'smtp' => [ + 'transport' => 'smtp', + 'url' => env('MAIL_URL'), + 'host' => env('MAIL_HOST', '127.0.0.1'), + 'port' => env('MAIL_PORT', 2525), + 'encryption' => env('MAIL_ENCRYPTION', 'tls'), + 'username' => env('MAIL_USERNAME'), + 'password' => env('MAIL_PASSWORD'), + 'timeout' => null, + 'local_domain' => env('MAIL_EHLO_DOMAIN', parse_url(env('APP_URL', 'http://localhost'), PHP_URL_HOST)), + ], + + 'ses' => [ + 'transport' => 'ses', + ], + + 'postmark' => [ + 'transport' => 'postmark', + // 'message_stream_id' => env('POSTMARK_MESSAGE_STREAM_ID'), + // 'client' => [ + // 'timeout' => 5, + // ], + ], + + 'resend' => [ + 'transport' => 'resend', + ], + + 'sendmail' => [ + 'transport' => 'sendmail', + 'path' => env('MAIL_SENDMAIL_PATH', '/usr/sbin/sendmail -bs -i'), + ], + + 'log' => [ + 'transport' => 'log', + 'channel' => env('MAIL_LOG_CHANNEL'), + ], + + 'array' => [ + 'transport' => 'array', + ], + + 'failover' => [ + 'transport' => 'failover', + 'mailers' => [ + 'smtp', + 'log', + ], + ], + + 'roundrobin' => [ + 'transport' => 'roundrobin', + 'mailers' => [ + 'ses', + 'postmark', + ], + ], + + ], + + /* + |-------------------------------------------------------------------------- + | Global "From" Address + |-------------------------------------------------------------------------- + | + | You may wish for all emails sent by your application to be sent from + | the same address. Here you may specify a name and address that is + | used globally for all emails that are sent by your application. + | + */ + + 'from' => [ + 'address' => env('MAIL_FROM_ADDRESS', 'hello@example.com'), + 'name' => env('MAIL_FROM_NAME', 'Example'), + ], + +]; diff --git a/config/queue.php b/config/queue.php new file mode 100644 index 0000000..8829481 --- /dev/null +++ b/config/queue.php @@ -0,0 +1,114 @@ + env('QUEUE_CONNECTION', 'database'), + + /* + |-------------------------------------------------------------------------- + | Queue Connections + |-------------------------------------------------------------------------- + | + | Here you may configure the connection options for every queue backend + | used by your application. An example configuration is provided for + | each backend supported by Laravel. You're also free to add more. + | + | Drivers: "sync", "database", "beanstalkd", "sqs", "redis", "null" + | + */ + + 'connections' => [ + + 'sync' => [ + 'driver' => 'sync', + ], + + 'database' => [ + 'driver' => 'database', + 'connection' => env('DB_QUEUE_CONNECTION'), + 'table' => env('DB_QUEUE_TABLE', 'jobs'), + 'queue' => env('DB_QUEUE', 'default'), + 'retry_after' => (int) env('DB_QUEUE_RETRY_AFTER', 90), + 'after_commit' => false, + ], + + 'beanstalkd' => [ + 'driver' => 'beanstalkd', + 'host' => env('BEANSTALKD_QUEUE_HOST', 'localhost'), + 'queue' => env('BEANSTALKD_QUEUE', 'default'), + 'retry_after' => (int) env('BEANSTALKD_QUEUE_RETRY_AFTER', 90), + 'block_for' => 0, + 'after_commit' => false, + ], + + 'sqs' => [ + 'driver' => 'sqs', + 'key' => env('AWS_ACCESS_KEY_ID'), + 'secret' => env('AWS_SECRET_ACCESS_KEY'), + 'prefix' => env('SQS_PREFIX', 'https://sqs.us-east-1.amazonaws.com/your-account-id'), + 'queue' => env('SQS_QUEUE', 'default'), + 'suffix' => env('SQS_SUFFIX'), + 'region' => env('AWS_DEFAULT_REGION', 'us-east-1'), + 'after_commit' => false, + ], + + 'redis' => [ + 'driver' => 'redis', + 'connection' => env('REDIS_QUEUE_CONNECTION', 'default'), + 'queue' => env('REDIS_QUEUE', 'default'), + 'retry_after' => (int) env('REDIS_QUEUE_RETRY_AFTER', 90), + 'block_for' => null, + 'after_commit' => false, + ], + + ], + + /* + |-------------------------------------------------------------------------- + | Job Batching + |-------------------------------------------------------------------------- + | + | The following options configure the database and table that store job + | batching information. These options can be updated to any database + | connection and table which has been defined by your application. + | + */ + + 'batching' => [ + 'database' => env('DB_CONNECTION', 'sqlite'), + 'table' => 'job_batches', + ], + + /* + |-------------------------------------------------------------------------- + | Failed Queue Jobs + |-------------------------------------------------------------------------- + | + | These options configure the behavior of failed queue job logging so you + | can control how and where failed jobs are stored. Laravel ships with + | support for storing failed jobs in a simple file or in a database. + | + | Supported drivers: "database-uuids", "dynamodb", "file", "null" + | + */ + + 'failed' => [ + 'driver' => env('QUEUE_FAILED_DRIVER', 'database-uuids'), + 'database' => env('DB_CONNECTION', 'sqlite'), + 'table' => 'failed_jobs', + ], + +]; diff --git a/config/sanctum.php b/config/sanctum.php new file mode 100644 index 0000000..c27254f --- /dev/null +++ b/config/sanctum.php @@ -0,0 +1,85 @@ + explode(',', env('SANCTUM_STATEFUL_DOMAINS', sprintf( + '%s%s', + 'localhost,localhost:3000,127.0.0.1,127.0.0.1:8000,::1', + Sanctum::currentApplicationUrlWithPort() + ))), + + /* + |-------------------------------------------------------------------------- + | Sanctum Guards + |-------------------------------------------------------------------------- + | + | This array contains the authentication guards that will be checked when + | Sanctum is trying to authenticate a request. If none of these guards + | are able to authenticate the request, Sanctum will use the bearer + | token that's present on an incoming request for authentication. + | + */ + + 'guard' => ['web'], + + /* + |-------------------------------------------------------------------------- + | Expiration Minutes + |-------------------------------------------------------------------------- + | + | This value controls the number of minutes until an issued token will be + | considered expired. This will override any values set in the token's + | "expires_at" attribute, but first-party sessions are not affected. + | + */ + + 'expiration' => null, + + /* + |-------------------------------------------------------------------------- + | Token Prefix + |-------------------------------------------------------------------------- + | + | Sanctum can prefix new tokens in order to take advantage of numerous + | security scanning initiatives maintained by open source platforms + | that notify developers if they commit tokens into repositories. + | + | See: https://docs.github.com/en/code-security/secret-scanning/about-secret-scanning + | + */ + + 'token_prefix' => env('SANCTUM_TOKEN_PREFIX', ''), + + /* + |-------------------------------------------------------------------------- + | Sanctum Middleware + |-------------------------------------------------------------------------- + | + | When authenticating your first-party SPA with Sanctum you may need to + | customize some of the middleware Sanctum uses while processing the + | request. You may change the middleware listed below as required. + | + */ + + 'middleware' => [ + 'authenticate_session' => Laravel\Sanctum\Http\Middleware\AuthenticateSession::class, + 'encrypt_cookies' => Illuminate\Cookie\Middleware\EncryptCookies::class, + 'validate_csrf_token' => Illuminate\Foundation\Http\Middleware\ValidateCsrfToken::class, + ], + +]; diff --git a/config/services.php b/config/services.php new file mode 100644 index 0000000..949e344 --- /dev/null +++ b/config/services.php @@ -0,0 +1,40 @@ + [ + 'token' => env('POSTMARK_TOKEN'), + ], + + 'ses' => [ + 'key' => env('AWS_ACCESS_KEY_ID'), + 'secret' => env('AWS_SECRET_ACCESS_KEY'), + 'region' => env('AWS_DEFAULT_REGION', 'us-east-1'), + ], + + 'resend' => [ + 'key' => env('RESEND_KEY'), + ], + + 'slack' => [ + 'notifications' => [ + 'bot_user_oauth_token' => env('SLACK_BOT_USER_OAUTH_TOKEN'), + 'channel' => env('SLACK_BOT_USER_DEFAULT_CHANNEL'), + ], + ], + +]; diff --git a/config/session.php b/config/session.php new file mode 100644 index 0000000..2d82fa8 --- /dev/null +++ b/config/session.php @@ -0,0 +1,219 @@ + env('SESSION_DRIVER', 'database'), + + /* + |-------------------------------------------------------------------------- + | Session Lifetime + |-------------------------------------------------------------------------- + | + | Here you may specify the number of minutes that you wish the session + | to be allowed to remain idle before it expires. If you want them + | to expire immediately when the browser is closed then you may + | indicate that via the expire_on_close configuration option. + | + */ + + 'lifetime' => env('SESSION_LIFETIME', 120), + + 'expire_on_close' => env('SESSION_EXPIRE_ON_CLOSE', false), + + /* + |-------------------------------------------------------------------------- + | Session Encryption + |-------------------------------------------------------------------------- + | + | This option allows you to easily specify that all of your session data + | should be encrypted before it's stored. All encryption is performed + | automatically by Laravel and you may use the session like normal. + | + */ + + 'encrypt' => env('SESSION_ENCRYPT', false), + + /* + |-------------------------------------------------------------------------- + | Session File Location + |-------------------------------------------------------------------------- + | + | When utilizing the "file" session driver, the session files are placed + | on disk. The default storage location is defined here; however, you + | are free to provide another location where they should be stored. + | + */ + + 'files' => storage_path('framework/sessions'), + + /* + |-------------------------------------------------------------------------- + | Session Database Connection + |-------------------------------------------------------------------------- + | + | When using the "database" or "redis" session drivers, you may specify a + | connection that should be used to manage these sessions. This should + | correspond to a connection in your database configuration options. + | + */ + + 'connection' => env('SESSION_CONNECTION'), + + /* + |-------------------------------------------------------------------------- + | Session Database Table + |-------------------------------------------------------------------------- + | + | When using the "database" session driver, you may specify the table to + | be used to store sessions. Of course, a sensible default is defined + | for you; however, you're welcome to change this to another table. + | + */ + + 'table' => env('SESSION_TABLE', 'sessions'), + + /* + |-------------------------------------------------------------------------- + | Session Cache Store + |-------------------------------------------------------------------------- + | + | When using one of the framework's cache driven session backends, you may + | define the cache store which should be used to store the session data + | between requests. This must match one of your defined cache stores. + | + | Affects: "apc", "dynamodb", "memcached", "redis" + | + */ + + 'store' => env('SESSION_STORE'), + + /* + |-------------------------------------------------------------------------- + | Session Sweeping Lottery + |-------------------------------------------------------------------------- + | + | Some session drivers must manually sweep their storage location to get + | rid of old sessions from storage. Here are the chances that it will + | happen on a given request. By default, the odds are 2 out of 100. + | + */ + + 'lottery' => [2, 100], + + /* + |-------------------------------------------------------------------------- + | Session Cookie Name + |-------------------------------------------------------------------------- + | + | Here you may change the name of the session cookie that is created by + | the framework. Typically, you should not need to change this value + | since doing so does not grant a meaningful security improvement. + | + */ + + 'cookie' => env( + 'SESSION_COOKIE', + Str::slug(env('APP_NAME', 'laravel'), '_').'_session' + ), + + /* + |-------------------------------------------------------------------------- + | Session Cookie Path + |-------------------------------------------------------------------------- + | + | The session cookie path determines the path for which the cookie will + | be regarded as available. Typically, this will be the root path of + | your application, but you're free to change this when necessary. + | + */ + + 'path' => env('SESSION_PATH', '/'), + + /* + |-------------------------------------------------------------------------- + | Session Cookie Domain + |-------------------------------------------------------------------------- + | + | This value determines the domain and subdomains the session cookie is + | available to. By default, the cookie will be available to the root + | domain and all subdomains. Typically, this shouldn't be changed. + | + */ + + 'domain' => env('SESSION_DOMAIN'), + + /* + |-------------------------------------------------------------------------- + | HTTPS Only Cookies + |-------------------------------------------------------------------------- + | + | By setting this option to true, session cookies will only be sent back + | to the server if the browser has a HTTPS connection. This will keep + | the cookie from being sent to you when it can't be done securely. + | + */ + + 'secure' => env('SESSION_SECURE_COOKIE'), + + /* + |-------------------------------------------------------------------------- + | HTTP Access Only + |-------------------------------------------------------------------------- + | + | Setting this value to true will prevent JavaScript from accessing the + | value of the cookie and the cookie will only be accessible through + | the HTTP protocol. It's unlikely you should disable this option. + | + */ + + 'http_only' => env('SESSION_HTTP_ONLY', true), + + /* + |-------------------------------------------------------------------------- + | Same-Site Cookies + |-------------------------------------------------------------------------- + | + | This option determines how your cookies behave when cross-site requests + | take place, and can be used to mitigate CSRF attacks. By default, we + | will set this value to "lax" to permit secure cross-site requests. + | + | See: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie#samesitesamesite-value + | + | Supported: "lax", "strict", "none", null + | + */ + + 'same_site' => env('SESSION_SAME_SITE', 'lax'), + + /* + |-------------------------------------------------------------------------- + | Partitioned Cookies + |-------------------------------------------------------------------------- + | + | Setting this value to true will tie the cookie to the top-level site for + | a cross-site context. Partitioned cookies are accepted by the browser + | when flagged "secure" and the Same-Site attribute is set to "none". + | + */ + + 'partitioned' => env('SESSION_PARTITIONED_COOKIE', false), + +]; diff --git a/database/.gitignore b/database/.gitignore new file mode 100644 index 0000000..9b19b93 --- /dev/null +++ b/database/.gitignore @@ -0,0 +1 @@ +*.sqlite* diff --git a/database/factories/UserFactory.php b/database/factories/UserFactory.php new file mode 100644 index 0000000..c6f6e5f --- /dev/null +++ b/database/factories/UserFactory.php @@ -0,0 +1,26 @@ + + */ +class UserFactory extends Factory +{ + protected static string $password = 'password'; + + public function definition(): array + { + return [ + 'name' => fake()->name(), + 'email' => fake()->unique()->safeEmail(), + 'password' => Hash::make(static::$password), + ]; + } +} diff --git a/database/factories/WalletFactory.php b/database/factories/WalletFactory.php new file mode 100644 index 0000000..299555d --- /dev/null +++ b/database/factories/WalletFactory.php @@ -0,0 +1,44 @@ + + */ +class WalletFactory extends Factory +{ + public function definition(): array + { + return [ + 'balance' => 0, + ]; + } + + public function balance(int $balance): static + { + return $this->state(fn (array $attributes) => [ + 'balance' => $balance, + ]); + } + + public function richChillGuy(): static + { + return $this + ->state(fn (array $attributes) => [ + 'balance' => 1_000_000, + ]) + ->has( + WalletTransaction::factory() + ->amount(1_000_000) + ->credit() + ->reason('Just a rich chill guy'), + 'transactions' + ); + } +} diff --git a/database/factories/WalletTransactionFactory.php b/database/factories/WalletTransactionFactory.php new file mode 100644 index 0000000..d66085d --- /dev/null +++ b/database/factories/WalletTransactionFactory.php @@ -0,0 +1,59 @@ + + */ +class WalletTransactionFactory extends Factory +{ + public function definition(): array + { + return [ + 'amount' => fake()->numberBetween(1, 100), + 'type' => fake()->randomElement([ + WalletTransactionType::DEBIT, + WalletTransactionType::CREDIT, + ]), + 'reason' => fake()->sentence(), + ]; + } + + public function credit(): self + { + return $this->state(function (array $attributes) { + return [ + 'type' => WalletTransactionType::CREDIT, + ]; + }); + } + + public function debit(): self + { + return $this->state(function (array $attributes) { + return [ + 'type' => WalletTransactionType::DEBIT, + ]; + }); + } + + public function amount(int $amount): self + { + return $this->state(fn (array $attributes) => [ + 'amount' => $amount, + ]); + } + + public function reason(string $reason): self + { + return $this->state(fn (array $attributes) => [ + 'reason' => $reason, + ]); + } +} diff --git a/database/factories/WalletTransferFactory.php b/database/factories/WalletTransferFactory.php new file mode 100644 index 0000000..fa085a0 --- /dev/null +++ b/database/factories/WalletTransferFactory.php @@ -0,0 +1,28 @@ + + */ +class WalletTransferFactory extends Factory +{ + public function definition(): array + { + return [ + 'amount' => fake()->numberBetween(1, 100), + ]; + } + + public function amount(int $amount): self + { + return $this->state(fn (array $attributes) => [ + 'amount' => $amount, + ]); + } +} diff --git a/database/migrations/0001_01_01_000000_create_users_table.php b/database/migrations/0001_01_01_000000_create_users_table.php new file mode 100644 index 0000000..3840d47 --- /dev/null +++ b/database/migrations/0001_01_01_000000_create_users_table.php @@ -0,0 +1,42 @@ +id(); + $table->string('name'); + $table->string('email')->unique(); + $table->string('password'); + $table->timestamps(); + }); + + Schema::create('sessions', function (Blueprint $table) { + $table->string('id')->primary(); + $table->foreignId('user_id')->nullable()->index(); + $table->string('ip_address', 45)->nullable(); + $table->text('user_agent')->nullable(); + $table->longText('payload'); + $table->integer('last_activity')->index(); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::dropIfExists('users'); + Schema::dropIfExists('sessions'); + } +}; diff --git a/database/migrations/0001_01_01_000001_create_cache_table.php b/database/migrations/0001_01_01_000001_create_cache_table.php new file mode 100644 index 0000000..960e12b --- /dev/null +++ b/database/migrations/0001_01_01_000001_create_cache_table.php @@ -0,0 +1,37 @@ +string('key')->primary(); + $table->mediumText('value'); + $table->integer('expiration'); + }); + + Schema::create('cache_locks', function (Blueprint $table) { + $table->string('key')->primary(); + $table->string('owner'); + $table->integer('expiration'); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::dropIfExists('cache'); + Schema::dropIfExists('cache_locks'); + } +}; diff --git a/database/migrations/0001_01_01_000002_create_jobs_table.php b/database/migrations/0001_01_01_000002_create_jobs_table.php new file mode 100644 index 0000000..0dcb8c4 --- /dev/null +++ b/database/migrations/0001_01_01_000002_create_jobs_table.php @@ -0,0 +1,59 @@ +id(); + $table->string('queue')->index(); + $table->longText('payload'); + $table->unsignedTinyInteger('attempts'); + $table->unsignedInteger('reserved_at')->nullable(); + $table->unsignedInteger('available_at'); + $table->unsignedInteger('created_at'); + }); + + Schema::create('job_batches', function (Blueprint $table) { + $table->string('id')->primary(); + $table->string('name'); + $table->integer('total_jobs'); + $table->integer('pending_jobs'); + $table->integer('failed_jobs'); + $table->longText('failed_job_ids'); + $table->mediumText('options')->nullable(); + $table->integer('cancelled_at')->nullable(); + $table->integer('created_at'); + $table->integer('finished_at')->nullable(); + }); + + Schema::create('failed_jobs', function (Blueprint $table) { + $table->id(); + $table->string('uuid')->unique(); + $table->text('connection'); + $table->text('queue'); + $table->longText('payload'); + $table->longText('exception'); + $table->timestamp('failed_at')->useCurrent(); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::dropIfExists('jobs'); + Schema::dropIfExists('job_batches'); + Schema::dropIfExists('failed_jobs'); + } +}; diff --git a/database/migrations/2024_12_02_153631_create_wallets_table.php b/database/migrations/2024_12_02_153631_create_wallets_table.php new file mode 100644 index 0000000..cea02fc --- /dev/null +++ b/database/migrations/2024_12_02_153631_create_wallets_table.php @@ -0,0 +1,33 @@ +id(); + + $table->foreignId('user_id')->constrained('users'); + $table->integer('balance')->default(0)->unsigned(); + + $table->timestamps(); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::dropIfExists('wallets'); + } +}; diff --git a/database/migrations/2024_12_02_153635_create_wallet_transactions_table.php b/database/migrations/2024_12_02_153635_create_wallet_transactions_table.php new file mode 100644 index 0000000..ac4bdc6 --- /dev/null +++ b/database/migrations/2024_12_02_153635_create_wallet_transactions_table.php @@ -0,0 +1,38 @@ +id(); + + $table->foreignId('wallet_id')->constrained('wallets'); + + $table->foreignId('transfer_id')->nullable()->constrained('wallet_transfers'); + + $table->integer('amount')->unsigned(); + $table->string('type'); + $table->string('reason'); + + $table->timestamps(); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::dropIfExists('wallet_transactions'); + } +}; diff --git a/database/migrations/2024_12_02_153635_create_wallet_transfers_table.php b/database/migrations/2024_12_02_153635_create_wallet_transfers_table.php new file mode 100644 index 0000000..c75406f --- /dev/null +++ b/database/migrations/2024_12_02_153635_create_wallet_transfers_table.php @@ -0,0 +1,35 @@ +id(); + + $table->foreignId('source_id')->constrained('wallets'); + $table->foreignId('target_id')->constrained('wallets'); + + $table->integer('amount')->unsigned(); + + $table->timestamps(); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::dropIfExists('wallet_transfers'); + } +}; diff --git a/database/migrations/2024_12_03_184444_create_personal_access_tokens_table.php b/database/migrations/2024_12_03_184444_create_personal_access_tokens_table.php new file mode 100644 index 0000000..8dd13c9 --- /dev/null +++ b/database/migrations/2024_12_03_184444_create_personal_access_tokens_table.php @@ -0,0 +1,35 @@ +id(); + $table->morphs('tokenable'); + $table->string('name'); + $table->string('token', 64)->unique(); + $table->text('abilities')->nullable(); + $table->timestamp('last_used_at')->nullable(); + $table->timestamp('expires_at')->nullable(); + $table->timestamps(); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::dropIfExists('personal_access_tokens'); + } +}; diff --git a/database/seeders/DatabaseSeeder.php b/database/seeders/DatabaseSeeder.php new file mode 100644 index 0000000..f925afd --- /dev/null +++ b/database/seeders/DatabaseSeeder.php @@ -0,0 +1,29 @@ +has(Wallet::factory()->richChillGuy())->create([ + 'name' => 'Rich Chill Guy', + 'email' => 'rich.chill.guy@test.fr', + ]); + + User::factory()->has(Wallet::factory())->create([ + 'name' => 'Another Guy', + 'email' => 'another.guy@test.fr', + ]); + } +} diff --git a/mcd.png b/mcd.png new file mode 100644 index 0000000000000000000000000000000000000000..bd844e9a5409353026698093feb40b54a5867772 GIT binary patch literal 79764 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" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@esbuild/aix-ppc64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.21.5.tgz", + "integrity": "sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "aix" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/android-arm": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.21.5.tgz", + "integrity": "sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/android-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.21.5.tgz", + "integrity": "sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/android-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.21.5.tgz", + "integrity": "sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/darwin-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.21.5.tgz", + "integrity": "sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/darwin-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.21.5.tgz", + "integrity": "sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/freebsd-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.21.5.tgz", + "integrity": "sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/freebsd-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.21.5.tgz", + "integrity": "sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-arm": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.21.5.tgz", + "integrity": "sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.21.5.tgz", + "integrity": "sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-ia32": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.21.5.tgz", + "integrity": "sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-loong64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.21.5.tgz", + "integrity": "sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg==", + "cpu": [ + "loong64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-mips64el": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.21.5.tgz", + "integrity": "sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg==", + "cpu": [ + "mips64el" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-ppc64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.21.5.tgz", + "integrity": "sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-riscv64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.21.5.tgz", + "integrity": "sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-s390x": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.21.5.tgz", + "integrity": "sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.21.5.tgz", + "integrity": "sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/netbsd-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.21.5.tgz", + "integrity": "sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/openbsd-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.21.5.tgz", + "integrity": "sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/sunos-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.21.5.tgz", + "integrity": "sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.21.5.tgz", + "integrity": "sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-ia32": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.21.5.tgz", + "integrity": "sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.21.5.tgz", + "integrity": "sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@isaacs/cliui": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", + "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==", + "dev": true, + "license": "ISC", + "dependencies": { + "string-width": "^5.1.2", + "string-width-cjs": "npm:string-width@^4.2.0", + "strip-ansi": "^7.0.1", + "strip-ansi-cjs": "npm:strip-ansi@^6.0.1", + "wrap-ansi": "^8.1.0", + "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@jridgewell/gen-mapping": { + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz", + "integrity": "sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/set-array": "^1.2.1", + "@jridgewell/sourcemap-codec": "^1.4.10", + "@jridgewell/trace-mapping": "^0.3.24" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", + "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/set-array": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.2.1.tgz", + "integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz", + "integrity": "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.25", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz", + "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" + } + }, + "node_modules/@nodelib/fs.scandir": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.stat": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.walk": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", + "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@pkgjs/parseargs": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", + "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==", + "dev": true, + "license": "MIT", + "optional": true, + "engines": { + "node": ">=14" + } + }, + "node_modules/@rollup/rollup-android-arm-eabi": { + "version": "4.28.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.28.0.tgz", + "integrity": "sha512-wLJuPLT6grGZsy34g4N1yRfYeouklTgPhH1gWXCYspenKYD0s3cR99ZevOGw5BexMNywkbV3UkjADisozBmpPQ==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-android-arm64": { + "version": "4.28.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.28.0.tgz", + "integrity": "sha512-eiNkznlo0dLmVG/6wf+Ifi/v78G4d4QxRhuUl+s8EWZpDewgk7PX3ZyECUXU0Zq/Ca+8nU8cQpNC4Xgn2gFNDA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-darwin-arm64": { + "version": "4.28.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.28.0.tgz", + "integrity": "sha512-lmKx9yHsppblnLQZOGxdO66gT77bvdBtr/0P+TPOseowE7D9AJoBw8ZDULRasXRWf1Z86/gcOdpBrV6VDUY36Q==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-darwin-x64": { + "version": "4.28.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.28.0.tgz", + "integrity": "sha512-8hxgfReVs7k9Js1uAIhS6zq3I+wKQETInnWQtgzt8JfGx51R1N6DRVy3F4o0lQwumbErRz52YqwjfvuwRxGv1w==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-freebsd-arm64": { + "version": "4.28.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.28.0.tgz", + "integrity": "sha512-lA1zZB3bFx5oxu9fYud4+g1mt+lYXCoch0M0V/xhqLoGatbzVse0wlSQ1UYOWKpuSu3gyN4qEc0Dxf/DII1bhQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/@rollup/rollup-freebsd-x64": { + "version": "4.28.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.28.0.tgz", + "integrity": "sha512-aI2plavbUDjCQB/sRbeUZWX9qp12GfYkYSJOrdYTL/C5D53bsE2/nBPuoiJKoWp5SN78v2Vr8ZPnB+/VbQ2pFA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/@rollup/rollup-linux-arm-gnueabihf": { + "version": "4.28.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.28.0.tgz", + "integrity": "sha512-WXveUPKtfqtaNvpf0iOb0M6xC64GzUX/OowbqfiCSXTdi/jLlOmH0Ba94/OkiY2yTGTwteo4/dsHRfh5bDCZ+w==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm-musleabihf": { + "version": "4.28.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.28.0.tgz", + "integrity": "sha512-yLc3O2NtOQR67lI79zsSc7lk31xjwcaocvdD1twL64PK1yNaIqCeWI9L5B4MFPAVGEVjH5k1oWSGuYX1Wutxpg==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-gnu": { + "version": "4.28.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.28.0.tgz", + "integrity": "sha512-+P9G9hjEpHucHRXqesY+3X9hD2wh0iNnJXX/QhS/J5vTdG6VhNYMxJ2rJkQOxRUd17u5mbMLHM7yWGZdAASfcg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-musl": { + "version": "4.28.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.28.0.tgz", + "integrity": "sha512-1xsm2rCKSTpKzi5/ypT5wfc+4bOGa/9yI/eaOLW0oMs7qpC542APWhl4A37AENGZ6St6GBMWhCCMM6tXgTIplw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-powerpc64le-gnu": { + "version": "4.28.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.28.0.tgz", + "integrity": "sha512-zgWxMq8neVQeXL+ouSf6S7DoNeo6EPgi1eeqHXVKQxqPy1B2NvTbaOUWPn/7CfMKL7xvhV0/+fq/Z/J69g1WAQ==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-riscv64-gnu": { + "version": "4.28.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.28.0.tgz", + "integrity": "sha512-VEdVYacLniRxbRJLNtzwGt5vwS0ycYshofI7cWAfj7Vg5asqj+pt+Q6x4n+AONSZW/kVm+5nklde0qs2EUwU2g==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-s390x-gnu": { + "version": "4.28.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.28.0.tgz", + "integrity": "sha512-LQlP5t2hcDJh8HV8RELD9/xlYtEzJkm/aWGsauvdO2ulfl3QYRjqrKW+mGAIWP5kdNCBheqqqYIGElSRCaXfpw==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-gnu": { + "version": "4.28.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.28.0.tgz", + "integrity": "sha512-Nl4KIzteVEKE9BdAvYoTkW19pa7LR/RBrT6F1dJCV/3pbjwDcaOq+edkP0LXuJ9kflW/xOK414X78r+K84+msw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-musl": { + "version": "4.28.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.28.0.tgz", + "integrity": "sha512-eKpJr4vBDOi4goT75MvW+0dXcNUqisK4jvibY9vDdlgLx+yekxSm55StsHbxUsRxSTt3JEQvlr3cGDkzcSP8bw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-win32-arm64-msvc": { + "version": "4.28.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.28.0.tgz", + "integrity": "sha512-Vi+WR62xWGsE/Oj+mD0FNAPY2MEox3cfyG0zLpotZdehPFXwz6lypkGs5y38Jd/NVSbOD02aVad6q6QYF7i8Bg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-ia32-msvc": { + "version": "4.28.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.28.0.tgz", + "integrity": "sha512-kN/Vpip8emMLn/eOza+4JwqDZBL6MPNpkdaEsgUtW1NYN3DZvZqSQrbKzJcTL6hd8YNmFTn7XGWMwccOcJBL0A==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-x64-msvc": { + "version": "4.28.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.28.0.tgz", + "integrity": "sha512-Bvno2/aZT6usSa7lRDL2+hMjVAGjuqaymF1ApZm31JXzniR/hvr14jpU+/z4X6Gt5BPlzosscyJZGUvguXIqeQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@tailwindcss/forms": { + "version": "0.5.9", + "resolved": "https://registry.npmjs.org/@tailwindcss/forms/-/forms-0.5.9.tgz", + "integrity": "sha512-tM4XVr2+UVTxXJzey9Twx48c1gcxFStqn1pQz0tRsX8o3DvxhN5oY5pvyAbUx7VTaZxpej4Zzvc6h+1RJBzpIg==", + "dev": true, + "license": "MIT", + "dependencies": { + "mini-svg-data-uri": "^1.2.3" + }, + "peerDependencies": { + "tailwindcss": ">=3.0.0 || >= 3.0.0-alpha.1 || >= 4.0.0-alpha.20" + } + }, + "node_modules/@types/estree": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.6.tgz", + "integrity": "sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==", + "dev": true, + "license": "MIT" + }, + "node_modules/@vue/reactivity": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/@vue/reactivity/-/reactivity-3.1.5.tgz", + "integrity": "sha512-1tdfLmNjWG6t/CsPldh+foumYFo3cpyCHgBYQ34ylaMsJ+SNHQ1kApMIa8jN+i593zQuaw3AdWH0nJTARzCFhg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vue/shared": "3.1.5" + } + }, + "node_modules/@vue/shared": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.1.5.tgz", + "integrity": "sha512-oJ4F3TnvpXaQwZJNF3ZK+kLPHKarDmJjJ6jyzVNDKH9md1dptjC7lWR//jrGuLdek/U6iltWxqAnYOu8gCiOvA==", + "dev": true, + "license": "MIT" + }, + "node_modules/alpinejs": { + "version": "3.14.5", + "resolved": "https://registry.npmjs.org/alpinejs/-/alpinejs-3.14.5.tgz", + "integrity": "sha512-S2Y9s15ONh9SiStZ8h7UYmCzMfM7chB4ddGHv2G1IXzAOrTVci01UcsafMgIOefjfiUXxPs3kPBzoYcyMZ2TZA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vue/reactivity": "~3.1.1" + } + }, + "node_modules/ansi-regex": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.1.0.tgz", + "integrity": "sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/any-promise": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/any-promise/-/any-promise-1.3.0.tgz", + "integrity": "sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==", + "dev": true, + "license": "MIT" + }, + "node_modules/anymatch": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", + "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", + "dev": true, + "license": "ISC", + "dependencies": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/arg": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/arg/-/arg-5.0.2.tgz", + "integrity": "sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==", + "dev": true, + "license": "MIT" + }, + "node_modules/asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", + "dev": true, + "license": "MIT" + }, + "node_modules/autoprefixer": { + "version": "10.4.20", + "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.20.tgz", + "integrity": "sha512-XY25y5xSv/wEoqzDyXXME4AFfkZI0P23z6Fs3YgymDnKJkCGOnkL0iTxCa85UTqaSgfcqyf3UA6+c7wUvx/16g==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/autoprefixer" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "browserslist": "^4.23.3", + "caniuse-lite": "^1.0.30001646", + "fraction.js": "^4.3.7", + "normalize-range": "^0.1.2", + "picocolors": "^1.0.1", + "postcss-value-parser": "^4.2.0" + }, + "bin": { + "autoprefixer": "bin/autoprefixer" + }, + "engines": { + "node": "^10 || ^12 || >=14" + }, + "peerDependencies": { + "postcss": "^8.1.0" + } + }, + "node_modules/axios": { + "version": "1.7.8", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.7.8.tgz", + "integrity": "sha512-Uu0wb7KNqK2t5K+YQyVCLM76prD5sRFjKHbJYCP1J7JFGEQ6nN7HWn9+04LAeiJ3ji54lgS/gZCH1oxyrf1SPw==", + "dev": true, + "license": "MIT", + "dependencies": { + "follow-redirects": "^1.15.6", + "form-data": "^4.0.0", + "proxy-from-env": "^1.1.0" + } + }, + "node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true, + "license": "MIT" + }, + "node_modules/binary-extensions": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz", + "integrity": "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/braces": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", + "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", + "dev": true, + "license": "MIT", + "dependencies": { + "fill-range": "^7.1.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/browserslist": { + "version": "4.24.2", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.24.2.tgz", + "integrity": "sha512-ZIc+Q62revdMcqC6aChtW4jz3My3klmCO1fEmINZY/8J3EpBg5/A/D0AKmBveUh6pgoeycoMkVMko84tuYS+Gg==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "caniuse-lite": "^1.0.30001669", + "electron-to-chromium": "^1.5.41", + "node-releases": "^2.0.18", + "update-browserslist-db": "^1.1.1" + }, + "bin": { + "browserslist": "cli.js" + }, + "engines": { + "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" + } + }, + "node_modules/camelcase-css": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/camelcase-css/-/camelcase-css-2.0.1.tgz", + "integrity": "sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 6" + } + }, + "node_modules/caniuse-lite": { + "version": "1.0.30001685", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001685.tgz", + "integrity": "sha512-e/kJN1EMyHQzgcMEEgoo+YTCO1NGCmIYHk5Qk8jT6AazWemS5QFKJ5ShCJlH3GZrNIdZofcNCEwZqbMjjKzmnA==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/caniuse-lite" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "CC-BY-4.0" + }, + "node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/chalk/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/chokidar": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", + "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==", + "dev": true, + "license": "MIT", + "dependencies": { + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "glob-parent": "~5.1.2", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.6.0" + }, + "engines": { + "node": ">= 8.10.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + } + }, + "node_modules/chokidar/node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/cliui": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", + "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.1", + "wrap-ansi": "^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/cliui/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/cliui/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true, + "license": "MIT" + }, + "node_modules/cliui/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/cliui/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/cliui/node_modules/wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true, + "license": "MIT" + }, + "node_modules/combined-stream": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "dev": true, + "license": "MIT", + "dependencies": { + "delayed-stream": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/commander": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/commander/-/commander-4.1.1.tgz", + "integrity": "sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 6" + } + }, + "node_modules/concurrently": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/concurrently/-/concurrently-9.1.0.tgz", + "integrity": "sha512-VxkzwMAn4LP7WyMnJNbHN5mKV9L2IbyDjpzemKr99sXNR3GqRNMMHdm7prV1ws9wg7ETj6WUkNOigZVsptwbgg==", + "dev": true, + "license": "MIT", + "dependencies": { + "chalk": "^4.1.2", + "lodash": "^4.17.21", + "rxjs": "^7.8.1", + "shell-quote": "^1.8.1", + "supports-color": "^8.1.1", + "tree-kill": "^1.2.2", + "yargs": "^17.7.2" + }, + "bin": { + "conc": "dist/bin/concurrently.js", + "concurrently": "dist/bin/concurrently.js" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/open-cli-tools/concurrently?sponsor=1" + } + }, + "node_modules/cross-spawn": { + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", + "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", + "dev": true, + "license": "MIT", + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/cssesc": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz", + "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==", + "dev": true, + "license": "MIT", + "bin": { + "cssesc": "bin/cssesc" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/didyoumean": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/didyoumean/-/didyoumean-1.2.2.tgz", + "integrity": "sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw==", + "dev": true, + "license": "Apache-2.0" + }, + "node_modules/dlv": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/dlv/-/dlv-1.1.3.tgz", + "integrity": "sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==", + "dev": true, + "license": "MIT" + }, + "node_modules/eastasianwidth": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", + "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==", + "dev": true, + "license": "MIT" + }, + "node_modules/electron-to-chromium": { + "version": "1.5.67", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.67.tgz", + "integrity": "sha512-nz88NNBsD7kQSAGGJyp8hS6xSPtWwqNogA0mjtc2nUYeEf3nURK9qpV18TuBdDmEDgVWotS8Wkzf+V52dSQ/LQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/emoji-regex": { + "version": "9.2.2", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", + "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", + "dev": true, + "license": "MIT" + }, + "node_modules/esbuild": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.21.5.tgz", + "integrity": "sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=12" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.21.5", + "@esbuild/android-arm": "0.21.5", + "@esbuild/android-arm64": "0.21.5", + "@esbuild/android-x64": "0.21.5", + "@esbuild/darwin-arm64": "0.21.5", + "@esbuild/darwin-x64": "0.21.5", + "@esbuild/freebsd-arm64": "0.21.5", + "@esbuild/freebsd-x64": "0.21.5", + "@esbuild/linux-arm": "0.21.5", + "@esbuild/linux-arm64": "0.21.5", + "@esbuild/linux-ia32": "0.21.5", + "@esbuild/linux-loong64": "0.21.5", + "@esbuild/linux-mips64el": "0.21.5", + "@esbuild/linux-ppc64": "0.21.5", + "@esbuild/linux-riscv64": "0.21.5", + "@esbuild/linux-s390x": "0.21.5", + "@esbuild/linux-x64": "0.21.5", + "@esbuild/netbsd-x64": "0.21.5", + "@esbuild/openbsd-x64": "0.21.5", + "@esbuild/sunos-x64": "0.21.5", + "@esbuild/win32-arm64": "0.21.5", + "@esbuild/win32-ia32": "0.21.5", + "@esbuild/win32-x64": "0.21.5" + } + }, + "node_modules/escalade": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", + "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/fast-glob": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.2.tgz", + "integrity": "sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==", + "dev": true, + "license": "MIT", + "dependencies": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.2", + "merge2": "^1.3.0", + "micromatch": "^4.0.4" + }, + "engines": { + "node": ">=8.6.0" + } + }, + "node_modules/fast-glob/node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/fastq": { + "version": "1.17.1", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.17.1.tgz", + "integrity": "sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==", + "dev": true, + "license": "ISC", + "dependencies": { + "reusify": "^1.0.4" + } + }, + "node_modules/fill-range": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", + "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", + "dev": true, + "license": "MIT", + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/follow-redirects": { + "version": "1.15.9", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.9.tgz", + "integrity": "sha512-gew4GsXizNgdoRyqmyfMHyAmXsZDk6mHkSxZFCzW9gwlbtOW44CDtYavM+y+72qD/Vq2l550kMF52DT8fOLJqQ==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/RubenVerborgh" + } + ], + "license": "MIT", + "engines": { + "node": ">=4.0" + }, + "peerDependenciesMeta": { + "debug": { + "optional": true + } + } + }, + "node_modules/foreground-child": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.3.0.tgz", + "integrity": "sha512-Ld2g8rrAyMYFXBhEqMz8ZAHBi4J4uS1i/CxGMDnjyFWddMXLVcDp051DZfu+t7+ab7Wv6SMqpWmyFIj5UbfFvg==", + "dev": true, + "license": "ISC", + "dependencies": { + "cross-spawn": "^7.0.0", + "signal-exit": "^4.0.1" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/form-data": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.1.tgz", + "integrity": "sha512-tzN8e4TX8+kkxGPK8D5u0FNmjPUjw3lwC9lSLxxoB/+GtsJG91CO8bSWy73APlgAZzZbXEYZJuxjkHH2w+Ezhw==", + "dev": true, + "license": "MIT", + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/fraction.js": { + "version": "4.3.7", + "resolved": "https://registry.npmjs.org/fraction.js/-/fraction.js-4.3.7.tgz", + "integrity": "sha512-ZsDfxO51wGAXREY55a7la9LScWpwv9RxIrYABrlvOFBlH/ShPnrtsXeuUIfXKKOVicNxQ+o8JTbJvjS4M89yew==", + "dev": true, + "license": "MIT", + "engines": { + "node": "*" + }, + "funding": { + "type": "patreon", + "url": "https://github.com/sponsors/rawify" + } + }, + "node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/function-bind": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "dev": true, + "license": "ISC", + "engines": { + "node": "6.* || 8.* || >= 10.*" + } + }, + "node_modules/glob": { + "version": "10.4.5", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz", + "integrity": "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==", + "dev": true, + "license": "ISC", + "dependencies": { + "foreground-child": "^3.1.0", + "jackspeak": "^3.1.2", + "minimatch": "^9.0.4", + "minipass": "^7.1.2", + "package-json-from-dist": "^1.0.0", + "path-scurry": "^1.11.1" + }, + "bin": { + "glob": "dist/esm/bin.mjs" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/glob-parent": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", + "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", + "dev": true, + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.3" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/hasown": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", + "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/is-binary-path": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "dev": true, + "license": "MIT", + "dependencies": { + "binary-extensions": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-core-module": { + "version": "2.15.1", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.15.1.tgz", + "integrity": "sha512-z0vtXSwucUJtANQWldhbtbt7BnL0vxiFjIdDLAatwhDYty2bad6s+rijD6Ri4YuYJubLzIJLUidCh09e1djEVQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "dev": true, + "license": "ISC" + }, + "node_modules/jackspeak": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-3.4.3.tgz", + "integrity": "sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "@isaacs/cliui": "^8.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + }, + "optionalDependencies": { + "@pkgjs/parseargs": "^0.11.0" + } + }, + "node_modules/jiti": { + "version": "1.21.6", + "resolved": "https://registry.npmjs.org/jiti/-/jiti-1.21.6.tgz", + "integrity": "sha512-2yTgeWTWzMWkHu6Jp9NKgePDaYHbntiwvYuuJLbbN9vl7DC9DvXKOB2BC3ZZ92D3cvV/aflH0osDfwpHepQ53w==", + "dev": true, + "license": "MIT", + "bin": { + "jiti": "bin/jiti.js" + } + }, + "node_modules/laravel-vite-plugin": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/laravel-vite-plugin/-/laravel-vite-plugin-1.0.6.tgz", + "integrity": "sha512-B34OqmZc/rV1KvSjst8SsUm/LKHsuDusw8jiZCIhlnTHXbXnK89JUM9pTJuk6E/Vc/1DT2gX7qNfhipak1WS8w==", + "dev": true, + "license": "MIT", + "dependencies": { + "picocolors": "^1.0.0", + "vite-plugin-full-reload": "^1.1.0" + }, + "bin": { + "clean-orphaned-assets": "bin/clean.js" + }, + "engines": { + "node": "^18.0.0 || >=20.0.0" + }, + "peerDependencies": { + "vite": "^5.0.0" + } + }, + "node_modules/lilconfig": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-2.1.0.tgz", + "integrity": "sha512-utWOt/GHzuUxnLKxB6dk81RoOeoNeHgbrXiuGk4yyF5qlRz+iIVWu56E2fqGHFrXz0QNUhLB/8nKqvRH66JKGQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + } + }, + "node_modules/lines-and-columns": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", + "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", + "dev": true, + "license": "MIT" + }, + "node_modules/lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", + "dev": true, + "license": "MIT" + }, + "node_modules/lru-cache": { + "version": "10.4.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", + "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/merge2": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 8" + } + }, + "node_modules/micromatch": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", + "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==", + "dev": true, + "license": "MIT", + "dependencies": { + "braces": "^3.0.3", + "picomatch": "^2.3.1" + }, + "engines": { + "node": ">=8.6" + } + }, + "node_modules/mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "dev": true, + "license": "MIT", + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mini-svg-data-uri": { + "version": "1.4.4", + "resolved": "https://registry.npmjs.org/mini-svg-data-uri/-/mini-svg-data-uri-1.4.4.tgz", + "integrity": "sha512-r9deDe9p5FJUPZAk3A59wGH7Ii9YrjjWw0jmw/liSbHl2CHiyXj6FcDXDu2K3TjVAXqiJdaw3xxwlZZr9E6nHg==", + "dev": true, + "license": "MIT", + "bin": { + "mini-svg-data-uri": "cli.js" + } + }, + "node_modules/minimatch": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/minipass": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz", + "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, + "node_modules/mz": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/mz/-/mz-2.7.0.tgz", + "integrity": "sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "any-promise": "^1.0.0", + "object-assign": "^4.0.1", + "thenify-all": "^1.0.0" + } + }, + "node_modules/nanoid": { + "version": "3.3.8", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.8.tgz", + "integrity": "sha512-WNLf5Sd8oZxOm+TzppcYk8gVOgP+l58xNy58D0nbUnOxOWRWvlcCV4kUF7ltmI6PsrLl/BgKEyS4mqsGChFN0w==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + } + }, + "node_modules/node-releases": { + "version": "2.0.18", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.18.tgz", + "integrity": "sha512-d9VeXT4SJ7ZeOqGX6R5EM022wpL+eWPooLI+5UpWn2jCT1aosUQEhQP214x33Wkwx3JQMvIm+tIoVOdodFS40g==", + "dev": true, + "license": "MIT" + }, + "node_modules/normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/normalize-range": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/normalize-range/-/normalize-range-0.1.2.tgz", + "integrity": "sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object-hash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/object-hash/-/object-hash-3.0.0.tgz", + "integrity": "sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 6" + } + }, + "node_modules/package-json-from-dist": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.1.tgz", + "integrity": "sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==", + "dev": true, + "license": "BlueOak-1.0.0" + }, + "node_modules/path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/path-parse": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", + "dev": true, + "license": "MIT" + }, + "node_modules/path-scurry": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.11.1.tgz", + "integrity": "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "lru-cache": "^10.2.0", + "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" + }, + "engines": { + "node": ">=16 || 14 >=14.18" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/picocolors": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", + "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", + "dev": true, + "license": "ISC" + }, + "node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/pirates": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.6.tgz", + "integrity": "sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 6" + } + }, + "node_modules/postcss": { + "version": "8.4.49", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.49.tgz", + "integrity": "sha512-OCVPnIObs4N29kxTjzLfUryOkvZEq+pf8jTF0lg8E7uETuWHA+v7j3c/xJmiqpX450191LlmZfUKkXxkTry7nA==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "nanoid": "^3.3.7", + "picocolors": "^1.1.1", + "source-map-js": "^1.2.1" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, + "node_modules/postcss-import": { + "version": "15.1.0", + "resolved": "https://registry.npmjs.org/postcss-import/-/postcss-import-15.1.0.tgz", + "integrity": "sha512-hpr+J05B2FVYUAXHeK1YyI267J/dDDhMU6B6civm8hSY1jYJnBXxzKDKDswzJmtLHryrjhnDjqqp/49t8FALew==", + "dev": true, + "license": "MIT", + "dependencies": { + "postcss-value-parser": "^4.0.0", + "read-cache": "^1.0.0", + "resolve": "^1.1.7" + }, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "postcss": "^8.0.0" + } + }, + "node_modules/postcss-js": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/postcss-js/-/postcss-js-4.0.1.tgz", + "integrity": "sha512-dDLF8pEO191hJMtlHFPRa8xsizHaM82MLfNkUHdUtVEV3tgTp5oj+8qbEqYM57SLfc74KSbw//4SeJma2LRVIw==", + "dev": true, + "license": "MIT", + "dependencies": { + "camelcase-css": "^2.0.1" + }, + "engines": { + "node": "^12 || ^14 || >= 16" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + "peerDependencies": { + "postcss": "^8.4.21" + } + }, + "node_modules/postcss-load-config": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/postcss-load-config/-/postcss-load-config-4.0.2.tgz", + "integrity": "sha512-bSVhyJGL00wMVoPUzAVAnbEoWyqRxkjv64tUl427SKnPrENtq6hJwUojroMz2VB+Q1edmi4IfrAPpami5VVgMQ==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "lilconfig": "^3.0.0", + "yaml": "^2.3.4" + }, + "engines": { + "node": ">= 14" + }, + "peerDependencies": { + "postcss": ">=8.0.9", + "ts-node": ">=9.0.0" + }, + "peerDependenciesMeta": { + "postcss": { + "optional": true + }, + "ts-node": { + "optional": true + } + } + }, + "node_modules/postcss-load-config/node_modules/lilconfig": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-3.1.2.tgz", + "integrity": "sha512-eop+wDAvpItUys0FWkHIKeC9ybYrTGbU41U5K7+bttZZeohvnY7M9dZ5kB21GNWiFT2q1OoPTvncPCgSOVO5ow==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/antonk52" + } + }, + "node_modules/postcss-nested": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/postcss-nested/-/postcss-nested-6.2.0.tgz", + "integrity": "sha512-HQbt28KulC5AJzG+cZtj9kvKB93CFCdLvog1WFLf1D+xmMvPGlBstkpTEZfK5+AN9hfJocyBFCNiqyS48bpgzQ==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "postcss-selector-parser": "^6.1.1" + }, + "engines": { + "node": ">=12.0" + }, + "peerDependencies": { + "postcss": "^8.2.14" + } + }, + "node_modules/postcss-selector-parser": { + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.1.2.tgz", + "integrity": "sha512-Q8qQfPiZ+THO/3ZrOrO0cJJKfpYCagtMUkXbnEfmgUjwXg6z/WBeOyS9APBBPCTSiDV+s4SwQGu8yFsiMRIudg==", + "dev": true, + "license": "MIT", + "dependencies": { + "cssesc": "^3.0.0", + "util-deprecate": "^1.0.2" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/postcss-value-parser": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz", + "integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/proxy-from-env": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", + "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==", + "dev": true, + "license": "MIT" + }, + "node_modules/queue-microtask": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/read-cache": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/read-cache/-/read-cache-1.0.0.tgz", + "integrity": "sha512-Owdv/Ft7IjOgm/i0xvNDZ1LrRANRfew4b2prF3OWMQLxLfu3bS8FVhCsrSCMK4lR56Y9ya+AThoTpDCTxCmpRA==", + "dev": true, + "license": "MIT", + "dependencies": { + "pify": "^2.3.0" + } + }, + "node_modules/readdirp": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "dev": true, + "license": "MIT", + "dependencies": { + "picomatch": "^2.2.1" + }, + "engines": { + "node": ">=8.10.0" + } + }, + "node_modules/require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/resolve": { + "version": "1.22.8", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz", + "integrity": "sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-core-module": "^2.13.0", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/reusify": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", + "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", + "dev": true, + "license": "MIT", + "engines": { + "iojs": ">=1.0.0", + "node": ">=0.10.0" + } + }, + "node_modules/rollup": { + "version": "4.28.0", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.28.0.tgz", + "integrity": "sha512-G9GOrmgWHBma4YfCcX8PjH0qhXSdH8B4HDE2o4/jaxj93S4DPCIDoLcXz99eWMji4hB29UFCEd7B2gwGJDR9cQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/estree": "1.0.6" + }, + "bin": { + "rollup": "dist/bin/rollup" + }, + "engines": { + "node": ">=18.0.0", + "npm": ">=8.0.0" + }, + "optionalDependencies": { + "@rollup/rollup-android-arm-eabi": "4.28.0", + "@rollup/rollup-android-arm64": "4.28.0", + "@rollup/rollup-darwin-arm64": "4.28.0", + "@rollup/rollup-darwin-x64": "4.28.0", + "@rollup/rollup-freebsd-arm64": "4.28.0", + "@rollup/rollup-freebsd-x64": "4.28.0", + "@rollup/rollup-linux-arm-gnueabihf": "4.28.0", + "@rollup/rollup-linux-arm-musleabihf": "4.28.0", + "@rollup/rollup-linux-arm64-gnu": "4.28.0", + "@rollup/rollup-linux-arm64-musl": "4.28.0", + "@rollup/rollup-linux-powerpc64le-gnu": "4.28.0", + "@rollup/rollup-linux-riscv64-gnu": "4.28.0", + "@rollup/rollup-linux-s390x-gnu": "4.28.0", + "@rollup/rollup-linux-x64-gnu": "4.28.0", + "@rollup/rollup-linux-x64-musl": "4.28.0", + "@rollup/rollup-win32-arm64-msvc": "4.28.0", + "@rollup/rollup-win32-ia32-msvc": "4.28.0", + "@rollup/rollup-win32-x64-msvc": "4.28.0", + "fsevents": "~2.3.2" + } + }, + "node_modules/run-parallel": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", + "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT", + "dependencies": { + "queue-microtask": "^1.2.2" + } + }, + "node_modules/rxjs": { + "version": "7.8.1", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.1.tgz", + "integrity": "sha512-AA3TVj+0A2iuIoQkWEK/tqFjBq2j+6PO6Y0zJcvzLAFhEFIO3HL0vls9hWLncZbAAbK0mar7oZ4V079I/qPMxg==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "tslib": "^2.1.0" + } + }, + "node_modules/shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, + "license": "MIT", + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/shell-quote": { + "version": "1.8.2", + "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.8.2.tgz", + "integrity": "sha512-AzqKpGKjrj7EM6rKVQEPpB288oCfnrEIuyoT9cyF4nmGa7V8Zk6f7RRqYisX8X9m+Q7bd632aZW4ky7EhbQztA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/signal-exit": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", + "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/source-map-js": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", + "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/string-width": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", + "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", + "dev": true, + "license": "MIT", + "dependencies": { + "eastasianwidth": "^0.2.0", + "emoji-regex": "^9.2.2", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/string-width-cjs": { + "name": "string-width", + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/string-width-cjs/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/string-width-cjs/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true, + "license": "MIT" + }, + "node_modules/string-width-cjs/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-ansi": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", + "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "node_modules/strip-ansi-cjs": { + "name": "strip-ansi", + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-ansi-cjs/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/sucrase": { + "version": "3.35.0", + "resolved": "https://registry.npmjs.org/sucrase/-/sucrase-3.35.0.tgz", + "integrity": "sha512-8EbVDiu9iN/nESwxeSxDKe0dunta1GOlHufmSSXxMD2z2/tMZpDMpvXQGsc+ajGo8y2uYUmixaSRUc/QPoQ0GA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.2", + "commander": "^4.0.0", + "glob": "^10.3.10", + "lines-and-columns": "^1.1.6", + "mz": "^2.7.0", + "pirates": "^4.0.1", + "ts-interface-checker": "^0.1.9" + }, + "bin": { + "sucrase": "bin/sucrase", + "sucrase-node": "bin/sucrase-node" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, + "node_modules/supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" + } + }, + "node_modules/supports-preserve-symlinks-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", + "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/tailwindcss": { + "version": "3.4.15", + "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.4.15.tgz", + "integrity": "sha512-r4MeXnfBmSOuKUWmXe6h2CcyfzJCEk4F0pptO5jlnYSIViUkVmsawj80N5h2lO3gwcmSb4n3PuN+e+GC1Guylw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@alloc/quick-lru": "^5.2.0", + "arg": "^5.0.2", + "chokidar": "^3.6.0", + "didyoumean": "^1.2.2", + "dlv": "^1.1.3", + "fast-glob": "^3.3.2", + "glob-parent": "^6.0.2", + "is-glob": "^4.0.3", + "jiti": "^1.21.6", + "lilconfig": "^2.1.0", + "micromatch": "^4.0.8", + "normalize-path": "^3.0.0", + "object-hash": "^3.0.0", + "picocolors": "^1.1.1", + "postcss": "^8.4.47", + "postcss-import": "^15.1.0", + "postcss-js": "^4.0.1", + "postcss-load-config": "^4.0.2", + "postcss-nested": "^6.2.0", + "postcss-selector-parser": "^6.1.2", + "resolve": "^1.22.8", + "sucrase": "^3.35.0" + }, + "bin": { + "tailwind": "lib/cli.js", + "tailwindcss": "lib/cli.js" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/thenify": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/thenify/-/thenify-3.3.1.tgz", + "integrity": "sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==", + "dev": true, + "license": "MIT", + "dependencies": { + "any-promise": "^1.0.0" + } + }, + "node_modules/thenify-all": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/thenify-all/-/thenify-all-1.6.0.tgz", + "integrity": "sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==", + "dev": true, + "license": "MIT", + "dependencies": { + "thenify": ">= 3.1.0 < 4" + }, + "engines": { + "node": ">=0.8" + } + }, + "node_modules/to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/tree-kill": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/tree-kill/-/tree-kill-1.2.2.tgz", + "integrity": "sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==", + "dev": true, + "license": "MIT", + "bin": { + "tree-kill": "cli.js" + } + }, + "node_modules/ts-interface-checker": { + "version": "0.1.13", + "resolved": "https://registry.npmjs.org/ts-interface-checker/-/ts-interface-checker-0.1.13.tgz", + "integrity": "sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==", + "dev": true, + "license": "Apache-2.0" + }, + "node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", + "dev": true, + "license": "0BSD" + }, + "node_modules/update-browserslist-db": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.1.tgz", + "integrity": "sha512-R8UzCaa9Az+38REPiJ1tXlImTJXlVfgHZsglwBD/k6nj76ctsH1E3q4doGrukiLQd3sGQYu56r5+lo5r94l29A==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "escalade": "^3.2.0", + "picocolors": "^1.1.0" + }, + "bin": { + "update-browserslist-db": "cli.js" + }, + "peerDependencies": { + "browserslist": ">= 4.21.0" + } + }, + "node_modules/util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", + "dev": true, + "license": "MIT" + }, + "node_modules/vite": { + "version": "5.4.11", + "resolved": "https://registry.npmjs.org/vite/-/vite-5.4.11.tgz", + "integrity": "sha512-c7jFQRklXua0mTzneGW9QVyxFjUgwcihC4bXEtujIo2ouWCe1Ajt/amn2PCxYnhYfd5k09JX3SB7OYWFKYqj8Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "esbuild": "^0.21.3", + "postcss": "^8.4.43", + "rollup": "^4.20.0" + }, + "bin": { + "vite": "bin/vite.js" + }, + "engines": { + "node": "^18.0.0 || >=20.0.0" + }, + "funding": { + "url": "https://github.com/vitejs/vite?sponsor=1" + }, + "optionalDependencies": { + "fsevents": "~2.3.3" + }, + "peerDependencies": { + "@types/node": "^18.0.0 || >=20.0.0", + "less": "*", + "lightningcss": "^1.21.0", + "sass": "*", + "sass-embedded": "*", + "stylus": "*", + "sugarss": "*", + "terser": "^5.4.0" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + }, + "less": { + "optional": true + }, + "lightningcss": { + "optional": true + }, + "sass": { + "optional": true + }, + "sass-embedded": { + "optional": true + }, + "stylus": { + "optional": true + }, + "sugarss": { + "optional": true + }, + "terser": { + "optional": true + } + } + }, + "node_modules/vite-plugin-full-reload": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/vite-plugin-full-reload/-/vite-plugin-full-reload-1.2.0.tgz", + "integrity": "sha512-kz18NW79x0IHbxRSHm0jttP4zoO9P9gXh+n6UTwlNKnviTTEpOlum6oS9SmecrTtSr+muHEn5TUuC75UovQzcA==", + "dev": true, + "license": "MIT", + "dependencies": { + "picocolors": "^1.0.0", + "picomatch": "^2.3.1" + } + }, + "node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "license": "ISC", + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/wrap-ansi": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", + "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^6.1.0", + "string-width": "^5.0.1", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/wrap-ansi-cjs": { + "name": "wrap-ansi", + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/wrap-ansi-cjs/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/wrap-ansi-cjs/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true, + "license": "MIT" + }, + "node_modules/wrap-ansi-cjs/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/wrap-ansi-cjs/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/wrap-ansi/node_modules/ansi-styles": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", + "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/y18n": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=10" + } + }, + "node_modules/yaml": { + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.6.1.tgz", + "integrity": "sha512-7r0XPzioN/Q9kXBro/XPnA6kznR73DHq+GXh5ON7ZozRO6aMjbmiBuKste2wslTFkC5d1dw0GooOCepZXJ2SAg==", + "dev": true, + "license": "ISC", + "bin": { + "yaml": "bin.mjs" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/yargs": { + "version": "17.7.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", + "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", + "dev": true, + "license": "MIT", + "dependencies": { + "cliui": "^8.0.1", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.3", + "y18n": "^5.0.5", + "yargs-parser": "^21.1.1" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/yargs-parser": { + "version": "21.1.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", + "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=12" + } + }, + "node_modules/yargs/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/yargs/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true, + "license": "MIT" + }, + "node_modules/yargs/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/yargs/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + } + } +} diff --git a/package.json b/package.json new file mode 100644 index 0000000..88756a9 --- /dev/null +++ b/package.json @@ -0,0 +1,19 @@ +{ + "private": true, + "type": "module", + "scripts": { + "build": "vite build", + "dev": "vite" + }, + "devDependencies": { + "@tailwindcss/forms": "^0.5.2", + "alpinejs": "^3.4.2", + "autoprefixer": "^10.4.2", + "axios": "^1.7.4", + "concurrently": "^9.0.1", + "laravel-vite-plugin": "^1.0", + "postcss": "^8.4.31", + "tailwindcss": "^3.1.0", + "vite": "^5.0" + } +} diff --git a/phpunit.xml b/phpunit.xml new file mode 100644 index 0000000..506b9a3 --- /dev/null +++ b/phpunit.xml @@ -0,0 +1,33 @@ + + + + + tests/Unit + + + tests/Feature + + + + + app + + + + + + + + + + + + + + + + diff --git a/pint.json b/pint.json new file mode 100644 index 0000000..e23b75b --- /dev/null +++ b/pint.json @@ -0,0 +1,13 @@ +{ + "preset": "laravel", + "rules": { + "declare_strict_types": true, + "method_argument_space": { + "on_multiline": "ensure_fully_multiline", + "keep_multiple_spaces_after_comma": true + }, + "blank_line_before_statement": { + "statements": ["break", "continue", "declare", "return", "throw", "try"] + } + } +} diff --git a/postcss.config.js b/postcss.config.js new file mode 100644 index 0000000..49c0612 --- /dev/null +++ b/postcss.config.js @@ -0,0 +1,6 @@ +export default { + plugins: { + tailwindcss: {}, + autoprefixer: {}, + }, +}; diff --git a/public/.htaccess b/public/.htaccess new file mode 100644 index 0000000..3aec5e2 --- /dev/null +++ b/public/.htaccess @@ -0,0 +1,21 @@ + + + Options -MultiViews -Indexes + + + RewriteEngine On + + # Handle Authorization Header + RewriteCond %{HTTP:Authorization} . + RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}] + + # Redirect Trailing Slashes If Not A Folder... + RewriteCond %{REQUEST_FILENAME} !-d + RewriteCond %{REQUEST_URI} (.+)/$ + RewriteRule ^ %1 [L,R=301] + + # Send Requests To Front Controller... + RewriteCond %{REQUEST_FILENAME} !-d + RewriteCond %{REQUEST_FILENAME} !-f + RewriteRule ^ index.php [L] + diff --git a/public/favicon.ico b/public/favicon.ico new file mode 100644 index 0000000..e69de29 diff --git a/public/index.php b/public/index.php new file mode 100644 index 0000000..d55a3b2 --- /dev/null +++ b/public/index.php @@ -0,0 +1,19 @@ +handleRequest(Request::capture()); diff --git a/public/robots.txt b/public/robots.txt new file mode 100644 index 0000000..eb05362 --- /dev/null +++ b/public/robots.txt @@ -0,0 +1,2 @@ +User-agent: * +Disallow: diff --git a/resources/css/app.css b/resources/css/app.css new file mode 100644 index 0000000..b5c61c9 --- /dev/null +++ b/resources/css/app.css @@ -0,0 +1,3 @@ +@tailwind base; +@tailwind components; +@tailwind utilities; diff --git a/resources/js/app.js b/resources/js/app.js new file mode 100644 index 0000000..a8093be --- /dev/null +++ b/resources/js/app.js @@ -0,0 +1,7 @@ +import './bootstrap'; + +import Alpine from 'alpinejs'; + +window.Alpine = Alpine; + +Alpine.start(); diff --git a/resources/js/bootstrap.js b/resources/js/bootstrap.js new file mode 100644 index 0000000..5f1390b --- /dev/null +++ b/resources/js/bootstrap.js @@ -0,0 +1,4 @@ +import axios from 'axios'; +window.axios = axios; + +window.axios.defaults.headers.common['X-Requested-With'] = 'XMLHttpRequest'; diff --git a/resources/views/auth/confirm-password.blade.php b/resources/views/auth/confirm-password.blade.php new file mode 100644 index 0000000..3d38186 --- /dev/null +++ b/resources/views/auth/confirm-password.blade.php @@ -0,0 +1,27 @@ + +
+ {{ __('This is a secure area of the application. Please confirm your password before continuing.') }} +
+ +
+ @csrf + + +
+ + + + + +
+ +
+ + {{ __('Confirm') }} + +
+
+
diff --git a/resources/views/auth/forgot-password.blade.php b/resources/views/auth/forgot-password.blade.php new file mode 100644 index 0000000..cb32e08 --- /dev/null +++ b/resources/views/auth/forgot-password.blade.php @@ -0,0 +1,25 @@ + +
+ {{ __('Forgot your password? No problem. Just let us know your email address and we will email you a password reset link that will allow you to choose a new one.') }} +
+ + + + +
+ @csrf + + +
+ + + +
+ +
+ + {{ __('Email Password Reset Link') }} + +
+
+
diff --git a/resources/views/auth/login.blade.php b/resources/views/auth/login.blade.php new file mode 100644 index 0000000..07a5414 --- /dev/null +++ b/resources/views/auth/login.blade.php @@ -0,0 +1,37 @@ + + + + +
+ @csrf + + +
+ + + +
+ + +
+ + + + + +
+ + +
+
diff --git a/resources/views/auth/register.blade.php b/resources/views/auth/register.blade.php new file mode 100644 index 0000000..a857242 --- /dev/null +++ b/resources/views/auth/register.blade.php @@ -0,0 +1,52 @@ + +
+ @csrf + + +
+ + + +
+ + +
+ + + +
+ + +
+ + + + + +
+ + +
+ + + + + +
+ +
+ + {{ __('Already registered?') }} + + + + {{ __('Register') }} + +
+
+
diff --git a/resources/views/auth/reset-password.blade.php b/resources/views/auth/reset-password.blade.php new file mode 100644 index 0000000..a6494cc --- /dev/null +++ b/resources/views/auth/reset-password.blade.php @@ -0,0 +1,39 @@ + +
+ @csrf + + + + + +
+ + + +
+ + +
+ + + +
+ + +
+ + + + + +
+ +
+ + {{ __('Reset Password') }} + +
+
+
diff --git a/resources/views/auth/verify-email.blade.php b/resources/views/auth/verify-email.blade.php new file mode 100644 index 0000000..eaf811d --- /dev/null +++ b/resources/views/auth/verify-email.blade.php @@ -0,0 +1,31 @@ + +
+ {{ __('Thanks for signing up! Before getting started, could you verify your email address by clicking on the link we just emailed to you? If you didn\'t receive the email, we will gladly send you another.') }} +
+ + @if (session('status') == 'verification-link-sent') +
+ {{ __('A new verification link has been sent to the email address you provided during registration.') }} +
+ @endif + +
+
+ @csrf + +
+ + {{ __('Resend Verification Email') }} + +
+
+ +
+ @csrf + + +
+
+
diff --git a/resources/views/components/application-logo.blade.php b/resources/views/components/application-logo.blade.php new file mode 100644 index 0000000..46579cf --- /dev/null +++ b/resources/views/components/application-logo.blade.php @@ -0,0 +1,3 @@ + + + diff --git a/resources/views/components/auth-session-status.blade.php b/resources/views/components/auth-session-status.blade.php new file mode 100644 index 0000000..c4bd6e2 --- /dev/null +++ b/resources/views/components/auth-session-status.blade.php @@ -0,0 +1,7 @@ +@props(['status']) + +@if ($status) +
merge(['class' => 'font-medium text-sm text-green-600']) }}> + {{ $status }} +
+@endif diff --git a/resources/views/components/danger-button.blade.php b/resources/views/components/danger-button.blade.php new file mode 100644 index 0000000..d17d288 --- /dev/null +++ b/resources/views/components/danger-button.blade.php @@ -0,0 +1,3 @@ + diff --git a/resources/views/components/dropdown-link.blade.php b/resources/views/components/dropdown-link.blade.php new file mode 100644 index 0000000..e0f8ce1 --- /dev/null +++ b/resources/views/components/dropdown-link.blade.php @@ -0,0 +1 @@ +merge(['class' => 'block w-full px-4 py-2 text-start text-sm leading-5 text-gray-700 hover:bg-gray-100 focus:outline-none focus:bg-gray-100 transition duration-150 ease-in-out']) }}>{{ $slot }} diff --git a/resources/views/components/dropdown.blade.php b/resources/views/components/dropdown.blade.php new file mode 100644 index 0000000..a46f7c8 --- /dev/null +++ b/resources/views/components/dropdown.blade.php @@ -0,0 +1,35 @@ +@props(['align' => 'right', 'width' => '48', 'contentClasses' => 'py-1 bg-white']) + +@php +$alignmentClasses = match ($align) { + 'left' => 'ltr:origin-top-left rtl:origin-top-right start-0', + 'top' => 'origin-top', + default => 'ltr:origin-top-right rtl:origin-top-left end-0', +}; + +$width = match ($width) { + '48' => 'w-48', + default => $width, +}; +@endphp + +
+
+ {{ $trigger }} +
+ + +
diff --git a/resources/views/components/input-error.blade.php b/resources/views/components/input-error.blade.php new file mode 100644 index 0000000..9e6da21 --- /dev/null +++ b/resources/views/components/input-error.blade.php @@ -0,0 +1,9 @@ +@props(['messages']) + +@if ($messages) +
    merge(['class' => 'text-sm text-red-600 space-y-1']) }}> + @foreach ((array) $messages as $message) +
  • {{ $message }}
  • + @endforeach +
+@endif diff --git a/resources/views/components/input-label.blade.php b/resources/views/components/input-label.blade.php new file mode 100644 index 0000000..1cc65e2 --- /dev/null +++ b/resources/views/components/input-label.blade.php @@ -0,0 +1,5 @@ +@props(['value']) + + diff --git a/resources/views/components/modal.blade.php b/resources/views/components/modal.blade.php new file mode 100644 index 0000000..70704c1 --- /dev/null +++ b/resources/views/components/modal.blade.php @@ -0,0 +1,78 @@ +@props([ + 'name', + 'show' => false, + 'maxWidth' => '2xl' +]) + +@php +$maxWidth = [ + 'sm' => 'sm:max-w-sm', + 'md' => 'sm:max-w-md', + 'lg' => 'sm:max-w-lg', + 'xl' => 'sm:max-w-xl', + '2xl' => 'sm:max-w-2xl', +][$maxWidth]; +@endphp + +
+
+
+
+ +
+ {{ $slot }} +
+
diff --git a/resources/views/components/nav-link.blade.php b/resources/views/components/nav-link.blade.php new file mode 100644 index 0000000..5c101a2 --- /dev/null +++ b/resources/views/components/nav-link.blade.php @@ -0,0 +1,11 @@ +@props(['active']) + +@php +$classes = ($active ?? false) + ? 'inline-flex items-center px-1 pt-1 border-b-2 border-indigo-400 text-sm font-medium leading-5 text-gray-900 focus:outline-none focus:border-indigo-700 transition duration-150 ease-in-out' + : 'inline-flex items-center px-1 pt-1 border-b-2 border-transparent text-sm font-medium leading-5 text-gray-500 hover:text-gray-700 hover:border-gray-300 focus:outline-none focus:text-gray-700 focus:border-gray-300 transition duration-150 ease-in-out'; +@endphp + +merge(['class' => $classes]) }}> + {{ $slot }} + diff --git a/resources/views/components/primary-button.blade.php b/resources/views/components/primary-button.blade.php new file mode 100644 index 0000000..d71f0b6 --- /dev/null +++ b/resources/views/components/primary-button.blade.php @@ -0,0 +1,3 @@ + diff --git a/resources/views/components/responsive-nav-link.blade.php b/resources/views/components/responsive-nav-link.blade.php new file mode 100644 index 0000000..43b91e7 --- /dev/null +++ b/resources/views/components/responsive-nav-link.blade.php @@ -0,0 +1,11 @@ +@props(['active']) + +@php +$classes = ($active ?? false) + ? 'block w-full ps-3 pe-4 py-2 border-l-4 border-indigo-400 text-start text-base font-medium text-indigo-700 bg-indigo-50 focus:outline-none focus:text-indigo-800 focus:bg-indigo-100 focus:border-indigo-700 transition duration-150 ease-in-out' + : 'block w-full ps-3 pe-4 py-2 border-l-4 border-transparent text-start text-base font-medium text-gray-600 hover:text-gray-800 hover:bg-gray-50 hover:border-gray-300 focus:outline-none focus:text-gray-800 focus:bg-gray-50 focus:border-gray-300 transition duration-150 ease-in-out'; +@endphp + +merge(['class' => $classes]) }}> + {{ $slot }} + diff --git a/resources/views/components/secondary-button.blade.php b/resources/views/components/secondary-button.blade.php new file mode 100644 index 0000000..b32b69f --- /dev/null +++ b/resources/views/components/secondary-button.blade.php @@ -0,0 +1,3 @@ + diff --git a/resources/views/components/text-input.blade.php b/resources/views/components/text-input.blade.php new file mode 100644 index 0000000..da1b12d --- /dev/null +++ b/resources/views/components/text-input.blade.php @@ -0,0 +1,3 @@ +@props(['disabled' => false]) + +merge(['class' => 'border-gray-300 focus:border-indigo-500 focus:ring-indigo-500 rounded-md shadow-sm']) }}> diff --git a/resources/views/dashboard.blade.php b/resources/views/dashboard.blade.php new file mode 100644 index 0000000..bbc2358 --- /dev/null +++ b/resources/views/dashboard.blade.php @@ -0,0 +1,133 @@ + + +

+ {{ __('Dashboard') }} +

+
+ +
+
+
+
@lang('Balance')
+
+
+ {{ \Illuminate\Support\Number::currencyCents($balance) }} +
+
+
+
+

@lang('Send money to a friend')

+
+ @csrf + + @if (session('money-sent-status') === 'success') + + @elseif (session('money-sent-status') === 'insufficient-balance') + + @endif + +
+ + + +
+
+ + + +
+
+ + + +
+ +
+ + {{ __('Send my money !') }} + +
+
+
+
+

@lang('Transactions history')

+ + + + + + + + + + + @foreach($transactions as $transaction) + + + + + + + @endforeach + +
+ @lang('ID') + + @lang('Reason') + + @lang('Description') + + @lang('Amount') +
+ {{$transaction->id}} + + {{$transaction->reason}} + + @if($transaction->is_transfer) + @if ($transaction->type->isCredit()) + @lang(':name sent you :amount', [ + 'amount' => Number::currencyCents($transaction->transfer->amount), + 'name' => $transaction->transfer->source->user->name, + ]) + @else + @lang('You sent :amount to :name', [ + 'amount' => Number::currencyCents($transaction->transfer->amount), + 'name' => $transaction->transfer->target->user->name, + ]) + @endif + @else + @lang('--') + @endif + type->isCredit() ? 'text-green-500' : 'text-red-500', + ])> + {{Number::currencyCents($transaction->type->isCredit() ? $transaction->amount : -$transaction->amount)}} +
+
+
+
+
diff --git a/resources/views/layouts/app.blade.php b/resources/views/layouts/app.blade.php new file mode 100644 index 0000000..c5ff315 --- /dev/null +++ b/resources/views/layouts/app.blade.php @@ -0,0 +1,36 @@ + + + + + + + + {{ config('app.name', 'Laravel') }} + + + + + + + @vite(['resources/css/app.css', 'resources/js/app.js']) + + +
+ @include('layouts.navigation') + + + @isset($header) +
+
+ {{ $header }} +
+
+ @endisset + + +
+ {{ $slot }} +
+
+ + diff --git a/resources/views/layouts/guest.blade.php b/resources/views/layouts/guest.blade.php new file mode 100644 index 0000000..11feb47 --- /dev/null +++ b/resources/views/layouts/guest.blade.php @@ -0,0 +1,30 @@ + + + + + + + + {{ config('app.name', 'Laravel') }} + + + + + + + @vite(['resources/css/app.css', 'resources/js/app.js']) + + +
+
+ + + +
+ +
+ {{ $slot }} +
+
+ + diff --git a/resources/views/layouts/navigation.blade.php b/resources/views/layouts/navigation.blade.php new file mode 100644 index 0000000..cb45013 --- /dev/null +++ b/resources/views/layouts/navigation.blade.php @@ -0,0 +1,92 @@ + diff --git a/routes/api.php b/routes/api.php new file mode 100644 index 0000000..18d3cab --- /dev/null +++ b/routes/api.php @@ -0,0 +1,15 @@ +middleware(['guest:sanctum', 'throttle:api.login']); + +Route::middleware(['auth:sanctum', 'throttle:api'])->prefix('v1')->group(function () { + Route::get('/account', AccountController::class); + Route::post('/wallet/send-money', SendMoneyController::class); +}); diff --git a/routes/auth.php b/routes/auth.php new file mode 100644 index 0000000..d9fe2f2 --- /dev/null +++ b/routes/auth.php @@ -0,0 +1,24 @@ +group(function () { + Route::get('register', [RegisteredUserController::class, 'create']) + ->name('register'); + + Route::post('register', [RegisteredUserController::class, 'store']); + + Route::get('login', [AuthenticatedSessionController::class, 'create']) + ->name('login'); + + Route::post('login', [AuthenticatedSessionController::class, 'store']); +}); + +Route::middleware('auth')->group(function () { + Route::post('logout', [AuthenticatedSessionController::class, 'destroy']) + ->name('logout'); +}); diff --git a/routes/console.php b/routes/console.php new file mode 100644 index 0000000..12eea61 --- /dev/null +++ b/routes/console.php @@ -0,0 +1,10 @@ +comment(Inspiring::quote()); +})->purpose('Display an inspiring quote')->hourly(); diff --git a/routes/web.php b/routes/web.php new file mode 100644 index 0000000..306ef89 --- /dev/null +++ b/routes/web.php @@ -0,0 +1,14 @@ +group(function () { + Route::get('/', DashboardController::class)->name('dashboard'); + Route::post('/send-money', [SendMoneyController::class, '__invoke'])->name('send-money'); +}); + +require __DIR__.'/auth.php'; diff --git a/screenshot.png b/screenshot.png new file mode 100644 index 0000000000000000000000000000000000000000..229c6f6daf09adcfd92d10ab32ae6cc973502ce0 GIT binary patch literal 76139 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 = app(PerformWalletTransaction::class); +}); + +test('perform a credit transaction', function () { + $wallet = Wallet::factory()->forUser()->richChillGuy()->create(); + + $this->action->execute($wallet, WalletTransactionType::CREDIT, 100, 'test'); + + expect($wallet->balance)->toBe(1_000_100); + + assertDatabaseHas('wallets', [ + 'id' => $wallet->id, + 'balance' => 1_000_100, + ]); + + assertDatabaseHas('wallet_transactions', [ + 'amount' => 100, + 'wallet_id' => $wallet->id, + 'type' => WalletTransactionType::CREDIT, + 'reason' => 'test', + ]); +}); + +test('perform a debit transaction', function () { + $wallet = Wallet::factory()->forUser()->richChillGuy()->create(); + + $this->action->execute($wallet, WalletTransactionType::DEBIT, 100, 'test'); + + expect($wallet->balance)->toBe(999_900); + + assertDatabaseHas('wallets', [ + 'id' => $wallet->id, + 'balance' => 999_900, + ]); + + assertDatabaseHas('wallet_transactions', [ + 'amount' => 100, + 'wallet_id' => $wallet->id, + 'type' => WalletTransactionType::DEBIT, + 'reason' => 'test', + ]); +}); + +test('cannot perform a debit transaction if balance is insufficient', function () { + $wallet = Wallet::factory()->forUser()->create(); + + expect(function () use ($wallet) { + $this->action->execute($wallet, WalletTransactionType::DEBIT, 100, 'test'); + })->toThrow(InsufficientBalance::class); + + assertDatabaseHas('wallets', [ + 'id' => $wallet->id, + 'balance' => 0, + ]); + + assertDatabaseCount('wallet_transactions', 0); +}); + +test('force a debit transaction when balance is insufficient', function () { + $wallet = Wallet::factory()->forUser()->create(); + + $this->action->execute(wallet: $wallet, type: WalletTransactionType::DEBIT, amount: 100, reason: 'test', force: true); + + expect($wallet->balance)->toBe(-100); + + assertDatabaseHas('wallets', [ + 'id' => $wallet->id, + 'balance' => -100, + ]); + + assertDatabaseHas('wallet_transactions', [ + 'amount' => 100, + 'wallet_id' => $wallet->id, + 'type' => WalletTransactionType::DEBIT, + 'reason' => 'test', + ]); +}); diff --git a/tests/Feature/Actions/PerformWalletTransferTest.php b/tests/Feature/Actions/PerformWalletTransferTest.php new file mode 100644 index 0000000..754c554 --- /dev/null +++ b/tests/Feature/Actions/PerformWalletTransferTest.php @@ -0,0 +1,66 @@ +action = app(PerformWalletTransfer::class); +}); + +test('perform a transfer', function () { + $sender = User::factory()->create(); + $recipient = User::factory()->create(); + + $source = Wallet::factory()->for($sender)->richChillGuy()->create(); + $target = Wallet::factory()->for($recipient)->create(); + + $transfer = $this->action->execute($sender, $recipient, 100, 'test'); + + expect($source->refresh()->balance)->toBe(999_900); + expect($target->refresh()->balance)->toBe(100); + + assertDatabaseHas('wallet_transactions', [ + 'amount' => 100, + 'wallet_id' => $target->id, + 'type' => WalletTransactionType::CREDIT, + 'transfer_id' => $transfer->id, + ]); + + assertDatabaseHas('wallet_transactions', [ + 'amount' => 100, + 'wallet_id' => $sender->id, + 'type' => WalletTransactionType::DEBIT, + 'transfer_id' => $transfer->id, + ]); + + assertDatabaseHas('wallet_transfers', [ + 'amount' => 100, + 'source_id' => $source->id, + 'target_id' => $target->id, + ]); +}); + +test('cannot perform a transfer with insufficient balance', function () { + $sender = User::factory()->create(); + $recipient = User::factory()->create(); + + $source = Wallet::factory()->balance(90)->for($sender)->create(); + $target = Wallet::factory()->for($recipient)->create(); + + expect(function () use ($sender, $recipient) { + $this->action->execute($sender, $recipient, 100, 'test'); + })->toThrow(InsufficientBalance::class); + + expect($source->refresh()->balance)->toBe(90); + expect($target->refresh()->balance)->toBe(0); + + assertDatabaseCount('wallet_transfers', 0); +}); diff --git a/tests/Feature/Api/AccountControllerTest.php b/tests/Feature/Api/AccountControllerTest.php new file mode 100644 index 0000000..394a46f --- /dev/null +++ b/tests/Feature/Api/AccountControllerTest.php @@ -0,0 +1,34 @@ +has(Wallet::factory()->richChillGuy()) + ->create(['name' => 'John Doe', 'email' => 'test@test.com']); + + actingAs($user); + + getJson(action(AccountController::class)) + ->assertOk() + ->assertJson([ + 'data' => [ + 'id' => $user->id, + 'name' => 'John Doe', + 'email' => $user->email, + 'balance' => 1_000_000, + ], + ]); +}); + +test('must be authenticated to get account data', function () { + getJson(action(AccountController::class)) + ->assertUnauthorized(); +}); diff --git a/tests/Feature/Api/LoginControllerTest.php b/tests/Feature/Api/LoginControllerTest.php new file mode 100644 index 0000000..b82c973 --- /dev/null +++ b/tests/Feature/Api/LoginControllerTest.php @@ -0,0 +1,34 @@ +create(['email' => 'test@test.com']); + + postJson(action(LoginController::class), [ + 'email' => 'test@test.com', + 'password' => 'password', + 'device_name' => 'Feature test', + ]) + ->assertCreated() + ->assertJsonStructure(['data' => ['token']]); + + assertCount(1, $user->refresh()->tokens); +}); + +test('bad login should return HTTP 400', function () { + postJson(action(LoginController::class), [ + 'email' => 'test@test.com', + 'password' => 'password', + 'device_name' => 'Feature test', + ]) + ->assertStatus(400) + ->assertJsonPath('message', 'Invalid credentials.') + ->assertJsonPath('code', 'BAD_LOGIN'); +}); diff --git a/tests/Feature/Api/SendMoneyControllerTest.php b/tests/Feature/Api/SendMoneyControllerTest.php new file mode 100644 index 0000000..b9ae3e9 --- /dev/null +++ b/tests/Feature/Api/SendMoneyControllerTest.php @@ -0,0 +1,66 @@ +has(Wallet::factory()->richChillGuy()) + ->create(); + + $recipient = User::factory() + ->has(Wallet::factory()) + ->create(); + + actingAs($user); + + postJson(action(SendMoneyController::class), [ + 'recipient_email' => $recipient->email, + 'amount' => 100, + 'reason' => 'Just a chill guy gift', + ]) + ->assertNoContent(201); + + expect($recipient->refresh()->wallet->balance)->toBe(100); + + assertDatabaseHas('wallet_transfers', [ + 'amount' => 100, + 'source_id' => $user->wallet->id, + 'target_id' => $recipient->wallet->id, + ]); + + assertDatabaseCount('wallet_transactions', 3); +}); + +test('cannot send money to a friend with insufficient balance', function () { + $user = User::factory() + ->has(Wallet::factory()) + ->create(); + + $recipient = User::factory() + ->has(Wallet::factory()) + ->create(); + + actingAs($user); + + postJson(action(SendMoneyController::class), [ + 'recipient_email' => $recipient->email, + 'amount' => 100, + 'reason' => 'Just a chill guy gift', + ]) + ->assertBadRequest() + ->assertJson([ + 'code' => 'INSUFFICIENT_BALANCE', + 'message' => 'Insufficient balance in wallet.', + ]); + + expect($recipient->refresh()->wallet->balance)->toBe(0); +}); diff --git a/tests/Feature/Auth/AuthenticationTest.php b/tests/Feature/Auth/AuthenticationTest.php new file mode 100644 index 0000000..d4d10b2 --- /dev/null +++ b/tests/Feature/Auth/AuthenticationTest.php @@ -0,0 +1,49 @@ +assertStatus(200); +}); + +test('users can authenticate using the login screen', function () { + $user = User::factory()->create(); + + $response = post('/login', [ + 'email' => $user->email, + 'password' => 'password', + ]); + + assertAuthenticated(); + $response->assertRedirect(route('dashboard', absolute: false)); +}); + +test('users can not authenticate with invalid password', function () { + $user = User::factory()->create(); + + post('/login', [ + 'email' => $user->email, + 'password' => 'wrong-password', + ]); + + assertGuest(); +}); + +test('users can logout', function () { + $user = User::factory()->create(); + + $response = actingAs($user)->post('/logout'); + + assertGuest(); + $response->assertRedirect('/'); +}); diff --git a/tests/Feature/Auth/RegistrationTest.php b/tests/Feature/Auth/RegistrationTest.php new file mode 100644 index 0000000..96345cd --- /dev/null +++ b/tests/Feature/Auth/RegistrationTest.php @@ -0,0 +1,25 @@ +assertStatus(200); +}); + +test('new users can register', function () { + $response = post('/register', [ + 'name' => 'Test User', + 'email' => 'test@example.com', + 'password' => 'password', + 'password_confirmation' => 'password', + ]); + + assertAuthenticated(); + $response->assertRedirect(route('dashboard', absolute: false)); +}); diff --git a/tests/Feature/DashboardTest.php b/tests/Feature/DashboardTest.php new file mode 100644 index 0000000..88409c3 --- /dev/null +++ b/tests/Feature/DashboardTest.php @@ -0,0 +1,69 @@ +has(Wallet::factory()->richChillGuy())->create(); + $wallet = Wallet::factory()->richChillGuy()->for($user)->create(); + + $response = actingAs($user)->get('/'); + + $response + ->assertOk() + ->assertSeeTextInOrder([ + __('Balance'), + Number::currencyCents($wallet->balance), + 'Transactions history', + 'Just a rich chill guy', + ]); +}); + +test('send money to a friend', function () { + $user = User::factory()->has(Wallet::factory()->richChillGuy())->create(); + $recipient = User::factory()->has(Wallet::factory())->create(); + + $response = actingAs($user)->post('/send-money', [ + 'recipient_email' => $recipient->email, + 'amount' => 10, // In euros, not cents + 'reason' => 'Just a chill guy gift', + ]); + + $response + ->assertRedirect('/') + ->assertSessionHas('money-sent-status', 'success') + ->assertSessionHas('money-sent-recipient-name', $recipient->name) + ->assertSessionHas('money-sent-amount', 10_00); + + actingAs($user)->get('/') + ->assertSeeTextInOrder([ + __('Balance'), + Number::currencyCents(1_000_000 - 10_00), + 'Transactions history', + 'Just a chill guy gift', + Number::currencyCents(-10_00), + 'Just a rich chill guy', + Number::currencyCents(1_000_000), + ]); +}); + +test('cannot send money to a friend with insufficient balance', function () { + $user = User::factory()->has(Wallet::factory())->create(); + $recipient = User::factory()->has(Wallet::factory())->create(); + + $response = actingAs($user)->post('/send-money', [ + 'recipient_email' => $recipient->email, + 'amount' => 10, // In euros, not cents + 'reason' => 'Just a chill guy gift', + ]); + + $response + ->assertRedirect('/') + ->assertSessionHas('money-sent-status', 'insufficient-balance') + ->assertSessionHas('money-sent-recipient-name', $recipient->name) + ->assertSessionHas('money-sent-amount', 10_00); +}); diff --git a/tests/Pest.php b/tests/Pest.php new file mode 100644 index 0000000..485e335 --- /dev/null +++ b/tests/Pest.php @@ -0,0 +1,18 @@ +extend(Tests\TestCase::class) + ->use(Illuminate\Foundation\Testing\RefreshDatabase::class) + ->in('Feature'); diff --git a/tests/TestCase.php b/tests/TestCase.php new file mode 100644 index 0000000..6ac0072 --- /dev/null +++ b/tests/TestCase.php @@ -0,0 +1,12 @@ +credit() + ->amount(100) + ->make(['transfer_id' => 1]); + + expect($transaction->is_transfer)->toBeTrue(); +}); + +test('that classic transactions aren\'t identified as transfers', function () { + $transaction = WalletTransaction::factory() + ->credit() + ->amount(100) + ->make(); + + expect($transaction->is_transfer)->toBeFalse(); +}); diff --git a/vite.config.js b/vite.config.js new file mode 100644 index 0000000..421b569 --- /dev/null +++ b/vite.config.js @@ -0,0 +1,11 @@ +import { defineConfig } from 'vite'; +import laravel from 'laravel-vite-plugin'; + +export default defineConfig({ + plugins: [ + laravel({ + input: ['resources/css/app.css', 'resources/js/app.js'], + refresh: true, + }), + ], +});