diff --git a/.env.local.example b/.env.local.example index 5832a85..2984803 100644 --- a/.env.local.example +++ b/.env.local.example @@ -17,17 +17,22 @@ DB_DATABASE=kcal DB_USERNAME=kcal DB_PASSWORD=kcal +#REDIS_URL= REDIS_HOST=redis +#REDIS_PASSWORD= REDIS_PORT=6379 +#REDIS_DB= + +#SCOUT_DRIVER=null + +#SCOUT_DRIVER=algolia +#ALGOLIA_APP_ID= +#ALGOLIA_SECRET= SCOUT_DRIVER=elastic ELASTIC_HOST=elasticsearch:9200 ELASTIC_PORT=9200 -MAIL_HOST=mailhog -MAIL_PORT=1025 -MAILHOG_ADMIN_PORT=8025 - BROADCAST_DRIVER=log CACHE_DRIVER=file QUEUE_CONNECTION=sync diff --git a/.env.prod.example b/.env.prod.example index 84c260f..bd57adb 100644 --- a/.env.prod.example +++ b/.env.prod.example @@ -15,14 +15,20 @@ DB_DATABASE= DB_USERNAME= DB_PASSWORD= -REDIS_HOST= -REDIS_PORT=6379 +#REDIS_URL= +#REDIS_HOST= +#REDIS_PASSWORD= +#REDIS_PORT=6379 +#REDIS_DB= -SCOUT_DRIVER=elastic -ELASTIC_HOST= +SCOUT_DRIVER=null -MAIL_HOST= -MAIL_PORT= +#SCOUT_DRIVER=algolia +#ALGOLIA_APP_ID= +#ALGOLIA_SECRET= + +#SCOUT_DRIVER=elastic +#ELASTIC_HOST= BROADCAST_DRIVER=log CACHE_DRIVER=file diff --git a/.gitignore b/.gitignore index 889fb39..f5fb7b5 100644 --- a/.gitignore +++ b/.gitignore @@ -15,3 +15,4 @@ Homestead.yaml docker-compose.override.yml npm-debug.log yarn-error.log +phpunit.xml diff --git a/.phpstorm.meta.php b/.phpstorm.meta.php index 6c65431..328a783 100644 --- a/.phpstorm.meta.php +++ b/.phpstorm.meta.php @@ -11,6 +11,14 @@ namespace PHPSTORM_META { */ override(new \Illuminate\Contracts\Container\Container, map([ '' => '@', + 'Algolia\AlgoliaSearch\AnalyticsClient' => \Algolia\AlgoliaSearch\AnalyticsClient::class, + 'Algolia\AlgoliaSearch\SearchClient' => \Algolia\AlgoliaSearch\SearchClient::class, + 'Algolia\ScoutExtended\Algolia' => \Algolia\ScoutExtended\Algolia::class, + 'Algolia\ScoutExtended\Contracts\LocalSettingsRepositoryContract' => \Algolia\ScoutExtended\Repositories\LocalSettingsRepository::class, + 'Algolia\ScoutExtended\Engines\AlgoliaEngine' => \Algolia\ScoutExtended\Engines\AlgoliaEngine::class, + 'Algolia\ScoutExtended\Helpers\SearchableFinder' => \Algolia\ScoutExtended\Helpers\SearchableFinder::class, + 'Algolia\ScoutExtended\Managers\EngineManager' => \Algolia\ScoutExtended\Managers\EngineManager::class, + 'Algolia\ScoutExtended\Searchable\AggregatorObserver' => \Algolia\ScoutExtended\Searchable\AggregatorObserver::class, 'Asm89\Stack\CorsService' => \Asm89\Stack\CorsService::class, 'CloudCreativity\LaravelJsonApi\Api\Repository' => \CloudCreativity\LaravelJsonApi\Api\Repository::class, 'CloudCreativity\LaravelJsonApi\Contracts\ContainerInterface' => \CloudCreativity\LaravelJsonApi\Container::class, @@ -37,6 +45,8 @@ namespace PHPSTORM_META { 'Facade\Ignition\QueryRecorder\QueryRecorder' => \Facade\Ignition\QueryRecorder\QueryRecorder::class, 'Illuminate\Auth\Middleware\RequirePassword' => \Illuminate\Auth\Middleware\RequirePassword::class, 'Illuminate\Broadcasting\BroadcastManager' => \Illuminate\Broadcasting\BroadcastManager::class, + 'Illuminate\Bus\BatchRepository' => \Illuminate\Bus\DatabaseBatchRepository::class, + 'Illuminate\Bus\DatabaseBatchRepository' => \Illuminate\Bus\DatabaseBatchRepository::class, 'Illuminate\Bus\Dispatcher' => \Illuminate\Bus\Dispatcher::class, 'Illuminate\Cache\RateLimiter' => \Illuminate\Cache\RateLimiter::class, 'Illuminate\Console\Scheduling\Schedule' => \Illuminate\Console\Scheduling\Schedule::class, @@ -61,7 +71,7 @@ namespace PHPSTORM_META { 'Illuminate\Routing\Contracts\ControllerDispatcher' => \Illuminate\Routing\ControllerDispatcher::class, 'Illuminate\Session\Middleware\StartSession' => \Illuminate\Session\Middleware\StartSession::class, 'Illuminate\Testing\ParallelTesting' => \Illuminate\Testing\ParallelTesting::class, - 'Laravel\Scout\EngineManager' => \Laravel\Scout\EngineManager::class, + 'Laravel\Scout\EngineManager' => \Algolia\ScoutExtended\Managers\EngineManager::class, 'Neomerx\JsonApi\Contracts\Encoder\Parameters\EncodingParametersInterface' => \CloudCreativity\LaravelJsonApi\Encoder\Parameters\EncodingParameters::class, 'Neomerx\JsonApi\Contracts\Http\Headers\HeaderParametersInterface' => \Neomerx\JsonApi\Http\Headers\HeaderParameters::class, 'NunoMaduro\Collision\Contracts\Provider' => \NunoMaduro\Collision\Provider::class, @@ -75,6 +85,7 @@ namespace PHPSTORM_META { 'auth' => \Illuminate\Auth\AuthManager::class, 'auth.driver' => \Illuminate\Auth\SessionGuard::class, 'auth.password' => \Illuminate\Auth\Passwords\PasswordBrokerManager::class, + 'auth.password.broker' => \Illuminate\Auth\Passwords\PasswordBroker::class, 'blade.compiler' => \Illuminate\View\Compilers\BladeCompiler::class, 'cache' => \Illuminate\Cache\CacheManager::class, 'cache.store' => \Illuminate\Cache\Repository::class, @@ -167,6 +178,7 @@ namespace PHPSTORM_META { 'composer' => \Illuminate\Support\Composer::class, 'cookie' => \Illuminate\Cookie\CookieJar::class, 'db' => \Illuminate\Database\DatabaseManager::class, + 'db.connection' => \Illuminate\Database\MySqlConnection::class, 'db.factory' => \Illuminate\Database\Connectors\ConnectionFactory::class, 'db.transactions' => \Illuminate\Database\DatabaseTransactionsManager::class, 'encrypter' => \Illuminate\Encryption\Encrypter::class, @@ -207,6 +219,14 @@ namespace PHPSTORM_META { ])); override(\Illuminate\Container\Container::makeWith(0), map([ '' => '@', + 'Algolia\AlgoliaSearch\AnalyticsClient' => \Algolia\AlgoliaSearch\AnalyticsClient::class, + 'Algolia\AlgoliaSearch\SearchClient' => \Algolia\AlgoliaSearch\SearchClient::class, + 'Algolia\ScoutExtended\Algolia' => \Algolia\ScoutExtended\Algolia::class, + 'Algolia\ScoutExtended\Contracts\LocalSettingsRepositoryContract' => \Algolia\ScoutExtended\Repositories\LocalSettingsRepository::class, + 'Algolia\ScoutExtended\Engines\AlgoliaEngine' => \Algolia\ScoutExtended\Engines\AlgoliaEngine::class, + 'Algolia\ScoutExtended\Helpers\SearchableFinder' => \Algolia\ScoutExtended\Helpers\SearchableFinder::class, + 'Algolia\ScoutExtended\Managers\EngineManager' => \Algolia\ScoutExtended\Managers\EngineManager::class, + 'Algolia\ScoutExtended\Searchable\AggregatorObserver' => \Algolia\ScoutExtended\Searchable\AggregatorObserver::class, 'Asm89\Stack\CorsService' => \Asm89\Stack\CorsService::class, 'CloudCreativity\LaravelJsonApi\Api\Repository' => \CloudCreativity\LaravelJsonApi\Api\Repository::class, 'CloudCreativity\LaravelJsonApi\Contracts\ContainerInterface' => \CloudCreativity\LaravelJsonApi\Container::class, @@ -233,6 +253,8 @@ namespace PHPSTORM_META { 'Facade\Ignition\QueryRecorder\QueryRecorder' => \Facade\Ignition\QueryRecorder\QueryRecorder::class, 'Illuminate\Auth\Middleware\RequirePassword' => \Illuminate\Auth\Middleware\RequirePassword::class, 'Illuminate\Broadcasting\BroadcastManager' => \Illuminate\Broadcasting\BroadcastManager::class, + 'Illuminate\Bus\BatchRepository' => \Illuminate\Bus\DatabaseBatchRepository::class, + 'Illuminate\Bus\DatabaseBatchRepository' => \Illuminate\Bus\DatabaseBatchRepository::class, 'Illuminate\Bus\Dispatcher' => \Illuminate\Bus\Dispatcher::class, 'Illuminate\Cache\RateLimiter' => \Illuminate\Cache\RateLimiter::class, 'Illuminate\Console\Scheduling\Schedule' => \Illuminate\Console\Scheduling\Schedule::class, @@ -257,7 +279,7 @@ namespace PHPSTORM_META { 'Illuminate\Routing\Contracts\ControllerDispatcher' => \Illuminate\Routing\ControllerDispatcher::class, 'Illuminate\Session\Middleware\StartSession' => \Illuminate\Session\Middleware\StartSession::class, 'Illuminate\Testing\ParallelTesting' => \Illuminate\Testing\ParallelTesting::class, - 'Laravel\Scout\EngineManager' => \Laravel\Scout\EngineManager::class, + 'Laravel\Scout\EngineManager' => \Algolia\ScoutExtended\Managers\EngineManager::class, 'Neomerx\JsonApi\Contracts\Encoder\Parameters\EncodingParametersInterface' => \CloudCreativity\LaravelJsonApi\Encoder\Parameters\EncodingParameters::class, 'Neomerx\JsonApi\Contracts\Http\Headers\HeaderParametersInterface' => \Neomerx\JsonApi\Http\Headers\HeaderParameters::class, 'NunoMaduro\Collision\Contracts\Provider' => \NunoMaduro\Collision\Provider::class, @@ -271,6 +293,7 @@ namespace PHPSTORM_META { 'auth' => \Illuminate\Auth\AuthManager::class, 'auth.driver' => \Illuminate\Auth\SessionGuard::class, 'auth.password' => \Illuminate\Auth\Passwords\PasswordBrokerManager::class, + 'auth.password.broker' => \Illuminate\Auth\Passwords\PasswordBroker::class, 'blade.compiler' => \Illuminate\View\Compilers\BladeCompiler::class, 'cache' => \Illuminate\Cache\CacheManager::class, 'cache.store' => \Illuminate\Cache\Repository::class, @@ -363,6 +386,7 @@ namespace PHPSTORM_META { 'composer' => \Illuminate\Support\Composer::class, 'cookie' => \Illuminate\Cookie\CookieJar::class, 'db' => \Illuminate\Database\DatabaseManager::class, + 'db.connection' => \Illuminate\Database\MySqlConnection::class, 'db.factory' => \Illuminate\Database\Connectors\ConnectionFactory::class, 'db.transactions' => \Illuminate\Database\DatabaseTransactionsManager::class, 'encrypter' => \Illuminate\Encryption\Encrypter::class, @@ -403,6 +427,14 @@ namespace PHPSTORM_META { ])); override(\Illuminate\Contracts\Container\Container::get(0), map([ '' => '@', + 'Algolia\AlgoliaSearch\AnalyticsClient' => \Algolia\AlgoliaSearch\AnalyticsClient::class, + 'Algolia\AlgoliaSearch\SearchClient' => \Algolia\AlgoliaSearch\SearchClient::class, + 'Algolia\ScoutExtended\Algolia' => \Algolia\ScoutExtended\Algolia::class, + 'Algolia\ScoutExtended\Contracts\LocalSettingsRepositoryContract' => \Algolia\ScoutExtended\Repositories\LocalSettingsRepository::class, + 'Algolia\ScoutExtended\Engines\AlgoliaEngine' => \Algolia\ScoutExtended\Engines\AlgoliaEngine::class, + 'Algolia\ScoutExtended\Helpers\SearchableFinder' => \Algolia\ScoutExtended\Helpers\SearchableFinder::class, + 'Algolia\ScoutExtended\Managers\EngineManager' => \Algolia\ScoutExtended\Managers\EngineManager::class, + 'Algolia\ScoutExtended\Searchable\AggregatorObserver' => \Algolia\ScoutExtended\Searchable\AggregatorObserver::class, 'Asm89\Stack\CorsService' => \Asm89\Stack\CorsService::class, 'CloudCreativity\LaravelJsonApi\Api\Repository' => \CloudCreativity\LaravelJsonApi\Api\Repository::class, 'CloudCreativity\LaravelJsonApi\Contracts\ContainerInterface' => \CloudCreativity\LaravelJsonApi\Container::class, @@ -429,6 +461,8 @@ namespace PHPSTORM_META { 'Facade\Ignition\QueryRecorder\QueryRecorder' => \Facade\Ignition\QueryRecorder\QueryRecorder::class, 'Illuminate\Auth\Middleware\RequirePassword' => \Illuminate\Auth\Middleware\RequirePassword::class, 'Illuminate\Broadcasting\BroadcastManager' => \Illuminate\Broadcasting\BroadcastManager::class, + 'Illuminate\Bus\BatchRepository' => \Illuminate\Bus\DatabaseBatchRepository::class, + 'Illuminate\Bus\DatabaseBatchRepository' => \Illuminate\Bus\DatabaseBatchRepository::class, 'Illuminate\Bus\Dispatcher' => \Illuminate\Bus\Dispatcher::class, 'Illuminate\Cache\RateLimiter' => \Illuminate\Cache\RateLimiter::class, 'Illuminate\Console\Scheduling\Schedule' => \Illuminate\Console\Scheduling\Schedule::class, @@ -453,7 +487,7 @@ namespace PHPSTORM_META { 'Illuminate\Routing\Contracts\ControllerDispatcher' => \Illuminate\Routing\ControllerDispatcher::class, 'Illuminate\Session\Middleware\StartSession' => \Illuminate\Session\Middleware\StartSession::class, 'Illuminate\Testing\ParallelTesting' => \Illuminate\Testing\ParallelTesting::class, - 'Laravel\Scout\EngineManager' => \Laravel\Scout\EngineManager::class, + 'Laravel\Scout\EngineManager' => \Algolia\ScoutExtended\Managers\EngineManager::class, 'Neomerx\JsonApi\Contracts\Encoder\Parameters\EncodingParametersInterface' => \CloudCreativity\LaravelJsonApi\Encoder\Parameters\EncodingParameters::class, 'Neomerx\JsonApi\Contracts\Http\Headers\HeaderParametersInterface' => \Neomerx\JsonApi\Http\Headers\HeaderParameters::class, 'NunoMaduro\Collision\Contracts\Provider' => \NunoMaduro\Collision\Provider::class, @@ -467,6 +501,7 @@ namespace PHPSTORM_META { 'auth' => \Illuminate\Auth\AuthManager::class, 'auth.driver' => \Illuminate\Auth\SessionGuard::class, 'auth.password' => \Illuminate\Auth\Passwords\PasswordBrokerManager::class, + 'auth.password.broker' => \Illuminate\Auth\Passwords\PasswordBroker::class, 'blade.compiler' => \Illuminate\View\Compilers\BladeCompiler::class, 'cache' => \Illuminate\Cache\CacheManager::class, 'cache.store' => \Illuminate\Cache\Repository::class, @@ -559,6 +594,7 @@ namespace PHPSTORM_META { 'composer' => \Illuminate\Support\Composer::class, 'cookie' => \Illuminate\Cookie\CookieJar::class, 'db' => \Illuminate\Database\DatabaseManager::class, + 'db.connection' => \Illuminate\Database\MySqlConnection::class, 'db.factory' => \Illuminate\Database\Connectors\ConnectionFactory::class, 'db.transactions' => \Illuminate\Database\DatabaseTransactionsManager::class, 'encrypter' => \Illuminate\Encryption\Encrypter::class, @@ -599,6 +635,14 @@ namespace PHPSTORM_META { ])); override(\Illuminate\Contracts\Container\Container::make(0), map([ '' => '@', + 'Algolia\AlgoliaSearch\AnalyticsClient' => \Algolia\AlgoliaSearch\AnalyticsClient::class, + 'Algolia\AlgoliaSearch\SearchClient' => \Algolia\AlgoliaSearch\SearchClient::class, + 'Algolia\ScoutExtended\Algolia' => \Algolia\ScoutExtended\Algolia::class, + 'Algolia\ScoutExtended\Contracts\LocalSettingsRepositoryContract' => \Algolia\ScoutExtended\Repositories\LocalSettingsRepository::class, + 'Algolia\ScoutExtended\Engines\AlgoliaEngine' => \Algolia\ScoutExtended\Engines\AlgoliaEngine::class, + 'Algolia\ScoutExtended\Helpers\SearchableFinder' => \Algolia\ScoutExtended\Helpers\SearchableFinder::class, + 'Algolia\ScoutExtended\Managers\EngineManager' => \Algolia\ScoutExtended\Managers\EngineManager::class, + 'Algolia\ScoutExtended\Searchable\AggregatorObserver' => \Algolia\ScoutExtended\Searchable\AggregatorObserver::class, 'Asm89\Stack\CorsService' => \Asm89\Stack\CorsService::class, 'CloudCreativity\LaravelJsonApi\Api\Repository' => \CloudCreativity\LaravelJsonApi\Api\Repository::class, 'CloudCreativity\LaravelJsonApi\Contracts\ContainerInterface' => \CloudCreativity\LaravelJsonApi\Container::class, @@ -625,6 +669,8 @@ namespace PHPSTORM_META { 'Facade\Ignition\QueryRecorder\QueryRecorder' => \Facade\Ignition\QueryRecorder\QueryRecorder::class, 'Illuminate\Auth\Middleware\RequirePassword' => \Illuminate\Auth\Middleware\RequirePassword::class, 'Illuminate\Broadcasting\BroadcastManager' => \Illuminate\Broadcasting\BroadcastManager::class, + 'Illuminate\Bus\BatchRepository' => \Illuminate\Bus\DatabaseBatchRepository::class, + 'Illuminate\Bus\DatabaseBatchRepository' => \Illuminate\Bus\DatabaseBatchRepository::class, 'Illuminate\Bus\Dispatcher' => \Illuminate\Bus\Dispatcher::class, 'Illuminate\Cache\RateLimiter' => \Illuminate\Cache\RateLimiter::class, 'Illuminate\Console\Scheduling\Schedule' => \Illuminate\Console\Scheduling\Schedule::class, @@ -649,7 +695,7 @@ namespace PHPSTORM_META { 'Illuminate\Routing\Contracts\ControllerDispatcher' => \Illuminate\Routing\ControllerDispatcher::class, 'Illuminate\Session\Middleware\StartSession' => \Illuminate\Session\Middleware\StartSession::class, 'Illuminate\Testing\ParallelTesting' => \Illuminate\Testing\ParallelTesting::class, - 'Laravel\Scout\EngineManager' => \Laravel\Scout\EngineManager::class, + 'Laravel\Scout\EngineManager' => \Algolia\ScoutExtended\Managers\EngineManager::class, 'Neomerx\JsonApi\Contracts\Encoder\Parameters\EncodingParametersInterface' => \CloudCreativity\LaravelJsonApi\Encoder\Parameters\EncodingParameters::class, 'Neomerx\JsonApi\Contracts\Http\Headers\HeaderParametersInterface' => \Neomerx\JsonApi\Http\Headers\HeaderParameters::class, 'NunoMaduro\Collision\Contracts\Provider' => \NunoMaduro\Collision\Provider::class, @@ -663,6 +709,7 @@ namespace PHPSTORM_META { 'auth' => \Illuminate\Auth\AuthManager::class, 'auth.driver' => \Illuminate\Auth\SessionGuard::class, 'auth.password' => \Illuminate\Auth\Passwords\PasswordBrokerManager::class, + 'auth.password.broker' => \Illuminate\Auth\Passwords\PasswordBroker::class, 'blade.compiler' => \Illuminate\View\Compilers\BladeCompiler::class, 'cache' => \Illuminate\Cache\CacheManager::class, 'cache.store' => \Illuminate\Cache\Repository::class, @@ -755,6 +802,7 @@ namespace PHPSTORM_META { 'composer' => \Illuminate\Support\Composer::class, 'cookie' => \Illuminate\Cookie\CookieJar::class, 'db' => \Illuminate\Database\DatabaseManager::class, + 'db.connection' => \Illuminate\Database\MySqlConnection::class, 'db.factory' => \Illuminate\Database\Connectors\ConnectionFactory::class, 'db.transactions' => \Illuminate\Database\DatabaseTransactionsManager::class, 'encrypter' => \Illuminate\Encryption\Encrypter::class, @@ -795,6 +843,14 @@ namespace PHPSTORM_META { ])); override(\Illuminate\Contracts\Container\Container::makeWith(0), map([ '' => '@', + 'Algolia\AlgoliaSearch\AnalyticsClient' => \Algolia\AlgoliaSearch\AnalyticsClient::class, + 'Algolia\AlgoliaSearch\SearchClient' => \Algolia\AlgoliaSearch\SearchClient::class, + 'Algolia\ScoutExtended\Algolia' => \Algolia\ScoutExtended\Algolia::class, + 'Algolia\ScoutExtended\Contracts\LocalSettingsRepositoryContract' => \Algolia\ScoutExtended\Repositories\LocalSettingsRepository::class, + 'Algolia\ScoutExtended\Engines\AlgoliaEngine' => \Algolia\ScoutExtended\Engines\AlgoliaEngine::class, + 'Algolia\ScoutExtended\Helpers\SearchableFinder' => \Algolia\ScoutExtended\Helpers\SearchableFinder::class, + 'Algolia\ScoutExtended\Managers\EngineManager' => \Algolia\ScoutExtended\Managers\EngineManager::class, + 'Algolia\ScoutExtended\Searchable\AggregatorObserver' => \Algolia\ScoutExtended\Searchable\AggregatorObserver::class, 'Asm89\Stack\CorsService' => \Asm89\Stack\CorsService::class, 'CloudCreativity\LaravelJsonApi\Api\Repository' => \CloudCreativity\LaravelJsonApi\Api\Repository::class, 'CloudCreativity\LaravelJsonApi\Contracts\ContainerInterface' => \CloudCreativity\LaravelJsonApi\Container::class, @@ -821,6 +877,8 @@ namespace PHPSTORM_META { 'Facade\Ignition\QueryRecorder\QueryRecorder' => \Facade\Ignition\QueryRecorder\QueryRecorder::class, 'Illuminate\Auth\Middleware\RequirePassword' => \Illuminate\Auth\Middleware\RequirePassword::class, 'Illuminate\Broadcasting\BroadcastManager' => \Illuminate\Broadcasting\BroadcastManager::class, + 'Illuminate\Bus\BatchRepository' => \Illuminate\Bus\DatabaseBatchRepository::class, + 'Illuminate\Bus\DatabaseBatchRepository' => \Illuminate\Bus\DatabaseBatchRepository::class, 'Illuminate\Bus\Dispatcher' => \Illuminate\Bus\Dispatcher::class, 'Illuminate\Cache\RateLimiter' => \Illuminate\Cache\RateLimiter::class, 'Illuminate\Console\Scheduling\Schedule' => \Illuminate\Console\Scheduling\Schedule::class, @@ -845,7 +903,7 @@ namespace PHPSTORM_META { 'Illuminate\Routing\Contracts\ControllerDispatcher' => \Illuminate\Routing\ControllerDispatcher::class, 'Illuminate\Session\Middleware\StartSession' => \Illuminate\Session\Middleware\StartSession::class, 'Illuminate\Testing\ParallelTesting' => \Illuminate\Testing\ParallelTesting::class, - 'Laravel\Scout\EngineManager' => \Laravel\Scout\EngineManager::class, + 'Laravel\Scout\EngineManager' => \Algolia\ScoutExtended\Managers\EngineManager::class, 'Neomerx\JsonApi\Contracts\Encoder\Parameters\EncodingParametersInterface' => \CloudCreativity\LaravelJsonApi\Encoder\Parameters\EncodingParameters::class, 'Neomerx\JsonApi\Contracts\Http\Headers\HeaderParametersInterface' => \Neomerx\JsonApi\Http\Headers\HeaderParameters::class, 'NunoMaduro\Collision\Contracts\Provider' => \NunoMaduro\Collision\Provider::class, @@ -859,6 +917,7 @@ namespace PHPSTORM_META { 'auth' => \Illuminate\Auth\AuthManager::class, 'auth.driver' => \Illuminate\Auth\SessionGuard::class, 'auth.password' => \Illuminate\Auth\Passwords\PasswordBrokerManager::class, + 'auth.password.broker' => \Illuminate\Auth\Passwords\PasswordBroker::class, 'blade.compiler' => \Illuminate\View\Compilers\BladeCompiler::class, 'cache' => \Illuminate\Cache\CacheManager::class, 'cache.store' => \Illuminate\Cache\Repository::class, @@ -951,6 +1010,7 @@ namespace PHPSTORM_META { 'composer' => \Illuminate\Support\Composer::class, 'cookie' => \Illuminate\Cookie\CookieJar::class, 'db' => \Illuminate\Database\DatabaseManager::class, + 'db.connection' => \Illuminate\Database\MySqlConnection::class, 'db.factory' => \Illuminate\Database\Connectors\ConnectionFactory::class, 'db.transactions' => \Illuminate\Database\DatabaseTransactionsManager::class, 'encrypter' => \Illuminate\Encryption\Encrypter::class, @@ -991,6 +1051,14 @@ namespace PHPSTORM_META { ])); override(\App::get(0), map([ '' => '@', + 'Algolia\AlgoliaSearch\AnalyticsClient' => \Algolia\AlgoliaSearch\AnalyticsClient::class, + 'Algolia\AlgoliaSearch\SearchClient' => \Algolia\AlgoliaSearch\SearchClient::class, + 'Algolia\ScoutExtended\Algolia' => \Algolia\ScoutExtended\Algolia::class, + 'Algolia\ScoutExtended\Contracts\LocalSettingsRepositoryContract' => \Algolia\ScoutExtended\Repositories\LocalSettingsRepository::class, + 'Algolia\ScoutExtended\Engines\AlgoliaEngine' => \Algolia\ScoutExtended\Engines\AlgoliaEngine::class, + 'Algolia\ScoutExtended\Helpers\SearchableFinder' => \Algolia\ScoutExtended\Helpers\SearchableFinder::class, + 'Algolia\ScoutExtended\Managers\EngineManager' => \Algolia\ScoutExtended\Managers\EngineManager::class, + 'Algolia\ScoutExtended\Searchable\AggregatorObserver' => \Algolia\ScoutExtended\Searchable\AggregatorObserver::class, 'Asm89\Stack\CorsService' => \Asm89\Stack\CorsService::class, 'CloudCreativity\LaravelJsonApi\Api\Repository' => \CloudCreativity\LaravelJsonApi\Api\Repository::class, 'CloudCreativity\LaravelJsonApi\Contracts\ContainerInterface' => \CloudCreativity\LaravelJsonApi\Container::class, @@ -1017,6 +1085,8 @@ namespace PHPSTORM_META { 'Facade\Ignition\QueryRecorder\QueryRecorder' => \Facade\Ignition\QueryRecorder\QueryRecorder::class, 'Illuminate\Auth\Middleware\RequirePassword' => \Illuminate\Auth\Middleware\RequirePassword::class, 'Illuminate\Broadcasting\BroadcastManager' => \Illuminate\Broadcasting\BroadcastManager::class, + 'Illuminate\Bus\BatchRepository' => \Illuminate\Bus\DatabaseBatchRepository::class, + 'Illuminate\Bus\DatabaseBatchRepository' => \Illuminate\Bus\DatabaseBatchRepository::class, 'Illuminate\Bus\Dispatcher' => \Illuminate\Bus\Dispatcher::class, 'Illuminate\Cache\RateLimiter' => \Illuminate\Cache\RateLimiter::class, 'Illuminate\Console\Scheduling\Schedule' => \Illuminate\Console\Scheduling\Schedule::class, @@ -1041,7 +1111,7 @@ namespace PHPSTORM_META { 'Illuminate\Routing\Contracts\ControllerDispatcher' => \Illuminate\Routing\ControllerDispatcher::class, 'Illuminate\Session\Middleware\StartSession' => \Illuminate\Session\Middleware\StartSession::class, 'Illuminate\Testing\ParallelTesting' => \Illuminate\Testing\ParallelTesting::class, - 'Laravel\Scout\EngineManager' => \Laravel\Scout\EngineManager::class, + 'Laravel\Scout\EngineManager' => \Algolia\ScoutExtended\Managers\EngineManager::class, 'Neomerx\JsonApi\Contracts\Encoder\Parameters\EncodingParametersInterface' => \CloudCreativity\LaravelJsonApi\Encoder\Parameters\EncodingParameters::class, 'Neomerx\JsonApi\Contracts\Http\Headers\HeaderParametersInterface' => \Neomerx\JsonApi\Http\Headers\HeaderParameters::class, 'NunoMaduro\Collision\Contracts\Provider' => \NunoMaduro\Collision\Provider::class, @@ -1055,6 +1125,7 @@ namespace PHPSTORM_META { 'auth' => \Illuminate\Auth\AuthManager::class, 'auth.driver' => \Illuminate\Auth\SessionGuard::class, 'auth.password' => \Illuminate\Auth\Passwords\PasswordBrokerManager::class, + 'auth.password.broker' => \Illuminate\Auth\Passwords\PasswordBroker::class, 'blade.compiler' => \Illuminate\View\Compilers\BladeCompiler::class, 'cache' => \Illuminate\Cache\CacheManager::class, 'cache.store' => \Illuminate\Cache\Repository::class, @@ -1147,6 +1218,7 @@ namespace PHPSTORM_META { 'composer' => \Illuminate\Support\Composer::class, 'cookie' => \Illuminate\Cookie\CookieJar::class, 'db' => \Illuminate\Database\DatabaseManager::class, + 'db.connection' => \Illuminate\Database\MySqlConnection::class, 'db.factory' => \Illuminate\Database\Connectors\ConnectionFactory::class, 'db.transactions' => \Illuminate\Database\DatabaseTransactionsManager::class, 'encrypter' => \Illuminate\Encryption\Encrypter::class, @@ -1187,6 +1259,14 @@ namespace PHPSTORM_META { ])); override(\App::make(0), map([ '' => '@', + 'Algolia\AlgoliaSearch\AnalyticsClient' => \Algolia\AlgoliaSearch\AnalyticsClient::class, + 'Algolia\AlgoliaSearch\SearchClient' => \Algolia\AlgoliaSearch\SearchClient::class, + 'Algolia\ScoutExtended\Algolia' => \Algolia\ScoutExtended\Algolia::class, + 'Algolia\ScoutExtended\Contracts\LocalSettingsRepositoryContract' => \Algolia\ScoutExtended\Repositories\LocalSettingsRepository::class, + 'Algolia\ScoutExtended\Engines\AlgoliaEngine' => \Algolia\ScoutExtended\Engines\AlgoliaEngine::class, + 'Algolia\ScoutExtended\Helpers\SearchableFinder' => \Algolia\ScoutExtended\Helpers\SearchableFinder::class, + 'Algolia\ScoutExtended\Managers\EngineManager' => \Algolia\ScoutExtended\Managers\EngineManager::class, + 'Algolia\ScoutExtended\Searchable\AggregatorObserver' => \Algolia\ScoutExtended\Searchable\AggregatorObserver::class, 'Asm89\Stack\CorsService' => \Asm89\Stack\CorsService::class, 'CloudCreativity\LaravelJsonApi\Api\Repository' => \CloudCreativity\LaravelJsonApi\Api\Repository::class, 'CloudCreativity\LaravelJsonApi\Contracts\ContainerInterface' => \CloudCreativity\LaravelJsonApi\Container::class, @@ -1213,6 +1293,8 @@ namespace PHPSTORM_META { 'Facade\Ignition\QueryRecorder\QueryRecorder' => \Facade\Ignition\QueryRecorder\QueryRecorder::class, 'Illuminate\Auth\Middleware\RequirePassword' => \Illuminate\Auth\Middleware\RequirePassword::class, 'Illuminate\Broadcasting\BroadcastManager' => \Illuminate\Broadcasting\BroadcastManager::class, + 'Illuminate\Bus\BatchRepository' => \Illuminate\Bus\DatabaseBatchRepository::class, + 'Illuminate\Bus\DatabaseBatchRepository' => \Illuminate\Bus\DatabaseBatchRepository::class, 'Illuminate\Bus\Dispatcher' => \Illuminate\Bus\Dispatcher::class, 'Illuminate\Cache\RateLimiter' => \Illuminate\Cache\RateLimiter::class, 'Illuminate\Console\Scheduling\Schedule' => \Illuminate\Console\Scheduling\Schedule::class, @@ -1237,7 +1319,7 @@ namespace PHPSTORM_META { 'Illuminate\Routing\Contracts\ControllerDispatcher' => \Illuminate\Routing\ControllerDispatcher::class, 'Illuminate\Session\Middleware\StartSession' => \Illuminate\Session\Middleware\StartSession::class, 'Illuminate\Testing\ParallelTesting' => \Illuminate\Testing\ParallelTesting::class, - 'Laravel\Scout\EngineManager' => \Laravel\Scout\EngineManager::class, + 'Laravel\Scout\EngineManager' => \Algolia\ScoutExtended\Managers\EngineManager::class, 'Neomerx\JsonApi\Contracts\Encoder\Parameters\EncodingParametersInterface' => \CloudCreativity\LaravelJsonApi\Encoder\Parameters\EncodingParameters::class, 'Neomerx\JsonApi\Contracts\Http\Headers\HeaderParametersInterface' => \Neomerx\JsonApi\Http\Headers\HeaderParameters::class, 'NunoMaduro\Collision\Contracts\Provider' => \NunoMaduro\Collision\Provider::class, @@ -1251,6 +1333,7 @@ namespace PHPSTORM_META { 'auth' => \Illuminate\Auth\AuthManager::class, 'auth.driver' => \Illuminate\Auth\SessionGuard::class, 'auth.password' => \Illuminate\Auth\Passwords\PasswordBrokerManager::class, + 'auth.password.broker' => \Illuminate\Auth\Passwords\PasswordBroker::class, 'blade.compiler' => \Illuminate\View\Compilers\BladeCompiler::class, 'cache' => \Illuminate\Cache\CacheManager::class, 'cache.store' => \Illuminate\Cache\Repository::class, @@ -1343,6 +1426,7 @@ namespace PHPSTORM_META { 'composer' => \Illuminate\Support\Composer::class, 'cookie' => \Illuminate\Cookie\CookieJar::class, 'db' => \Illuminate\Database\DatabaseManager::class, + 'db.connection' => \Illuminate\Database\MySqlConnection::class, 'db.factory' => \Illuminate\Database\Connectors\ConnectionFactory::class, 'db.transactions' => \Illuminate\Database\DatabaseTransactionsManager::class, 'encrypter' => \Illuminate\Encryption\Encrypter::class, @@ -1383,6 +1467,14 @@ namespace PHPSTORM_META { ])); override(\App::makeWith(0), map([ '' => '@', + 'Algolia\AlgoliaSearch\AnalyticsClient' => \Algolia\AlgoliaSearch\AnalyticsClient::class, + 'Algolia\AlgoliaSearch\SearchClient' => \Algolia\AlgoliaSearch\SearchClient::class, + 'Algolia\ScoutExtended\Algolia' => \Algolia\ScoutExtended\Algolia::class, + 'Algolia\ScoutExtended\Contracts\LocalSettingsRepositoryContract' => \Algolia\ScoutExtended\Repositories\LocalSettingsRepository::class, + 'Algolia\ScoutExtended\Engines\AlgoliaEngine' => \Algolia\ScoutExtended\Engines\AlgoliaEngine::class, + 'Algolia\ScoutExtended\Helpers\SearchableFinder' => \Algolia\ScoutExtended\Helpers\SearchableFinder::class, + 'Algolia\ScoutExtended\Managers\EngineManager' => \Algolia\ScoutExtended\Managers\EngineManager::class, + 'Algolia\ScoutExtended\Searchable\AggregatorObserver' => \Algolia\ScoutExtended\Searchable\AggregatorObserver::class, 'Asm89\Stack\CorsService' => \Asm89\Stack\CorsService::class, 'CloudCreativity\LaravelJsonApi\Api\Repository' => \CloudCreativity\LaravelJsonApi\Api\Repository::class, 'CloudCreativity\LaravelJsonApi\Contracts\ContainerInterface' => \CloudCreativity\LaravelJsonApi\Container::class, @@ -1409,6 +1501,8 @@ namespace PHPSTORM_META { 'Facade\Ignition\QueryRecorder\QueryRecorder' => \Facade\Ignition\QueryRecorder\QueryRecorder::class, 'Illuminate\Auth\Middleware\RequirePassword' => \Illuminate\Auth\Middleware\RequirePassword::class, 'Illuminate\Broadcasting\BroadcastManager' => \Illuminate\Broadcasting\BroadcastManager::class, + 'Illuminate\Bus\BatchRepository' => \Illuminate\Bus\DatabaseBatchRepository::class, + 'Illuminate\Bus\DatabaseBatchRepository' => \Illuminate\Bus\DatabaseBatchRepository::class, 'Illuminate\Bus\Dispatcher' => \Illuminate\Bus\Dispatcher::class, 'Illuminate\Cache\RateLimiter' => \Illuminate\Cache\RateLimiter::class, 'Illuminate\Console\Scheduling\Schedule' => \Illuminate\Console\Scheduling\Schedule::class, @@ -1433,7 +1527,7 @@ namespace PHPSTORM_META { 'Illuminate\Routing\Contracts\ControllerDispatcher' => \Illuminate\Routing\ControllerDispatcher::class, 'Illuminate\Session\Middleware\StartSession' => \Illuminate\Session\Middleware\StartSession::class, 'Illuminate\Testing\ParallelTesting' => \Illuminate\Testing\ParallelTesting::class, - 'Laravel\Scout\EngineManager' => \Laravel\Scout\EngineManager::class, + 'Laravel\Scout\EngineManager' => \Algolia\ScoutExtended\Managers\EngineManager::class, 'Neomerx\JsonApi\Contracts\Encoder\Parameters\EncodingParametersInterface' => \CloudCreativity\LaravelJsonApi\Encoder\Parameters\EncodingParameters::class, 'Neomerx\JsonApi\Contracts\Http\Headers\HeaderParametersInterface' => \Neomerx\JsonApi\Http\Headers\HeaderParameters::class, 'NunoMaduro\Collision\Contracts\Provider' => \NunoMaduro\Collision\Provider::class, @@ -1447,6 +1541,7 @@ namespace PHPSTORM_META { 'auth' => \Illuminate\Auth\AuthManager::class, 'auth.driver' => \Illuminate\Auth\SessionGuard::class, 'auth.password' => \Illuminate\Auth\Passwords\PasswordBrokerManager::class, + 'auth.password.broker' => \Illuminate\Auth\Passwords\PasswordBroker::class, 'blade.compiler' => \Illuminate\View\Compilers\BladeCompiler::class, 'cache' => \Illuminate\Cache\CacheManager::class, 'cache.store' => \Illuminate\Cache\Repository::class, @@ -1539,6 +1634,7 @@ namespace PHPSTORM_META { 'composer' => \Illuminate\Support\Composer::class, 'cookie' => \Illuminate\Cookie\CookieJar::class, 'db' => \Illuminate\Database\DatabaseManager::class, + 'db.connection' => \Illuminate\Database\MySqlConnection::class, 'db.factory' => \Illuminate\Database\Connectors\ConnectionFactory::class, 'db.transactions' => \Illuminate\Database\DatabaseTransactionsManager::class, 'encrypter' => \Illuminate\Encryption\Encrypter::class, @@ -1579,6 +1675,14 @@ namespace PHPSTORM_META { ])); override(\app(0), map([ '' => '@', + 'Algolia\AlgoliaSearch\AnalyticsClient' => \Algolia\AlgoliaSearch\AnalyticsClient::class, + 'Algolia\AlgoliaSearch\SearchClient' => \Algolia\AlgoliaSearch\SearchClient::class, + 'Algolia\ScoutExtended\Algolia' => \Algolia\ScoutExtended\Algolia::class, + 'Algolia\ScoutExtended\Contracts\LocalSettingsRepositoryContract' => \Algolia\ScoutExtended\Repositories\LocalSettingsRepository::class, + 'Algolia\ScoutExtended\Engines\AlgoliaEngine' => \Algolia\ScoutExtended\Engines\AlgoliaEngine::class, + 'Algolia\ScoutExtended\Helpers\SearchableFinder' => \Algolia\ScoutExtended\Helpers\SearchableFinder::class, + 'Algolia\ScoutExtended\Managers\EngineManager' => \Algolia\ScoutExtended\Managers\EngineManager::class, + 'Algolia\ScoutExtended\Searchable\AggregatorObserver' => \Algolia\ScoutExtended\Searchable\AggregatorObserver::class, 'Asm89\Stack\CorsService' => \Asm89\Stack\CorsService::class, 'CloudCreativity\LaravelJsonApi\Api\Repository' => \CloudCreativity\LaravelJsonApi\Api\Repository::class, 'CloudCreativity\LaravelJsonApi\Contracts\ContainerInterface' => \CloudCreativity\LaravelJsonApi\Container::class, @@ -1605,6 +1709,8 @@ namespace PHPSTORM_META { 'Facade\Ignition\QueryRecorder\QueryRecorder' => \Facade\Ignition\QueryRecorder\QueryRecorder::class, 'Illuminate\Auth\Middleware\RequirePassword' => \Illuminate\Auth\Middleware\RequirePassword::class, 'Illuminate\Broadcasting\BroadcastManager' => \Illuminate\Broadcasting\BroadcastManager::class, + 'Illuminate\Bus\BatchRepository' => \Illuminate\Bus\DatabaseBatchRepository::class, + 'Illuminate\Bus\DatabaseBatchRepository' => \Illuminate\Bus\DatabaseBatchRepository::class, 'Illuminate\Bus\Dispatcher' => \Illuminate\Bus\Dispatcher::class, 'Illuminate\Cache\RateLimiter' => \Illuminate\Cache\RateLimiter::class, 'Illuminate\Console\Scheduling\Schedule' => \Illuminate\Console\Scheduling\Schedule::class, @@ -1629,7 +1735,7 @@ namespace PHPSTORM_META { 'Illuminate\Routing\Contracts\ControllerDispatcher' => \Illuminate\Routing\ControllerDispatcher::class, 'Illuminate\Session\Middleware\StartSession' => \Illuminate\Session\Middleware\StartSession::class, 'Illuminate\Testing\ParallelTesting' => \Illuminate\Testing\ParallelTesting::class, - 'Laravel\Scout\EngineManager' => \Laravel\Scout\EngineManager::class, + 'Laravel\Scout\EngineManager' => \Algolia\ScoutExtended\Managers\EngineManager::class, 'Neomerx\JsonApi\Contracts\Encoder\Parameters\EncodingParametersInterface' => \CloudCreativity\LaravelJsonApi\Encoder\Parameters\EncodingParameters::class, 'Neomerx\JsonApi\Contracts\Http\Headers\HeaderParametersInterface' => \Neomerx\JsonApi\Http\Headers\HeaderParameters::class, 'NunoMaduro\Collision\Contracts\Provider' => \NunoMaduro\Collision\Provider::class, @@ -1643,6 +1749,7 @@ namespace PHPSTORM_META { 'auth' => \Illuminate\Auth\AuthManager::class, 'auth.driver' => \Illuminate\Auth\SessionGuard::class, 'auth.password' => \Illuminate\Auth\Passwords\PasswordBrokerManager::class, + 'auth.password.broker' => \Illuminate\Auth\Passwords\PasswordBroker::class, 'blade.compiler' => \Illuminate\View\Compilers\BladeCompiler::class, 'cache' => \Illuminate\Cache\CacheManager::class, 'cache.store' => \Illuminate\Cache\Repository::class, @@ -1735,6 +1842,7 @@ namespace PHPSTORM_META { 'composer' => \Illuminate\Support\Composer::class, 'cookie' => \Illuminate\Cookie\CookieJar::class, 'db' => \Illuminate\Database\DatabaseManager::class, + 'db.connection' => \Illuminate\Database\MySqlConnection::class, 'db.factory' => \Illuminate\Database\Connectors\ConnectionFactory::class, 'db.transactions' => \Illuminate\Database\DatabaseTransactionsManager::class, 'encrypter' => \Illuminate\Encryption\Encrypter::class, @@ -1775,6 +1883,14 @@ namespace PHPSTORM_META { ])); override(\resolve(0), map([ '' => '@', + 'Algolia\AlgoliaSearch\AnalyticsClient' => \Algolia\AlgoliaSearch\AnalyticsClient::class, + 'Algolia\AlgoliaSearch\SearchClient' => \Algolia\AlgoliaSearch\SearchClient::class, + 'Algolia\ScoutExtended\Algolia' => \Algolia\ScoutExtended\Algolia::class, + 'Algolia\ScoutExtended\Contracts\LocalSettingsRepositoryContract' => \Algolia\ScoutExtended\Repositories\LocalSettingsRepository::class, + 'Algolia\ScoutExtended\Engines\AlgoliaEngine' => \Algolia\ScoutExtended\Engines\AlgoliaEngine::class, + 'Algolia\ScoutExtended\Helpers\SearchableFinder' => \Algolia\ScoutExtended\Helpers\SearchableFinder::class, + 'Algolia\ScoutExtended\Managers\EngineManager' => \Algolia\ScoutExtended\Managers\EngineManager::class, + 'Algolia\ScoutExtended\Searchable\AggregatorObserver' => \Algolia\ScoutExtended\Searchable\AggregatorObserver::class, 'Asm89\Stack\CorsService' => \Asm89\Stack\CorsService::class, 'CloudCreativity\LaravelJsonApi\Api\Repository' => \CloudCreativity\LaravelJsonApi\Api\Repository::class, 'CloudCreativity\LaravelJsonApi\Contracts\ContainerInterface' => \CloudCreativity\LaravelJsonApi\Container::class, @@ -1801,6 +1917,8 @@ namespace PHPSTORM_META { 'Facade\Ignition\QueryRecorder\QueryRecorder' => \Facade\Ignition\QueryRecorder\QueryRecorder::class, 'Illuminate\Auth\Middleware\RequirePassword' => \Illuminate\Auth\Middleware\RequirePassword::class, 'Illuminate\Broadcasting\BroadcastManager' => \Illuminate\Broadcasting\BroadcastManager::class, + 'Illuminate\Bus\BatchRepository' => \Illuminate\Bus\DatabaseBatchRepository::class, + 'Illuminate\Bus\DatabaseBatchRepository' => \Illuminate\Bus\DatabaseBatchRepository::class, 'Illuminate\Bus\Dispatcher' => \Illuminate\Bus\Dispatcher::class, 'Illuminate\Cache\RateLimiter' => \Illuminate\Cache\RateLimiter::class, 'Illuminate\Console\Scheduling\Schedule' => \Illuminate\Console\Scheduling\Schedule::class, @@ -1825,7 +1943,7 @@ namespace PHPSTORM_META { 'Illuminate\Routing\Contracts\ControllerDispatcher' => \Illuminate\Routing\ControllerDispatcher::class, 'Illuminate\Session\Middleware\StartSession' => \Illuminate\Session\Middleware\StartSession::class, 'Illuminate\Testing\ParallelTesting' => \Illuminate\Testing\ParallelTesting::class, - 'Laravel\Scout\EngineManager' => \Laravel\Scout\EngineManager::class, + 'Laravel\Scout\EngineManager' => \Algolia\ScoutExtended\Managers\EngineManager::class, 'Neomerx\JsonApi\Contracts\Encoder\Parameters\EncodingParametersInterface' => \CloudCreativity\LaravelJsonApi\Encoder\Parameters\EncodingParameters::class, 'Neomerx\JsonApi\Contracts\Http\Headers\HeaderParametersInterface' => \Neomerx\JsonApi\Http\Headers\HeaderParameters::class, 'NunoMaduro\Collision\Contracts\Provider' => \NunoMaduro\Collision\Provider::class, @@ -1839,6 +1957,7 @@ namespace PHPSTORM_META { 'auth' => \Illuminate\Auth\AuthManager::class, 'auth.driver' => \Illuminate\Auth\SessionGuard::class, 'auth.password' => \Illuminate\Auth\Passwords\PasswordBrokerManager::class, + 'auth.password.broker' => \Illuminate\Auth\Passwords\PasswordBroker::class, 'blade.compiler' => \Illuminate\View\Compilers\BladeCompiler::class, 'cache' => \Illuminate\Cache\CacheManager::class, 'cache.store' => \Illuminate\Cache\Repository::class, @@ -1931,6 +2050,7 @@ namespace PHPSTORM_META { 'composer' => \Illuminate\Support\Composer::class, 'cookie' => \Illuminate\Cookie\CookieJar::class, 'db' => \Illuminate\Database\DatabaseManager::class, + 'db.connection' => \Illuminate\Database\MySqlConnection::class, 'db.factory' => \Illuminate\Database\Connectors\ConnectionFactory::class, 'db.transactions' => \Illuminate\Database\DatabaseTransactionsManager::class, 'encrypter' => \Illuminate\Encryption\Encrypter::class, @@ -1971,6 +2091,14 @@ namespace PHPSTORM_META { ])); override(\Psr\Container\ContainerInterface::get(0), map([ '' => '@', + 'Algolia\AlgoliaSearch\AnalyticsClient' => \Algolia\AlgoliaSearch\AnalyticsClient::class, + 'Algolia\AlgoliaSearch\SearchClient' => \Algolia\AlgoliaSearch\SearchClient::class, + 'Algolia\ScoutExtended\Algolia' => \Algolia\ScoutExtended\Algolia::class, + 'Algolia\ScoutExtended\Contracts\LocalSettingsRepositoryContract' => \Algolia\ScoutExtended\Repositories\LocalSettingsRepository::class, + 'Algolia\ScoutExtended\Engines\AlgoliaEngine' => \Algolia\ScoutExtended\Engines\AlgoliaEngine::class, + 'Algolia\ScoutExtended\Helpers\SearchableFinder' => \Algolia\ScoutExtended\Helpers\SearchableFinder::class, + 'Algolia\ScoutExtended\Managers\EngineManager' => \Algolia\ScoutExtended\Managers\EngineManager::class, + 'Algolia\ScoutExtended\Searchable\AggregatorObserver' => \Algolia\ScoutExtended\Searchable\AggregatorObserver::class, 'Asm89\Stack\CorsService' => \Asm89\Stack\CorsService::class, 'CloudCreativity\LaravelJsonApi\Api\Repository' => \CloudCreativity\LaravelJsonApi\Api\Repository::class, 'CloudCreativity\LaravelJsonApi\Contracts\ContainerInterface' => \CloudCreativity\LaravelJsonApi\Container::class, @@ -1997,6 +2125,8 @@ namespace PHPSTORM_META { 'Facade\Ignition\QueryRecorder\QueryRecorder' => \Facade\Ignition\QueryRecorder\QueryRecorder::class, 'Illuminate\Auth\Middleware\RequirePassword' => \Illuminate\Auth\Middleware\RequirePassword::class, 'Illuminate\Broadcasting\BroadcastManager' => \Illuminate\Broadcasting\BroadcastManager::class, + 'Illuminate\Bus\BatchRepository' => \Illuminate\Bus\DatabaseBatchRepository::class, + 'Illuminate\Bus\DatabaseBatchRepository' => \Illuminate\Bus\DatabaseBatchRepository::class, 'Illuminate\Bus\Dispatcher' => \Illuminate\Bus\Dispatcher::class, 'Illuminate\Cache\RateLimiter' => \Illuminate\Cache\RateLimiter::class, 'Illuminate\Console\Scheduling\Schedule' => \Illuminate\Console\Scheduling\Schedule::class, @@ -2021,7 +2151,7 @@ namespace PHPSTORM_META { 'Illuminate\Routing\Contracts\ControllerDispatcher' => \Illuminate\Routing\ControllerDispatcher::class, 'Illuminate\Session\Middleware\StartSession' => \Illuminate\Session\Middleware\StartSession::class, 'Illuminate\Testing\ParallelTesting' => \Illuminate\Testing\ParallelTesting::class, - 'Laravel\Scout\EngineManager' => \Laravel\Scout\EngineManager::class, + 'Laravel\Scout\EngineManager' => \Algolia\ScoutExtended\Managers\EngineManager::class, 'Neomerx\JsonApi\Contracts\Encoder\Parameters\EncodingParametersInterface' => \CloudCreativity\LaravelJsonApi\Encoder\Parameters\EncodingParameters::class, 'Neomerx\JsonApi\Contracts\Http\Headers\HeaderParametersInterface' => \Neomerx\JsonApi\Http\Headers\HeaderParameters::class, 'NunoMaduro\Collision\Contracts\Provider' => \NunoMaduro\Collision\Provider::class, @@ -2035,6 +2165,7 @@ namespace PHPSTORM_META { 'auth' => \Illuminate\Auth\AuthManager::class, 'auth.driver' => \Illuminate\Auth\SessionGuard::class, 'auth.password' => \Illuminate\Auth\Passwords\PasswordBrokerManager::class, + 'auth.password.broker' => \Illuminate\Auth\Passwords\PasswordBroker::class, 'blade.compiler' => \Illuminate\View\Compilers\BladeCompiler::class, 'cache' => \Illuminate\Cache\CacheManager::class, 'cache.store' => \Illuminate\Cache\Repository::class, @@ -2127,6 +2258,7 @@ namespace PHPSTORM_META { 'composer' => \Illuminate\Support\Composer::class, 'cookie' => \Illuminate\Cookie\CookieJar::class, 'db' => \Illuminate\Database\DatabaseManager::class, + 'db.connection' => \Illuminate\Database\MySqlConnection::class, 'db.factory' => \Illuminate\Database\Connectors\ConnectionFactory::class, 'db.transactions' => \Illuminate\Database\DatabaseTransactionsManager::class, 'encrypter' => \Illuminate\Encryption\Encrypter::class, diff --git a/Procfile b/Procfile new file mode 100644 index 0000000..48aab52 --- /dev/null +++ b/Procfile @@ -0,0 +1 @@ +web: vendor/bin/heroku-php-apache2 public/ diff --git a/README.md b/README.md index 269485c..9aeb4a1 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,84 @@ # kcal – the personal food nutrition journal [![CI Status](https://github.com/kcal-app/kcal/actions/workflows/ci.yml/badge.svg)](https://github.com/kcal-app/kcal/actions/workflows/ci.yml) -[![Coverage \status](https://coveralls.io/repos/github/kcal-app/kcal/badge.svg)](https://coveralls.io/github/kcal-app/kcal?branch=tests) +[![Coverage Status](https://coveralls.io/repos/github/kcal-app/kcal/badge.svg)](https://coveralls.io/github/kcal-app/kcal) + +## Deployment + +### Heroku + +[![Deploy](https://www.herokucdn.com/deploy/button.svg)](https://heroku.com/deploy) + +The default username and password for a Heroku deployment is `kcal`/`kcal`. + +#### Using Heroku CLI + +For a manual deploy using Heroku CLI, execute the following after initial deployment: + + heroku run php artisan migrate + heroku run php artisan user:add + heroku config:set APP_KEY=$(php artisan --no-ansi key:generate --show) + +#### Search drivers + +See the [Search](#search-mag) section for information about supported drivers. Additional +environment variable configuration is necessary when using any search driver other +than the default ("null"). + +#### Redis Add-on + +The [Heroku Redis](https://elements.heroku.com/addons/heroku-redis) add-on can be +added to the app and will work without any configuration changes. It is left out +of the default build only because it takes a very long time to provision. + +## Search :mag: + +The "ingredient" (food or recipe) search for journal entries and recipe ingredients +supports three different backends using the `SCOUT_DRIVER` environment variable. +In all cases, always ensure that the `SCOUT_DRIVER` environment variable is only +set once in kcal's `.env` file. + +Currently, the food and recipe *list* searches do not take advantage of these +search drivers. Support for those searches will be added if the Laravel JSON:API +adds support for Scout (see: laravel-json-api/laravel#32). + +### Algolia (`algolia`) + +1. [Create and/or log in](https://www.algolia.com/users/sign_in) to an Algolia account. + +1. Create an application for kcal. + +1. Navigate to the application's "API Keys" section. + +1. Using the **Application ID** and **Admin API Key** values, update kcal's `.env` file: + + SCOUT_DRIVER=algolia + ALGOLIA_APP_ID= + ALGOLIA_SECRET= + +### ElasticSearch (`elastic`) + +1. Determine the host and port for your ElasticSearch service. + +1. Update kcal's `.env` file. + + SCOUT_DRIVER=elastic + ELASTIC_HOST= + ELASTIC_PORT= + + Note: The `ELASTIC_PORT` variable is a convenience option specifically for + Docker Compose configurations and is not strictly required. + +1. Run Elastic's migrations. + + php artisan elastic:migrate + +### Fallback (`null`) + +The fallback driver is a simple `WHERE ... LIKE` clause search on a couple of key +fields. Results will not be ordered by relevance, and some fields will not be +searched (e.g. the tags fields). Using one of the other options is highly recommended. + +Set `SCOUT_DRIVER=null` in kcal's `.env` file to use the fallback driver. ## Development @@ -52,5 +130,5 @@ The default username and password is `admin@kcal.test`. -Once the application finishing starting, navigate to [http://127.0.0.1:8080](http://127.0.0.1:8080) +Once the application finishes starting, navigate to [http://127.0.0.1:8080](http://127.0.0.1:8080) (or [http://kcal.test:8080](http://kcal.test:8080) if configured). diff --git a/_ide_helper.php b/_ide_helper.php index 7f1b756..2517b18 100644 --- a/_ide_helper.php +++ b/_ide_helper.php @@ -4327,16 +4327,27 @@ { /** @var \Illuminate\Database\DatabaseManager $instance */ $instance->setReconnector($reconnector); + } + /** + * Determine if the connected database is a MariaDB database. + * + * @return bool + * @static + */ + public static function isMaria() + { + /** @var \Illuminate\Database\MySqlConnection $instance */ + return $instance->isMaria(); } /** * Get a schema builder instance for the connection. * - * @return \Illuminate\Database\Schema\SQLiteBuilder + * @return \Illuminate\Database\Schema\MySqlBuilder * @static */ public static function getSchemaBuilder() { - /** @var \Illuminate\Database\SQLiteConnection $instance */ + /** @var \Illuminate\Database\MySqlConnection $instance */ return $instance->getSchemaBuilder(); } /** @@ -4344,12 +4355,12 @@ * * @param \Illuminate\Filesystem\Filesystem|null $files * @param callable|null $processFactory - * @throws \RuntimeException + * @return \Illuminate\Database\Schema\MySqlSchemaState * @static */ public static function getSchemaState($files = null, $processFactory = null) { - /** @var \Illuminate\Database\SQLiteConnection $instance */ + /** @var \Illuminate\Database\MySqlConnection $instance */ return $instance->getSchemaState($files, $processFactory); } /** @@ -4360,7 +4371,7 @@ */ public static function useDefaultQueryGrammar() { //Method inherited from \Illuminate\Database\Connection - /** @var \Illuminate\Database\SQLiteConnection $instance */ + /** @var \Illuminate\Database\MySqlConnection $instance */ $instance->useDefaultQueryGrammar(); } /** @@ -4371,7 +4382,7 @@ */ public static function useDefaultSchemaGrammar() { //Method inherited from \Illuminate\Database\Connection - /** @var \Illuminate\Database\SQLiteConnection $instance */ + /** @var \Illuminate\Database\MySqlConnection $instance */ $instance->useDefaultSchemaGrammar(); } /** @@ -4382,7 +4393,7 @@ */ public static function useDefaultPostProcessor() { //Method inherited from \Illuminate\Database\Connection - /** @var \Illuminate\Database\SQLiteConnection $instance */ + /** @var \Illuminate\Database\MySqlConnection $instance */ $instance->useDefaultPostProcessor(); } /** @@ -4395,7 +4406,7 @@ */ public static function table($table, $as = null) { //Method inherited from \Illuminate\Database\Connection - /** @var \Illuminate\Database\SQLiteConnection $instance */ + /** @var \Illuminate\Database\MySqlConnection $instance */ return $instance->table($table, $as); } /** @@ -4406,7 +4417,7 @@ */ public static function query() { //Method inherited from \Illuminate\Database\Connection - /** @var \Illuminate\Database\SQLiteConnection $instance */ + /** @var \Illuminate\Database\MySqlConnection $instance */ return $instance->query(); } /** @@ -4420,7 +4431,7 @@ */ public static function selectOne($query, $bindings = [], $useReadPdo = true) { //Method inherited from \Illuminate\Database\Connection - /** @var \Illuminate\Database\SQLiteConnection $instance */ + /** @var \Illuminate\Database\MySqlConnection $instance */ return $instance->selectOne($query, $bindings, $useReadPdo); } /** @@ -4433,7 +4444,7 @@ */ public static function selectFromWriteConnection($query, $bindings = []) { //Method inherited from \Illuminate\Database\Connection - /** @var \Illuminate\Database\SQLiteConnection $instance */ + /** @var \Illuminate\Database\MySqlConnection $instance */ return $instance->selectFromWriteConnection($query, $bindings); } /** @@ -4447,7 +4458,7 @@ */ public static function select($query, $bindings = [], $useReadPdo = true) { //Method inherited from \Illuminate\Database\Connection - /** @var \Illuminate\Database\SQLiteConnection $instance */ + /** @var \Illuminate\Database\MySqlConnection $instance */ return $instance->select($query, $bindings, $useReadPdo); } /** @@ -4461,7 +4472,7 @@ */ public static function cursor($query, $bindings = [], $useReadPdo = true) { //Method inherited from \Illuminate\Database\Connection - /** @var \Illuminate\Database\SQLiteConnection $instance */ + /** @var \Illuminate\Database\MySqlConnection $instance */ return $instance->cursor($query, $bindings, $useReadPdo); } /** @@ -4474,7 +4485,7 @@ */ public static function insert($query, $bindings = []) { //Method inherited from \Illuminate\Database\Connection - /** @var \Illuminate\Database\SQLiteConnection $instance */ + /** @var \Illuminate\Database\MySqlConnection $instance */ return $instance->insert($query, $bindings); } /** @@ -4487,7 +4498,7 @@ */ public static function update($query, $bindings = []) { //Method inherited from \Illuminate\Database\Connection - /** @var \Illuminate\Database\SQLiteConnection $instance */ + /** @var \Illuminate\Database\MySqlConnection $instance */ return $instance->update($query, $bindings); } /** @@ -4500,7 +4511,7 @@ */ public static function delete($query, $bindings = []) { //Method inherited from \Illuminate\Database\Connection - /** @var \Illuminate\Database\SQLiteConnection $instance */ + /** @var \Illuminate\Database\MySqlConnection $instance */ return $instance->delete($query, $bindings); } /** @@ -4513,7 +4524,7 @@ */ public static function statement($query, $bindings = []) { //Method inherited from \Illuminate\Database\Connection - /** @var \Illuminate\Database\SQLiteConnection $instance */ + /** @var \Illuminate\Database\MySqlConnection $instance */ return $instance->statement($query, $bindings); } /** @@ -4526,7 +4537,7 @@ */ public static function affectingStatement($query, $bindings = []) { //Method inherited from \Illuminate\Database\Connection - /** @var \Illuminate\Database\SQLiteConnection $instance */ + /** @var \Illuminate\Database\MySqlConnection $instance */ return $instance->affectingStatement($query, $bindings); } /** @@ -4538,7 +4549,7 @@ */ public static function unprepared($query) { //Method inherited from \Illuminate\Database\Connection - /** @var \Illuminate\Database\SQLiteConnection $instance */ + /** @var \Illuminate\Database\MySqlConnection $instance */ return $instance->unprepared($query); } /** @@ -4550,7 +4561,7 @@ */ public static function pretend($callback) { //Method inherited from \Illuminate\Database\Connection - /** @var \Illuminate\Database\SQLiteConnection $instance */ + /** @var \Illuminate\Database\MySqlConnection $instance */ return $instance->pretend($callback); } /** @@ -4563,7 +4574,7 @@ */ public static function bindValues($statement, $bindings) { //Method inherited from \Illuminate\Database\Connection - /** @var \Illuminate\Database\SQLiteConnection $instance */ + /** @var \Illuminate\Database\MySqlConnection $instance */ $instance->bindValues($statement, $bindings); } /** @@ -4575,7 +4586,7 @@ */ public static function prepareBindings($bindings) { //Method inherited from \Illuminate\Database\Connection - /** @var \Illuminate\Database\SQLiteConnection $instance */ + /** @var \Illuminate\Database\MySqlConnection $instance */ return $instance->prepareBindings($bindings); } /** @@ -4589,7 +4600,7 @@ */ public static function logQuery($query, $bindings, $time = null) { //Method inherited from \Illuminate\Database\Connection - /** @var \Illuminate\Database\SQLiteConnection $instance */ + /** @var \Illuminate\Database\MySqlConnection $instance */ $instance->logQuery($query, $bindings, $time); } /** @@ -4601,7 +4612,7 @@ */ public static function listen($callback) { //Method inherited from \Illuminate\Database\Connection - /** @var \Illuminate\Database\SQLiteConnection $instance */ + /** @var \Illuminate\Database\MySqlConnection $instance */ $instance->listen($callback); } /** @@ -4613,7 +4624,7 @@ */ public static function raw($value) { //Method inherited from \Illuminate\Database\Connection - /** @var \Illuminate\Database\SQLiteConnection $instance */ + /** @var \Illuminate\Database\MySqlConnection $instance */ return $instance->raw($value); } /** @@ -4625,7 +4636,7 @@ */ public static function recordsHaveBeenModified($value = true) { //Method inherited from \Illuminate\Database\Connection - /** @var \Illuminate\Database\SQLiteConnection $instance */ + /** @var \Illuminate\Database\MySqlConnection $instance */ $instance->recordsHaveBeenModified($value); } /** @@ -4636,7 +4647,7 @@ */ public static function forgetRecordModificationState() { //Method inherited from \Illuminate\Database\Connection - /** @var \Illuminate\Database\SQLiteConnection $instance */ + /** @var \Illuminate\Database\MySqlConnection $instance */ $instance->forgetRecordModificationState(); } /** @@ -4647,7 +4658,7 @@ */ public static function isDoctrineAvailable() { //Method inherited from \Illuminate\Database\Connection - /** @var \Illuminate\Database\SQLiteConnection $instance */ + /** @var \Illuminate\Database\MySqlConnection $instance */ return $instance->isDoctrineAvailable(); } /** @@ -4660,7 +4671,7 @@ */ public static function getDoctrineColumn($table, $column) { //Method inherited from \Illuminate\Database\Connection - /** @var \Illuminate\Database\SQLiteConnection $instance */ + /** @var \Illuminate\Database\MySqlConnection $instance */ return $instance->getDoctrineColumn($table, $column); } /** @@ -4671,7 +4682,7 @@ */ public static function getDoctrineSchemaManager() { //Method inherited from \Illuminate\Database\Connection - /** @var \Illuminate\Database\SQLiteConnection $instance */ + /** @var \Illuminate\Database\MySqlConnection $instance */ return $instance->getDoctrineSchemaManager(); } /** @@ -4682,7 +4693,7 @@ */ public static function getDoctrineConnection() { //Method inherited from \Illuminate\Database\Connection - /** @var \Illuminate\Database\SQLiteConnection $instance */ + /** @var \Illuminate\Database\MySqlConnection $instance */ return $instance->getDoctrineConnection(); } /** @@ -4693,7 +4704,7 @@ */ public static function getPdo() { //Method inherited from \Illuminate\Database\Connection - /** @var \Illuminate\Database\SQLiteConnection $instance */ + /** @var \Illuminate\Database\MySqlConnection $instance */ return $instance->getPdo(); } /** @@ -4704,7 +4715,7 @@ */ public static function getRawPdo() { //Method inherited from \Illuminate\Database\Connection - /** @var \Illuminate\Database\SQLiteConnection $instance */ + /** @var \Illuminate\Database\MySqlConnection $instance */ return $instance->getRawPdo(); } /** @@ -4715,7 +4726,7 @@ */ public static function getReadPdo() { //Method inherited from \Illuminate\Database\Connection - /** @var \Illuminate\Database\SQLiteConnection $instance */ + /** @var \Illuminate\Database\MySqlConnection $instance */ return $instance->getReadPdo(); } /** @@ -4726,31 +4737,31 @@ */ public static function getRawReadPdo() { //Method inherited from \Illuminate\Database\Connection - /** @var \Illuminate\Database\SQLiteConnection $instance */ + /** @var \Illuminate\Database\MySqlConnection $instance */ return $instance->getRawReadPdo(); } /** * Set the PDO connection. * * @param \PDO|\Closure|null $pdo - * @return \Illuminate\Database\SQLiteConnection + * @return \Illuminate\Database\MySqlConnection * @static */ public static function setPdo($pdo) { //Method inherited from \Illuminate\Database\Connection - /** @var \Illuminate\Database\SQLiteConnection $instance */ + /** @var \Illuminate\Database\MySqlConnection $instance */ return $instance->setPdo($pdo); } /** * Set the PDO connection used for reading. * * @param \PDO|\Closure|null $pdo - * @return \Illuminate\Database\SQLiteConnection + * @return \Illuminate\Database\MySqlConnection * @static */ public static function setReadPdo($pdo) { //Method inherited from \Illuminate\Database\Connection - /** @var \Illuminate\Database\SQLiteConnection $instance */ + /** @var \Illuminate\Database\MySqlConnection $instance */ return $instance->setReadPdo($pdo); } /** @@ -4761,7 +4772,7 @@ */ public static function getName() { //Method inherited from \Illuminate\Database\Connection - /** @var \Illuminate\Database\SQLiteConnection $instance */ + /** @var \Illuminate\Database\MySqlConnection $instance */ return $instance->getName(); } /** @@ -4773,7 +4784,7 @@ */ public static function getConfig($option = null) { //Method inherited from \Illuminate\Database\Connection - /** @var \Illuminate\Database\SQLiteConnection $instance */ + /** @var \Illuminate\Database\MySqlConnection $instance */ return $instance->getConfig($option); } /** @@ -4784,7 +4795,7 @@ */ public static function getDriverName() { //Method inherited from \Illuminate\Database\Connection - /** @var \Illuminate\Database\SQLiteConnection $instance */ + /** @var \Illuminate\Database\MySqlConnection $instance */ return $instance->getDriverName(); } /** @@ -4795,19 +4806,19 @@ */ public static function getQueryGrammar() { //Method inherited from \Illuminate\Database\Connection - /** @var \Illuminate\Database\SQLiteConnection $instance */ + /** @var \Illuminate\Database\MySqlConnection $instance */ return $instance->getQueryGrammar(); } /** * Set the query grammar used by the connection. * * @param \Illuminate\Database\Query\Grammars\Grammar $grammar - * @return \Illuminate\Database\SQLiteConnection + * @return \Illuminate\Database\MySqlConnection * @static */ public static function setQueryGrammar($grammar) { //Method inherited from \Illuminate\Database\Connection - /** @var \Illuminate\Database\SQLiteConnection $instance */ + /** @var \Illuminate\Database\MySqlConnection $instance */ return $instance->setQueryGrammar($grammar); } /** @@ -4818,19 +4829,19 @@ */ public static function getSchemaGrammar() { //Method inherited from \Illuminate\Database\Connection - /** @var \Illuminate\Database\SQLiteConnection $instance */ + /** @var \Illuminate\Database\MySqlConnection $instance */ return $instance->getSchemaGrammar(); } /** * Set the schema grammar used by the connection. * * @param \Illuminate\Database\Schema\Grammars\Grammar $grammar - * @return \Illuminate\Database\SQLiteConnection + * @return \Illuminate\Database\MySqlConnection * @static */ public static function setSchemaGrammar($grammar) { //Method inherited from \Illuminate\Database\Connection - /** @var \Illuminate\Database\SQLiteConnection $instance */ + /** @var \Illuminate\Database\MySqlConnection $instance */ return $instance->setSchemaGrammar($grammar); } /** @@ -4841,19 +4852,19 @@ */ public static function getPostProcessor() { //Method inherited from \Illuminate\Database\Connection - /** @var \Illuminate\Database\SQLiteConnection $instance */ + /** @var \Illuminate\Database\MySqlConnection $instance */ return $instance->getPostProcessor(); } /** * Set the query post processor used by the connection. * * @param \Illuminate\Database\Query\Processors\Processor $processor - * @return \Illuminate\Database\SQLiteConnection + * @return \Illuminate\Database\MySqlConnection * @static */ public static function setPostProcessor($processor) { //Method inherited from \Illuminate\Database\Connection - /** @var \Illuminate\Database\SQLiteConnection $instance */ + /** @var \Illuminate\Database\MySqlConnection $instance */ return $instance->setPostProcessor($processor); } /** @@ -4864,19 +4875,19 @@ */ public static function getEventDispatcher() { //Method inherited from \Illuminate\Database\Connection - /** @var \Illuminate\Database\SQLiteConnection $instance */ + /** @var \Illuminate\Database\MySqlConnection $instance */ return $instance->getEventDispatcher(); } /** * Set the event dispatcher instance on the connection. * * @param \Illuminate\Contracts\Events\Dispatcher $events - * @return \Illuminate\Database\SQLiteConnection + * @return \Illuminate\Database\MySqlConnection * @static */ public static function setEventDispatcher($events) { //Method inherited from \Illuminate\Database\Connection - /** @var \Illuminate\Database\SQLiteConnection $instance */ + /** @var \Illuminate\Database\MySqlConnection $instance */ return $instance->setEventDispatcher($events); } /** @@ -4887,19 +4898,19 @@ */ public static function unsetEventDispatcher() { //Method inherited from \Illuminate\Database\Connection - /** @var \Illuminate\Database\SQLiteConnection $instance */ + /** @var \Illuminate\Database\MySqlConnection $instance */ $instance->unsetEventDispatcher(); } /** * Set the transaction manager instance on the connection. * * @param \Illuminate\Database\DatabaseTransactionsManager $manager - * @return \Illuminate\Database\SQLiteConnection + * @return \Illuminate\Database\MySqlConnection * @static */ public static function setTransactionManager($manager) { //Method inherited from \Illuminate\Database\Connection - /** @var \Illuminate\Database\SQLiteConnection $instance */ + /** @var \Illuminate\Database\MySqlConnection $instance */ return $instance->setTransactionManager($manager); } /** @@ -4910,7 +4921,7 @@ */ public static function unsetTransactionManager() { //Method inherited from \Illuminate\Database\Connection - /** @var \Illuminate\Database\SQLiteConnection $instance */ + /** @var \Illuminate\Database\MySqlConnection $instance */ $instance->unsetTransactionManager(); } /** @@ -4921,7 +4932,7 @@ */ public static function pretending() { //Method inherited from \Illuminate\Database\Connection - /** @var \Illuminate\Database\SQLiteConnection $instance */ + /** @var \Illuminate\Database\MySqlConnection $instance */ return $instance->pretending(); } /** @@ -4932,7 +4943,7 @@ */ public static function getQueryLog() { //Method inherited from \Illuminate\Database\Connection - /** @var \Illuminate\Database\SQLiteConnection $instance */ + /** @var \Illuminate\Database\MySqlConnection $instance */ return $instance->getQueryLog(); } /** @@ -4943,7 +4954,7 @@ */ public static function flushQueryLog() { //Method inherited from \Illuminate\Database\Connection - /** @var \Illuminate\Database\SQLiteConnection $instance */ + /** @var \Illuminate\Database\MySqlConnection $instance */ $instance->flushQueryLog(); } /** @@ -4954,7 +4965,7 @@ */ public static function enableQueryLog() { //Method inherited from \Illuminate\Database\Connection - /** @var \Illuminate\Database\SQLiteConnection $instance */ + /** @var \Illuminate\Database\MySqlConnection $instance */ $instance->enableQueryLog(); } /** @@ -4965,7 +4976,7 @@ */ public static function disableQueryLog() { //Method inherited from \Illuminate\Database\Connection - /** @var \Illuminate\Database\SQLiteConnection $instance */ + /** @var \Illuminate\Database\MySqlConnection $instance */ $instance->disableQueryLog(); } /** @@ -4976,7 +4987,7 @@ */ public static function logging() { //Method inherited from \Illuminate\Database\Connection - /** @var \Illuminate\Database\SQLiteConnection $instance */ + /** @var \Illuminate\Database\MySqlConnection $instance */ return $instance->logging(); } /** @@ -4987,19 +4998,19 @@ */ public static function getDatabaseName() { //Method inherited from \Illuminate\Database\Connection - /** @var \Illuminate\Database\SQLiteConnection $instance */ + /** @var \Illuminate\Database\MySqlConnection $instance */ return $instance->getDatabaseName(); } /** * Set the name of the connected database. * * @param string $database - * @return \Illuminate\Database\SQLiteConnection + * @return \Illuminate\Database\MySqlConnection * @static */ public static function setDatabaseName($database) { //Method inherited from \Illuminate\Database\Connection - /** @var \Illuminate\Database\SQLiteConnection $instance */ + /** @var \Illuminate\Database\MySqlConnection $instance */ return $instance->setDatabaseName($database); } /** @@ -5010,19 +5021,19 @@ */ public static function getTablePrefix() { //Method inherited from \Illuminate\Database\Connection - /** @var \Illuminate\Database\SQLiteConnection $instance */ + /** @var \Illuminate\Database\MySqlConnection $instance */ return $instance->getTablePrefix(); } /** * Set the table prefix in use by the connection. * * @param string $prefix - * @return \Illuminate\Database\SQLiteConnection + * @return \Illuminate\Database\MySqlConnection * @static */ public static function setTablePrefix($prefix) { //Method inherited from \Illuminate\Database\Connection - /** @var \Illuminate\Database\SQLiteConnection $instance */ + /** @var \Illuminate\Database\MySqlConnection $instance */ return $instance->setTablePrefix($prefix); } /** @@ -5034,7 +5045,7 @@ */ public static function withTablePrefix($grammar) { //Method inherited from \Illuminate\Database\Connection - /** @var \Illuminate\Database\SQLiteConnection $instance */ + /** @var \Illuminate\Database\MySqlConnection $instance */ return $instance->withTablePrefix($grammar); } /** @@ -5047,7 +5058,7 @@ */ public static function resolverFor($driver, $callback) { //Method inherited from \Illuminate\Database\Connection - \Illuminate\Database\SQLiteConnection::resolverFor($driver, $callback); + \Illuminate\Database\MySqlConnection::resolverFor($driver, $callback); } /** * Get the connection resolver for the given driver. @@ -5058,7 +5069,7 @@ */ public static function getResolver($driver) { //Method inherited from \Illuminate\Database\Connection - return \Illuminate\Database\SQLiteConnection::getResolver($driver); + return \Illuminate\Database\MySqlConnection::getResolver($driver); } /** * Execute a Closure within a transaction. @@ -5071,7 +5082,7 @@ */ public static function transaction($callback, $attempts = 1) { //Method inherited from \Illuminate\Database\Connection - /** @var \Illuminate\Database\SQLiteConnection $instance */ + /** @var \Illuminate\Database\MySqlConnection $instance */ return $instance->transaction($callback, $attempts); } /** @@ -5083,7 +5094,7 @@ */ public static function beginTransaction() { //Method inherited from \Illuminate\Database\Connection - /** @var \Illuminate\Database\SQLiteConnection $instance */ + /** @var \Illuminate\Database\MySqlConnection $instance */ $instance->beginTransaction(); } /** @@ -5095,7 +5106,7 @@ */ public static function commit() { //Method inherited from \Illuminate\Database\Connection - /** @var \Illuminate\Database\SQLiteConnection $instance */ + /** @var \Illuminate\Database\MySqlConnection $instance */ $instance->commit(); } /** @@ -5108,7 +5119,7 @@ */ public static function rollBack($toLevel = null) { //Method inherited from \Illuminate\Database\Connection - /** @var \Illuminate\Database\SQLiteConnection $instance */ + /** @var \Illuminate\Database\MySqlConnection $instance */ $instance->rollBack($toLevel); } /** @@ -5119,7 +5130,7 @@ */ public static function transactionLevel() { //Method inherited from \Illuminate\Database\Connection - /** @var \Illuminate\Database\SQLiteConnection $instance */ + /** @var \Illuminate\Database\MySqlConnection $instance */ return $instance->transactionLevel(); } /** @@ -5131,7 +5142,7 @@ */ public static function afterCommit($callback) { //Method inherited from \Illuminate\Database\Connection - /** @var \Illuminate\Database\SQLiteConnection $instance */ + /** @var \Illuminate\Database\MySqlConnection $instance */ $instance->afterCommit($callback); } @@ -11839,7 +11850,7 @@ */ public static function createDatabase($name) { - /** @var \Illuminate\Database\Schema\SQLiteBuilder $instance */ + /** @var \Illuminate\Database\Schema\MySqlBuilder $instance */ return $instance->createDatabase($name); } /** @@ -11851,8 +11862,32 @@ */ public static function dropDatabaseIfExists($name) { - /** @var \Illuminate\Database\Schema\SQLiteBuilder $instance */ + /** @var \Illuminate\Database\Schema\MySqlBuilder $instance */ return $instance->dropDatabaseIfExists($name); + } + /** + * Determine if the given table exists. + * + * @param string $table + * @return bool + * @static + */ + public static function hasTable($table) + { + /** @var \Illuminate\Database\Schema\MySqlBuilder $instance */ + return $instance->hasTable($table); + } + /** + * Get the column listing for a given table. + * + * @param string $table + * @return array + * @static + */ + public static function getColumnListing($table) + { + /** @var \Illuminate\Database\Schema\MySqlBuilder $instance */ + return $instance->getColumnListing($table); } /** * Drop all tables from the database. @@ -11862,7 +11897,7 @@ */ public static function dropAllTables() { - /** @var \Illuminate\Database\Schema\SQLiteBuilder $instance */ + /** @var \Illuminate\Database\Schema\MySqlBuilder $instance */ $instance->dropAllTables(); } /** @@ -11873,19 +11908,30 @@ */ public static function dropAllViews() { - /** @var \Illuminate\Database\Schema\SQLiteBuilder $instance */ + /** @var \Illuminate\Database\Schema\MySqlBuilder $instance */ $instance->dropAllViews(); } /** - * Empty the database file. + * Get all of the table names for the database. * - * @return void + * @return array * @static */ - public static function refreshDatabaseFile() + public static function getAllTables() { - /** @var \Illuminate\Database\Schema\SQLiteBuilder $instance */ - $instance->refreshDatabaseFile(); + /** @var \Illuminate\Database\Schema\MySqlBuilder $instance */ + return $instance->getAllTables(); + } + /** + * Get all of the view names for the database. + * + * @return array + * @static + */ + public static function getAllViews() + { + /** @var \Illuminate\Database\Schema\MySqlBuilder $instance */ + return $instance->getAllViews(); } /** * Set the default string length for migrations. @@ -11896,7 +11942,7 @@ */ public static function defaultStringLength($length) { //Method inherited from \Illuminate\Database\Schema\Builder - \Illuminate\Database\Schema\SQLiteBuilder::defaultStringLength($length); + \Illuminate\Database\Schema\MySqlBuilder::defaultStringLength($length); } /** * Set the default morph key type for migrations. @@ -11907,7 +11953,7 @@ */ public static function defaultMorphKeyType($type) { //Method inherited from \Illuminate\Database\Schema\Builder - \Illuminate\Database\Schema\SQLiteBuilder::defaultMorphKeyType($type); + \Illuminate\Database\Schema\MySqlBuilder::defaultMorphKeyType($type); } /** * Set the default morph key type for migrations to UUIDs. @@ -11917,19 +11963,7 @@ */ public static function morphUsingUuids() { //Method inherited from \Illuminate\Database\Schema\Builder - \Illuminate\Database\Schema\SQLiteBuilder::morphUsingUuids(); - } - /** - * Determine if the given table exists. - * - * @param string $table - * @return bool - * @static - */ - public static function hasTable($table) - { //Method inherited from \Illuminate\Database\Schema\Builder - /** @var \Illuminate\Database\Schema\SQLiteBuilder $instance */ - return $instance->hasTable($table); + \Illuminate\Database\Schema\MySqlBuilder::morphUsingUuids(); } /** * Determine if the given table has a given column. @@ -11941,7 +11975,7 @@ */ public static function hasColumn($table, $column) { //Method inherited from \Illuminate\Database\Schema\Builder - /** @var \Illuminate\Database\Schema\SQLiteBuilder $instance */ + /** @var \Illuminate\Database\Schema\MySqlBuilder $instance */ return $instance->hasColumn($table, $column); } /** @@ -11954,7 +11988,7 @@ */ public static function hasColumns($table, $columns) { //Method inherited from \Illuminate\Database\Schema\Builder - /** @var \Illuminate\Database\Schema\SQLiteBuilder $instance */ + /** @var \Illuminate\Database\Schema\MySqlBuilder $instance */ return $instance->hasColumns($table, $columns); } /** @@ -11967,20 +12001,8 @@ */ public static function getColumnType($table, $column) { //Method inherited from \Illuminate\Database\Schema\Builder - /** @var \Illuminate\Database\Schema\SQLiteBuilder $instance */ + /** @var \Illuminate\Database\Schema\MySqlBuilder $instance */ return $instance->getColumnType($table, $column); - } - /** - * Get the column listing for a given table. - * - * @param string $table - * @return array - * @static - */ - public static function getColumnListing($table) - { //Method inherited from \Illuminate\Database\Schema\Builder - /** @var \Illuminate\Database\Schema\SQLiteBuilder $instance */ - return $instance->getColumnListing($table); } /** * Modify a table on the schema. @@ -11992,7 +12014,7 @@ */ public static function table($table, $callback) { //Method inherited from \Illuminate\Database\Schema\Builder - /** @var \Illuminate\Database\Schema\SQLiteBuilder $instance */ + /** @var \Illuminate\Database\Schema\MySqlBuilder $instance */ $instance->table($table, $callback); } /** @@ -12005,7 +12027,7 @@ */ public static function create($table, $callback) { //Method inherited from \Illuminate\Database\Schema\Builder - /** @var \Illuminate\Database\Schema\SQLiteBuilder $instance */ + /** @var \Illuminate\Database\Schema\MySqlBuilder $instance */ $instance->create($table, $callback); } /** @@ -12017,7 +12039,7 @@ */ public static function drop($table) { //Method inherited from \Illuminate\Database\Schema\Builder - /** @var \Illuminate\Database\Schema\SQLiteBuilder $instance */ + /** @var \Illuminate\Database\Schema\MySqlBuilder $instance */ $instance->drop($table); } /** @@ -12029,7 +12051,7 @@ */ public static function dropIfExists($table) { //Method inherited from \Illuminate\Database\Schema\Builder - /** @var \Illuminate\Database\Schema\SQLiteBuilder $instance */ + /** @var \Illuminate\Database\Schema\MySqlBuilder $instance */ $instance->dropIfExists($table); } /** @@ -12042,7 +12064,7 @@ */ public static function dropColumns($table, $columns) { //Method inherited from \Illuminate\Database\Schema\Builder - /** @var \Illuminate\Database\Schema\SQLiteBuilder $instance */ + /** @var \Illuminate\Database\Schema\MySqlBuilder $instance */ $instance->dropColumns($table, $columns); } /** @@ -12054,20 +12076,8 @@ */ public static function dropAllTypes() { //Method inherited from \Illuminate\Database\Schema\Builder - /** @var \Illuminate\Database\Schema\SQLiteBuilder $instance */ + /** @var \Illuminate\Database\Schema\MySqlBuilder $instance */ $instance->dropAllTypes(); - } - /** - * Get all of the table names for the database. - * - * @return void - * @throws \LogicException - * @static - */ - public static function getAllTables() - { //Method inherited from \Illuminate\Database\Schema\Builder - /** @var \Illuminate\Database\Schema\SQLiteBuilder $instance */ - $instance->getAllTables(); } /** * Rename a table on the schema. @@ -12079,7 +12089,7 @@ */ public static function rename($from, $to) { //Method inherited from \Illuminate\Database\Schema\Builder - /** @var \Illuminate\Database\Schema\SQLiteBuilder $instance */ + /** @var \Illuminate\Database\Schema\MySqlBuilder $instance */ $instance->rename($from, $to); } /** @@ -12090,7 +12100,7 @@ */ public static function enableForeignKeyConstraints() { //Method inherited from \Illuminate\Database\Schema\Builder - /** @var \Illuminate\Database\Schema\SQLiteBuilder $instance */ + /** @var \Illuminate\Database\Schema\MySqlBuilder $instance */ return $instance->enableForeignKeyConstraints(); } /** @@ -12101,7 +12111,7 @@ */ public static function disableForeignKeyConstraints() { //Method inherited from \Illuminate\Database\Schema\Builder - /** @var \Illuminate\Database\Schema\SQLiteBuilder $instance */ + /** @var \Illuminate\Database\Schema\MySqlBuilder $instance */ return $instance->disableForeignKeyConstraints(); } /** @@ -12117,7 +12127,7 @@ */ public static function registerCustomDoctrineType($class, $name, $type) { //Method inherited from \Illuminate\Database\Schema\Builder - /** @var \Illuminate\Database\Schema\SQLiteBuilder $instance */ + /** @var \Illuminate\Database\Schema\MySqlBuilder $instance */ $instance->registerCustomDoctrineType($class, $name, $type); } /** @@ -12128,19 +12138,19 @@ */ public static function getConnection() { //Method inherited from \Illuminate\Database\Schema\Builder - /** @var \Illuminate\Database\Schema\SQLiteBuilder $instance */ + /** @var \Illuminate\Database\Schema\MySqlBuilder $instance */ return $instance->getConnection(); } /** * Set the database connection instance. * * @param \Illuminate\Database\Connection $connection - * @return \Illuminate\Database\Schema\SQLiteBuilder + * @return \Illuminate\Database\Schema\MySqlBuilder * @static */ public static function setConnection($connection) { //Method inherited from \Illuminate\Database\Schema\Builder - /** @var \Illuminate\Database\Schema\SQLiteBuilder $instance */ + /** @var \Illuminate\Database\Schema\MySqlBuilder $instance */ return $instance->setConnection($connection); } /** @@ -12152,7 +12162,7 @@ */ public static function blueprintResolver($resolver) { //Method inherited from \Illuminate\Database\Schema\Builder - /** @var \Illuminate\Database\Schema\SQLiteBuilder $instance */ + /** @var \Illuminate\Database\Schema\MySqlBuilder $instance */ $instance->blueprintResolver($resolver); } @@ -16665,6 +16675,19 @@ namespace { return $instance->unless($value, $callback, $default); } + /** + * + * + * @see \Algolia\ScoutExtended\ScoutExtendedServiceProvider::registerMacros() + * @param array $array + * @param array|null $transformers + * @static + */ + public static function transform($array, $transformers = null) + { + return \Illuminate\Database\Eloquent\Builder::transform($array, $transformers); + } + /** * Set the columns to be selected. * diff --git a/app.json b/app.json new file mode 100644 index 0000000..a7320be --- /dev/null +++ b/app.json @@ -0,0 +1,47 @@ +{ + "name": "kcal – the personal food nutrition journal", + "description": "Self-hostable web app for food and recipe nutrition tracking.", + "keywords": [ + "cooking", + "fitness", + "food", + "heath", + "laravel", + "nutrition", + "php", + "recipes", + "self-host" + ], + "repository": "https://github.com/kcal-app/kcal", + "website": "http://demo.kcal.cooking", + "buildpacks": [ + { + "url": "heroku/php" + } + ], + "addons": [ + "heroku-postgresql" + ], + "env": { + "APP_KEY": { + "description": "Used for the auth system.", + "generator": "secret" + }, + "APP_TIMEZONE": { + "description": "Application time zone.", + "value": "Etc/UTC" + }, + "DB_CONNECTION": { + "description": "Database driver.", + "value": "pgsql" + }, + "SCOUT_DRIVER": { + "description": "Search driver ('algolia', 'elastic', or 'null').", + "value": "null" + } + }, + "scripts": { + "postdeploy": "php artisan migrate --force && php artisan user:add kcal kcal --name=Admin" + }, + "success_url": "/" +} diff --git a/app/Console/Commands/UserAdd.php b/app/Console/Commands/UserAdd.php new file mode 100644 index 0000000..1333c32 --- /dev/null +++ b/app/Console/Commands/UserAdd.php @@ -0,0 +1,90 @@ +arguments(); + if (!$arguments['username']) { + $arguments['username'] = $this->ask('Enter a username for the user'); + } + + // Check for an existing user. + if (User::whereUsername($arguments['username'])->exists()) { + $this->error("User `{$arguments['username']}` already exists."); + return 1; + } + + $random_password = FALSE; + if (!$arguments['password']) { + $arguments['password'] = $this->secret('Enter a password for the user (leave blank for a random password)'); + if (!empty($arguments['password'])) { + $password_confirm = $this->secret('Re-type the password to confirm'); + if ($arguments['password'] !== $password_confirm) { + $this->error('Passwords did not match.'); + return 1; + } + } + } + if (empty($arguments['password'])) { + $arguments['password'] = Str::random(); + $random_password = TRUE; + } + + $options = $this->options(); + if (!$options['name']) { + $options['name'] = $this->ask('Enter a name for the user (optional)'); + } + + if (empty($arguments['username']) || empty($arguments['password'])) { + $this->error('Username and password must be provided.'); + return 1; + } + + User::create([ + 'username' => $arguments['username'], + 'password' => Hash::make($arguments['password']), + 'name' => $options['name'] ?: $arguments['username'], + 'remember_token' => Str::random(10), + ])->save(); + + $this->info("User `{$arguments['username']}` added!"); + + if ($random_password) { + $this->info("Password: {$arguments['password']}"); + } + + return 0; + } +} diff --git a/app/Http/Controllers/Auth/AuthenticatedSessionController.php b/app/Http/Controllers/Auth/AuthenticatedSessionController.php index 97dc47d..50d07d7 100644 --- a/app/Http/Controllers/Auth/AuthenticatedSessionController.php +++ b/app/Http/Controllers/Auth/AuthenticatedSessionController.php @@ -5,6 +5,8 @@ namespace App\Http\Controllers\Auth; use App\Http\Controllers\Controller; use App\Http\Requests\Auth\LoginRequest; use App\Providers\RouteServiceProvider; +use Illuminate\Contracts\View\View; +use Illuminate\Http\RedirectResponse; use Illuminate\Http\Request; use Illuminate\Support\Facades\Auth; @@ -12,43 +14,30 @@ class AuthenticatedSessionController extends Controller { /** * Display the login view. - * - * @return \Illuminate\View\View */ - public function create() + public function create(): View { return view('auth.login'); } /** * Handle an incoming authentication request. - * - * @param \App\Http\Requests\Auth\LoginRequest $request - * @return \Illuminate\Http\RedirectResponse */ - public function store(LoginRequest $request) + public function store(LoginRequest $request): RedirectResponse { $request->authenticate(); - $request->session()->regenerate(); - return redirect(RouteServiceProvider::HOME); } /** * Destroy an authenticated session. - * - * @param \Illuminate\Http\Request $request - * @return \Illuminate\Http\RedirectResponse */ - public function destroy(Request $request) + 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/ConfirmablePasswordController.php b/app/Http/Controllers/Auth/ConfirmablePasswordController.php deleted file mode 100644 index 661d19b..0000000 --- a/app/Http/Controllers/Auth/ConfirmablePasswordController.php +++ /dev/null @@ -1,45 +0,0 @@ -validate([ - 'email' => $request->user()->email, - 'password' => $request->password, - ])) { - throw ValidationException::withMessages([ - 'password' => __('auth.password'), - ]); - } - - $request->session()->put('auth.password_confirmed_at', time()); - - return redirect()->intended(RouteServiceProvider::HOME); - } -} diff --git a/app/Http/Controllers/Auth/NewPasswordController.php b/app/Http/Controllers/Auth/NewPasswordController.php deleted file mode 100644 index cb881f3..0000000 --- a/app/Http/Controllers/Auth/NewPasswordController.php +++ /dev/null @@ -1,63 +0,0 @@ - $request]); - } - - /** - * Handle an incoming new password request. - * - * @param \Illuminate\Http\Request $request - * @return \Illuminate\Http\RedirectResponse - * - * @throws \Illuminate\Validation\ValidationException - */ - public function store(Request $request) - { - $request->validate([ - 'token' => 'required', - 'email' => 'required|email', - 'password' => 'required|string|confirmed|min:8', - ]); - - // Here we will attempt to reset the user's password. If it is successful we - // will update the password on an actual user model and persist it to the - // database. Otherwise we will parse the error and return the response. - $status = Password::reset( - $request->only('email', 'password', 'password_confirmation', 'token'), - function ($user) use ($request) { - $user->forceFill([ - 'password' => Hash::make($request->password), - 'remember_token' => Str::random(60), - ])->save(); - - event(new PasswordReset($user)); - } - ); - - // If the password was successfully reset, we will redirect the user back to - // the application's home authenticated view. If there is an error we can - // redirect them back to where they came from with their error message. - return $status == Password::PASSWORD_RESET - ? redirect()->route('login')->with('status', __($status)) - : back()->withInput($request->only('email')) - ->withErrors(['email' => __($status)]); - } -} diff --git a/app/Http/Controllers/Auth/PasswordResetLinkController.php b/app/Http/Controllers/Auth/PasswordResetLinkController.php deleted file mode 100644 index 5181588..0000000 --- a/app/Http/Controllers/Auth/PasswordResetLinkController.php +++ /dev/null @@ -1,47 +0,0 @@ -validate([ - 'email' => 'required|email', - ]); - - // We will send the password reset link to this user. Once we have attempted - // to send the link, we will examine the response then see the message we - // need to show to the user. Finally, we'll send out a proper response. - $status = Password::sendResetLink( - $request->only('email') - ); - - return $status == Password::RESET_LINK_SENT - ? back()->with('status', __($status)) - : back()->withInput($request->only('email')) - ->withErrors(['email' => __($status)]); - } -} diff --git a/app/Http/Controllers/IngredientPickerController.php b/app/Http/Controllers/IngredientPickerController.php index 7bdbba7..a02f5c8 100644 --- a/app/Http/Controllers/IngredientPickerController.php +++ b/app/Http/Controllers/IngredientPickerController.php @@ -4,6 +4,7 @@ namespace App\Http\Controllers; use App\Models\Food; use App\Models\Recipe; +use App\Search\Ingredient; use ElasticScoutDriverPlus\Builders\MultiMatchQueryBuilder; use ElasticScoutDriverPlus\Builders\TermsQueryBuilder; use Illuminate\Database\Eloquent\Collection; @@ -20,28 +21,62 @@ class IngredientPickerController extends Controller $results = new Collection(); $term = $request->query->get('term'); if (!empty($term)) { - $results = Food::boolSearch() - ->join(Recipe::class) + $results = match (config('scout.driver')) { + 'algolia' => $this->searchWithAlgolia($term), + 'elastic' => $this->searchWithElasticSearch($term), + default => $this->searchWithDatabaseLike($term), + }; - // Attempt to match exact phrase first. - ->should('match_phrase', ['name' => $term]) - - // Attempt multi-match search on all relevant fields with search-as-you-type on name. - ->should((new MultiMatchQueryBuilder()) - ->fields(['name', 'name._2gram', 'name._3gram', 'detail', 'brand', 'source']) - ->query($term) - ->type('bool_prefix') - ->analyzer('simple') - ->fuzziness('AUTO')) - - // Attempt to match on any tags in the term. - ->should((new TermsQueryBuilder()) - ->terms('tags', explode(' ', $term))) - - // Get resulting models. - ->execute() - ->models(); } return response()->json($results->values()); } + + /** + * Search using an Algolia service. + */ + private function searchWithAlgolia(string $term): Collection { + return Ingredient::search($term)->take(10)->get(); + } + + /** + * Search using an ElasticSearch service. + */ + private function searchWithElasticSearch(string $term): Collection { + return Food::boolSearch() + ->join(Recipe::class) + + // Attempt to match exact phrase first. + ->should('match_phrase', ['name' => $term]) + + // Attempt multi-match search on all relevant fields with search-as-you-type on name. + ->should((new MultiMatchQueryBuilder()) + ->fields(['name', 'name._2gram', 'name._3gram', 'detail', 'brand', 'source']) + ->query($term) + ->type('bool_prefix') + ->analyzer('simple') + ->fuzziness('AUTO')) + + // Attempt to match on any tags in the term. + ->should((new TermsQueryBuilder()) + ->terms('tags', explode(' ', $term))) + + // Get resulting models. + ->execute() + ->models(); + } + + /** + * Search using basic database WHERE ... LIKE queries. + */ + private function searchWithDatabaseLike(string $term): Collection { + $foods = Food::query()->where('foods.name', 'like', "%{$term}%") + ->orWhere('foods.detail', 'like', "%{$term}%") + ->orWhere('foods.brand', 'like', "%{$term}%") + ->get(); + $recipes = Recipe::query()->where('recipes.name', 'like', "%{$term}%") + ->orWhere('recipes.description', 'like', "%{$term}%") + ->orWhere('recipes.source', 'like', "%{$term}%") + ->get(); + return $foods->merge($recipes); + } } diff --git a/app/Http/Requests/Auth/LoginRequest.php b/app/Http/Requests/Auth/LoginRequest.php index 8e98c6c..84c9a2c 100644 --- a/app/Http/Requests/Auth/LoginRequest.php +++ b/app/Http/Requests/Auth/LoginRequest.php @@ -29,7 +29,7 @@ class LoginRequest extends FormRequest public function rules() { return [ - 'email' => 'required|string|email', + 'username' => 'required|string', 'password' => 'required|string', ]; } @@ -45,11 +45,11 @@ class LoginRequest extends FormRequest { $this->ensureIsNotRateLimited(); - if (! Auth::attempt($this->only('email', 'password'), $this->filled('remember'))) { + if (! Auth::attempt($this->only('username', 'password'), $this->filled('remember'))) { RateLimiter::hit($this->throttleKey()); throw ValidationException::withMessages([ - 'email' => 'auth.failed', + 'username' => 'auth.failed', ]); } @@ -74,7 +74,7 @@ class LoginRequest extends FormRequest $seconds = RateLimiter::availableIn($this->throttleKey()); throw ValidationException::withMessages([ - 'email' => trans('auth.throttle', [ + 'username' => trans('auth.throttle', [ 'seconds' => $seconds, 'minutes' => ceil($seconds / 60), ]), @@ -88,6 +88,6 @@ class LoginRequest extends FormRequest */ public function throttleKey() { - return Str::lower($this->input('email')).'|'.$this->ip(); + return Str::lower($this->input('username')).'|'.$this->ip(); } } diff --git a/app/JsonApi/Schemas/UserSchema.php b/app/JsonApi/Schemas/UserSchema.php index db658f4..74c2501 100644 --- a/app/JsonApi/Schemas/UserSchema.php +++ b/app/JsonApi/Schemas/UserSchema.php @@ -26,8 +26,8 @@ class UserSchema extends SchemaProvider public function getAttributes($resource): array { return [ + 'username' => $resource->username, 'name' => $resource->name, - 'email' => $resource->email, 'createdAt' => $resource->created_at, 'updatedAt' => $resource->updated_at, ]; diff --git a/app/Models/User.php b/app/Models/User.php index 4660f1b..7d96cde 100644 --- a/app/Models/User.php +++ b/app/Models/User.php @@ -15,29 +15,29 @@ use Illuminate\Support\Facades\Auth; * * @property int $id * @property string $name - * @property string $email + * @property string $username * @property string $password * @property string|null $remember_token - * @property \Illuminate\Support\Carbon|null $created_at - * @property \Illuminate\Support\Carbon|null $updated_at + * @property Carbon|null $created_at + * @property Carbon|null $updated_at + * @property-read \Illuminate\Database\Eloquent\Collection|\App\Models\Goal[] $goals + * @property-read int|null $goals_count + * @property-read \Illuminate\Database\Eloquent\Collection|\App\Models\JournalEntry[] $journalEntries + * @property-read int|null $journal_entries_count * @property-read \Illuminate\Notifications\DatabaseNotificationCollection|\Illuminate\Notifications\DatabaseNotification[] $notifications * @property-read int|null $notifications_count + * @method static \Database\Factories\UserFactory factory(...$parameters) * @method static \Illuminate\Database\Eloquent\Builder|User newModelQuery() * @method static \Illuminate\Database\Eloquent\Builder|User newQuery() * @method static \Illuminate\Database\Eloquent\Builder|User query() * @method static \Illuminate\Database\Eloquent\Builder|User whereCreatedAt($value) - * @method static \Illuminate\Database\Eloquent\Builder|User whereEmail($value) * @method static \Illuminate\Database\Eloquent\Builder|User whereId($value) * @method static \Illuminate\Database\Eloquent\Builder|User whereName($value) * @method static \Illuminate\Database\Eloquent\Builder|User wherePassword($value) * @method static \Illuminate\Database\Eloquent\Builder|User whereRememberToken($value) * @method static \Illuminate\Database\Eloquent\Builder|User whereUpdatedAt($value) + * @method static \Illuminate\Database\Eloquent\Builder|User whereUsername($value) * @mixin \Eloquent - * @property-read \Illuminate\Database\Eloquent\Collection|\App\Models\Goal[] $goals - * @property-read int|null $goals_count - * @method static \Database\Factories\UserFactory factory(...$parameters) - * @property-read \Illuminate\Database\Eloquent\Collection|\App\Models\JournalEntry[] $journalEntries - * @property-read int|null $journal_entries_count */ final class User extends Authenticatable { @@ -47,9 +47,9 @@ final class User extends Authenticatable * @inheritdoc */ protected $fillable = [ - 'name', - 'email', + 'username', 'password', + 'name', ]; /** diff --git a/app/Providers/AppServiceProvider.php b/app/Providers/AppServiceProvider.php index 0899dab..5ecdb0f 100644 --- a/app/Providers/AppServiceProvider.php +++ b/app/Providers/AppServiceProvider.php @@ -2,6 +2,7 @@ namespace App\Providers; +use App\Search\Ingredient; use CloudCreativity\LaravelJsonApi\LaravelJsonApi; use Illuminate\Support\ServiceProvider; @@ -25,5 +26,9 @@ class AppServiceProvider extends ServiceProvider public function boot() { LaravelJsonApi::defaultApi('v1'); + + if (config('scout.driver') === 'algolia') { + Ingredient::bootSearchable(); + } } } diff --git a/app/Providers/EventServiceProvider.php b/app/Providers/EventServiceProvider.php index a9f10a6..b5eaac8 100644 --- a/app/Providers/EventServiceProvider.php +++ b/app/Providers/EventServiceProvider.php @@ -2,10 +2,7 @@ namespace App\Providers; -use Illuminate\Auth\Events\Registered; -use Illuminate\Auth\Listeners\SendEmailVerificationNotification; use Illuminate\Foundation\Support\Providers\EventServiceProvider as ServiceProvider; -use Illuminate\Support\Facades\Event; class EventServiceProvider extends ServiceProvider { @@ -14,11 +11,7 @@ class EventServiceProvider extends ServiceProvider * * @var array */ - protected $listen = [ - Registered::class => [ - SendEmailVerificationNotification::class, - ], - ]; + protected $listen = []; /** * Register any events for your application. diff --git a/app/Search/Ingredient.php b/app/Search/Ingredient.php new file mode 100644 index 0000000..0feda28 --- /dev/null +++ b/app/Search/Ingredient.php @@ -0,0 +1,16 @@ +=5.6.0" + }, + "require-dev": { + "phpunit/phpunit": "^9.4 || ^6.5 || ^5.7" + }, + "suggest": { + "ext-gmp": "To convert GMP numbers into PHP code" + }, + "type": "library", + "autoload": { + "psr-4": { + "Riimu\\Kit\\PHPEncoder\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Riikka Kalliomäki", + "email": "riikka.kalliomaki@gmail.com", + "homepage": "http://riimu.net" + } + ], + "description": "Highly customizable alternative to var_export for PHP code generation", + "homepage": "http://kit.riimu.net", + "keywords": [ + "code", + "encoder", + "export", + "generator", + "variable" + ], + "support": { + "issues": "https://github.com/Riimu/Kit-PHPEncoder/issues", + "source": "https://github.com/Riimu/Kit-PHPEncoder/tree/v2.4.1" + }, + "time": "2020-11-29T16:53:17+00:00" + }, { "name": "spatie/eloquent-sortable", "version": "3.11.0", @@ -11211,7 +11421,11 @@ "prefer-stable": false, "prefer-lowest": false, "platform": { - "php": "^8.0" + "php": "^8.0", + "ext-fileinfo": "*", + "ext-gd": "*", + "ext-json": "*", + "ext-mbstring": "*" }, "platform-dev": [], "plugin-api-version": "2.0.0" diff --git a/config/app.php b/config/app.php index de9f718..a3643da 100644 --- a/config/app.php +++ b/config/app.php @@ -117,9 +117,12 @@ return [ | to a random, 32 character string, otherwise these encrypted strings | will not be safe. Please do this before deploying an application! | + | MD5 is used here to enforce the 32 character string requirement while + | allowing flexibility in the actual APP_KEY length. + | */ - 'key' => env('APP_KEY'), + 'key' => md5(env('APP_KEY')), 'cipher' => 'AES-256-CBC', diff --git a/database/factories/UserFactory.php b/database/factories/UserFactory.php index 57b9350..f2d1bb8 100644 --- a/database/factories/UserFactory.php +++ b/database/factories/UserFactory.php @@ -4,6 +4,7 @@ namespace Database\Factories; use App\Models\User; use Illuminate\Database\Eloquent\Factories\Factory; +use Illuminate\Support\Facades\Hash; use Illuminate\Support\Str; class UserFactory extends Factory @@ -19,9 +20,9 @@ class UserFactory extends Factory public function definition(): array { return [ + 'username' => $this->faker->unique()->userName, + 'password' => Hash::make('password'), 'name' => $this->faker->name, - 'email' => $this->faker->unique()->safeEmail, - 'password' => '$2y$10$92IXUNpkjO0rOQ5byMi.Ye4oKoEa3Ro9llC/.og/at2.uheWG/igi', // password 'remember_token' => Str::random(10), ]; } diff --git a/database/migrations/2014_10_12_000000_create_users_table.php b/database/migrations/2014_10_12_000000_create_users_table.php index d4708bc..a94d44e 100644 --- a/database/migrations/2014_10_12_000000_create_users_table.php +++ b/database/migrations/2014_10_12_000000_create_users_table.php @@ -15,9 +15,9 @@ class CreateUsersTable extends Migration { Schema::create('users', function (Blueprint $table) { $table->id(); - $table->string('name'); - $table->string('email')->unique(); + $table->string('username')->unique(); $table->string('password'); + $table->string('name'); $table->rememberToken(); $table->timestamps(); }); diff --git a/database/seeders/UserSeeder.php b/database/seeders/UserSeeder.php index a096fa6..7f209ea 100644 --- a/database/seeders/UserSeeder.php +++ b/database/seeders/UserSeeder.php @@ -15,9 +15,9 @@ class UserSeeder extends Seeder public function run(): void { User::factory()->create([ + 'username' => 'admin', + 'password' => Hash::make('admin'), 'name' => 'Admin', - 'email' => 'admin@kcal.test', - 'password' => Hash::make('admin@kcal.test'), 'remember_token' => Str::random(10), ]); } diff --git a/docker-compose.yml b/docker-compose.yml index 2263e42..3f442a1 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -63,13 +63,6 @@ services: - 'redis-data:/data' networks: - sail - mailhog: - image: 'mailhog/mailhog:latest' - ports: - - '${MAIL_PORT:-1025}:1025' - - '${MAILHOG_ADMIN_PORT:-8025}:8025' - networks: - - sail networks: sail: driver: bridge diff --git a/phpunit.xml b/phpunit.xml.dist similarity index 100% rename from phpunit.xml rename to phpunit.xml.dist diff --git a/public/css/app.css b/public/css/app.css index 347383e..bc30633 100644 --- a/public/css/app.css +++ b/public/css/app.css @@ -1,3 +1,3 @@ /*! tailwindcss v2.0.4 | MIT License | https://tailwindcss.com*/ -/*! modern-normalize v1.0.0 | MIT License | https://github.com/sindresorhus/modern-normalize */:root{-moz-tab-size:4;-o-tab-size:4;tab-size:4}html{line-height:1.15;-webkit-text-size-adjust:100%}body{margin:0;font-family:system-ui,-apple-system,Segoe UI,Roboto,Helvetica,Arial,sans-serif,Apple Color Emoji,Segoe UI Emoji}hr{height:0;color:inherit}abbr[title]{-webkit-text-decoration:underline dotted;text-decoration:underline dotted}b,strong{font-weight:bolder}code,kbd,pre,samp{font-family:ui-monospace,SFMono-Regular,Consolas,Liberation Mono,Menlo,monospace;font-size:1em}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit}button,input,optgroup,select,textarea{font-family:inherit;font-size:100%;line-height:1.15;margin:0}button,select{text-transform:none}[type=button],[type=reset],[type=submit],button{-webkit-appearance:button}legend{padding:0}progress{vertical-align:baseline}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}summary{display:list-item}blockquote,dd,dl,figure,h1,h2,h3,h4,h5,h6,hr,p,pre{margin:0}button{background-color:transparent;background-image:none}button:focus{outline:1px dotted;outline:5px auto -webkit-focus-ring-color}fieldset,ol,ul{margin:0;padding:0}ol,ul{list-style:none}html{font-family:ui-sans-serif,system-ui,-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Helvetica Neue,Arial,Noto Sans,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol,Noto Color Emoji;line-height:1.5}body{font-family:inherit;line-height:inherit}*,:after,:before{box-sizing:border-box;border:0 solid #e5e7eb}hr{border-top-width:1px}img{border-style:solid}textarea{resize:vertical}input::-moz-placeholder, textarea::-moz-placeholder{color:#9ca3af}input:-ms-input-placeholder, textarea:-ms-input-placeholder{color:#9ca3af}input::placeholder,textarea::placeholder{color:#9ca3af}button{cursor:pointer}table{border-collapse:collapse}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;text-decoration:inherit}button,input,optgroup,select,textarea{padding:0;line-height:inherit;color:inherit}code,kbd,pre,samp{font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace}audio,canvas,embed,iframe,img,object,svg,video{display:block;vertical-align:middle}img,video{max-width:100%;height:auto}[type=date],[type=email],[type=number],[type=password],[type=search],[type=text],[type=time],[type=url],select,textarea{-webkit-appearance:none;-moz-appearance:none;appearance:none;background-color:#fff;border-color:#6b7280;border-width:1px;border-radius:0;padding:.5rem .75rem;font-size:1rem;line-height:1.5rem}[type=date]:focus,[type=email]:focus,[type=number]:focus,[type=password]:focus,[type=search]:focus,[type=text]:focus,[type=time]:focus,[type=url]:focus,select:focus,textarea:focus{outline:2px solid transparent;outline-offset:2px;--tw-ring-inset:var(--tw-empty,/*!*/ /*!*/);--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-color:#2563eb;--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow,0 0 transparent);border-color:#2563eb}input::-moz-placeholder, textarea::-moz-placeholder{color:#6b7280;opacity:1}input:-ms-input-placeholder, textarea:-ms-input-placeholder{color:#6b7280;opacity:1}input::placeholder,textarea::placeholder{color:#6b7280;opacity:1}select{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='none' viewBox='0 0 20 20'%3E%3Cpath stroke='%236b7280' stroke-linecap='round' stroke-linejoin='round' stroke-width='1.5' d='M6 8l4 4 4-4'/%3E%3C/svg%3E");background-position:right .5rem center;background-repeat:no-repeat;background-size:1.5em 1.5em;padding-right:2.5rem;-webkit-print-color-adjust:exact;color-adjust:exact}[type=checkbox]{-webkit-appearance:none;-moz-appearance:none;appearance:none;padding:0;-webkit-print-color-adjust:exact;color-adjust:exact;display:inline-block;vertical-align:middle;background-origin:border-box;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;flex-shrink:0;height:1rem;width:1rem;color:#2563eb;background-color:#fff;border-color:#6b7280;border-width:1px;border-radius:0}[type=checkbox]:focus{outline:2px solid transparent;outline-offset:2px;--tw-ring-inset:var(--tw-empty,/*!*/ /*!*/);--tw-ring-offset-width:2px;--tw-ring-offset-color:#fff;--tw-ring-color:#2563eb;--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow,0 0 transparent)}[type=checkbox]:checked{background-size:100% 100%;background-position:50%;background-repeat:no-repeat;background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg viewBox='0 0 16 16' fill='%23fff' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M12.207 4.793a1 1 0 010 1.414l-5 5a1 1 0 01-1.414 0l-2-2a1 1 0 011.414-1.414L6.5 9.086l4.293-4.293a1 1 0 011.414 0z'/%3E%3C/svg%3E")}[type=checkbox]:checked,[type=checkbox]:checked:focus,[type=checkbox]:checked:hover{border-color:transparent;background-color:currentColor}[type=checkbox]:indeterminate{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='none' viewBox='0 0 16 16'%3E%3Cpath stroke='%23fff' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='M4 8h8'/%3E%3C/svg%3E");border-color:transparent;background-color:currentColor;background-size:100% 100%;background-position:50%;background-repeat:no-repeat}[type=checkbox]:indeterminate:focus,[type=checkbox]:indeterminate:hover{border-color:transparent;background-color:currentColor}[type=file]{background:unset;border-color:inherit;border-width:0;border-radius:0;padding:0;font-size:unset;line-height:inherit}[type=file]:focus{outline:1px auto -webkit-focus-ring-color}.prose{color:#374151;max-width:65ch}.prose [class~=lead]{color:#4b5563;font-size:1.25em;line-height:1.6;margin-top:1.2em;margin-bottom:1.2em}.prose a{color:#111827;text-decoration:underline;font-weight:500}.prose strong{color:#111827;font-weight:600}.prose ol[type=A]{--list-counter-style:upper-alpha}.prose ol[type=a]{--list-counter-style:lower-alpha}.prose ol[type=i]{--list-counter-style:lower-roman}.prose ol[type="1"]{--list-counter-style:decimal}.prose ol>li{position:relative;padding-left:1.75em}.prose ol>li:before{content:counter(list-item,var(--list-counter-style,decimal)) ".";position:absolute;font-weight:400;color:#6b7280;left:0}.prose ul>li{position:relative;padding-left:1.75em}.prose ul>li:before{content:"";position:absolute;background-color:#d1d5db;border-radius:50%;width:.375em;height:.375em;top:.6875em;left:.25em}.prose hr{border-color:#e5e7eb;border-top-width:1px;margin-top:3em;margin-bottom:3em}.prose blockquote{font-weight:500;font-style:italic;color:#111827;border-left-width:.25rem;border-left-color:#e5e7eb;quotes:"\201C""\201D""\2018""\2019";margin-top:1.6em;margin-bottom:1.6em;padding-left:1em}.prose blockquote p:first-of-type:before{content:open-quote}.prose blockquote p:last-of-type:after{content:close-quote}.prose h1{color:#111827;font-weight:800;font-size:2.25em;margin-top:0;margin-bottom:.8888889em;line-height:1.1111111}.prose h2{color:#111827;font-weight:700;font-size:1.5em;margin-top:2em;margin-bottom:1em;line-height:1.3333333}.prose h3{font-size:1.25em;margin-top:1.6em;margin-bottom:.6em;line-height:1.6}.prose h3,.prose h4{color:#111827;font-weight:600}.prose h4{margin-top:1.5em;margin-bottom:.5em;line-height:1.5}.prose figure figcaption{color:#6b7280;font-size:.875em;line-height:1.4285714;margin-top:.8571429em}.prose code{color:#111827;font-weight:600;font-size:.875em}.prose code:after,.prose code:before{content:"`"}.prose a code{color:#111827}.prose pre{color:#e5e7eb;background-color:#1f2937;overflow-x:auto;font-size:.875em;line-height:1.7142857;margin-top:1.7142857em;margin-bottom:1.7142857em;border-radius:.375rem;padding:.8571429em 1.1428571em}.prose pre code{background-color:transparent;border-width:0;border-radius:0;padding:0;font-weight:400;color:inherit;font-size:inherit;font-family:inherit;line-height:inherit}.prose pre code:after,.prose pre code:before{content:none}.prose table{width:100%;table-layout:auto;text-align:left;margin-top:2em;margin-bottom:2em;font-size:.875em;line-height:1.7142857}.prose thead{color:#111827;font-weight:600;border-bottom-width:1px;border-bottom-color:#d1d5db}.prose thead th{vertical-align:bottom;padding-right:.5714286em;padding-bottom:.5714286em;padding-left:.5714286em}.prose tbody tr{border-bottom-width:1px;border-bottom-color:#e5e7eb}.prose tbody tr:last-child{border-bottom-width:0}.prose tbody td{vertical-align:top;padding:.5714286em}.prose{font-size:1rem;line-height:1.75}.prose p{margin-top:1.25em;margin-bottom:1.25em}.prose figure,.prose img,.prose video{margin-top:2em;margin-bottom:2em}.prose figure>*{margin-top:0;margin-bottom:0}.prose h2 code{font-size:.875em}.prose h3 code{font-size:.9em}.prose ol,.prose ul{margin-top:1.25em;margin-bottom:1.25em}.prose li{margin-top:.5em;margin-bottom:.5em}.prose>ul>li p{margin-top:.75em;margin-bottom:.75em}.prose>ul>li>:first-child{margin-top:1.25em}.prose>ul>li>:last-child{margin-bottom:1.25em}.prose>ol>li>:first-child{margin-top:1.25em}.prose>ol>li>:last-child{margin-bottom:1.25em}.prose ol ol,.prose ol ul,.prose ul ol,.prose ul ul{margin-top:.75em;margin-bottom:.75em}.prose h2+*,.prose h3+*,.prose h4+*,.prose hr+*{margin-top:0}.prose thead th:first-child{padding-left:0}.prose thead th:last-child{padding-right:0}.prose tbody td:first-child{padding-left:0}.prose tbody td:last-child{padding-right:0}.prose>:first-child{margin-top:0}.prose>:last-child{margin-bottom:0}.prose-lg{font-size:1.125rem;line-height:1.7777778}.prose-lg p{margin-top:1.3333333em;margin-bottom:1.3333333em}.prose-lg [class~=lead]{font-size:1.2222222em;line-height:1.4545455;margin-top:1.0909091em;margin-bottom:1.0909091em}.prose-lg blockquote{margin-top:1.6666667em;margin-bottom:1.6666667em;padding-left:1em}.prose-lg h1{font-size:2.6666667em;margin-top:0;margin-bottom:.8333333em;line-height:1}.prose-lg h2{font-size:1.6666667em;margin-top:1.8666667em;margin-bottom:1.0666667em;line-height:1.3333333}.prose-lg h3{font-size:1.3333333em;margin-top:1.6666667em;margin-bottom:.6666667em;line-height:1.5}.prose-lg h4{margin-top:1.7777778em;margin-bottom:.4444444em;line-height:1.5555556}.prose-lg figure,.prose-lg img,.prose-lg video{margin-top:1.7777778em;margin-bottom:1.7777778em}.prose-lg figure>*{margin-top:0;margin-bottom:0}.prose-lg figure figcaption{font-size:.8888889em;line-height:1.5;margin-top:1em}.prose-lg code{font-size:.8888889em}.prose-lg h2 code{font-size:.8666667em}.prose-lg h3 code{font-size:.875em}.prose-lg pre{font-size:.8888889em;line-height:1.75;margin-top:2em;margin-bottom:2em;border-radius:.375rem;padding:1em 1.5em}.prose-lg ol,.prose-lg ul{margin-top:1.3333333em;margin-bottom:1.3333333em}.prose-lg li{margin-top:.6666667em;margin-bottom:.6666667em}.prose-lg ol>li{padding-left:1.6666667em}.prose-lg ol>li:before{left:0}.prose-lg ul>li{padding-left:1.6666667em}.prose-lg ul>li:before{width:.3333333em;height:.3333333em;top:.72222em;left:.2222222em}.prose-lg>ul>li p{margin-top:.8888889em;margin-bottom:.8888889em}.prose-lg>ul>li>:first-child{margin-top:1.3333333em}.prose-lg>ul>li>:last-child{margin-bottom:1.3333333em}.prose-lg>ol>li>:first-child{margin-top:1.3333333em}.prose-lg>ol>li>:last-child{margin-bottom:1.3333333em}.prose-lg ol ol,.prose-lg ol ul,.prose-lg ul ol,.prose-lg ul ul{margin-top:.8888889em;margin-bottom:.8888889em}.prose-lg hr{margin-top:3.1111111em;margin-bottom:3.1111111em}.prose-lg h2+*,.prose-lg h3+*,.prose-lg h4+*,.prose-lg hr+*{margin-top:0}.prose-lg table{font-size:.8888889em;line-height:1.5}.prose-lg thead th{padding-right:.75em;padding-bottom:.75em;padding-left:.75em}.prose-lg thead th:first-child{padding-left:0}.prose-lg thead th:last-child{padding-right:0}.prose-lg tbody td{padding:.75em}.prose-lg tbody td:first-child{padding-left:0}.prose-lg tbody td:last-child{padding-right:0}.prose-lg>:first-child{margin-top:0}.prose-lg>:last-child{margin-bottom:0}.space-y-1>:not([hidden])~:not([hidden]){--tw-space-y-reverse:0;margin-top:calc(0.25rem*(1 - var(--tw-space-y-reverse)));margin-bottom:calc(0.25rem*var(--tw-space-y-reverse))}.space-y-2>:not([hidden])~:not([hidden]){--tw-space-y-reverse:0;margin-top:calc(0.5rem*(1 - var(--tw-space-y-reverse)));margin-bottom:calc(0.5rem*var(--tw-space-y-reverse))}.space-x-2>:not([hidden])~:not([hidden]){--tw-space-x-reverse:0;margin-right:calc(0.5rem*var(--tw-space-x-reverse));margin-left:calc(0.5rem*(1 - var(--tw-space-x-reverse)))}.space-y-4>:not([hidden])~:not([hidden]){--tw-space-y-reverse:0;margin-top:calc(1rem*(1 - var(--tw-space-y-reverse)));margin-bottom:calc(1rem*var(--tw-space-y-reverse))}.space-x-4>:not([hidden])~:not([hidden]){--tw-space-x-reverse:0;margin-right:calc(1rem*var(--tw-space-x-reverse));margin-left:calc(1rem*(1 - var(--tw-space-x-reverse)))}.space-x-8>:not([hidden])~:not([hidden]){--tw-space-x-reverse:0;margin-right:calc(2rem*var(--tw-space-x-reverse));margin-left:calc(2rem*(1 - var(--tw-space-x-reverse)))}.bg-clip-border{background-clip:border-box}.bg-clip-text{-webkit-background-clip:text;background-clip:text}.bg-white{--tw-bg-opacity:1;background-color:rgba(255,255,255,var(--tw-bg-opacity))}.bg-gray-100{--tw-bg-opacity:1;background-color:rgba(243,244,246,var(--tw-bg-opacity))}.bg-gray-200{--tw-bg-opacity:1;background-color:rgba(229,231,235,var(--tw-bg-opacity))}.bg-gray-600{--tw-bg-opacity:1;background-color:rgba(75,85,99,var(--tw-bg-opacity))}.bg-gray-800{--tw-bg-opacity:1;background-color:rgba(31,41,55,var(--tw-bg-opacity))}.bg-red-200{--tw-bg-opacity:1;background-color:rgba(254,202,202,var(--tw-bg-opacity))}.bg-red-800{--tw-bg-opacity:1;background-color:rgba(153,27,27,var(--tw-bg-opacity))}.bg-green-200{--tw-bg-opacity:1;background-color:rgba(167,243,208,var(--tw-bg-opacity))}.bg-green-500{--tw-bg-opacity:1;background-color:rgba(16,185,129,var(--tw-bg-opacity))}.bg-green-800{--tw-bg-opacity:1;background-color:rgba(6,95,70,var(--tw-bg-opacity))}.bg-blue-800{--tw-bg-opacity:1;background-color:rgba(30,64,175,var(--tw-bg-opacity))}.hover\:bg-gray-100:hover{--tw-bg-opacity:1;background-color:rgba(243,244,246,var(--tw-bg-opacity))}.hover\:bg-gray-300:hover{--tw-bg-opacity:1;background-color:rgba(209,213,219,var(--tw-bg-opacity))}.hover\:bg-gray-700:hover{--tw-bg-opacity:1;background-color:rgba(55,65,81,var(--tw-bg-opacity))}.hover\:bg-red-700:hover{--tw-bg-opacity:1;background-color:rgba(185,28,28,var(--tw-bg-opacity))}.hover\:bg-yellow-300:hover{--tw-bg-opacity:1;background-color:rgba(252,211,77,var(--tw-bg-opacity))}.hover\:bg-green-700:hover{--tw-bg-opacity:1;background-color:rgba(4,120,87,var(--tw-bg-opacity))}.hover\:bg-blue-700:hover{--tw-bg-opacity:1;background-color:rgba(29,78,216,var(--tw-bg-opacity))}.hover\:bg-indigo-600:hover{--tw-bg-opacity:1;background-color:rgba(79,70,229,var(--tw-bg-opacity))}.focus\:bg-gray-100:focus{--tw-bg-opacity:1;background-color:rgba(243,244,246,var(--tw-bg-opacity))}.bg-gradient-to-r{background-image:linear-gradient(90deg,var(--tw-gradient-stops))}.from-red-400{--tw-gradient-from:#f87171;--tw-gradient-stops:var(--tw-gradient-from),var(--tw-gradient-to,rgba(248,113,113,0))}.to-blue-500{--tw-gradient-to:#3b82f6}.bg-center{background-position:50%}.bg-no-repeat{background-repeat:no-repeat}.bg-cover{background-size:cover}.border-transparent{border-color:transparent}.border-black{--tw-border-opacity:1;border-color:rgba(0,0,0,var(--tw-border-opacity))}.border-gray-100{--tw-border-opacity:1;border-color:rgba(243,244,246,var(--tw-border-opacity))}.border-gray-200{--tw-border-opacity:1;border-color:rgba(229,231,235,var(--tw-border-opacity))}.border-gray-300{--tw-border-opacity:1;border-color:rgba(209,213,219,var(--tw-border-opacity))}.border-gray-400{--tw-border-opacity:1;border-color:rgba(156,163,175,var(--tw-border-opacity))}.border-gray-500{--tw-border-opacity:1;border-color:rgba(107,114,128,var(--tw-border-opacity))}.border-blue-100{--tw-border-opacity:1;border-color:rgba(219,234,254,var(--tw-border-opacity))}.border-blue-200{--tw-border-opacity:1;border-color:rgba(191,219,254,var(--tw-border-opacity))}.border-indigo-400{--tw-border-opacity:1;border-color:rgba(129,140,248,var(--tw-border-opacity))}.hover\:border-gray-300:hover{--tw-border-opacity:1;border-color:rgba(209,213,219,var(--tw-border-opacity))}.hover\:border-red-300:hover{--tw-border-opacity:1;border-color:rgba(252,165,165,var(--tw-border-opacity))}.focus\:border-gray-300:focus{--tw-border-opacity:1;border-color:rgba(209,213,219,var(--tw-border-opacity))}.focus\:border-gray-900:focus{--tw-border-opacity:1;border-color:rgba(17,24,39,var(--tw-border-opacity))}.focus\:border-red-900:focus{--tw-border-opacity:1;border-color:rgba(127,29,29,var(--tw-border-opacity))}.focus\:border-green-900:focus{--tw-border-opacity:1;border-color:rgba(6,78,59,var(--tw-border-opacity))}.focus\:border-blue-900:focus{--tw-border-opacity:1;border-color:rgba(30,58,138,var(--tw-border-opacity))}.focus\:border-indigo-300:focus{--tw-border-opacity:1;border-color:rgba(165,180,252,var(--tw-border-opacity))}.focus\:border-indigo-700:focus{--tw-border-opacity:1;border-color:rgba(67,56,202,var(--tw-border-opacity))}.rounded{border-radius:.25rem}.rounded-md{border-radius:.375rem}.rounded-full{border-radius:9999px}.border-2{border-width:2px}.border{border-width:1px}.border-b-0{border-bottom-width:0}.border-b-2{border-bottom-width:2px}.border-t-4{border-top-width:4px}.border-b-4{border-bottom-width:4px}.border-t-8{border-top-width:8px}.border-b-8{border-bottom-width:8px}.border-t{border-top-width:1px}.border-r{border-right-width:1px}.border-b{border-bottom-width:1px}.cursor-default{cursor:default}.cursor-pointer{cursor:pointer}.cursor-move{cursor:move}.block{display:block}.inline-block{display:inline-block}.inline{display:inline}.flex{display:flex}.inline-flex{display:inline-flex}.table{display:table}.grid{display:grid}.inline-grid{display:inline-grid}.hidden{display:none}.flex-row{flex-direction:row}.flex-col{flex-direction:column}.flex-wrap{flex-wrap:wrap}.items-start{align-items:flex-start}.items-end{align-items:flex-end}.items-center{align-items:center}.items-baseline{align-items:baseline}.self-center{align-self:center}.justify-end{justify-content:flex-end}.justify-center{justify-content:center}.justify-between{justify-content:space-between}.flex-1{flex:1 1 0%}.flex-auto{flex:1 1 auto}.flex-none{flex:none}.float-right{float:right}.font-sans{font-family:ui-sans-serif,system-ui,-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Helvetica Neue,Arial,Noto Sans,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol,Noto Color Emoji}.font-normal{font-weight:400}.font-medium{font-weight:500}.font-semibold{font-weight:600}.font-bold{font-weight:700}.font-extrabold{font-weight:800}.font-black{font-weight:900}.h-5{height:1.25rem}.h-6{height:1.5rem}.h-8{height:2rem}.h-10{height:2.5rem}.h-16{height:4rem}.h-20{height:5rem}.h-24{height:6rem}.h-32{height:8rem}.h-full{height:100%}.text-xs{font-size:.75rem;line-height:1rem}.text-sm{font-size:.875rem;line-height:1.25rem}.text-base{font-size:1rem;line-height:1.5rem}.text-lg{font-size:1.125rem}.text-lg,.text-xl{line-height:1.75rem}.text-xl{font-size:1.25rem}.text-2xl{font-size:1.5rem;line-height:2rem}.text-3xl{font-size:1.875rem;line-height:2.25rem}.text-4xl{font-size:2.25rem;line-height:2.5rem}.text-5xl{font-size:3rem;line-height:1}.text-6xl{font-size:3.75rem;line-height:1}.leading-5{line-height:1.25rem}.leading-7{line-height:1.75rem}.leading-none{line-height:1}.leading-tight{line-height:1.25}.leading-snug{line-height:1.375}.leading-relaxed{line-height:1.625}.leading-loose{line-height:2}.list-inside{list-style-position:inside}.list-disc{list-style-type:disc}.m-1{margin:.25rem}.m-auto{margin:auto}.my-2{margin-top:.5rem;margin-bottom:.5rem}.my-4{margin-top:1rem;margin-bottom:1rem}.mx-auto{margin-left:auto;margin-right:auto}.mt-1{margin-top:.25rem}.mr-1{margin-right:.25rem}.mb-1{margin-bottom:.25rem}.ml-1{margin-left:.25rem}.mt-2{margin-top:.5rem}.mr-2{margin-right:.5rem}.mb-2{margin-bottom:.5rem}.ml-2{margin-left:.5rem}.mt-3{margin-top:.75rem}.ml-3{margin-left:.75rem}.mt-4{margin-top:1rem}.mb-4{margin-bottom:1rem}.ml-4{margin-left:1rem}.mt-6{margin-top:1.5rem}.mt-8{margin-top:2rem}.ml-12{margin-left:3rem}.-mt-px{margin-top:-1px}.max-w-xs{max-width:20rem}.max-w-md{max-width:28rem}.max-w-xl{max-width:36rem}.max-w-6xl{max-width:72rem}.max-w-7xl{max-width:80rem}.min-h-screen{min-height:100vh}.opacity-0{opacity:0}.opacity-5{opacity:.05}.opacity-25{opacity:.25}.opacity-100{opacity:1}.disabled\:opacity-25:disabled{opacity:.25}.focus\:outline-none:focus{outline:2px solid transparent;outline-offset:2px}.overflow-hidden{overflow:hidden}.p-1{padding:.25rem}.p-2{padding:.5rem}.p-6{padding:1.5rem}.py-1{padding-top:.25rem;padding-bottom:.25rem}.px-1{padding-left:.25rem;padding-right:.25rem}.py-2{padding-top:.5rem;padding-bottom:.5rem}.px-2{padding-left:.5rem;padding-right:.5rem}.py-4{padding-top:1rem;padding-bottom:1rem}.px-4{padding-left:1rem;padding-right:1rem}.px-5{padding-left:1.25rem;padding-right:1.25rem}.py-6{padding-top:1.5rem;padding-bottom:1.5rem}.px-6{padding-left:1.5rem;padding-right:1.5rem}.pt-1{padding-top:.25rem}.pt-2{padding-top:.5rem}.pl-2{padding-left:.5rem}.pb-3{padding-bottom:.75rem}.pb-4{padding-bottom:1rem}.pt-6{padding-top:1.5rem}.pt-8{padding-top:2rem}.pointer-events-none{pointer-events:none}.fixed{position:fixed}.absolute{position:absolute}.relative{position:relative}.top-0{top:0}.right-0{right:0}.left-0{left:0}*{--tw-shadow:0 0 transparent}.shadow-sm{--tw-shadow:0 1px 2px 0 rgba(0,0,0,0.05)}.shadow,.shadow-sm{box-shadow:var(--tw-ring-offset-shadow,0 0 transparent),var(--tw-ring-shadow,0 0 transparent),var(--tw-shadow)}.shadow{--tw-shadow:0 1px 3px 0 rgba(0,0,0,0.1),0 1px 2px 0 rgba(0,0,0,0.06)}.shadow-md{--tw-shadow:0 4px 6px -1px rgba(0,0,0,0.1),0 2px 4px -1px rgba(0,0,0,0.06)}.shadow-lg,.shadow-md{box-shadow:var(--tw-ring-offset-shadow,0 0 transparent),var(--tw-ring-shadow,0 0 transparent),var(--tw-shadow)}.shadow-lg{--tw-shadow:0 10px 15px -3px rgba(0,0,0,0.1),0 4px 6px -2px rgba(0,0,0,0.05)}*{--tw-ring-inset:var(--tw-empty,/*!*/ /*!*/);--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-color:rgba(59,130,246,0.5);--tw-ring-offset-shadow:0 0 transparent;--tw-ring-shadow:0 0 transparent}.ring-1{--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color)}.focus\:ring:focus,.ring-1{box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow,0 0 transparent)}.focus\:ring:focus{--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(3px + var(--tw-ring-offset-width)) var(--tw-ring-color)}.ring-black{--tw-ring-opacity:1;--tw-ring-color:rgba(0,0,0,var(--tw-ring-opacity))}.ring-gray-300{--tw-ring-opacity:1;--tw-ring-color:rgba(209,213,219,var(--tw-ring-opacity))}.ring-red-300{--tw-ring-opacity:1;--tw-ring-color:rgba(252,165,165,var(--tw-ring-opacity))}.ring-green-300{--tw-ring-opacity:1;--tw-ring-color:rgba(110,231,183,var(--tw-ring-opacity))}.ring-green-600{--tw-ring-opacity:1;--tw-ring-color:rgba(5,150,105,var(--tw-ring-opacity))}.ring-blue-300{--tw-ring-opacity:1;--tw-ring-color:rgba(147,197,253,var(--tw-ring-opacity))}.focus\:ring-indigo-200:focus{--tw-ring-opacity:1;--tw-ring-color:rgba(199,210,254,var(--tw-ring-opacity))}.ring-opacity-5{--tw-ring-opacity:0.05}.focus\:ring-opacity-50:focus{--tw-ring-opacity:0.5}.fill-current{fill:currentColor}.text-center{text-align:center}.text-right{text-align:right}.text-transparent{color:transparent}.text-white{--tw-text-opacity:1;color:rgba(255,255,255,var(--tw-text-opacity))}.text-gray-200{--tw-text-opacity:1;color:rgba(229,231,235,var(--tw-text-opacity))}.text-gray-300{--tw-text-opacity:1;color:rgba(209,213,219,var(--tw-text-opacity))}.text-gray-400{--tw-text-opacity:1;color:rgba(156,163,175,var(--tw-text-opacity))}.text-gray-500{--tw-text-opacity:1;color:rgba(107,114,128,var(--tw-text-opacity))}.text-gray-600{--tw-text-opacity:1;color:rgba(75,85,99,var(--tw-text-opacity))}.text-gray-700{--tw-text-opacity:1;color:rgba(55,65,81,var(--tw-text-opacity))}.text-gray-800{--tw-text-opacity:1;color:rgba(31,41,55,var(--tw-text-opacity))}.text-gray-900{--tw-text-opacity:1;color:rgba(17,24,39,var(--tw-text-opacity))}.text-red-100{--tw-text-opacity:1;color:rgba(254,226,226,var(--tw-text-opacity))}.text-red-500{--tw-text-opacity:1;color:rgba(239,68,68,var(--tw-text-opacity))}.text-red-600{--tw-text-opacity:1;color:rgba(220,38,38,var(--tw-text-opacity))}.text-red-800{--tw-text-opacity:1;color:rgba(153,27,27,var(--tw-text-opacity))}.text-yellow-500{--tw-text-opacity:1;color:rgba(245,158,11,var(--tw-text-opacity))}.text-green-500{--tw-text-opacity:1;color:rgba(16,185,129,var(--tw-text-opacity))}.text-green-600{--tw-text-opacity:1;color:rgba(5,150,105,var(--tw-text-opacity))}.text-indigo-600{--tw-text-opacity:1;color:rgba(79,70,229,var(--tw-text-opacity))}.hover\:text-white:hover{--tw-text-opacity:1;color:rgba(255,255,255,var(--tw-text-opacity))}.hover\:text-gray-600:hover{--tw-text-opacity:1;color:rgba(75,85,99,var(--tw-text-opacity))}.hover\:text-gray-700:hover{--tw-text-opacity:1;color:rgba(55,65,81,var(--tw-text-opacity))}.hover\:text-gray-900:hover{--tw-text-opacity:1;color:rgba(17,24,39,var(--tw-text-opacity))}.hover\:text-red-700:hover{--tw-text-opacity:1;color:rgba(185,28,28,var(--tw-text-opacity))}.hover\:text-green-700:hover{--tw-text-opacity:1;color:rgba(4,120,87,var(--tw-text-opacity))}.focus\:text-gray-700:focus{--tw-text-opacity:1;color:rgba(55,65,81,var(--tw-text-opacity))}.truncate{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.italic{font-style:italic}.uppercase{text-transform:uppercase}.lowercase{text-transform:lowercase}.underline{text-decoration:underline}.antialiased{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.subpixel-antialiased{-webkit-font-smoothing:auto;-moz-osx-font-smoothing:auto}.tracking-wider{letter-spacing:.05em}.tracking-widest{letter-spacing:.1em}.align-top{vertical-align:top}.align-middle{vertical-align:middle}.w-5{width:1.25rem}.w-6{width:1.5rem}.w-8{width:2rem}.w-10{width:2.5rem}.w-20{width:5rem}.w-24{width:6rem}.w-48{width:12rem}.w-72{width:18rem}.w-auto{width:auto}.w-full{width:100%}.z-40{z-index:40}.z-50{z-index:50}.gap-4{gap:1rem}.gap-x-3{-moz-column-gap:.75rem;column-gap:.75rem}.gap-y-1{row-gap:.25rem}.grid-cols-1{grid-template-columns:repeat(1,minmax(0,1fr))}.grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.transform{--tw-translate-x:0;--tw-translate-y:0;--tw-rotate:0;--tw-skew-x:0;--tw-skew-y:0;--tw-scale-x:1;--tw-scale-y:1;transform:translateX(var(--tw-translate-x)) translateY(var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.origin-top{transform-origin:top}.origin-top-right{transform-origin:top right}.origin-top-left{transform-origin:top left}.scale-95{--tw-scale-x:.95;--tw-scale-y:.95}.scale-100{--tw-scale-x:1;--tw-scale-y:1}.transition{transition-property:background-color,border-color,color,fill,stroke,opacity,box-shadow,transform;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.ease-in{transition-timing-function:cubic-bezier(.4,0,1,1)}.ease-out{transition-timing-function:cubic-bezier(0,0,.2,1)}.ease-in-out{transition-timing-function:cubic-bezier(.4,0,.2,1)}.duration-75{transition-duration:75ms}.duration-150{transition-duration:.15s}.duration-200{transition-duration:.2s}@-webkit-keyframes spin{to{transform:rotate(1turn)}}@keyframes spin{to{transform:rotate(1turn)}}@-webkit-keyframes ping{75%,to{transform:scale(2);opacity:0}}@keyframes ping{75%,to{transform:scale(2);opacity:0}}@-webkit-keyframes pulse{50%{opacity:.5}}@keyframes pulse{50%{opacity:.5}}@-webkit-keyframes bounce{0%,to{transform:translateY(-25%);-webkit-animation-timing-function:cubic-bezier(.8,0,1,1);animation-timing-function:cubic-bezier(.8,0,1,1)}50%{transform:none;-webkit-animation-timing-function:cubic-bezier(0,0,.2,1);animation-timing-function:cubic-bezier(0,0,.2,1)}}@keyframes bounce{0%,to{transform:translateY(-25%);-webkit-animation-timing-function:cubic-bezier(.8,0,1,1);animation-timing-function:cubic-bezier(.8,0,1,1)}50%{transform:none;-webkit-animation-timing-function:cubic-bezier(0,0,.2,1);animation-timing-function:cubic-bezier(0,0,.2,1)}}.animate-spin{-webkit-animation:spin 1s linear infinite;animation:spin 1s linear infinite}[x-cloak]{display:none!important}@media (min-width:640px){.sm\:space-y-0>:not([hidden])~:not([hidden]){--tw-space-y-reverse:0;margin-top:calc(0px*(1 - var(--tw-space-y-reverse)));margin-bottom:calc(0px*var(--tw-space-y-reverse))}.sm\:space-x-4>:not([hidden])~:not([hidden]){--tw-space-x-reverse:0;margin-right:calc(1rem*var(--tw-space-x-reverse));margin-left:calc(1rem*(1 - var(--tw-space-x-reverse)))}.sm\:rounded-lg{border-radius:.5rem}.sm\:block{display:block}.sm\:flex-row{flex-direction:row}.sm\:items-center{align-items:center}.sm\:justify-start{justify-content:flex-start}.sm\:justify-center{justify-content:center}.sm\:h-48{height:12rem}.sm\:ml-6{margin-left:1.5rem}.sm\:max-w-md{max-width:28rem}.sm\:px-6{padding-left:1.5rem;padding-right:1.5rem}.sm\:pt-0{padding-top:0}.sm\:w-auto{width:auto}.sm\:w-3\/5{width:60%}.sm\:w-5\/12{width:41.666667%}}@media (min-width:768px){.md\:space-y-0>:not([hidden])~:not([hidden]){--tw-space-y-reverse:0;margin-top:calc(0px*(1 - var(--tw-space-y-reverse)));margin-bottom:calc(0px*var(--tw-space-y-reverse))}.md\:space-x-4>:not([hidden])~:not([hidden]){--tw-space-x-reverse:0;margin-right:calc(1rem*var(--tw-space-x-reverse));margin-left:calc(1rem*(1 - var(--tw-space-x-reverse)))}.md\:hidden{display:none}.md\:flex-row{flex-direction:row}.md\:h-64{height:16rem}.md\:text-9xl{font-size:8rem;line-height:1}.md\:w-72{width:18rem}.md\:w-auto{width:auto}.md\:w-1\/2{width:50%}.md\:w-2\/3{width:66.666667%}.md\:w-1\/4{width:25%}.md\:w-3\/4{width:75%}.md\:w-5\/6{width:83.333333%}.md\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}}@media (min-width:1024px){.lg\:h-96{height:24rem}.lg\:px-8{padding-left:2rem;padding-right:2rem}.lg\:w-1\/2{width:50%}.lg\:w-1\/3{width:33.333333%}.lg\:w-3\/4{width:75%}.lg\:w-4\/12{width:33.333333%}.lg\:grid-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}} +/*! modern-normalize v1.0.0 | MIT License | https://github.com/sindresorhus/modern-normalize */:root{-moz-tab-size:4;-o-tab-size:4;tab-size:4}html{line-height:1.15;-webkit-text-size-adjust:100%}body{margin:0;font-family:system-ui,-apple-system,Segoe UI,Roboto,Helvetica,Arial,sans-serif,Apple Color Emoji,Segoe UI Emoji}hr{height:0;color:inherit}abbr[title]{-webkit-text-decoration:underline dotted;text-decoration:underline dotted}b,strong{font-weight:bolder}code,kbd,pre,samp{font-family:ui-monospace,SFMono-Regular,Consolas,Liberation Mono,Menlo,monospace;font-size:1em}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit}button,input,optgroup,select,textarea{font-family:inherit;font-size:100%;line-height:1.15;margin:0}button,select{text-transform:none}[type=button],[type=reset],[type=submit],button{-webkit-appearance:button}legend{padding:0}progress{vertical-align:baseline}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}summary{display:list-item}blockquote,dd,dl,figure,h1,h2,h3,h4,h5,h6,hr,p,pre{margin:0}button{background-color:transparent;background-image:none}button:focus{outline:1px dotted;outline:5px auto -webkit-focus-ring-color}fieldset,ol,ul{margin:0;padding:0}ol,ul{list-style:none}html{font-family:ui-sans-serif,system-ui,-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Helvetica Neue,Arial,Noto Sans,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol,Noto Color Emoji;line-height:1.5}body{font-family:inherit;line-height:inherit}*,:after,:before{box-sizing:border-box;border:0 solid #e5e7eb}hr{border-top-width:1px}img{border-style:solid}textarea{resize:vertical}input::-moz-placeholder, textarea::-moz-placeholder{color:#9ca3af}input:-ms-input-placeholder, textarea:-ms-input-placeholder{color:#9ca3af}input::placeholder,textarea::placeholder{color:#9ca3af}[role=button],button{cursor:pointer}table{border-collapse:collapse}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;text-decoration:inherit}button,input,optgroup,select,textarea{padding:0;line-height:inherit;color:inherit}code,kbd,pre,samp{font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace}audio,canvas,embed,iframe,img,object,svg,video{display:block;vertical-align:middle}img,video{max-width:100%;height:auto}[type=date],[type=email],[type=number],[type=password],[type=search],[type=text],[type=time],[type=url],select,textarea{-webkit-appearance:none;-moz-appearance:none;appearance:none;background-color:#fff;border-color:#6b7280;border-width:1px;border-radius:0;padding:.5rem .75rem;font-size:1rem;line-height:1.5rem}[type=date]:focus,[type=email]:focus,[type=number]:focus,[type=password]:focus,[type=search]:focus,[type=text]:focus,[type=time]:focus,[type=url]:focus,select:focus,textarea:focus{outline:2px solid transparent;outline-offset:2px;--tw-ring-inset:var(--tw-empty,/*!*/ /*!*/);--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-color:#2563eb;--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow,0 0 transparent);border-color:#2563eb}input::-moz-placeholder, textarea::-moz-placeholder{color:#6b7280;opacity:1}input:-ms-input-placeholder, textarea:-ms-input-placeholder{color:#6b7280;opacity:1}input::placeholder,textarea::placeholder{color:#6b7280;opacity:1}select{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='none' viewBox='0 0 20 20'%3E%3Cpath stroke='%236b7280' stroke-linecap='round' stroke-linejoin='round' stroke-width='1.5' d='M6 8l4 4 4-4'/%3E%3C/svg%3E");background-position:right .5rem center;background-repeat:no-repeat;background-size:1.5em 1.5em;padding-right:2.5rem;-webkit-print-color-adjust:exact;color-adjust:exact}[type=checkbox]{-webkit-appearance:none;-moz-appearance:none;appearance:none;padding:0;-webkit-print-color-adjust:exact;color-adjust:exact;display:inline-block;vertical-align:middle;background-origin:border-box;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;flex-shrink:0;height:1rem;width:1rem;color:#2563eb;background-color:#fff;border-color:#6b7280;border-width:1px;border-radius:0}[type=checkbox]:focus{outline:2px solid transparent;outline-offset:2px;--tw-ring-inset:var(--tw-empty,/*!*/ /*!*/);--tw-ring-offset-width:2px;--tw-ring-offset-color:#fff;--tw-ring-color:#2563eb;--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow,0 0 transparent)}[type=checkbox]:checked{background-size:100% 100%;background-position:50%;background-repeat:no-repeat;background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg viewBox='0 0 16 16' fill='%23fff' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M12.207 4.793a1 1 0 010 1.414l-5 5a1 1 0 01-1.414 0l-2-2a1 1 0 011.414-1.414L6.5 9.086l4.293-4.293a1 1 0 011.414 0z'/%3E%3C/svg%3E")}[type=checkbox]:checked,[type=checkbox]:checked:focus,[type=checkbox]:checked:hover{border-color:transparent;background-color:currentColor}[type=checkbox]:indeterminate{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='none' viewBox='0 0 16 16'%3E%3Cpath stroke='%23fff' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='M4 8h8'/%3E%3C/svg%3E");border-color:transparent;background-color:currentColor;background-size:100% 100%;background-position:50%;background-repeat:no-repeat}[type=checkbox]:indeterminate:focus,[type=checkbox]:indeterminate:hover{border-color:transparent;background-color:currentColor}[type=file]{background:unset;border-color:inherit;border-width:0;border-radius:0;padding:0;font-size:unset;line-height:inherit}[type=file]:focus{outline:1px auto -webkit-focus-ring-color}.prose{color:#374151;max-width:65ch}.prose [class~=lead]{color:#4b5563;font-size:1.25em;line-height:1.6;margin-top:1.2em;margin-bottom:1.2em}.prose a{color:#111827;text-decoration:underline;font-weight:500}.prose strong{color:#111827;font-weight:600}.prose ol[type=A]{--list-counter-style:upper-alpha}.prose ol[type=a]{--list-counter-style:lower-alpha}.prose ol[type=i]{--list-counter-style:lower-roman}.prose ol[type="1"]{--list-counter-style:decimal}.prose ol>li{position:relative;padding-left:1.75em}.prose ol>li:before{content:counter(list-item,var(--list-counter-style,decimal)) ".";position:absolute;font-weight:400;color:#6b7280;left:0}.prose ul>li{position:relative;padding-left:1.75em}.prose ul>li:before{content:"";position:absolute;background-color:#d1d5db;border-radius:50%;width:.375em;height:.375em;top:.6875em;left:.25em}.prose hr{border-color:#e5e7eb;border-top-width:1px;margin-top:3em;margin-bottom:3em}.prose blockquote{font-weight:500;font-style:italic;color:#111827;border-left-width:.25rem;border-left-color:#e5e7eb;quotes:"\201C""\201D""\2018""\2019";margin-top:1.6em;margin-bottom:1.6em;padding-left:1em}.prose blockquote p:first-of-type:before{content:open-quote}.prose blockquote p:last-of-type:after{content:close-quote}.prose h1{color:#111827;font-weight:800;font-size:2.25em;margin-top:0;margin-bottom:.8888889em;line-height:1.1111111}.prose h2{color:#111827;font-weight:700;font-size:1.5em;margin-top:2em;margin-bottom:1em;line-height:1.3333333}.prose h3{font-size:1.25em;margin-top:1.6em;margin-bottom:.6em;line-height:1.6}.prose h3,.prose h4{color:#111827;font-weight:600}.prose h4{margin-top:1.5em;margin-bottom:.5em;line-height:1.5}.prose figure figcaption{color:#6b7280;font-size:.875em;line-height:1.4285714;margin-top:.8571429em}.prose code{color:#111827;font-weight:600;font-size:.875em}.prose code:after,.prose code:before{content:"`"}.prose a code{color:#111827}.prose pre{color:#e5e7eb;background-color:#1f2937;overflow-x:auto;font-size:.875em;line-height:1.7142857;margin-top:1.7142857em;margin-bottom:1.7142857em;border-radius:.375rem;padding:.8571429em 1.1428571em}.prose pre code{background-color:transparent;border-width:0;border-radius:0;padding:0;font-weight:400;color:inherit;font-size:inherit;font-family:inherit;line-height:inherit}.prose pre code:after,.prose pre code:before{content:none}.prose table{width:100%;table-layout:auto;text-align:left;margin-top:2em;margin-bottom:2em;font-size:.875em;line-height:1.7142857}.prose thead{color:#111827;font-weight:600;border-bottom-width:1px;border-bottom-color:#d1d5db}.prose thead th{vertical-align:bottom;padding-right:.5714286em;padding-bottom:.5714286em;padding-left:.5714286em}.prose tbody tr{border-bottom-width:1px;border-bottom-color:#e5e7eb}.prose tbody tr:last-child{border-bottom-width:0}.prose tbody td{vertical-align:top;padding:.5714286em}.prose{font-size:1rem;line-height:1.75}.prose p{margin-top:1.25em;margin-bottom:1.25em}.prose figure,.prose img,.prose video{margin-top:2em;margin-bottom:2em}.prose figure>*{margin-top:0;margin-bottom:0}.prose h2 code{font-size:.875em}.prose h3 code{font-size:.9em}.prose ol,.prose ul{margin-top:1.25em;margin-bottom:1.25em}.prose li{margin-top:.5em;margin-bottom:.5em}.prose>ul>li p{margin-top:.75em;margin-bottom:.75em}.prose>ul>li>:first-child{margin-top:1.25em}.prose>ul>li>:last-child{margin-bottom:1.25em}.prose>ol>li>:first-child{margin-top:1.25em}.prose>ol>li>:last-child{margin-bottom:1.25em}.prose ol ol,.prose ol ul,.prose ul ol,.prose ul ul{margin-top:.75em;margin-bottom:.75em}.prose h2+*,.prose h3+*,.prose h4+*,.prose hr+*{margin-top:0}.prose thead th:first-child{padding-left:0}.prose thead th:last-child{padding-right:0}.prose tbody td:first-child{padding-left:0}.prose tbody td:last-child{padding-right:0}.prose>:first-child{margin-top:0}.prose>:last-child{margin-bottom:0}.prose-lg{font-size:1.125rem;line-height:1.7777778}.prose-lg p{margin-top:1.3333333em;margin-bottom:1.3333333em}.prose-lg [class~=lead]{font-size:1.2222222em;line-height:1.4545455;margin-top:1.0909091em;margin-bottom:1.0909091em}.prose-lg blockquote{margin-top:1.6666667em;margin-bottom:1.6666667em;padding-left:1em}.prose-lg h1{font-size:2.6666667em;margin-top:0;margin-bottom:.8333333em;line-height:1}.prose-lg h2{font-size:1.6666667em;margin-top:1.8666667em;margin-bottom:1.0666667em;line-height:1.3333333}.prose-lg h3{font-size:1.3333333em;margin-top:1.6666667em;margin-bottom:.6666667em;line-height:1.5}.prose-lg h4{margin-top:1.7777778em;margin-bottom:.4444444em;line-height:1.5555556}.prose-lg figure,.prose-lg img,.prose-lg video{margin-top:1.7777778em;margin-bottom:1.7777778em}.prose-lg figure>*{margin-top:0;margin-bottom:0}.prose-lg figure figcaption{font-size:.8888889em;line-height:1.5;margin-top:1em}.prose-lg code{font-size:.8888889em}.prose-lg h2 code{font-size:.8666667em}.prose-lg h3 code{font-size:.875em}.prose-lg pre{font-size:.8888889em;line-height:1.75;margin-top:2em;margin-bottom:2em;border-radius:.375rem;padding:1em 1.5em}.prose-lg ol,.prose-lg ul{margin-top:1.3333333em;margin-bottom:1.3333333em}.prose-lg li{margin-top:.6666667em;margin-bottom:.6666667em}.prose-lg ol>li{padding-left:1.6666667em}.prose-lg ol>li:before{left:0}.prose-lg ul>li{padding-left:1.6666667em}.prose-lg ul>li:before{width:.3333333em;height:.3333333em;top:.72222em;left:.2222222em}.prose-lg>ul>li p{margin-top:.8888889em;margin-bottom:.8888889em}.prose-lg>ul>li>:first-child{margin-top:1.3333333em}.prose-lg>ul>li>:last-child{margin-bottom:1.3333333em}.prose-lg>ol>li>:first-child{margin-top:1.3333333em}.prose-lg>ol>li>:last-child{margin-bottom:1.3333333em}.prose-lg ol ol,.prose-lg ol ul,.prose-lg ul ol,.prose-lg ul ul{margin-top:.8888889em;margin-bottom:.8888889em}.prose-lg hr{margin-top:3.1111111em;margin-bottom:3.1111111em}.prose-lg h2+*,.prose-lg h3+*,.prose-lg h4+*,.prose-lg hr+*{margin-top:0}.prose-lg table{font-size:.8888889em;line-height:1.5}.prose-lg thead th{padding-right:.75em;padding-bottom:.75em;padding-left:.75em}.prose-lg thead th:first-child{padding-left:0}.prose-lg thead th:last-child{padding-right:0}.prose-lg tbody td{padding:.75em}.prose-lg tbody td:first-child{padding-left:0}.prose-lg tbody td:last-child{padding-right:0}.prose-lg>:first-child{margin-top:0}.prose-lg>:last-child{margin-bottom:0}.space-y-1>:not([hidden])~:not([hidden]){--tw-space-y-reverse:0;margin-top:calc(0.25rem*(1 - var(--tw-space-y-reverse)));margin-bottom:calc(0.25rem*var(--tw-space-y-reverse))}.space-y-2>:not([hidden])~:not([hidden]){--tw-space-y-reverse:0;margin-top:calc(0.5rem*(1 - var(--tw-space-y-reverse)));margin-bottom:calc(0.5rem*var(--tw-space-y-reverse))}.space-x-2>:not([hidden])~:not([hidden]){--tw-space-x-reverse:0;margin-right:calc(0.5rem*var(--tw-space-x-reverse));margin-left:calc(0.5rem*(1 - var(--tw-space-x-reverse)))}.space-y-4>:not([hidden])~:not([hidden]){--tw-space-y-reverse:0;margin-top:calc(1rem*(1 - var(--tw-space-y-reverse)));margin-bottom:calc(1rem*var(--tw-space-y-reverse))}.space-x-4>:not([hidden])~:not([hidden]){--tw-space-x-reverse:0;margin-right:calc(1rem*var(--tw-space-x-reverse));margin-left:calc(1rem*(1 - var(--tw-space-x-reverse)))}.space-x-8>:not([hidden])~:not([hidden]){--tw-space-x-reverse:0;margin-right:calc(2rem*var(--tw-space-x-reverse));margin-left:calc(2rem*(1 - var(--tw-space-x-reverse)))}.bg-clip-border{background-clip:border-box}.bg-clip-text{-webkit-background-clip:text;background-clip:text}.bg-white{--tw-bg-opacity:1;background-color:rgba(255,255,255,var(--tw-bg-opacity))}.bg-gray-100{--tw-bg-opacity:1;background-color:rgba(243,244,246,var(--tw-bg-opacity))}.bg-gray-200{--tw-bg-opacity:1;background-color:rgba(229,231,235,var(--tw-bg-opacity))}.bg-gray-600{--tw-bg-opacity:1;background-color:rgba(75,85,99,var(--tw-bg-opacity))}.bg-gray-800{--tw-bg-opacity:1;background-color:rgba(31,41,55,var(--tw-bg-opacity))}.bg-red-200{--tw-bg-opacity:1;background-color:rgba(254,202,202,var(--tw-bg-opacity))}.bg-red-800{--tw-bg-opacity:1;background-color:rgba(153,27,27,var(--tw-bg-opacity))}.bg-green-200{--tw-bg-opacity:1;background-color:rgba(167,243,208,var(--tw-bg-opacity))}.bg-green-500{--tw-bg-opacity:1;background-color:rgba(16,185,129,var(--tw-bg-opacity))}.bg-green-800{--tw-bg-opacity:1;background-color:rgba(6,95,70,var(--tw-bg-opacity))}.bg-blue-800{--tw-bg-opacity:1;background-color:rgba(30,64,175,var(--tw-bg-opacity))}.hover\:bg-gray-100:hover{--tw-bg-opacity:1;background-color:rgba(243,244,246,var(--tw-bg-opacity))}.hover\:bg-gray-300:hover{--tw-bg-opacity:1;background-color:rgba(209,213,219,var(--tw-bg-opacity))}.hover\:bg-gray-700:hover{--tw-bg-opacity:1;background-color:rgba(55,65,81,var(--tw-bg-opacity))}.hover\:bg-red-700:hover{--tw-bg-opacity:1;background-color:rgba(185,28,28,var(--tw-bg-opacity))}.hover\:bg-yellow-300:hover{--tw-bg-opacity:1;background-color:rgba(252,211,77,var(--tw-bg-opacity))}.hover\:bg-green-700:hover{--tw-bg-opacity:1;background-color:rgba(4,120,87,var(--tw-bg-opacity))}.hover\:bg-blue-700:hover{--tw-bg-opacity:1;background-color:rgba(29,78,216,var(--tw-bg-opacity))}.hover\:bg-indigo-600:hover{--tw-bg-opacity:1;background-color:rgba(79,70,229,var(--tw-bg-opacity))}.focus\:bg-gray-100:focus{--tw-bg-opacity:1;background-color:rgba(243,244,246,var(--tw-bg-opacity))}.bg-gradient-to-r{background-image:linear-gradient(90deg,var(--tw-gradient-stops))}.from-red-400{--tw-gradient-from:#f87171;--tw-gradient-stops:var(--tw-gradient-from),var(--tw-gradient-to,rgba(248,113,113,0))}.to-blue-500{--tw-gradient-to:#3b82f6}.bg-center{background-position:50%}.bg-no-repeat{background-repeat:no-repeat}.bg-cover{background-size:cover}.border-transparent{border-color:transparent}.border-black{--tw-border-opacity:1;border-color:rgba(0,0,0,var(--tw-border-opacity))}.border-gray-100{--tw-border-opacity:1;border-color:rgba(243,244,246,var(--tw-border-opacity))}.border-gray-200{--tw-border-opacity:1;border-color:rgba(229,231,235,var(--tw-border-opacity))}.border-gray-300{--tw-border-opacity:1;border-color:rgba(209,213,219,var(--tw-border-opacity))}.border-gray-400{--tw-border-opacity:1;border-color:rgba(156,163,175,var(--tw-border-opacity))}.border-gray-500{--tw-border-opacity:1;border-color:rgba(107,114,128,var(--tw-border-opacity))}.border-blue-100{--tw-border-opacity:1;border-color:rgba(219,234,254,var(--tw-border-opacity))}.border-blue-200{--tw-border-opacity:1;border-color:rgba(191,219,254,var(--tw-border-opacity))}.border-indigo-400{--tw-border-opacity:1;border-color:rgba(129,140,248,var(--tw-border-opacity))}.hover\:border-gray-300:hover{--tw-border-opacity:1;border-color:rgba(209,213,219,var(--tw-border-opacity))}.hover\:border-red-300:hover{--tw-border-opacity:1;border-color:rgba(252,165,165,var(--tw-border-opacity))}.focus\:border-gray-300:focus{--tw-border-opacity:1;border-color:rgba(209,213,219,var(--tw-border-opacity))}.focus\:border-gray-900:focus{--tw-border-opacity:1;border-color:rgba(17,24,39,var(--tw-border-opacity))}.focus\:border-red-900:focus{--tw-border-opacity:1;border-color:rgba(127,29,29,var(--tw-border-opacity))}.focus\:border-green-900:focus{--tw-border-opacity:1;border-color:rgba(6,78,59,var(--tw-border-opacity))}.focus\:border-blue-900:focus{--tw-border-opacity:1;border-color:rgba(30,58,138,var(--tw-border-opacity))}.focus\:border-indigo-300:focus{--tw-border-opacity:1;border-color:rgba(165,180,252,var(--tw-border-opacity))}.focus\:border-indigo-700:focus{--tw-border-opacity:1;border-color:rgba(67,56,202,var(--tw-border-opacity))}.rounded{border-radius:.25rem}.rounded-md{border-radius:.375rem}.rounded-full{border-radius:9999px}.border-2{border-width:2px}.border{border-width:1px}.border-b-0{border-bottom-width:0}.border-b-2{border-bottom-width:2px}.border-t-4{border-top-width:4px}.border-b-4{border-bottom-width:4px}.border-t-8{border-top-width:8px}.border-b-8{border-bottom-width:8px}.border-t{border-top-width:1px}.border-r{border-right-width:1px}.border-b{border-bottom-width:1px}.cursor-default{cursor:default}.cursor-pointer{cursor:pointer}.cursor-move{cursor:move}.block{display:block}.inline-block{display:inline-block}.inline{display:inline}.flex{display:flex}.inline-flex{display:inline-flex}.table{display:table}.grid{display:grid}.inline-grid{display:inline-grid}.hidden{display:none}.flex-row{flex-direction:row}.flex-col{flex-direction:column}.flex-wrap{flex-wrap:wrap}.items-start{align-items:flex-start}.items-end{align-items:flex-end}.items-center{align-items:center}.items-baseline{align-items:baseline}.self-center{align-self:center}.justify-end{justify-content:flex-end}.justify-center{justify-content:center}.justify-between{justify-content:space-between}.flex-1{flex:1 1 0%}.flex-auto{flex:1 1 auto}.flex-none{flex:none}.float-right{float:right}.font-sans{font-family:ui-sans-serif,system-ui,-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Helvetica Neue,Arial,Noto Sans,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol,Noto Color Emoji}.font-normal{font-weight:400}.font-medium{font-weight:500}.font-semibold{font-weight:600}.font-bold{font-weight:700}.font-extrabold{font-weight:800}.font-black{font-weight:900}.h-5{height:1.25rem}.h-6{height:1.5rem}.h-8{height:2rem}.h-10{height:2.5rem}.h-16{height:4rem}.h-20{height:5rem}.h-24{height:6rem}.h-32{height:8rem}.h-full{height:100%}.text-xs{font-size:.75rem;line-height:1rem}.text-sm{font-size:.875rem;line-height:1.25rem}.text-base{font-size:1rem;line-height:1.5rem}.text-lg{font-size:1.125rem}.text-lg,.text-xl{line-height:1.75rem}.text-xl{font-size:1.25rem}.text-2xl{font-size:1.5rem;line-height:2rem}.text-3xl{font-size:1.875rem;line-height:2.25rem}.text-4xl{font-size:2.25rem;line-height:2.5rem}.text-5xl{font-size:3rem;line-height:1}.text-6xl{font-size:3.75rem;line-height:1}.leading-5{line-height:1.25rem}.leading-7{line-height:1.75rem}.leading-none{line-height:1}.leading-tight{line-height:1.25}.leading-snug{line-height:1.375}.leading-relaxed{line-height:1.625}.leading-loose{line-height:2}.list-inside{list-style-position:inside}.list-disc{list-style-type:disc}.m-1{margin:.25rem}.m-auto{margin:auto}.my-2{margin-top:.5rem;margin-bottom:.5rem}.my-4{margin-top:1rem;margin-bottom:1rem}.mx-auto{margin-left:auto;margin-right:auto}.mt-1{margin-top:.25rem}.mr-1{margin-right:.25rem}.mb-1{margin-bottom:.25rem}.ml-1{margin-left:.25rem}.mt-2{margin-top:.5rem}.mr-2{margin-right:.5rem}.mb-2{margin-bottom:.5rem}.ml-2{margin-left:.5rem}.mt-3{margin-top:.75rem}.ml-3{margin-left:.75rem}.mt-4{margin-top:1rem}.mb-4{margin-bottom:1rem}.ml-4{margin-left:1rem}.mt-6{margin-top:1.5rem}.mt-8{margin-top:2rem}.ml-12{margin-left:3rem}.-mt-px{margin-top:-1px}.max-w-xs{max-width:20rem}.max-w-md{max-width:28rem}.max-w-xl{max-width:36rem}.max-w-6xl{max-width:72rem}.max-w-7xl{max-width:80rem}.min-h-screen{min-height:100vh}.opacity-0{opacity:0}.opacity-5{opacity:.05}.opacity-25{opacity:.25}.opacity-100{opacity:1}.disabled\:opacity-25:disabled{opacity:.25}.focus\:outline-none:focus{outline:2px solid transparent;outline-offset:2px}.overflow-hidden{overflow:hidden}.p-1{padding:.25rem}.p-2{padding:.5rem}.p-6{padding:1.5rem}.py-1{padding-top:.25rem;padding-bottom:.25rem}.px-1{padding-left:.25rem;padding-right:.25rem}.py-2{padding-top:.5rem;padding-bottom:.5rem}.px-2{padding-left:.5rem;padding-right:.5rem}.py-4{padding-top:1rem;padding-bottom:1rem}.px-4{padding-left:1rem;padding-right:1rem}.px-5{padding-left:1.25rem;padding-right:1.25rem}.py-6{padding-top:1.5rem;padding-bottom:1.5rem}.px-6{padding-left:1.5rem;padding-right:1.5rem}.pt-1{padding-top:.25rem}.pt-2{padding-top:.5rem}.pl-2{padding-left:.5rem}.pb-3{padding-bottom:.75rem}.pb-4{padding-bottom:1rem}.pt-6{padding-top:1.5rem}.pt-8{padding-top:2rem}.pt-12{padding-top:3rem}.pointer-events-none{pointer-events:none}.fixed{position:fixed}.absolute{position:absolute}.relative{position:relative}.top-0{top:0}.right-0{right:0}.left-0{left:0}*{--tw-shadow:0 0 transparent}.shadow-sm{--tw-shadow:0 1px 2px 0 rgba(0,0,0,0.05)}.shadow,.shadow-sm{box-shadow:var(--tw-ring-offset-shadow,0 0 transparent),var(--tw-ring-shadow,0 0 transparent),var(--tw-shadow)}.shadow{--tw-shadow:0 1px 3px 0 rgba(0,0,0,0.1),0 1px 2px 0 rgba(0,0,0,0.06)}.shadow-md{--tw-shadow:0 4px 6px -1px rgba(0,0,0,0.1),0 2px 4px -1px rgba(0,0,0,0.06)}.shadow-lg,.shadow-md{box-shadow:var(--tw-ring-offset-shadow,0 0 transparent),var(--tw-ring-shadow,0 0 transparent),var(--tw-shadow)}.shadow-lg{--tw-shadow:0 10px 15px -3px rgba(0,0,0,0.1),0 4px 6px -2px rgba(0,0,0,0.05)}*{--tw-ring-inset:var(--tw-empty,/*!*/ /*!*/);--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-color:rgba(59,130,246,0.5);--tw-ring-offset-shadow:0 0 transparent;--tw-ring-shadow:0 0 transparent}.ring-1{--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color)}.focus\:ring:focus,.ring-1{box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow,0 0 transparent)}.focus\:ring:focus{--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(3px + var(--tw-ring-offset-width)) var(--tw-ring-color)}.ring-black{--tw-ring-opacity:1;--tw-ring-color:rgba(0,0,0,var(--tw-ring-opacity))}.ring-gray-300{--tw-ring-opacity:1;--tw-ring-color:rgba(209,213,219,var(--tw-ring-opacity))}.ring-red-300{--tw-ring-opacity:1;--tw-ring-color:rgba(252,165,165,var(--tw-ring-opacity))}.ring-green-300{--tw-ring-opacity:1;--tw-ring-color:rgba(110,231,183,var(--tw-ring-opacity))}.ring-green-600{--tw-ring-opacity:1;--tw-ring-color:rgba(5,150,105,var(--tw-ring-opacity))}.ring-blue-300{--tw-ring-opacity:1;--tw-ring-color:rgba(147,197,253,var(--tw-ring-opacity))}.focus\:ring-indigo-200:focus{--tw-ring-opacity:1;--tw-ring-color:rgba(199,210,254,var(--tw-ring-opacity))}.ring-opacity-5{--tw-ring-opacity:0.05}.focus\:ring-opacity-50:focus{--tw-ring-opacity:0.5}.fill-current{fill:currentColor}.text-center{text-align:center}.text-right{text-align:right}.text-transparent{color:transparent}.text-white{--tw-text-opacity:1;color:rgba(255,255,255,var(--tw-text-opacity))}.text-gray-200{--tw-text-opacity:1;color:rgba(229,231,235,var(--tw-text-opacity))}.text-gray-300{--tw-text-opacity:1;color:rgba(209,213,219,var(--tw-text-opacity))}.text-gray-400{--tw-text-opacity:1;color:rgba(156,163,175,var(--tw-text-opacity))}.text-gray-500{--tw-text-opacity:1;color:rgba(107,114,128,var(--tw-text-opacity))}.text-gray-600{--tw-text-opacity:1;color:rgba(75,85,99,var(--tw-text-opacity))}.text-gray-700{--tw-text-opacity:1;color:rgba(55,65,81,var(--tw-text-opacity))}.text-gray-800{--tw-text-opacity:1;color:rgba(31,41,55,var(--tw-text-opacity))}.text-gray-900{--tw-text-opacity:1;color:rgba(17,24,39,var(--tw-text-opacity))}.text-red-100{--tw-text-opacity:1;color:rgba(254,226,226,var(--tw-text-opacity))}.text-red-500{--tw-text-opacity:1;color:rgba(239,68,68,var(--tw-text-opacity))}.text-red-600{--tw-text-opacity:1;color:rgba(220,38,38,var(--tw-text-opacity))}.text-red-800{--tw-text-opacity:1;color:rgba(153,27,27,var(--tw-text-opacity))}.text-yellow-500{--tw-text-opacity:1;color:rgba(245,158,11,var(--tw-text-opacity))}.text-green-500{--tw-text-opacity:1;color:rgba(16,185,129,var(--tw-text-opacity))}.text-green-600{--tw-text-opacity:1;color:rgba(5,150,105,var(--tw-text-opacity))}.text-indigo-600{--tw-text-opacity:1;color:rgba(79,70,229,var(--tw-text-opacity))}.hover\:text-white:hover{--tw-text-opacity:1;color:rgba(255,255,255,var(--tw-text-opacity))}.hover\:text-gray-600:hover{--tw-text-opacity:1;color:rgba(75,85,99,var(--tw-text-opacity))}.hover\:text-gray-700:hover{--tw-text-opacity:1;color:rgba(55,65,81,var(--tw-text-opacity))}.hover\:text-gray-900:hover{--tw-text-opacity:1;color:rgba(17,24,39,var(--tw-text-opacity))}.hover\:text-red-700:hover{--tw-text-opacity:1;color:rgba(185,28,28,var(--tw-text-opacity))}.hover\:text-green-700:hover{--tw-text-opacity:1;color:rgba(4,120,87,var(--tw-text-opacity))}.focus\:text-gray-700:focus{--tw-text-opacity:1;color:rgba(55,65,81,var(--tw-text-opacity))}.truncate{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.italic{font-style:italic}.uppercase{text-transform:uppercase}.lowercase{text-transform:lowercase}.underline{text-decoration:underline}.antialiased{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.subpixel-antialiased{-webkit-font-smoothing:auto;-moz-osx-font-smoothing:auto}.tracking-wider{letter-spacing:.05em}.tracking-widest{letter-spacing:.1em}.align-top{vertical-align:top}.align-middle{vertical-align:middle}.break-all{word-break:break-all}.w-5{width:1.25rem}.w-6{width:1.5rem}.w-8{width:2rem}.w-10{width:2.5rem}.w-20{width:5rem}.w-24{width:6rem}.w-48{width:12rem}.w-72{width:18rem}.w-auto{width:auto}.w-full{width:100%}.z-40{z-index:40}.z-50{z-index:50}.gap-4{gap:1rem}.gap-x-3{-moz-column-gap:.75rem;column-gap:.75rem}.gap-y-1{row-gap:.25rem}.grid-cols-1{grid-template-columns:repeat(1,minmax(0,1fr))}.grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.transform{--tw-translate-x:0;--tw-translate-y:0;--tw-rotate:0;--tw-skew-x:0;--tw-skew-y:0;--tw-scale-x:1;--tw-scale-y:1;transform:translateX(var(--tw-translate-x)) translateY(var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.origin-top{transform-origin:top}.origin-top-right{transform-origin:top right}.origin-top-left{transform-origin:top left}.scale-95{--tw-scale-x:.95;--tw-scale-y:.95}.scale-100{--tw-scale-x:1;--tw-scale-y:1}.transition{transition-property:background-color,border-color,color,fill,stroke,opacity,box-shadow,transform;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.ease-in{transition-timing-function:cubic-bezier(.4,0,1,1)}.ease-out{transition-timing-function:cubic-bezier(0,0,.2,1)}.ease-in-out{transition-timing-function:cubic-bezier(.4,0,.2,1)}.duration-75{transition-duration:75ms}.duration-150{transition-duration:.15s}.duration-200{transition-duration:.2s}@-webkit-keyframes spin{to{transform:rotate(1turn)}}@keyframes spin{to{transform:rotate(1turn)}}@-webkit-keyframes ping{75%,to{transform:scale(2);opacity:0}}@keyframes ping{75%,to{transform:scale(2);opacity:0}}@-webkit-keyframes pulse{50%{opacity:.5}}@keyframes pulse{50%{opacity:.5}}@-webkit-keyframes bounce{0%,to{transform:translateY(-25%);-webkit-animation-timing-function:cubic-bezier(.8,0,1,1);animation-timing-function:cubic-bezier(.8,0,1,1)}50%{transform:none;-webkit-animation-timing-function:cubic-bezier(0,0,.2,1);animation-timing-function:cubic-bezier(0,0,.2,1)}}@keyframes bounce{0%,to{transform:translateY(-25%);-webkit-animation-timing-function:cubic-bezier(.8,0,1,1);animation-timing-function:cubic-bezier(.8,0,1,1)}50%{transform:none;-webkit-animation-timing-function:cubic-bezier(0,0,.2,1);animation-timing-function:cubic-bezier(0,0,.2,1)}}.animate-spin{-webkit-animation:spin 1s linear infinite;animation:spin 1s linear infinite}[x-cloak]{display:none!important}@media (min-width:640px){.sm\:space-y-0>:not([hidden])~:not([hidden]){--tw-space-y-reverse:0;margin-top:calc(0px*(1 - var(--tw-space-y-reverse)));margin-bottom:calc(0px*var(--tw-space-y-reverse))}.sm\:space-x-4>:not([hidden])~:not([hidden]){--tw-space-x-reverse:0;margin-right:calc(1rem*var(--tw-space-x-reverse));margin-left:calc(1rem*(1 - var(--tw-space-x-reverse)))}.sm\:rounded-lg{border-radius:.5rem}.sm\:block{display:block}.sm\:flex-row{flex-direction:row}.sm\:items-center{align-items:center}.sm\:justify-start{justify-content:flex-start}.sm\:justify-center{justify-content:center}.sm\:h-48{height:12rem}.sm\:ml-6{margin-left:1.5rem}.sm\:max-w-md{max-width:28rem}.sm\:px-6{padding-left:1.5rem;padding-right:1.5rem}.sm\:pt-0{padding-top:0}.sm\:w-auto{width:auto}.sm\:w-3\/5{width:60%}.sm\:w-5\/12{width:41.666667%}}@media (min-width:768px){.md\:space-y-0>:not([hidden])~:not([hidden]){--tw-space-y-reverse:0;margin-top:calc(0px*(1 - var(--tw-space-y-reverse)));margin-bottom:calc(0px*var(--tw-space-y-reverse))}.md\:space-x-4>:not([hidden])~:not([hidden]){--tw-space-x-reverse:0;margin-right:calc(1rem*var(--tw-space-x-reverse));margin-left:calc(1rem*(1 - var(--tw-space-x-reverse)))}.md\:hidden{display:none}.md\:flex-row{flex-direction:row}.md\:h-64{height:16rem}.md\:text-9xl{font-size:8rem;line-height:1}.md\:w-72{width:18rem}.md\:w-auto{width:auto}.md\:w-1\/2{width:50%}.md\:w-2\/3{width:66.666667%}.md\:w-1\/4{width:25%}.md\:w-3\/4{width:75%}.md\:w-5\/6{width:83.333333%}.md\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}}@media (min-width:1024px){.lg\:h-96{height:24rem}.lg\:px-8{padding-left:2rem;padding-right:2rem}.lg\:w-1\/2{width:50%}.lg\:w-1\/3{width:33.333333%}.lg\:w-3\/4{width:75%}.lg\:w-4\/12{width:33.333333%}.lg\:grid-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}} diff --git a/public/images/search-by-algolia-light-background.svg b/public/images/search-by-algolia-light-background.svg new file mode 100644 index 0000000..f1c841e --- /dev/null +++ b/public/images/search-by-algolia-light-background.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/resources/views/auth/confirm-password.blade.php b/resources/views/auth/confirm-password.blade.php deleted file mode 100644 index 4a7248d..0000000 --- a/resources/views/auth/confirm-password.blade.php +++ /dev/null @@ -1,35 +0,0 @@ - - Confirm Password - - - - - - - -
- 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 deleted file mode 100644 index 832a20f..0000000 --- a/resources/views/auth/forgot-password.blade.php +++ /dev/null @@ -1,35 +0,0 @@ - - Forgot Password - - - - - - - -
- 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 index d6dcd8a..8a72cc5 100644 --- a/resources/views/auth/login.blade.php +++ b/resources/views/auth/login.blade.php @@ -16,11 +16,11 @@
@csrf - +
- + - +
diff --git a/resources/views/auth/reset-password.blade.php b/resources/views/auth/reset-password.blade.php deleted file mode 100644 index 9040d2e..0000000 --- a/resources/views/auth/reset-password.blade.php +++ /dev/null @@ -1,48 +0,0 @@ - - Reset Password - - - - - - - - - - - - @csrf - - - - - -
- - - -
- - -
- - - -
- - -
- - - -
- -
- Reset Password - -
- -
-
diff --git a/resources/views/auth/verify-email.blade.php b/resources/views/auth/verify-email.blade.php deleted file mode 100644 index 5fdf2e7..0000000 --- a/resources/views/auth/verify-email.blade.php +++ /dev/null @@ -1,35 +0,0 @@ - - Verify Email - - - - - - - -
- 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/search-by-algolia.blade.php b/resources/views/components/search-by-algolia.blade.php new file mode 100644 index 0000000..eb588a9 --- /dev/null +++ b/resources/views/components/search-by-algolia.blade.php @@ -0,0 +1,5 @@ + diff --git a/resources/views/journal-entries/create.blade.php b/resources/views/journal-entries/create.blade.php index 214f57a..c4b035c 100644 --- a/resources/views/journal-entries/create.blade.php +++ b/resources/views/journal-entries/create.blade.php @@ -24,13 +24,16 @@
+ -
Add entries
+ @if(config('scout.driver') === 'algolia') + + @endif @once @push('scripts') diff --git a/resources/views/layouts/navigation.blade.php b/resources/views/layouts/navigation.blade.php index 1afffbe..d48f4b5 100644 --- a/resources/views/layouts/navigation.blade.php +++ b/resources/views/layouts/navigation.blade.php @@ -34,7 +34,7 @@
{{ Auth::user()->name }}
-
{{ Auth::user()->email }}
+
{{ Auth::user()->username }}
diff --git a/resources/views/recipes/edit.blade.php b/resources/views/recipes/edit.blade.php index c84f4ba..b078b0e 100644 --- a/resources/views/recipes/edit.blade.php +++ b/resources/views/recipes/edit.blade.php @@ -182,6 +182,9 @@
+ @if(config('scout.driver') === 'algolia') + + @endif @once @push('styles') diff --git a/tests/Feature/Http/Controllers/Auth/AuthenticationTest.php b/tests/Feature/Http/Controllers/Auth/AuthenticationTest.php index eb2dc0c..6c08eee 100644 --- a/tests/Feature/Http/Controllers/Auth/AuthenticationTest.php +++ b/tests/Feature/Http/Controllers/Auth/AuthenticationTest.php @@ -21,7 +21,7 @@ class AuthenticationTest extends TestCase { $user = User::factory()->create(); $response = $this->post('/login', [ - 'email' => $user->email, + 'username' => $user->username, 'password' => 'password', ]); $this->assertAuthenticated(); @@ -32,7 +32,7 @@ class AuthenticationTest extends TestCase { $user = User::factory()->create(); $this->post('/login', [ - 'email' => $user->email, + 'username' => $user->username, 'password' => 'wrong-password', ]); $this->assertGuest(); diff --git a/tests/Feature/Http/Controllers/Auth/PasswordConfirmationTest.php b/tests/Feature/Http/Controllers/Auth/PasswordConfirmationTest.php deleted file mode 100644 index 289f503..0000000 --- a/tests/Feature/Http/Controllers/Auth/PasswordConfirmationTest.php +++ /dev/null @@ -1,44 +0,0 @@ -create(); - - $response = $this->actingAs($user)->get('/confirm-password'); - - $response->assertStatus(200); - } - - public function testPasswordCanBeConfirmed() - { - $user = User::factory()->create(); - - $response = $this->actingAs($user)->post('/confirm-password', [ - 'password' => 'password', - ]); - - $response->assertRedirect(); - $response->assertSessionHasNoErrors(); - } - - public function testPasswordIsNotConfirmedWithInvalidPassword() - { - $user = User::factory()->create(); - - $response = $this->actingAs($user)->post('/confirm-password', [ - 'password' => 'wrong-password', - ]); - - $response->assertSessionHasErrors(); - } -} diff --git a/tests/Feature/Http/Controllers/Auth/PasswordResetTest.php b/tests/Feature/Http/Controllers/Auth/PasswordResetTest.php deleted file mode 100644 index 908035f..0000000 --- a/tests/Feature/Http/Controllers/Auth/PasswordResetTest.php +++ /dev/null @@ -1,71 +0,0 @@ -get('/forgot-password'); - - $response->assertStatus(200); - } - - public function testResetPasswordLinkCanBeRequested() - { - Notification::fake(); - - $user = User::factory()->create(); - - $this->post('/forgot-password', ['email' => $user->email]); - - Notification::assertSentTo($user, ResetPassword::class); - } - - public function testResetPasswordScreenCanBeRendered() - { - Notification::fake(); - - $user = User::factory()->create(); - - $this->post('/forgot-password', ['email' => $user->email]); - - Notification::assertSentTo($user, ResetPassword::class, function ($notification) { - $response = $this->get('/reset-password/'.$notification->token); - - $response->assertStatus(200); - - return true; - }); - } - - public function testPasswordCanBeResetWithValidToken() - { - Notification::fake(); - - $user = User::factory()->create(); - - $this->post('/forgot-password', ['email' => $user->email]); - - Notification::assertSentTo($user, ResetPassword::class, function ($notification) use ($user) { - $response = $this->post('/reset-password', [ - 'token' => $notification->token, - 'email' => $user->email, - 'password' => 'password', - 'password_confirmation' => 'password', - ]); - - $response->assertSessionHasNoErrors(); - - return true; - }); - } -} diff --git a/tests/LogsIn.php b/tests/LogsIn.php index dfb5601..df7146d 100644 --- a/tests/LogsIn.php +++ b/tests/LogsIn.php @@ -15,7 +15,7 @@ trait LogsIn { $this->user = User::factory()->create(); $this->post('/login', [ - 'email' => $this->user->email, + 'username' => $this->user->username, 'password' => 'password', ]); }