From 6f751ead83586f90a86bd38e19f8ec5b63549ef7 Mon Sep 17 00:00:00 2001 From: Enoch Date: Mon, 5 Feb 2024 00:00:23 +0800 Subject: [PATCH] Composer Version Change --- app/controller/IndexController.php | 2 +- app/view/domain.html | 112 + composer.json | 11 +- composer.lock | 1366 ++++-- config/plugin/webman-tech/debugbar/app.php | 13 - .../plugin/webman-tech/debugbar/bootstrap.php | 9 - .../webman-tech/debugbar/middleware.php | 9 - config/plugin/webman-tech/debugbar/route.php | 5 - .../20240204114015_my_new_migration.php | 24 + phinx.php | 21 + vendor/bin/phinx | 120 + vendor/bin/phinx.bat | 5 + vendor/brick/math/CHANGELOG.md | 445 ++ vendor/brick/math/LICENSE | 20 + vendor/brick/math/composer.json | 34 + vendor/brick/math/src/BigDecimal.php | 786 ++++ vendor/brick/math/src/BigInteger.php | 1079 +++++ vendor/brick/math/src/BigNumber.php | 512 +++ vendor/brick/math/src/BigRational.php | 445 ++ .../src/Exception/DivisionByZeroException.php | 35 + .../Exception/IntegerOverflowException.php | 23 + .../math/src/Exception/MathException.php | 12 + .../src/Exception/NegativeNumberException.php | 12 + .../src/Exception/NumberFormatException.php | 33 + .../Exception/RoundingNecessaryException.php | 19 + vendor/brick/math/src/Internal/Calculator.php | 676 +++ .../Internal/Calculator/BcMathCalculator.php | 75 + .../src/Internal/Calculator/GmpCalculator.php | 108 + .../Internal/Calculator/NativeCalculator.php | 581 +++ vendor/brick/math/src/RoundingMode.php | 107 + vendor/cakephp/core/App.php | 269 ++ vendor/cakephp/core/BasePlugin.php | 305 ++ vendor/cakephp/core/ClassLoader.php | 139 + vendor/cakephp/core/Configure.php | 498 +++ .../core/Configure/ConfigEngineInterface.php | 44 + .../core/Configure/Engine/IniConfig.php | 203 + .../core/Configure/Engine/JsonConfig.php | 115 + .../core/Configure/Engine/PhpConfig.php | 114 + .../core/Configure/FileConfigTrait.php | 72 + .../core/ConsoleApplicationInterface.php | 42 + vendor/cakephp/core/Container.php | 28 + .../core/ContainerApplicationInterface.php | 45 + vendor/cakephp/core/ContainerInterface.php | 32 + vendor/cakephp/core/ConventionsTrait.php | 156 + .../cakephp/core/Exception/CakeException.php | 123 + vendor/cakephp/core/Exception/Exception.php | 21 + .../core/Exception/MissingPluginException.php | 26 + .../cakephp/core/HttpApplicationInterface.php | 43 + vendor/cakephp/core/InstanceConfigTrait.php | 312 ++ vendor/cakephp/core/LICENSE.txt | 22 + vendor/cakephp/core/ObjectRegistry.php | 416 ++ vendor/cakephp/core/Plugin.php | 136 + .../core/PluginApplicationInterface.php | 75 + vendor/cakephp/core/PluginCollection.php | 363 ++ vendor/cakephp/core/PluginInterface.php | 135 + vendor/cakephp/core/README.md | 37 + vendor/cakephp/core/Retry/CommandRetry.php | 94 + .../core/Retry/RetryStrategyInterface.php | 35 + vendor/cakephp/core/ServiceConfig.php | 50 + vendor/cakephp/core/ServiceProvider.php | 132 + vendor/cakephp/core/StaticConfigTrait.php | 325 ++ .../core/TestSuite/ContainerStubTrait.php | 181 + vendor/cakephp/core/composer.json | 44 + vendor/cakephp/core/functions.php | 340 ++ vendor/cakephp/core/functions_global.php | 190 + vendor/cakephp/database/Connection.php | 1197 +++++ .../cakephp/database/ConstraintsInterface.php | 49 + vendor/cakephp/database/Driver.php | 559 +++ vendor/cakephp/database/Driver/Mysql.php | 345 ++ vendor/cakephp/database/Driver/Postgres.php | 348 ++ .../database/Driver/SqlDialectTrait.php | 315 ++ vendor/cakephp/database/Driver/Sqlite.php | 385 ++ vendor/cakephp/database/Driver/Sqlserver.php | 569 +++ .../Driver/TupleComparisonTranslatorTrait.php | 113 + vendor/cakephp/database/DriverInterface.php | 336 ++ vendor/cakephp/database/Exception.php | 10 + .../database/Exception/DatabaseException.php | 37 + .../Exception/MissingConnectionException.php | 30 + .../Exception/MissingDriverException.php | 30 + .../Exception/MissingExtensionException.php | 31 + .../NestedTransactionRollbackException.php | 41 + .../Expression/AggregateExpression.php | 253 ++ .../database/Expression/BetweenExpression.php | 144 + .../database/Expression/CaseExpression.php | 251 ++ .../Expression/CaseExpressionTrait.php | 109 + .../Expression/CaseStatementExpression.php | 597 +++ .../Expression/CommonTableExpression.php | 239 + .../database/Expression/Comparison.php | 7 + .../Expression/ComparisonExpression.php | 324 ++ .../database/Expression/FieldInterface.php | 39 + .../database/Expression/FieldTrait.php | 51 + .../Expression/FunctionExpression.php | 178 + .../Expression/IdentifierExpression.php | 119 + .../database/Expression/OrderByExpression.php | 88 + .../Expression/OrderClauseExpression.php | 90 + .../database/Expression/QueryExpression.php | 876 ++++ .../database/Expression/StringExpression.php | 87 + .../database/Expression/TupleComparison.php | 231 + .../database/Expression/UnaryExpression.php | 118 + .../database/Expression/ValuesExpression.php | 325 ++ .../Expression/WhenThenExpression.php | 350 ++ .../database/Expression/WindowExpression.php | 335 ++ .../database/Expression/WindowInterface.php | 163 + .../cakephp/database/ExpressionInterface.php | 44 + .../cakephp/database/FieldTypeConverter.php | 140 + vendor/cakephp/database/FunctionsBuilder.php | 376 ++ vendor/cakephp/database/IdentifierQuoter.php | 269 ++ vendor/cakephp/database/LICENSE.txt | 22 + vendor/cakephp/database/Log/LoggedQuery.php | 176 + .../cakephp/database/Log/LoggingStatement.php | 219 + vendor/cakephp/database/Log/QueryLogger.php | 57 + vendor/cakephp/database/PostgresCompiler.php | 93 + vendor/cakephp/database/Query.php | 2516 +++++++++++ vendor/cakephp/database/Query/DeleteQuery.php | 222 + vendor/cakephp/database/Query/InsertQuery.php | 322 ++ vendor/cakephp/database/Query/SelectQuery.php | 127 + vendor/cakephp/database/Query/UpdateQuery.php | 182 + vendor/cakephp/database/QueryCompiler.php | 462 ++ vendor/cakephp/database/README.md | 358 ++ .../database/Retry/ErrorCodeWaitStrategy.php | 69 + .../database/Retry/ReconnectStrategy.php | 124 + vendor/cakephp/database/Schema/BaseSchema.php | 10 + .../database/Schema/CachedCollection.php | 131 + vendor/cakephp/database/Schema/Collection.php | 168 + .../database/Schema/CollectionInterface.php | 54 + .../cakephp/database/Schema/MysqlSchema.php | 10 + .../database/Schema/MysqlSchemaDialect.php | 669 +++ .../database/Schema/PostgresSchema.php | 10 + .../database/Schema/PostgresSchemaDialect.php | 704 +++ .../cakephp/database/Schema/SchemaDialect.php | 346 ++ .../database/Schema/SqlGeneratorInterface.php | 72 + .../cakephp/database/Schema/SqliteSchema.php | 10 + .../database/Schema/SqliteSchemaDialect.php | 649 +++ .../database/Schema/SqlserverSchema.php | 10 + .../Schema/SqlserverSchemaDialect.php | 707 +++ .../cakephp/database/Schema/TableSchema.php | 793 ++++ .../Schema/TableSchemaAwareInterface.php | 38 + .../database/Schema/TableSchemaInterface.php | 283 ++ vendor/cakephp/database/SchemaCache.php | 114 + vendor/cakephp/database/SqlDialectTrait.php | 10 + vendor/cakephp/database/SqliteCompiler.php | 33 + vendor/cakephp/database/SqlserverCompiler.php | 167 + .../database/Statement/BufferResultsTrait.php | 45 + .../database/Statement/BufferedStatement.php | 361 ++ .../database/Statement/CallbackStatement.php | 77 + .../database/Statement/MysqlStatement.php | 46 + .../database/Statement/PDOStatement.php | 176 + .../database/Statement/SqliteStatement.php | 70 + .../database/Statement/SqlserverStatement.php | 53 + .../database/Statement/StatementDecorator.php | 373 ++ .../cakephp/database/StatementInterface.php | 203 + vendor/cakephp/database/Type.php | 9 + vendor/cakephp/database/Type/BaseType.php | 80 + .../database/Type/BatchCastingInterface.php | 37 + vendor/cakephp/database/Type/BinaryType.php | 92 + .../cakephp/database/Type/BinaryUuidType.php | 145 + vendor/cakephp/database/Type/BoolType.php | 126 + .../Type/ColumnSchemaAwareInterface.php | 29 + .../database/Type/DateTimeFractionalType.php | 42 + .../database/Type/DateTimeTimezoneType.php | 44 + vendor/cakephp/database/Type/DateTimeType.php | 563 +++ vendor/cakephp/database/Type/DateType.php | 174 + vendor/cakephp/database/Type/DecimalType.php | 190 + .../Type/ExpressionTypeCasterTrait.php | 80 + .../database/Type/ExpressionTypeInterface.php | 36 + vendor/cakephp/database/Type/FloatType.php | 171 + vendor/cakephp/database/Type/IntegerType.php | 129 + vendor/cakephp/database/Type/JsonType.php | 124 + .../Type/OptionalConvertInterface.php | 32 + vendor/cakephp/database/Type/StringType.php | 110 + vendor/cakephp/database/Type/TimeType.php | 52 + vendor/cakephp/database/Type/UuidType.php | 67 + .../cakephp/database/TypeConverterTrait.php | 66 + vendor/cakephp/database/TypeFactory.php | 171 + vendor/cakephp/database/TypeInterface.php | 91 + vendor/cakephp/database/TypeMap.php | 160 + vendor/cakephp/database/TypeMapTrait.php | 89 + .../cakephp/database/TypedResultInterface.php | 38 + vendor/cakephp/database/TypedResultTrait.php | 53 + vendor/cakephp/database/ValueBinder.php | 163 + vendor/cakephp/database/composer.json | 40 + .../datasource/ConnectionInterface.php | 154 + .../cakephp/datasource/ConnectionManager.php | 216 + .../cakephp/datasource/ConnectionRegistry.php | 104 + vendor/cakephp/datasource/EntityInterface.php | 288 ++ vendor/cakephp/datasource/EntityTrait.php | 1304 ++++++ .../Exception/InvalidPrimaryKeyException.php | 26 + .../MissingDatasourceConfigException.php | 28 + .../Exception/MissingDatasourceException.php | 28 + .../Exception/MissingModelException.php | 30 + .../Exception/PageOutOfBoundsException.php | 10 + .../Exception/RecordNotFoundException.php | 26 + vendor/cakephp/datasource/FactoryLocator.php | 103 + .../cakephp/datasource/FixtureInterface.php | 73 + .../datasource/InvalidPropertyInterface.php | 61 + vendor/cakephp/datasource/LICENSE.txt | 22 + .../datasource/Locator/AbstractLocator.php | 115 + .../datasource/Locator/LocatorInterface.php | 68 + vendor/cakephp/datasource/ModelAwareTrait.php | 241 + vendor/cakephp/datasource/Paginator.php | 10 + .../cakephp/datasource/PaginatorInterface.php | 10 + .../Exception/PageOutOfBoundsException.php | 35 + .../datasource/Paging/NumericPaginator.php | 734 ++++ .../datasource/Paging/PaginatorInterface.php | 50 + .../datasource/Paging/SimplePaginator.php | 49 + vendor/cakephp/datasource/QueryCacher.php | 137 + vendor/cakephp/datasource/QueryInterface.php | 406 ++ vendor/cakephp/datasource/QueryTrait.php | 1465 +++++++ vendor/cakephp/datasource/README.md | 82 + .../datasource/RepositoryInterface.php | 252 ++ .../cakephp/datasource/ResultSetDecorator.php | 61 + .../cakephp/datasource/ResultSetInterface.php | 30 + vendor/cakephp/datasource/RuleInvoker.php | 142 + vendor/cakephp/datasource/RulesAwareTrait.php | 120 + vendor/cakephp/datasource/RulesChecker.php | 330 ++ vendor/cakephp/datasource/SchemaInterface.php | 166 + vendor/cakephp/datasource/SimplePaginator.php | 10 + vendor/cakephp/datasource/composer.json | 42 + vendor/cakephp/utility/CookieCryptTrait.php | 192 + vendor/cakephp/utility/Crypto/OpenSsl.php | 79 + .../utility/Exception/XmlException.php | 25 + vendor/cakephp/utility/Hash.php | 1271 ++++++ vendor/cakephp/utility/Inflector.php | 524 +++ vendor/cakephp/utility/LICENSE.txt | 22 + .../cakephp/utility/MergeVariablesTrait.php | 118 + vendor/cakephp/utility/README.md | 91 + vendor/cakephp/utility/Security.php | 309 ++ vendor/cakephp/utility/Text.php | 1180 +++++ vendor/cakephp/utility/Xml.php | 502 +++ vendor/cakephp/utility/bootstrap.php | 21 + vendor/cakephp/utility/composer.json | 43 + vendor/composer/autoload_classmap.php | 2 + vendor/composer/autoload_files.php | 11 +- vendor/composer/autoload_psr4.php | 13 +- vendor/composer/autoload_static.php | 77 +- vendor/composer/installed.json | 1016 ++++- vendor/composer/installed.php | 150 +- .../Inflector/Rules/English/Inflectible.php | 3 - .../illuminate/database/Capsule/Manager.php | 202 + .../database/ClassMorphViolationException.php | 29 + .../database/Concerns/BuildsQueries.php | 506 +++ .../database/Concerns/CompilesJsonPaths.php | 64 + .../database/Concerns/ExplainsQueries.php | 24 + .../database/Concerns/ManagesTransactions.php | 352 ++ .../database/Concerns/ParsesSearchPath.php | 25 + .../database/ConfigurationUrlParser.php | 10 + vendor/illuminate/database/Connection.php | 1593 +++++++ .../database/ConnectionInterface.php | 170 + .../database/ConnectionResolver.php | 92 + .../database/ConnectionResolverInterface.php | 29 + .../database/Connectors/ConnectionFactory.php | 277 ++ .../database/Connectors/Connector.php | 139 + .../Connectors/ConnectorInterface.php | 14 + .../database/Connectors/MySqlConnector.php | 208 + .../database/Connectors/PostgresConnector.php | 216 + .../database/Connectors/SQLiteConnector.php | 39 + .../Connectors/SqlServerConnector.php | 233 + .../Console/DatabaseInspectionCommand.php | 246 ++ .../illuminate/database/Console/DbCommand.php | 227 + .../database/Console/DumpCommand.php | 101 + .../Console/Factories/FactoryMakeCommand.php | 154 + .../Console/Factories/stubs/factory.stub | 23 + .../Console/Migrations/BaseCommand.php | 51 + .../Console/Migrations/FreshCommand.php | 120 + .../Console/Migrations/InstallCommand.php | 70 + .../Console/Migrations/MigrateCommand.php | 281 ++ .../Console/Migrations/MigrateMakeCommand.php | 144 + .../Console/Migrations/RefreshCommand.php | 159 + .../Console/Migrations/ResetCommand.php | 91 + .../Console/Migrations/RollbackCommand.php | 91 + .../Console/Migrations/StatusCommand.php | 132 + .../Console/Migrations/TableGuesser.php | 37 + .../database/Console/MonitorCommand.php | 151 + .../database/Console/PruneCommand.php | 186 + .../database/Console/Seeds/SeedCommand.php | 151 + .../Console/Seeds/SeederMakeCommand.php | 103 + .../Console/Seeds/WithoutModelEvents.php | 19 + .../database/Console/Seeds/stubs/seeder.stub | 19 + .../database/Console/ShowCommand.php | 189 + .../database/Console/TableCommand.php | 246 ++ .../database/Console/WipeCommand.php | 125 + .../database/DBAL/TimestampType.php | 99 + .../illuminate/database/DatabaseManager.php | 471 ++ .../database/DatabaseServiceProvider.php | 113 + .../database/DatabaseTransactionRecord.php | 73 + .../database/DatabaseTransactionsManager.php | 133 + .../illuminate/database/DeadlockException.php | 10 + .../database/DetectsConcurrencyErrors.php | 37 + .../database/DetectsLostConnections.php | 66 + .../BroadcastableModelEventOccurred.php | 144 + .../database/Eloquent/BroadcastsEvents.php | 197 + .../illuminate/database/Eloquent/Builder.php | 1952 +++++++++ .../database/Eloquent/Casts/ArrayObject.php | 46 + .../database/Eloquent/Casts/AsArrayObject.php | 42 + .../database/Eloquent/Casts/AsCollection.php | 38 + .../Eloquent/Casts/AsEncryptedArrayObject.php | 45 + .../Eloquent/Casts/AsEncryptedCollection.php | 41 + .../Eloquent/Casts/AsEnumArrayObject.php | 84 + .../Eloquent/Casts/AsEnumCollection.php | 80 + .../database/Eloquent/Casts/AsStringable.php | 32 + .../database/Eloquent/Casts/Attribute.php | 105 + .../database/Eloquent/Collection.php | 782 ++++ .../Eloquent/Concerns/GuardsAttributes.php | 255 ++ .../Eloquent/Concerns/HasAttributes.php | 2232 ++++++++++ .../database/Eloquent/Concerns/HasEvents.php | 415 ++ .../Eloquent/Concerns/HasGlobalScopes.php | 71 + .../Eloquent/Concerns/HasRelationships.php | 927 ++++ .../Eloquent/Concerns/HasTimestamps.php | 224 + .../database/Eloquent/Concerns/HasUlids.php | 96 + .../database/Eloquent/Concerns/HasUuids.php | 96 + .../Eloquent/Concerns/HidesAttributes.php | 124 + .../Concerns/QueriesRelationships.php | 879 ++++ .../Factories/BelongsToManyRelationship.php | 76 + .../Factories/BelongsToRelationship.php | 97 + .../Eloquent/Factories/CrossJoinSequence.php | 26 + .../database/Eloquent/Factories/Factory.php | 926 ++++ .../Eloquent/Factories/HasFactory.php | 32 + .../Eloquent/Factories/Relationship.php | 75 + .../database/Eloquent/Factories/Sequence.php | 63 + .../Eloquent/HigherOrderBuilderProxy.php | 50 + .../Eloquent/InvalidCastException.php | 48 + .../Eloquent/JsonEncodingException.php | 49 + .../Eloquent/MassAssignmentException.php | 10 + .../database/Eloquent/MassPrunable.php | 48 + .../Eloquent/MissingAttributeException.php | 23 + vendor/illuminate/database/Eloquent/Model.php | 2396 ++++++++++ .../Eloquent/ModelNotFoundException.php | 69 + .../PendingHasThroughRelationship.php | 90 + .../illuminate/database/Eloquent/Prunable.php | 67 + .../database/Eloquent/QueueEntityResolver.php | 29 + .../Eloquent/RelationNotFoundException.php | 46 + .../database/Eloquent/Relations/BelongsTo.php | 383 ++ .../Eloquent/Relations/BelongsToMany.php | 1503 +++++++ .../Eloquent/Relations/Concerns/AsPivot.php | 333 ++ .../Relations/Concerns/CanBeOneOfMany.php | 310 ++ .../Concerns/ComparesRelatedModels.php | 77 + .../Concerns/InteractsWithDictionary.php | 36 + .../Concerns/InteractsWithPivotTable.php | 681 +++ .../Concerns/SupportsDefaultModels.php | 63 + .../database/Eloquent/Relations/HasMany.php | 49 + .../Eloquent/Relations/HasManyThrough.php | 772 ++++ .../database/Eloquent/Relations/HasOne.php | 137 + .../Eloquent/Relations/HasOneOrMany.php | 486 +++ .../Eloquent/Relations/HasOneThrough.php | 77 + .../database/Eloquent/Relations/MorphMany.php | 62 + .../database/Eloquent/Relations/MorphOne.php | 137 + .../Eloquent/Relations/MorphOneOrMany.php | 127 + .../Eloquent/Relations/MorphPivot.php | 182 + .../database/Eloquent/Relations/MorphTo.php | 396 ++ .../Eloquent/Relations/MorphToMany.php | 209 + .../database/Eloquent/Relations/Pivot.php | 25 + .../database/Eloquent/Relations/Relation.php | 503 +++ vendor/illuminate/database/Eloquent/Scope.php | 15 + .../database/Eloquent/SoftDeletes.php | 249 ++ .../database/Eloquent/SoftDeletingScope.php | 148 + .../database/Events/ConnectionEstablished.php | 8 + .../database/Events/ConnectionEvent.php | 32 + .../database/Events/DatabaseBusy.php | 32 + .../database/Events/DatabaseRefreshed.php | 10 + .../database/Events/MigrationEnded.php | 8 + .../database/Events/MigrationEvent.php | 36 + .../database/Events/MigrationStarted.php | 8 + .../database/Events/MigrationsEnded.php | 8 + .../database/Events/MigrationsEvent.php | 26 + .../database/Events/MigrationsStarted.php | 8 + .../database/Events/ModelsPruned.php | 33 + .../database/Events/NoPendingMigrations.php | 24 + .../database/Events/QueryExecuted.php | 59 + .../database/Events/SchemaDumped.php | 41 + .../database/Events/SchemaLoaded.php | 41 + .../database/Events/StatementPrepared.php | 33 + .../database/Events/TransactionBeginning.php | 8 + .../database/Events/TransactionCommitted.php | 8 + .../database/Events/TransactionCommitting.php | 8 + .../database/Events/TransactionRolledBack.php | 8 + vendor/illuminate/database/Grammar.php | 253 ++ vendor/illuminate/database/LICENSE.md | 21 + .../LazyLoadingViolationException.php | 39 + .../database/LostConnectionException.php | 10 + .../database/MigrationServiceProvider.php | 222 + .../DatabaseMigrationRepository.php | 224 + .../database/Migrations/Migration.php | 30 + .../database/Migrations/MigrationCreator.php | 231 + .../MigrationRepositoryInterface.php | 88 + .../database/Migrations/Migrator.php | 773 ++++ .../Migrations/stubs/migration.create.stub | 31 + .../database/Migrations/stubs/migration.stub | 28 + .../Migrations/stubs/migration.update.stub | 32 + .../MultipleColumnsSelectedException.php | 10 + .../MultipleRecordsFoundException.php | 40 + .../illuminate/database/MySqlConnection.php | 91 + .../PDO/Concerns/ConnectsToDatabase.php | 30 + vendor/illuminate/database/PDO/Connection.php | 182 + .../illuminate/database/PDO/MySqlDriver.php | 19 + .../database/PDO/PostgresDriver.php | 19 + .../illuminate/database/PDO/SQLiteDriver.php | 19 + .../database/PDO/SqlServerConnection.php | 152 + .../database/PDO/SqlServerDriver.php | 32 + .../database/PostgresConnection.php | 80 + vendor/illuminate/database/Query/Builder.php | 3874 +++++++++++++++++ .../illuminate/database/Query/Expression.php | 44 + .../database/Query/Grammars/Grammar.php | 1348 ++++++ .../database/Query/Grammars/MySqlGrammar.php | 381 ++ .../Query/Grammars/PostgresGrammar.php | 701 +++ .../database/Query/Grammars/SQLiteGrammar.php | 369 ++ .../Query/Grammars/SqlServerGrammar.php | 634 +++ .../illuminate/database/Query/IndexHint.php | 33 + .../illuminate/database/Query/JoinClause.php | 146 + .../Query/Processors/MySqlProcessor.php | 19 + .../Query/Processors/PostgresProcessor.php | 45 + .../database/Query/Processors/Processor.php | 49 + .../Query/Processors/SQLiteProcessor.php | 19 + .../Query/Processors/SqlServerProcessor.php | 70 + vendor/illuminate/database/QueryException.php | 79 + vendor/illuminate/database/README.md | 69 + .../database/RecordsNotFoundException.php | 10 + .../illuminate/database/SQLiteConnection.php | 115 + .../SQLiteDatabaseDoesNotExistException.php | 28 + .../illuminate/database/Schema/Blueprint.php | 1829 ++++++++ vendor/illuminate/database/Schema/Builder.php | 495 +++ .../database/Schema/ColumnDefinition.php | 38 + .../Schema/ForeignIdColumnDefinition.php | 52 + .../database/Schema/ForeignKeyDefinition.php | 76 + .../database/Schema/Grammars/ChangeColumn.php | 235 + .../database/Schema/Grammars/Grammar.php | 345 ++ .../database/Schema/Grammars/MySqlGrammar.php | 1221 ++++++ .../Schema/Grammars/PostgresGrammar.php | 1141 +++++ .../database/Schema/Grammars/RenameColumn.php | 84 + .../Schema/Grammars/SQLiteGrammar.php | 1005 +++++ .../Schema/Grammars/SqlServerGrammar.php | 973 +++++ .../database/Schema/IndexDefinition.php | 16 + .../database/Schema/MySqlBuilder.php | 140 + .../database/Schema/MySqlSchemaState.php | 170 + .../database/Schema/PostgresBuilder.php | 248 ++ .../database/Schema/PostgresSchemaState.php | 79 + .../database/Schema/SQLiteBuilder.php | 102 + .../database/Schema/SchemaState.php | 122 + .../database/Schema/SqlServerBuilder.php | 78 + .../database/Schema/SqliteSchemaState.php | 99 + vendor/illuminate/database/Seeder.php | 195 + .../database/SqlServerConnection.php | 123 + vendor/illuminate/database/composer.json | 52 + .../pagination/AbstractCursorPaginator.php | 671 +++ .../pagination/AbstractPaginator.php | 797 ++++ vendor/illuminate/pagination/Cursor.php | 132 + .../illuminate/pagination/CursorPaginator.php | 172 + vendor/illuminate/pagination/LICENSE.md | 21 + .../pagination/LengthAwarePaginator.php | 231 + .../pagination/PaginationServiceProvider.php | 34 + .../illuminate/pagination/PaginationState.php | 35 + vendor/illuminate/pagination/Paginator.php | 176 + vendor/illuminate/pagination/UrlWindow.php | 220 + vendor/illuminate/pagination/composer.json | 37 + .../resources/views/bootstrap-4.blade.php | 46 + .../resources/views/bootstrap-5.blade.php | 88 + .../resources/views/default.blade.php | 46 + .../resources/views/semantic-ui.blade.php | 36 + .../views/simple-bootstrap-4.blade.php | 27 + .../views/simple-bootstrap-5.blade.php | 29 + .../resources/views/simple-default.blade.php | 19 + .../resources/views/simple-tailwind.blade.php | 25 + .../resources/views/tailwind.blade.php | 106 + vendor/maximebf/debugbar/composer.json | 43 - .../DebugBar/Bridge/CacheCacheCollector.php | 75 - .../src/DebugBar/Bridge/DoctrineCollector.php | 115 - .../src/DebugBar/Bridge/MonologCollector.php | 118 - .../Bridge/NamespacedTwigProfileCollector.php | 204 - .../src/DebugBar/Bridge/Propel2Collector.php | 307 -- .../src/DebugBar/Bridge/PropelCollector.php | 253 -- .../src/DebugBar/Bridge/SlimCollector.php | 66 - .../Bridge/SwiftMailer/SwiftLogCollector.php | 53 - .../Bridge/SwiftMailer/SwiftMailCollector.php | 92 - .../Bridge/Symfony/SymfonyMailCollector.php | 84 - .../Twig/TimeableTwigExtensionProfiler.php | 60 - .../Bridge/Twig/TraceableTwigEnvironment.php | 419 -- .../Bridge/Twig/TraceableTwigTemplate.php | 138 - .../DebugBar/Bridge/Twig/TwigCollector.php | 89 - .../DebugBar/Bridge/TwigProfileCollector.php | 199 - .../DataCollector/AggregatedCollector.php | 190 - .../DebugBar/DataCollector/AssetProvider.php | 43 - .../DataCollector/ConfigCollector.php | 120 - .../DebugBar/DataCollector/DataCollector.php | 318 -- .../DataCollector/DataCollectorInterface.php | 31 - .../DataCollector/ExceptionsCollector.php | 197 - .../DataCollector/LocalizationCollector.php | 73 - .../DataCollector/MemoryCollector.php | 111 - .../MessagesAggregateInterface.php | 21 - .../DataCollector/MessagesCollector.php | 271 -- .../DataCollector/PDO/PDOCollector.php | 209 - .../DataCollector/PDO/TraceablePDO.php | 321 -- .../PDO/TraceablePDOStatement.php | 131 - .../DataCollector/PDO/TracedStatement.php | 277 -- .../DataCollector/PhpInfoCollector.php | 51 - .../src/DebugBar/DataCollector/Renderable.php | 25 - .../DataCollector/RequestDataCollector.php | 100 - .../DataCollector/TimeDataCollector.php | 271 -- .../DebugBar/DataFormatter/DataFormatter.php | 87 - .../DataFormatter/DataFormatterInterface.php | 42 - .../DataFormatter/DebugBarVarDumper.php | 313 -- .../VarDumper/DebugBarHtmlDumper.php | 25 - .../debugbar/src/DebugBar/DebugBar.php | 497 --- .../src/DebugBar/DebugBarException.php | 16 - .../src/DebugBar/HttpDriverInterface.php | 64 - .../src/DebugBar/JavascriptRenderer.php | 1202 ----- .../debugbar/src/DebugBar/OpenHandler.php | 117 - .../debugbar/src/DebugBar/PhpHttpDriver.php | 70 - .../src/DebugBar/RequestIdGenerator.php | 43 - .../DebugBar/RequestIdGeneratorInterface.php | 25 - .../src/DebugBar/Resources/debugbar.css | 313 -- .../src/DebugBar/Resources/debugbar.js | 1222 ------ .../src/DebugBar/Resources/openhandler.css | 70 - .../src/DebugBar/Resources/openhandler.js | 202 - .../font-awesome/css/font-awesome.min.css | 4 - .../vendor/font-awesome/fonts/FontAwesome.otf | Bin 134808 -> 0 bytes .../fonts/fontawesome-webfont.eot | Bin 165742 -> 0 bytes .../fonts/fontawesome-webfont.svg | 2671 ------------ .../fonts/fontawesome-webfont.ttf | Bin 165548 -> 0 bytes .../fonts/fontawesome-webfont.woff | Bin 98024 -> 0 bytes .../fonts/fontawesome-webfont.woff2 | Bin 77160 -> 0 bytes .../vendor/highlightjs/highlight.pack.js | 1 - .../vendor/highlightjs/styles/github.css | 82 - .../vendor/jquery/dist/jquery.min.js | 2 - .../src/DebugBar/Resources/widgets.css | 271 -- .../src/DebugBar/Resources/widgets.js | 606 --- .../Resources/widgets/mails/widget.css | 12 - .../Resources/widgets/mails/widget.js | 40 - .../Resources/widgets/sqlqueries/widget.css | 118 - .../Resources/widgets/sqlqueries/widget.js | 171 - .../Resources/widgets/templates/widget.css | 73 - .../Resources/widgets/templates/widget.js | 98 - .../src/DebugBar/StandardDebugBar.php | 34 - .../src/DebugBar/Storage/FileStorage.php | 128 - .../src/DebugBar/Storage/MemcachedStorage.php | 158 - .../src/DebugBar/Storage/PdoStorage.php | 137 - .../src/DebugBar/Storage/RedisStorage.php | 106 - .../src/DebugBar/Storage/StorageInterface.php | 45 - .../DebugBar/Storage/pdo_storage_schema.sql | 16 - vendor/nesbot/carbon/readme.md | 4 +- vendor/nesbot/carbon/sponsors.php | 13 +- .../nesbot/carbon/src/Carbon/CarbonPeriod.php | 10 +- vendor/nesbot/carbon/src/Carbon/Lang/uk.php | 2 +- vendor/psr/log/composer.json | 2 +- vendor/psr/log/src/LoggerAwareInterface.php | 2 +- vendor/psr/log/src/LoggerAwareTrait.php | 2 +- vendor/psr/log/src/LoggerInterface.php | 18 +- vendor/psr/log/src/LoggerTrait.php | 18 +- vendor/psr/log/src/NullLogger.php | 2 +- vendor/psr/simple-cache/composer.json | 2 +- .../psr/simple-cache/src/CacheInterface.php | 16 +- vendor/robmorgan/phinx/.stickler.yml | 12 + vendor/robmorgan/phinx/LICENSE | 23 + vendor/robmorgan/phinx/README.md | 143 + vendor/robmorgan/phinx/app/phinx.php | 36 + vendor/robmorgan/phinx/app/web.php | 83 + vendor/robmorgan/phinx/bin/phinx | 28 + vendor/robmorgan/phinx/bin/phinx.bat | 41 + vendor/robmorgan/phinx/composer.json | 87 + vendor/robmorgan/phinx/data/phinx.json.dist | 38 + vendor/robmorgan/phinx/data/phinx.php.dist | 41 + vendor/robmorgan/phinx/data/phinx.yml.dist | 35 + .../robmorgan/phinx/docs/config/__init__.py | 0 vendor/robmorgan/phinx/docs/config/all.py | 43 + vendor/robmorgan/phinx/docs/en/commands.rst | 411 ++ vendor/robmorgan/phinx/docs/en/conf.py | 9 + .../robmorgan/phinx/docs/en/configuration.rst | 534 +++ vendor/robmorgan/phinx/docs/en/contents.rst | 14 + .../phinx/docs/en/copyright.rst} | 36 +- vendor/robmorgan/phinx/docs/en/goals.rst | 13 + vendor/robmorgan/phinx/docs/en/index.rst | 33 + vendor/robmorgan/phinx/docs/en/install.rst | 28 + vendor/robmorgan/phinx/docs/en/intro.rst | 16 + vendor/robmorgan/phinx/docs/en/migrations.rst | 1934 ++++++++ vendor/robmorgan/phinx/docs/en/namespaces.rst | 154 + vendor/robmorgan/phinx/docs/en/seeding.rst | 234 + vendor/robmorgan/phinx/phpstan-baseline.neon | 27 + .../phinx/src/Phinx/Config/Config.php | 553 +++ .../src/Phinx/Config/ConfigInterface.php | 171 + .../phinx/src/Phinx/Config/FeatureFlags.php | 41 + .../Phinx/Config/NamespaceAwareInterface.php | 33 + .../src/Phinx/Config/NamespaceAwareTrait.php | 74 + .../Phinx/Console/Command/AbstractCommand.php | 427 ++ .../src/Phinx/Console/Command/Breakpoint.php | 109 + .../src/Phinx/Console/Command/Create.php | 326 ++ .../phinx/src/Phinx/Console/Command/Init.php | 171 + .../src/Phinx/Console/Command/ListAliases.php | 80 + .../src/Phinx/Console/Command/Migrate.php | 140 + .../src/Phinx/Console/Command/Rollback.php | 171 + .../src/Phinx/Console/Command/SeedCreate.php | 219 + .../src/Phinx/Console/Command/SeedRun.php | 121 + .../src/Phinx/Console/Command/Status.php | 94 + .../phinx/src/Phinx/Console/Command/Test.php | 97 + .../src/Phinx/Console/PhinxApplication.php | 72 + .../phinx/src/Phinx/Db/Action/Action.php | 38 + .../phinx/src/Phinx/Db/Action/AddColumn.php | 62 + .../src/Phinx/Db/Action/AddForeignKey.php | 78 + .../phinx/src/Phinx/Db/Action/AddIndex.php | 67 + .../src/Phinx/Db/Action/ChangeColumn.php | 87 + .../src/Phinx/Db/Action/ChangeComment.php | 42 + .../src/Phinx/Db/Action/ChangePrimaryKey.php | 42 + .../phinx/src/Phinx/Db/Action/CreateTable.php | 12 + .../src/Phinx/Db/Action/DropForeignKey.php | 68 + .../phinx/src/Phinx/Db/Action/DropIndex.php | 75 + .../phinx/src/Phinx/Db/Action/DropTable.php | 12 + .../src/Phinx/Db/Action/RemoveColumn.php | 59 + .../src/Phinx/Db/Action/RenameColumn.php | 79 + .../phinx/src/Phinx/Db/Action/RenameTable.php | 42 + .../src/Phinx/Db/Adapter/AbstractAdapter.php | 412 ++ .../src/Phinx/Db/Adapter/AdapterFactory.php | 172 + .../src/Phinx/Db/Adapter/AdapterInterface.php | 505 +++ .../src/Phinx/Db/Adapter/AdapterWrapper.php | 487 +++ .../Db/Adapter/DirectActionInterface.php | 139 + .../src/Phinx/Db/Adapter/MysqlAdapter.php | 1545 +++++++ .../phinx/src/Phinx/Db/Adapter/PdoAdapter.php | 1029 +++++ .../src/Phinx/Db/Adapter/PostgresAdapter.php | 1675 +++++++ .../src/Phinx/Db/Adapter/ProxyAdapter.php | 129 + .../src/Phinx/Db/Adapter/SQLiteAdapter.php | 1953 +++++++++ .../src/Phinx/Db/Adapter/SqlServerAdapter.php | 1373 ++++++ .../Phinx/Db/Adapter/TablePrefixAdapter.php | 494 +++ .../Phinx/Db/Adapter/TimedOutputAdapter.php | 423 ++ .../UnsupportedColumnTypeException.php | 19 + .../src/Phinx/Db/Adapter/WrapperInterface.php | 39 + .../phinx/src/Phinx/Db/Plan/AlterTable.php | 72 + .../phinx/src/Phinx/Db/Plan/Intent.php | 55 + .../phinx/src/Phinx/Db/Plan/NewTable.php | 101 + .../phinx/src/Phinx/Db/Plan/Plan.php | 492 +++ .../Phinx/Db/Plan/Solver/ActionSplitter.php | 103 + vendor/robmorgan/phinx/src/Phinx/Db/Table.php | 721 +++ .../phinx/src/Phinx/Db/Table/Column.php | 801 ++++ .../phinx/src/Phinx/Db/Table/ForeignKey.php | 237 + .../phinx/src/Phinx/Db/Table/Index.php | 227 + .../phinx/src/Phinx/Db/Table/Table.php | 84 + .../src/Phinx/Db/Util/AlterInstructions.php | 122 + .../src/Phinx/Migration/AbstractMigration.php | 338 ++ .../Migration/AbstractTemplateCreation.php | 74 + .../src/Phinx/Migration/CreationInterface.php | 69 + .../IrreversibleMigrationException.php | 20 + .../phinx/src/Phinx/Migration/Manager.php | 1141 +++++ .../Phinx/Migration/Manager/Environment.php | 397 ++ .../Migration.change.template.php.dist | 24 + .../Migration.up_down.template.php.dist | 18 + .../Phinx/Migration/MigrationInterface.php | 269 ++ .../phinx/src/Phinx/Seed/AbstractSeed.php | 222 + .../src/Phinx/Seed/Seed.template.php.dist | 20 + .../phinx/src/Phinx/Seed/SeedInterface.php | 188 + .../phinx/src/Phinx/Util/Expression.php | 41 + .../phinx/src/Phinx/Util/Literal.php | 41 + .../robmorgan/phinx/src/Phinx/Util/Util.php | 361 ++ .../phinx/src/Phinx/Wrapper/TextWrapper.php | 249 ++ .../phinx/src/composer_autoloader.php | 23 + .../symfony/config/Builder/ClassBuilder.php | 171 + .../config/Builder/ConfigBuilderGenerator.php | 581 +++ .../ConfigBuilderGeneratorInterface.php | 27 + .../config/Builder/ConfigBuilderInterface.php | 30 + vendor/symfony/config/Builder/Method.php | 34 + vendor/symfony/config/Builder/Property.php | 86 + vendor/symfony/config/CHANGELOG.md | 134 + vendor/symfony/config/ConfigCache.php | 60 + vendor/symfony/config/ConfigCacheFactory.php | 47 + .../config/ConfigCacheFactoryInterface.php | 30 + .../symfony/config/ConfigCacheInterface.php | 45 + .../symfony/config/Definition/ArrayNode.php | 402 ++ vendor/symfony/config/Definition/BaseNode.php | 510 +++ .../symfony/config/Definition/BooleanNode.php | 55 + .../Builder/ArrayNodeDefinition.php | 525 +++ .../Builder/BooleanNodeDefinition.php | 51 + .../Builder/BuilderAwareInterface.php | 25 + .../Definition/Builder/EnumNodeDefinition.php | 54 + .../config/Definition/Builder/ExprBuilder.php | 242 + .../Builder/FloatNodeDefinition.php | 30 + .../Builder/IntegerNodeDefinition.php | 30 + .../Definition/Builder/MergeBuilder.php | 61 + .../config/Definition/Builder/NodeBuilder.php | 201 + .../Definition/Builder/NodeDefinition.php | 342 ++ .../Builder/NodeParentInterface.php | 21 + .../Builder/NormalizationBuilder.php | 60 + .../Builder/NumericNodeDefinition.php | 69 + .../Builder/ParentNodeDefinitionInterface.php | 49 + .../Builder/ScalarNodeDefinition.php | 30 + .../config/Definition/Builder/TreeBuilder.php | 61 + .../Definition/Builder/ValidationBuilder.php | 44 + .../Builder/VariableNodeDefinition.php | 67 + .../Definition/ConfigurationInterface.php | 29 + .../Definition/Dumper/XmlReferenceDumper.php | 304 ++ .../Definition/Dumper/YamlReferenceDumper.php | 251 ++ vendor/symfony/config/Definition/EnumNode.php | 65 + .../Exception/DuplicateKeyException.php | 22 + .../config/Definition/Exception/Exception.php | 21 + .../Exception/ForbiddenOverwriteException.php | 22 + .../InvalidConfigurationException.php | 47 + .../Exception/InvalidDefinitionException.php | 21 + .../Exception/InvalidTypeException.php | 21 + .../Exception/UnsetKeyException.php | 22 + .../symfony/config/Definition/FloatNode.php | 51 + .../symfony/config/Definition/IntegerNode.php | 46 + .../config/Definition/NodeInterface.php | 77 + .../symfony/config/Definition/NumericNode.php | 64 + .../symfony/config/Definition/Processor.php | 91 + .../Definition/PrototypeNodeInterface.php | 25 + .../config/Definition/PrototypedArrayNode.php | 344 ++ .../symfony/config/Definition/ScalarNode.php | 67 + .../config/Definition/VariableNode.php | 138 + ...LoaderImportCircularReferenceException.php | 27 + .../FileLocatorFileNotFoundException.php | 34 + .../config/Exception/LoaderLoadException.php | 104 + vendor/symfony/config/FileLocator.php | 94 + .../symfony/config/FileLocatorInterface.php | 34 + vendor/symfony/config/LICENSE | 19 + .../config/Loader/DelegatingLoader.php | 50 + vendor/symfony/config/Loader/FileLoader.php | 178 + .../symfony/config/Loader/GlobFileLoader.php | 36 + vendor/symfony/config/Loader/Loader.php | 76 + .../symfony/config/Loader/LoaderInterface.php | 50 + .../symfony/config/Loader/LoaderResolver.php | 68 + .../config/Loader/LoaderResolverInterface.php | 27 + .../config/Loader/ParamConfigurator.php | 32 + vendor/symfony/config/README.md | 15 + .../Resource/ClassExistenceResource.php | 232 + .../config/Resource/ComposerResource.php | 67 + .../config/Resource/DirectoryResource.php | 99 + .../config/Resource/FileExistenceResource.php | 56 + .../symfony/config/Resource/FileResource.php | 63 + .../symfony/config/Resource/GlobResource.php | 243 ++ .../Resource/ReflectionClassResource.php | 257 ++ .../config/Resource/ResourceInterface.php | 31 + .../Resource/SelfCheckingResourceChecker.php | 46 + .../SelfCheckingResourceInterface.php | 28 + .../config/ResourceCheckerConfigCache.php | 182 + .../ResourceCheckerConfigCacheFactory.php | 44 + .../config/ResourceCheckerInterface.php | 45 + .../Util/Exception/InvalidXmlException.php | 22 + .../Util/Exception/XmlParsingException.php | 21 + vendor/symfony/config/Util/XmlUtils.php | 269 ++ vendor/symfony/config/composer.json | 45 + vendor/symfony/filesystem/CHANGELOG.md | 82 + .../Exception/ExceptionInterface.php | 21 + .../Exception/FileNotFoundException.php | 34 + .../filesystem/Exception/IOException.php | 39 + .../Exception/IOExceptionInterface.php | 25 + .../Exception/InvalidArgumentException.php | 19 + .../filesystem/Exception/RuntimeException.php | 19 + vendor/symfony/filesystem/Filesystem.php | 737 ++++ vendor/symfony/filesystem/LICENSE | 19 + vendor/symfony/filesystem/Path.php | 819 ++++ vendor/symfony/filesystem/README.md | 13 + vendor/symfony/filesystem/composer.json | 30 + vendor/symfony/polyfill-php81/LICENSE | 19 + vendor/symfony/polyfill-php81/Php81.php | 37 + vendor/symfony/polyfill-php81/README.md | 18 + .../Resources/stubs/CURLStringFile.php | 51 + .../Resources/stubs/ReturnTypeWillChange.php | 20 + vendor/symfony/polyfill-php81/bootstrap.php | 28 + vendor/symfony/polyfill-php81/composer.json | 36 + vendor/webman-tech/debugbar/.gitignore | 6 - vendor/webman-tech/debugbar/README.md | 23 - vendor/webman-tech/debugbar/composer.json | 23 - .../debugbar/src/Bootstrap/LaravelQuery.php | 43 - .../src/Bootstrap/LaravelRedisExec.php | 44 - .../DataCollector/LaravelQueryCollector.php | 231 - .../DataCollector/LaravelRedisCollector.php | 135 - .../src/DataCollector/MemoryCollector.php | 23 - .../src/DataCollector/PhpInfoCollector.php | 18 - .../DataCollector/RequestDataCollector.php | 60 - .../src/DataCollector/RouteCollector.php | 66 - .../src/DataCollector/SessionCollector.php | 56 - .../src/DataCollector/ThinkPdoCollector.php | 62 - .../src/DataCollector/TimeDataCollector.php | 24 - .../src/DataCollector/WebmanCollector.php | 49 - vendor/webman-tech/debugbar/src/DebugBar.php | 58 - .../webman-tech/debugbar/src/Ext/HttpExt.php | 76 - .../debugbar/src/Helper/ArrayHelper.php | 39 - .../debugbar/src/Helper/StringHelper.php | 57 - vendor/webman-tech/debugbar/src/Install.php | 74 - .../Laravel/DataCollector/QueryCollector.php | 593 --- .../Laravel/DataFormatter/QueryFormatter.php | 90 - .../debugbar/src/Laravel/README.md | 2 - .../Laravel/Resources/sqlqueries/widget.js | 274 -- .../src/Middleware/DebugBarMiddleware.php | 32 - .../src/Resources/webman-debugbar.css | 796 ---- .../src/Storage/AutoCleanFileStorage.php | 76 - .../debugbar/src/Storage/FileStorage.php | 54 - .../debugbar/src/Traits/DebugBarOverwrite.php | 50 - .../debugbar/src/WebmanDebugBar.php | 478 -- .../debugbar/src/WebmanHttpDriver.php | 75 - .../debugbar/src/WebmanJavascriptRenderer.php | 73 - .../plugin/webman-tech/debugbar/app.php | 13 - .../plugin/webman-tech/debugbar/bootstrap.php | 9 - .../webman-tech/debugbar/middleware.php | 9 - .../plugin/webman-tech/debugbar/route.php | 5 - vendor/workerman/workerman/Protocols/Dns.php | 2 +- 789 files changed, 135417 insertions(+), 18510 deletions(-) create mode 100644 app/view/domain.html delete mode 100644 config/plugin/webman-tech/debugbar/app.php delete mode 100644 config/plugin/webman-tech/debugbar/bootstrap.php delete mode 100644 config/plugin/webman-tech/debugbar/middleware.php delete mode 100644 config/plugin/webman-tech/debugbar/route.php create mode 100644 database/migrations/20240204114015_my_new_migration.php create mode 100644 phinx.php create mode 100755 vendor/bin/phinx create mode 100755 vendor/bin/phinx.bat create mode 100644 vendor/brick/math/CHANGELOG.md create mode 100644 vendor/brick/math/LICENSE create mode 100644 vendor/brick/math/composer.json create mode 100644 vendor/brick/math/src/BigDecimal.php create mode 100644 vendor/brick/math/src/BigInteger.php create mode 100644 vendor/brick/math/src/BigNumber.php create mode 100644 vendor/brick/math/src/BigRational.php create mode 100644 vendor/brick/math/src/Exception/DivisionByZeroException.php create mode 100644 vendor/brick/math/src/Exception/IntegerOverflowException.php create mode 100644 vendor/brick/math/src/Exception/MathException.php create mode 100644 vendor/brick/math/src/Exception/NegativeNumberException.php create mode 100644 vendor/brick/math/src/Exception/NumberFormatException.php create mode 100644 vendor/brick/math/src/Exception/RoundingNecessaryException.php create mode 100644 vendor/brick/math/src/Internal/Calculator.php create mode 100644 vendor/brick/math/src/Internal/Calculator/BcMathCalculator.php create mode 100644 vendor/brick/math/src/Internal/Calculator/GmpCalculator.php create mode 100644 vendor/brick/math/src/Internal/Calculator/NativeCalculator.php create mode 100644 vendor/brick/math/src/RoundingMode.php create mode 100644 vendor/cakephp/core/App.php create mode 100644 vendor/cakephp/core/BasePlugin.php create mode 100644 vendor/cakephp/core/ClassLoader.php create mode 100644 vendor/cakephp/core/Configure.php create mode 100644 vendor/cakephp/core/Configure/ConfigEngineInterface.php create mode 100644 vendor/cakephp/core/Configure/Engine/IniConfig.php create mode 100644 vendor/cakephp/core/Configure/Engine/JsonConfig.php create mode 100644 vendor/cakephp/core/Configure/Engine/PhpConfig.php create mode 100644 vendor/cakephp/core/Configure/FileConfigTrait.php create mode 100644 vendor/cakephp/core/ConsoleApplicationInterface.php create mode 100644 vendor/cakephp/core/Container.php create mode 100644 vendor/cakephp/core/ContainerApplicationInterface.php create mode 100644 vendor/cakephp/core/ContainerInterface.php create mode 100644 vendor/cakephp/core/ConventionsTrait.php create mode 100644 vendor/cakephp/core/Exception/CakeException.php create mode 100644 vendor/cakephp/core/Exception/Exception.php create mode 100644 vendor/cakephp/core/Exception/MissingPluginException.php create mode 100644 vendor/cakephp/core/HttpApplicationInterface.php create mode 100644 vendor/cakephp/core/InstanceConfigTrait.php create mode 100644 vendor/cakephp/core/LICENSE.txt create mode 100644 vendor/cakephp/core/ObjectRegistry.php create mode 100644 vendor/cakephp/core/Plugin.php create mode 100644 vendor/cakephp/core/PluginApplicationInterface.php create mode 100644 vendor/cakephp/core/PluginCollection.php create mode 100644 vendor/cakephp/core/PluginInterface.php create mode 100644 vendor/cakephp/core/README.md create mode 100644 vendor/cakephp/core/Retry/CommandRetry.php create mode 100644 vendor/cakephp/core/Retry/RetryStrategyInterface.php create mode 100644 vendor/cakephp/core/ServiceConfig.php create mode 100644 vendor/cakephp/core/ServiceProvider.php create mode 100644 vendor/cakephp/core/StaticConfigTrait.php create mode 100644 vendor/cakephp/core/TestSuite/ContainerStubTrait.php create mode 100644 vendor/cakephp/core/composer.json create mode 100644 vendor/cakephp/core/functions.php create mode 100644 vendor/cakephp/core/functions_global.php create mode 100644 vendor/cakephp/database/Connection.php create mode 100644 vendor/cakephp/database/ConstraintsInterface.php create mode 100644 vendor/cakephp/database/Driver.php create mode 100644 vendor/cakephp/database/Driver/Mysql.php create mode 100644 vendor/cakephp/database/Driver/Postgres.php create mode 100644 vendor/cakephp/database/Driver/SqlDialectTrait.php create mode 100644 vendor/cakephp/database/Driver/Sqlite.php create mode 100644 vendor/cakephp/database/Driver/Sqlserver.php create mode 100644 vendor/cakephp/database/Driver/TupleComparisonTranslatorTrait.php create mode 100644 vendor/cakephp/database/DriverInterface.php create mode 100644 vendor/cakephp/database/Exception.php create mode 100644 vendor/cakephp/database/Exception/DatabaseException.php create mode 100644 vendor/cakephp/database/Exception/MissingConnectionException.php create mode 100644 vendor/cakephp/database/Exception/MissingDriverException.php create mode 100644 vendor/cakephp/database/Exception/MissingExtensionException.php create mode 100644 vendor/cakephp/database/Exception/NestedTransactionRollbackException.php create mode 100644 vendor/cakephp/database/Expression/AggregateExpression.php create mode 100644 vendor/cakephp/database/Expression/BetweenExpression.php create mode 100644 vendor/cakephp/database/Expression/CaseExpression.php create mode 100644 vendor/cakephp/database/Expression/CaseExpressionTrait.php create mode 100644 vendor/cakephp/database/Expression/CaseStatementExpression.php create mode 100644 vendor/cakephp/database/Expression/CommonTableExpression.php create mode 100644 vendor/cakephp/database/Expression/Comparison.php create mode 100644 vendor/cakephp/database/Expression/ComparisonExpression.php create mode 100644 vendor/cakephp/database/Expression/FieldInterface.php create mode 100644 vendor/cakephp/database/Expression/FieldTrait.php create mode 100644 vendor/cakephp/database/Expression/FunctionExpression.php create mode 100644 vendor/cakephp/database/Expression/IdentifierExpression.php create mode 100644 vendor/cakephp/database/Expression/OrderByExpression.php create mode 100644 vendor/cakephp/database/Expression/OrderClauseExpression.php create mode 100644 vendor/cakephp/database/Expression/QueryExpression.php create mode 100644 vendor/cakephp/database/Expression/StringExpression.php create mode 100644 vendor/cakephp/database/Expression/TupleComparison.php create mode 100644 vendor/cakephp/database/Expression/UnaryExpression.php create mode 100644 vendor/cakephp/database/Expression/ValuesExpression.php create mode 100644 vendor/cakephp/database/Expression/WhenThenExpression.php create mode 100644 vendor/cakephp/database/Expression/WindowExpression.php create mode 100644 vendor/cakephp/database/Expression/WindowInterface.php create mode 100644 vendor/cakephp/database/ExpressionInterface.php create mode 100644 vendor/cakephp/database/FieldTypeConverter.php create mode 100644 vendor/cakephp/database/FunctionsBuilder.php create mode 100644 vendor/cakephp/database/IdentifierQuoter.php create mode 100644 vendor/cakephp/database/LICENSE.txt create mode 100644 vendor/cakephp/database/Log/LoggedQuery.php create mode 100644 vendor/cakephp/database/Log/LoggingStatement.php create mode 100644 vendor/cakephp/database/Log/QueryLogger.php create mode 100644 vendor/cakephp/database/PostgresCompiler.php create mode 100644 vendor/cakephp/database/Query.php create mode 100644 vendor/cakephp/database/Query/DeleteQuery.php create mode 100644 vendor/cakephp/database/Query/InsertQuery.php create mode 100644 vendor/cakephp/database/Query/SelectQuery.php create mode 100644 vendor/cakephp/database/Query/UpdateQuery.php create mode 100644 vendor/cakephp/database/QueryCompiler.php create mode 100644 vendor/cakephp/database/README.md create mode 100644 vendor/cakephp/database/Retry/ErrorCodeWaitStrategy.php create mode 100644 vendor/cakephp/database/Retry/ReconnectStrategy.php create mode 100644 vendor/cakephp/database/Schema/BaseSchema.php create mode 100644 vendor/cakephp/database/Schema/CachedCollection.php create mode 100644 vendor/cakephp/database/Schema/Collection.php create mode 100644 vendor/cakephp/database/Schema/CollectionInterface.php create mode 100644 vendor/cakephp/database/Schema/MysqlSchema.php create mode 100644 vendor/cakephp/database/Schema/MysqlSchemaDialect.php create mode 100644 vendor/cakephp/database/Schema/PostgresSchema.php create mode 100644 vendor/cakephp/database/Schema/PostgresSchemaDialect.php create mode 100644 vendor/cakephp/database/Schema/SchemaDialect.php create mode 100644 vendor/cakephp/database/Schema/SqlGeneratorInterface.php create mode 100644 vendor/cakephp/database/Schema/SqliteSchema.php create mode 100644 vendor/cakephp/database/Schema/SqliteSchemaDialect.php create mode 100644 vendor/cakephp/database/Schema/SqlserverSchema.php create mode 100644 vendor/cakephp/database/Schema/SqlserverSchemaDialect.php create mode 100644 vendor/cakephp/database/Schema/TableSchema.php create mode 100644 vendor/cakephp/database/Schema/TableSchemaAwareInterface.php create mode 100644 vendor/cakephp/database/Schema/TableSchemaInterface.php create mode 100644 vendor/cakephp/database/SchemaCache.php create mode 100644 vendor/cakephp/database/SqlDialectTrait.php create mode 100644 vendor/cakephp/database/SqliteCompiler.php create mode 100644 vendor/cakephp/database/SqlserverCompiler.php create mode 100644 vendor/cakephp/database/Statement/BufferResultsTrait.php create mode 100644 vendor/cakephp/database/Statement/BufferedStatement.php create mode 100644 vendor/cakephp/database/Statement/CallbackStatement.php create mode 100644 vendor/cakephp/database/Statement/MysqlStatement.php create mode 100644 vendor/cakephp/database/Statement/PDOStatement.php create mode 100644 vendor/cakephp/database/Statement/SqliteStatement.php create mode 100644 vendor/cakephp/database/Statement/SqlserverStatement.php create mode 100644 vendor/cakephp/database/Statement/StatementDecorator.php create mode 100644 vendor/cakephp/database/StatementInterface.php create mode 100644 vendor/cakephp/database/Type.php create mode 100644 vendor/cakephp/database/Type/BaseType.php create mode 100644 vendor/cakephp/database/Type/BatchCastingInterface.php create mode 100644 vendor/cakephp/database/Type/BinaryType.php create mode 100644 vendor/cakephp/database/Type/BinaryUuidType.php create mode 100644 vendor/cakephp/database/Type/BoolType.php create mode 100644 vendor/cakephp/database/Type/ColumnSchemaAwareInterface.php create mode 100644 vendor/cakephp/database/Type/DateTimeFractionalType.php create mode 100644 vendor/cakephp/database/Type/DateTimeTimezoneType.php create mode 100644 vendor/cakephp/database/Type/DateTimeType.php create mode 100644 vendor/cakephp/database/Type/DateType.php create mode 100644 vendor/cakephp/database/Type/DecimalType.php create mode 100644 vendor/cakephp/database/Type/ExpressionTypeCasterTrait.php create mode 100644 vendor/cakephp/database/Type/ExpressionTypeInterface.php create mode 100644 vendor/cakephp/database/Type/FloatType.php create mode 100644 vendor/cakephp/database/Type/IntegerType.php create mode 100644 vendor/cakephp/database/Type/JsonType.php create mode 100644 vendor/cakephp/database/Type/OptionalConvertInterface.php create mode 100644 vendor/cakephp/database/Type/StringType.php create mode 100644 vendor/cakephp/database/Type/TimeType.php create mode 100644 vendor/cakephp/database/Type/UuidType.php create mode 100644 vendor/cakephp/database/TypeConverterTrait.php create mode 100644 vendor/cakephp/database/TypeFactory.php create mode 100644 vendor/cakephp/database/TypeInterface.php create mode 100644 vendor/cakephp/database/TypeMap.php create mode 100644 vendor/cakephp/database/TypeMapTrait.php create mode 100644 vendor/cakephp/database/TypedResultInterface.php create mode 100644 vendor/cakephp/database/TypedResultTrait.php create mode 100644 vendor/cakephp/database/ValueBinder.php create mode 100644 vendor/cakephp/database/composer.json create mode 100644 vendor/cakephp/datasource/ConnectionInterface.php create mode 100644 vendor/cakephp/datasource/ConnectionManager.php create mode 100644 vendor/cakephp/datasource/ConnectionRegistry.php create mode 100644 vendor/cakephp/datasource/EntityInterface.php create mode 100644 vendor/cakephp/datasource/EntityTrait.php create mode 100644 vendor/cakephp/datasource/Exception/InvalidPrimaryKeyException.php create mode 100644 vendor/cakephp/datasource/Exception/MissingDatasourceConfigException.php create mode 100644 vendor/cakephp/datasource/Exception/MissingDatasourceException.php create mode 100644 vendor/cakephp/datasource/Exception/MissingModelException.php create mode 100644 vendor/cakephp/datasource/Exception/PageOutOfBoundsException.php create mode 100644 vendor/cakephp/datasource/Exception/RecordNotFoundException.php create mode 100644 vendor/cakephp/datasource/FactoryLocator.php create mode 100644 vendor/cakephp/datasource/FixtureInterface.php create mode 100644 vendor/cakephp/datasource/InvalidPropertyInterface.php create mode 100644 vendor/cakephp/datasource/LICENSE.txt create mode 100644 vendor/cakephp/datasource/Locator/AbstractLocator.php create mode 100644 vendor/cakephp/datasource/Locator/LocatorInterface.php create mode 100644 vendor/cakephp/datasource/ModelAwareTrait.php create mode 100644 vendor/cakephp/datasource/Paginator.php create mode 100644 vendor/cakephp/datasource/PaginatorInterface.php create mode 100644 vendor/cakephp/datasource/Paging/Exception/PageOutOfBoundsException.php create mode 100644 vendor/cakephp/datasource/Paging/NumericPaginator.php create mode 100644 vendor/cakephp/datasource/Paging/PaginatorInterface.php create mode 100644 vendor/cakephp/datasource/Paging/SimplePaginator.php create mode 100644 vendor/cakephp/datasource/QueryCacher.php create mode 100644 vendor/cakephp/datasource/QueryInterface.php create mode 100644 vendor/cakephp/datasource/QueryTrait.php create mode 100644 vendor/cakephp/datasource/README.md create mode 100644 vendor/cakephp/datasource/RepositoryInterface.php create mode 100644 vendor/cakephp/datasource/ResultSetDecorator.php create mode 100644 vendor/cakephp/datasource/ResultSetInterface.php create mode 100644 vendor/cakephp/datasource/RuleInvoker.php create mode 100644 vendor/cakephp/datasource/RulesAwareTrait.php create mode 100644 vendor/cakephp/datasource/RulesChecker.php create mode 100644 vendor/cakephp/datasource/SchemaInterface.php create mode 100644 vendor/cakephp/datasource/SimplePaginator.php create mode 100644 vendor/cakephp/datasource/composer.json create mode 100644 vendor/cakephp/utility/CookieCryptTrait.php create mode 100644 vendor/cakephp/utility/Crypto/OpenSsl.php create mode 100644 vendor/cakephp/utility/Exception/XmlException.php create mode 100644 vendor/cakephp/utility/Hash.php create mode 100644 vendor/cakephp/utility/Inflector.php create mode 100644 vendor/cakephp/utility/LICENSE.txt create mode 100644 vendor/cakephp/utility/MergeVariablesTrait.php create mode 100644 vendor/cakephp/utility/README.md create mode 100644 vendor/cakephp/utility/Security.php create mode 100644 vendor/cakephp/utility/Text.php create mode 100644 vendor/cakephp/utility/Xml.php create mode 100644 vendor/cakephp/utility/bootstrap.php create mode 100644 vendor/cakephp/utility/composer.json create mode 100755 vendor/illuminate/database/Capsule/Manager.php create mode 100644 vendor/illuminate/database/ClassMorphViolationException.php create mode 100644 vendor/illuminate/database/Concerns/BuildsQueries.php create mode 100644 vendor/illuminate/database/Concerns/CompilesJsonPaths.php create mode 100644 vendor/illuminate/database/Concerns/ExplainsQueries.php create mode 100644 vendor/illuminate/database/Concerns/ManagesTransactions.php create mode 100644 vendor/illuminate/database/Concerns/ParsesSearchPath.php create mode 100644 vendor/illuminate/database/ConfigurationUrlParser.php create mode 100755 vendor/illuminate/database/Connection.php create mode 100755 vendor/illuminate/database/ConnectionInterface.php create mode 100755 vendor/illuminate/database/ConnectionResolver.php create mode 100755 vendor/illuminate/database/ConnectionResolverInterface.php create mode 100755 vendor/illuminate/database/Connectors/ConnectionFactory.php create mode 100755 vendor/illuminate/database/Connectors/Connector.php create mode 100755 vendor/illuminate/database/Connectors/ConnectorInterface.php create mode 100755 vendor/illuminate/database/Connectors/MySqlConnector.php create mode 100755 vendor/illuminate/database/Connectors/PostgresConnector.php create mode 100755 vendor/illuminate/database/Connectors/SQLiteConnector.php create mode 100755 vendor/illuminate/database/Connectors/SqlServerConnector.php create mode 100644 vendor/illuminate/database/Console/DatabaseInspectionCommand.php create mode 100644 vendor/illuminate/database/Console/DbCommand.php create mode 100644 vendor/illuminate/database/Console/DumpCommand.php create mode 100644 vendor/illuminate/database/Console/Factories/FactoryMakeCommand.php create mode 100644 vendor/illuminate/database/Console/Factories/stubs/factory.stub create mode 100755 vendor/illuminate/database/Console/Migrations/BaseCommand.php create mode 100644 vendor/illuminate/database/Console/Migrations/FreshCommand.php create mode 100755 vendor/illuminate/database/Console/Migrations/InstallCommand.php create mode 100755 vendor/illuminate/database/Console/Migrations/MigrateCommand.php create mode 100644 vendor/illuminate/database/Console/Migrations/MigrateMakeCommand.php create mode 100755 vendor/illuminate/database/Console/Migrations/RefreshCommand.php create mode 100755 vendor/illuminate/database/Console/Migrations/ResetCommand.php create mode 100755 vendor/illuminate/database/Console/Migrations/RollbackCommand.php create mode 100644 vendor/illuminate/database/Console/Migrations/StatusCommand.php create mode 100644 vendor/illuminate/database/Console/Migrations/TableGuesser.php create mode 100644 vendor/illuminate/database/Console/MonitorCommand.php create mode 100644 vendor/illuminate/database/Console/PruneCommand.php create mode 100644 vendor/illuminate/database/Console/Seeds/SeedCommand.php create mode 100644 vendor/illuminate/database/Console/Seeds/SeederMakeCommand.php create mode 100644 vendor/illuminate/database/Console/Seeds/WithoutModelEvents.php create mode 100644 vendor/illuminate/database/Console/Seeds/stubs/seeder.stub create mode 100644 vendor/illuminate/database/Console/ShowCommand.php create mode 100644 vendor/illuminate/database/Console/TableCommand.php create mode 100644 vendor/illuminate/database/Console/WipeCommand.php create mode 100644 vendor/illuminate/database/DBAL/TimestampType.php create mode 100755 vendor/illuminate/database/DatabaseManager.php create mode 100755 vendor/illuminate/database/DatabaseServiceProvider.php create mode 100755 vendor/illuminate/database/DatabaseTransactionRecord.php create mode 100755 vendor/illuminate/database/DatabaseTransactionsManager.php create mode 100644 vendor/illuminate/database/DeadlockException.php create mode 100644 vendor/illuminate/database/DetectsConcurrencyErrors.php create mode 100644 vendor/illuminate/database/DetectsLostConnections.php create mode 100644 vendor/illuminate/database/Eloquent/BroadcastableModelEventOccurred.php create mode 100644 vendor/illuminate/database/Eloquent/BroadcastsEvents.php create mode 100755 vendor/illuminate/database/Eloquent/Builder.php create mode 100644 vendor/illuminate/database/Eloquent/Casts/ArrayObject.php create mode 100644 vendor/illuminate/database/Eloquent/Casts/AsArrayObject.php create mode 100644 vendor/illuminate/database/Eloquent/Casts/AsCollection.php create mode 100644 vendor/illuminate/database/Eloquent/Casts/AsEncryptedArrayObject.php create mode 100644 vendor/illuminate/database/Eloquent/Casts/AsEncryptedCollection.php create mode 100644 vendor/illuminate/database/Eloquent/Casts/AsEnumArrayObject.php create mode 100644 vendor/illuminate/database/Eloquent/Casts/AsEnumCollection.php create mode 100644 vendor/illuminate/database/Eloquent/Casts/AsStringable.php create mode 100644 vendor/illuminate/database/Eloquent/Casts/Attribute.php create mode 100755 vendor/illuminate/database/Eloquent/Collection.php create mode 100644 vendor/illuminate/database/Eloquent/Concerns/GuardsAttributes.php create mode 100644 vendor/illuminate/database/Eloquent/Concerns/HasAttributes.php create mode 100644 vendor/illuminate/database/Eloquent/Concerns/HasEvents.php create mode 100644 vendor/illuminate/database/Eloquent/Concerns/HasGlobalScopes.php create mode 100644 vendor/illuminate/database/Eloquent/Concerns/HasRelationships.php create mode 100644 vendor/illuminate/database/Eloquent/Concerns/HasTimestamps.php create mode 100644 vendor/illuminate/database/Eloquent/Concerns/HasUlids.php create mode 100644 vendor/illuminate/database/Eloquent/Concerns/HasUuids.php create mode 100644 vendor/illuminate/database/Eloquent/Concerns/HidesAttributes.php create mode 100644 vendor/illuminate/database/Eloquent/Concerns/QueriesRelationships.php create mode 100644 vendor/illuminate/database/Eloquent/Factories/BelongsToManyRelationship.php create mode 100644 vendor/illuminate/database/Eloquent/Factories/BelongsToRelationship.php create mode 100644 vendor/illuminate/database/Eloquent/Factories/CrossJoinSequence.php create mode 100644 vendor/illuminate/database/Eloquent/Factories/Factory.php create mode 100644 vendor/illuminate/database/Eloquent/Factories/HasFactory.php create mode 100644 vendor/illuminate/database/Eloquent/Factories/Relationship.php create mode 100644 vendor/illuminate/database/Eloquent/Factories/Sequence.php create mode 100644 vendor/illuminate/database/Eloquent/HigherOrderBuilderProxy.php create mode 100644 vendor/illuminate/database/Eloquent/InvalidCastException.php create mode 100644 vendor/illuminate/database/Eloquent/JsonEncodingException.php create mode 100755 vendor/illuminate/database/Eloquent/MassAssignmentException.php create mode 100644 vendor/illuminate/database/Eloquent/MassPrunable.php create mode 100755 vendor/illuminate/database/Eloquent/MissingAttributeException.php create mode 100644 vendor/illuminate/database/Eloquent/Model.php create mode 100755 vendor/illuminate/database/Eloquent/ModelNotFoundException.php create mode 100644 vendor/illuminate/database/Eloquent/PendingHasThroughRelationship.php create mode 100644 vendor/illuminate/database/Eloquent/Prunable.php create mode 100644 vendor/illuminate/database/Eloquent/QueueEntityResolver.php create mode 100755 vendor/illuminate/database/Eloquent/RelationNotFoundException.php create mode 100755 vendor/illuminate/database/Eloquent/Relations/BelongsTo.php create mode 100755 vendor/illuminate/database/Eloquent/Relations/BelongsToMany.php create mode 100644 vendor/illuminate/database/Eloquent/Relations/Concerns/AsPivot.php create mode 100644 vendor/illuminate/database/Eloquent/Relations/Concerns/CanBeOneOfMany.php create mode 100644 vendor/illuminate/database/Eloquent/Relations/Concerns/ComparesRelatedModels.php create mode 100644 vendor/illuminate/database/Eloquent/Relations/Concerns/InteractsWithDictionary.php create mode 100644 vendor/illuminate/database/Eloquent/Relations/Concerns/InteractsWithPivotTable.php create mode 100644 vendor/illuminate/database/Eloquent/Relations/Concerns/SupportsDefaultModels.php create mode 100755 vendor/illuminate/database/Eloquent/Relations/HasMany.php create mode 100644 vendor/illuminate/database/Eloquent/Relations/HasManyThrough.php create mode 100755 vendor/illuminate/database/Eloquent/Relations/HasOne.php create mode 100755 vendor/illuminate/database/Eloquent/Relations/HasOneOrMany.php create mode 100644 vendor/illuminate/database/Eloquent/Relations/HasOneThrough.php create mode 100755 vendor/illuminate/database/Eloquent/Relations/MorphMany.php create mode 100755 vendor/illuminate/database/Eloquent/Relations/MorphOne.php create mode 100755 vendor/illuminate/database/Eloquent/Relations/MorphOneOrMany.php create mode 100644 vendor/illuminate/database/Eloquent/Relations/MorphPivot.php create mode 100644 vendor/illuminate/database/Eloquent/Relations/MorphTo.php create mode 100644 vendor/illuminate/database/Eloquent/Relations/MorphToMany.php create mode 100755 vendor/illuminate/database/Eloquent/Relations/Pivot.php create mode 100755 vendor/illuminate/database/Eloquent/Relations/Relation.php create mode 100644 vendor/illuminate/database/Eloquent/Scope.php create mode 100644 vendor/illuminate/database/Eloquent/SoftDeletes.php create mode 100644 vendor/illuminate/database/Eloquent/SoftDeletingScope.php create mode 100644 vendor/illuminate/database/Events/ConnectionEstablished.php create mode 100644 vendor/illuminate/database/Events/ConnectionEvent.php create mode 100644 vendor/illuminate/database/Events/DatabaseBusy.php create mode 100644 vendor/illuminate/database/Events/DatabaseRefreshed.php create mode 100644 vendor/illuminate/database/Events/MigrationEnded.php create mode 100644 vendor/illuminate/database/Events/MigrationEvent.php create mode 100644 vendor/illuminate/database/Events/MigrationStarted.php create mode 100644 vendor/illuminate/database/Events/MigrationsEnded.php create mode 100644 vendor/illuminate/database/Events/MigrationsEvent.php create mode 100644 vendor/illuminate/database/Events/MigrationsStarted.php create mode 100644 vendor/illuminate/database/Events/ModelsPruned.php create mode 100644 vendor/illuminate/database/Events/NoPendingMigrations.php create mode 100644 vendor/illuminate/database/Events/QueryExecuted.php create mode 100644 vendor/illuminate/database/Events/SchemaDumped.php create mode 100644 vendor/illuminate/database/Events/SchemaLoaded.php create mode 100644 vendor/illuminate/database/Events/StatementPrepared.php create mode 100644 vendor/illuminate/database/Events/TransactionBeginning.php create mode 100644 vendor/illuminate/database/Events/TransactionCommitted.php create mode 100644 vendor/illuminate/database/Events/TransactionCommitting.php create mode 100644 vendor/illuminate/database/Events/TransactionRolledBack.php create mode 100755 vendor/illuminate/database/Grammar.php create mode 100644 vendor/illuminate/database/LICENSE.md create mode 100644 vendor/illuminate/database/LazyLoadingViolationException.php create mode 100644 vendor/illuminate/database/LostConnectionException.php create mode 100755 vendor/illuminate/database/MigrationServiceProvider.php create mode 100755 vendor/illuminate/database/Migrations/DatabaseMigrationRepository.php create mode 100755 vendor/illuminate/database/Migrations/Migration.php create mode 100755 vendor/illuminate/database/Migrations/MigrationCreator.php create mode 100755 vendor/illuminate/database/Migrations/MigrationRepositoryInterface.php create mode 100755 vendor/illuminate/database/Migrations/Migrator.php create mode 100755 vendor/illuminate/database/Migrations/stubs/migration.create.stub create mode 100755 vendor/illuminate/database/Migrations/stubs/migration.stub create mode 100755 vendor/illuminate/database/Migrations/stubs/migration.update.stub create mode 100644 vendor/illuminate/database/MultipleColumnsSelectedException.php create mode 100755 vendor/illuminate/database/MultipleRecordsFoundException.php create mode 100755 vendor/illuminate/database/MySqlConnection.php create mode 100644 vendor/illuminate/database/PDO/Concerns/ConnectsToDatabase.php create mode 100644 vendor/illuminate/database/PDO/Connection.php create mode 100644 vendor/illuminate/database/PDO/MySqlDriver.php create mode 100644 vendor/illuminate/database/PDO/PostgresDriver.php create mode 100644 vendor/illuminate/database/PDO/SQLiteDriver.php create mode 100644 vendor/illuminate/database/PDO/SqlServerConnection.php create mode 100644 vendor/illuminate/database/PDO/SqlServerDriver.php create mode 100755 vendor/illuminate/database/PostgresConnection.php create mode 100755 vendor/illuminate/database/Query/Builder.php create mode 100755 vendor/illuminate/database/Query/Expression.php create mode 100755 vendor/illuminate/database/Query/Grammars/Grammar.php create mode 100755 vendor/illuminate/database/Query/Grammars/MySqlGrammar.php create mode 100755 vendor/illuminate/database/Query/Grammars/PostgresGrammar.php create mode 100755 vendor/illuminate/database/Query/Grammars/SQLiteGrammar.php create mode 100755 vendor/illuminate/database/Query/Grammars/SqlServerGrammar.php create mode 100755 vendor/illuminate/database/Query/IndexHint.php create mode 100755 vendor/illuminate/database/Query/JoinClause.php create mode 100644 vendor/illuminate/database/Query/Processors/MySqlProcessor.php create mode 100755 vendor/illuminate/database/Query/Processors/PostgresProcessor.php create mode 100755 vendor/illuminate/database/Query/Processors/Processor.php create mode 100644 vendor/illuminate/database/Query/Processors/SQLiteProcessor.php create mode 100755 vendor/illuminate/database/Query/Processors/SqlServerProcessor.php create mode 100644 vendor/illuminate/database/QueryException.php create mode 100755 vendor/illuminate/database/README.md create mode 100755 vendor/illuminate/database/RecordsNotFoundException.php create mode 100755 vendor/illuminate/database/SQLiteConnection.php create mode 100644 vendor/illuminate/database/SQLiteDatabaseDoesNotExistException.php create mode 100755 vendor/illuminate/database/Schema/Blueprint.php create mode 100755 vendor/illuminate/database/Schema/Builder.php create mode 100644 vendor/illuminate/database/Schema/ColumnDefinition.php create mode 100644 vendor/illuminate/database/Schema/ForeignIdColumnDefinition.php create mode 100644 vendor/illuminate/database/Schema/ForeignKeyDefinition.php create mode 100644 vendor/illuminate/database/Schema/Grammars/ChangeColumn.php create mode 100755 vendor/illuminate/database/Schema/Grammars/Grammar.php create mode 100755 vendor/illuminate/database/Schema/Grammars/MySqlGrammar.php create mode 100755 vendor/illuminate/database/Schema/Grammars/PostgresGrammar.php create mode 100644 vendor/illuminate/database/Schema/Grammars/RenameColumn.php create mode 100755 vendor/illuminate/database/Schema/Grammars/SQLiteGrammar.php create mode 100755 vendor/illuminate/database/Schema/Grammars/SqlServerGrammar.php create mode 100644 vendor/illuminate/database/Schema/IndexDefinition.php create mode 100755 vendor/illuminate/database/Schema/MySqlBuilder.php create mode 100644 vendor/illuminate/database/Schema/MySqlSchemaState.php create mode 100755 vendor/illuminate/database/Schema/PostgresBuilder.php create mode 100644 vendor/illuminate/database/Schema/PostgresSchemaState.php create mode 100644 vendor/illuminate/database/Schema/SQLiteBuilder.php create mode 100644 vendor/illuminate/database/Schema/SchemaState.php create mode 100644 vendor/illuminate/database/Schema/SqlServerBuilder.php create mode 100644 vendor/illuminate/database/Schema/SqliteSchemaState.php create mode 100755 vendor/illuminate/database/Seeder.php create mode 100755 vendor/illuminate/database/SqlServerConnection.php create mode 100644 vendor/illuminate/database/composer.json create mode 100644 vendor/illuminate/pagination/AbstractCursorPaginator.php create mode 100644 vendor/illuminate/pagination/AbstractPaginator.php create mode 100644 vendor/illuminate/pagination/Cursor.php create mode 100644 vendor/illuminate/pagination/CursorPaginator.php create mode 100644 vendor/illuminate/pagination/LICENSE.md create mode 100644 vendor/illuminate/pagination/LengthAwarePaginator.php create mode 100755 vendor/illuminate/pagination/PaginationServiceProvider.php create mode 100644 vendor/illuminate/pagination/PaginationState.php create mode 100644 vendor/illuminate/pagination/Paginator.php create mode 100644 vendor/illuminate/pagination/UrlWindow.php create mode 100755 vendor/illuminate/pagination/composer.json create mode 100644 vendor/illuminate/pagination/resources/views/bootstrap-4.blade.php create mode 100644 vendor/illuminate/pagination/resources/views/bootstrap-5.blade.php create mode 100644 vendor/illuminate/pagination/resources/views/default.blade.php create mode 100644 vendor/illuminate/pagination/resources/views/semantic-ui.blade.php create mode 100644 vendor/illuminate/pagination/resources/views/simple-bootstrap-4.blade.php create mode 100644 vendor/illuminate/pagination/resources/views/simple-bootstrap-5.blade.php create mode 100644 vendor/illuminate/pagination/resources/views/simple-default.blade.php create mode 100644 vendor/illuminate/pagination/resources/views/simple-tailwind.blade.php create mode 100644 vendor/illuminate/pagination/resources/views/tailwind.blade.php delete mode 100644 vendor/maximebf/debugbar/composer.json delete mode 100644 vendor/maximebf/debugbar/src/DebugBar/Bridge/CacheCacheCollector.php delete mode 100644 vendor/maximebf/debugbar/src/DebugBar/Bridge/DoctrineCollector.php delete mode 100644 vendor/maximebf/debugbar/src/DebugBar/Bridge/MonologCollector.php delete mode 100644 vendor/maximebf/debugbar/src/DebugBar/Bridge/NamespacedTwigProfileCollector.php delete mode 100644 vendor/maximebf/debugbar/src/DebugBar/Bridge/Propel2Collector.php delete mode 100644 vendor/maximebf/debugbar/src/DebugBar/Bridge/PropelCollector.php delete mode 100644 vendor/maximebf/debugbar/src/DebugBar/Bridge/SlimCollector.php delete mode 100644 vendor/maximebf/debugbar/src/DebugBar/Bridge/SwiftMailer/SwiftLogCollector.php delete mode 100644 vendor/maximebf/debugbar/src/DebugBar/Bridge/SwiftMailer/SwiftMailCollector.php delete mode 100644 vendor/maximebf/debugbar/src/DebugBar/Bridge/Symfony/SymfonyMailCollector.php delete mode 100644 vendor/maximebf/debugbar/src/DebugBar/Bridge/Twig/TimeableTwigExtensionProfiler.php delete mode 100644 vendor/maximebf/debugbar/src/DebugBar/Bridge/Twig/TraceableTwigEnvironment.php delete mode 100644 vendor/maximebf/debugbar/src/DebugBar/Bridge/Twig/TraceableTwigTemplate.php delete mode 100644 vendor/maximebf/debugbar/src/DebugBar/Bridge/Twig/TwigCollector.php delete mode 100644 vendor/maximebf/debugbar/src/DebugBar/Bridge/TwigProfileCollector.php delete mode 100644 vendor/maximebf/debugbar/src/DebugBar/DataCollector/AggregatedCollector.php delete mode 100644 vendor/maximebf/debugbar/src/DebugBar/DataCollector/AssetProvider.php delete mode 100644 vendor/maximebf/debugbar/src/DebugBar/DataCollector/ConfigCollector.php delete mode 100644 vendor/maximebf/debugbar/src/DebugBar/DataCollector/DataCollector.php delete mode 100644 vendor/maximebf/debugbar/src/DebugBar/DataCollector/DataCollectorInterface.php delete mode 100644 vendor/maximebf/debugbar/src/DebugBar/DataCollector/ExceptionsCollector.php delete mode 100644 vendor/maximebf/debugbar/src/DebugBar/DataCollector/LocalizationCollector.php delete mode 100644 vendor/maximebf/debugbar/src/DebugBar/DataCollector/MemoryCollector.php delete mode 100644 vendor/maximebf/debugbar/src/DebugBar/DataCollector/MessagesAggregateInterface.php delete mode 100644 vendor/maximebf/debugbar/src/DebugBar/DataCollector/MessagesCollector.php delete mode 100644 vendor/maximebf/debugbar/src/DebugBar/DataCollector/PDO/PDOCollector.php delete mode 100644 vendor/maximebf/debugbar/src/DebugBar/DataCollector/PDO/TraceablePDO.php delete mode 100644 vendor/maximebf/debugbar/src/DebugBar/DataCollector/PDO/TraceablePDOStatement.php delete mode 100644 vendor/maximebf/debugbar/src/DebugBar/DataCollector/PDO/TracedStatement.php delete mode 100644 vendor/maximebf/debugbar/src/DebugBar/DataCollector/PhpInfoCollector.php delete mode 100644 vendor/maximebf/debugbar/src/DebugBar/DataCollector/Renderable.php delete mode 100644 vendor/maximebf/debugbar/src/DebugBar/DataCollector/RequestDataCollector.php delete mode 100644 vendor/maximebf/debugbar/src/DebugBar/DataCollector/TimeDataCollector.php delete mode 100644 vendor/maximebf/debugbar/src/DebugBar/DataFormatter/DataFormatter.php delete mode 100644 vendor/maximebf/debugbar/src/DebugBar/DataFormatter/DataFormatterInterface.php delete mode 100644 vendor/maximebf/debugbar/src/DebugBar/DataFormatter/DebugBarVarDumper.php delete mode 100644 vendor/maximebf/debugbar/src/DebugBar/DataFormatter/VarDumper/DebugBarHtmlDumper.php delete mode 100644 vendor/maximebf/debugbar/src/DebugBar/DebugBar.php delete mode 100644 vendor/maximebf/debugbar/src/DebugBar/DebugBarException.php delete mode 100644 vendor/maximebf/debugbar/src/DebugBar/HttpDriverInterface.php delete mode 100644 vendor/maximebf/debugbar/src/DebugBar/JavascriptRenderer.php delete mode 100644 vendor/maximebf/debugbar/src/DebugBar/OpenHandler.php delete mode 100644 vendor/maximebf/debugbar/src/DebugBar/PhpHttpDriver.php delete mode 100644 vendor/maximebf/debugbar/src/DebugBar/RequestIdGenerator.php delete mode 100644 vendor/maximebf/debugbar/src/DebugBar/RequestIdGeneratorInterface.php delete mode 100644 vendor/maximebf/debugbar/src/DebugBar/Resources/debugbar.css delete mode 100644 vendor/maximebf/debugbar/src/DebugBar/Resources/debugbar.js delete mode 100644 vendor/maximebf/debugbar/src/DebugBar/Resources/openhandler.css delete mode 100644 vendor/maximebf/debugbar/src/DebugBar/Resources/openhandler.js delete mode 100644 vendor/maximebf/debugbar/src/DebugBar/Resources/vendor/font-awesome/css/font-awesome.min.css delete mode 100644 vendor/maximebf/debugbar/src/DebugBar/Resources/vendor/font-awesome/fonts/FontAwesome.otf delete mode 100644 vendor/maximebf/debugbar/src/DebugBar/Resources/vendor/font-awesome/fonts/fontawesome-webfont.eot delete mode 100644 vendor/maximebf/debugbar/src/DebugBar/Resources/vendor/font-awesome/fonts/fontawesome-webfont.svg delete mode 100644 vendor/maximebf/debugbar/src/DebugBar/Resources/vendor/font-awesome/fonts/fontawesome-webfont.ttf delete mode 100644 vendor/maximebf/debugbar/src/DebugBar/Resources/vendor/font-awesome/fonts/fontawesome-webfont.woff delete mode 100644 vendor/maximebf/debugbar/src/DebugBar/Resources/vendor/font-awesome/fonts/fontawesome-webfont.woff2 delete mode 100644 vendor/maximebf/debugbar/src/DebugBar/Resources/vendor/highlightjs/highlight.pack.js delete mode 100644 vendor/maximebf/debugbar/src/DebugBar/Resources/vendor/highlightjs/styles/github.css delete mode 100644 vendor/maximebf/debugbar/src/DebugBar/Resources/vendor/jquery/dist/jquery.min.js delete mode 100644 vendor/maximebf/debugbar/src/DebugBar/Resources/widgets.css delete mode 100644 vendor/maximebf/debugbar/src/DebugBar/Resources/widgets.js delete mode 100644 vendor/maximebf/debugbar/src/DebugBar/Resources/widgets/mails/widget.css delete mode 100644 vendor/maximebf/debugbar/src/DebugBar/Resources/widgets/mails/widget.js delete mode 100644 vendor/maximebf/debugbar/src/DebugBar/Resources/widgets/sqlqueries/widget.css delete mode 100644 vendor/maximebf/debugbar/src/DebugBar/Resources/widgets/sqlqueries/widget.js delete mode 100644 vendor/maximebf/debugbar/src/DebugBar/Resources/widgets/templates/widget.css delete mode 100644 vendor/maximebf/debugbar/src/DebugBar/Resources/widgets/templates/widget.js delete mode 100644 vendor/maximebf/debugbar/src/DebugBar/StandardDebugBar.php delete mode 100644 vendor/maximebf/debugbar/src/DebugBar/Storage/FileStorage.php delete mode 100644 vendor/maximebf/debugbar/src/DebugBar/Storage/MemcachedStorage.php delete mode 100644 vendor/maximebf/debugbar/src/DebugBar/Storage/PdoStorage.php delete mode 100644 vendor/maximebf/debugbar/src/DebugBar/Storage/RedisStorage.php delete mode 100644 vendor/maximebf/debugbar/src/DebugBar/Storage/StorageInterface.php delete mode 100644 vendor/maximebf/debugbar/src/DebugBar/Storage/pdo_storage_schema.sql create mode 100644 vendor/robmorgan/phinx/.stickler.yml create mode 100644 vendor/robmorgan/phinx/LICENSE create mode 100644 vendor/robmorgan/phinx/README.md create mode 100644 vendor/robmorgan/phinx/app/phinx.php create mode 100644 vendor/robmorgan/phinx/app/web.php create mode 100755 vendor/robmorgan/phinx/bin/phinx create mode 100644 vendor/robmorgan/phinx/bin/phinx.bat create mode 100644 vendor/robmorgan/phinx/composer.json create mode 100644 vendor/robmorgan/phinx/data/phinx.json.dist create mode 100644 vendor/robmorgan/phinx/data/phinx.php.dist create mode 100644 vendor/robmorgan/phinx/data/phinx.yml.dist create mode 100644 vendor/robmorgan/phinx/docs/config/__init__.py create mode 100644 vendor/robmorgan/phinx/docs/config/all.py create mode 100644 vendor/robmorgan/phinx/docs/en/commands.rst create mode 100644 vendor/robmorgan/phinx/docs/en/conf.py create mode 100644 vendor/robmorgan/phinx/docs/en/configuration.rst create mode 100644 vendor/robmorgan/phinx/docs/en/contents.rst rename vendor/{maximebf/debugbar/LICENSE => robmorgan/phinx/docs/en/copyright.rst} (76%) create mode 100644 vendor/robmorgan/phinx/docs/en/goals.rst create mode 100644 vendor/robmorgan/phinx/docs/en/index.rst create mode 100644 vendor/robmorgan/phinx/docs/en/install.rst create mode 100644 vendor/robmorgan/phinx/docs/en/intro.rst create mode 100644 vendor/robmorgan/phinx/docs/en/migrations.rst create mode 100644 vendor/robmorgan/phinx/docs/en/namespaces.rst create mode 100644 vendor/robmorgan/phinx/docs/en/seeding.rst create mode 100644 vendor/robmorgan/phinx/phpstan-baseline.neon create mode 100644 vendor/robmorgan/phinx/src/Phinx/Config/Config.php create mode 100644 vendor/robmorgan/phinx/src/Phinx/Config/ConfigInterface.php create mode 100644 vendor/robmorgan/phinx/src/Phinx/Config/FeatureFlags.php create mode 100644 vendor/robmorgan/phinx/src/Phinx/Config/NamespaceAwareInterface.php create mode 100644 vendor/robmorgan/phinx/src/Phinx/Config/NamespaceAwareTrait.php create mode 100644 vendor/robmorgan/phinx/src/Phinx/Console/Command/AbstractCommand.php create mode 100644 vendor/robmorgan/phinx/src/Phinx/Console/Command/Breakpoint.php create mode 100644 vendor/robmorgan/phinx/src/Phinx/Console/Command/Create.php create mode 100644 vendor/robmorgan/phinx/src/Phinx/Console/Command/Init.php create mode 100644 vendor/robmorgan/phinx/src/Phinx/Console/Command/ListAliases.php create mode 100644 vendor/robmorgan/phinx/src/Phinx/Console/Command/Migrate.php create mode 100644 vendor/robmorgan/phinx/src/Phinx/Console/Command/Rollback.php create mode 100644 vendor/robmorgan/phinx/src/Phinx/Console/Command/SeedCreate.php create mode 100644 vendor/robmorgan/phinx/src/Phinx/Console/Command/SeedRun.php create mode 100644 vendor/robmorgan/phinx/src/Phinx/Console/Command/Status.php create mode 100644 vendor/robmorgan/phinx/src/Phinx/Console/Command/Test.php create mode 100644 vendor/robmorgan/phinx/src/Phinx/Console/PhinxApplication.php create mode 100644 vendor/robmorgan/phinx/src/Phinx/Db/Action/Action.php create mode 100644 vendor/robmorgan/phinx/src/Phinx/Db/Action/AddColumn.php create mode 100644 vendor/robmorgan/phinx/src/Phinx/Db/Action/AddForeignKey.php create mode 100644 vendor/robmorgan/phinx/src/Phinx/Db/Action/AddIndex.php create mode 100644 vendor/robmorgan/phinx/src/Phinx/Db/Action/ChangeColumn.php create mode 100644 vendor/robmorgan/phinx/src/Phinx/Db/Action/ChangeComment.php create mode 100644 vendor/robmorgan/phinx/src/Phinx/Db/Action/ChangePrimaryKey.php create mode 100644 vendor/robmorgan/phinx/src/Phinx/Db/Action/CreateTable.php create mode 100644 vendor/robmorgan/phinx/src/Phinx/Db/Action/DropForeignKey.php create mode 100644 vendor/robmorgan/phinx/src/Phinx/Db/Action/DropIndex.php create mode 100644 vendor/robmorgan/phinx/src/Phinx/Db/Action/DropTable.php create mode 100644 vendor/robmorgan/phinx/src/Phinx/Db/Action/RemoveColumn.php create mode 100644 vendor/robmorgan/phinx/src/Phinx/Db/Action/RenameColumn.php create mode 100644 vendor/robmorgan/phinx/src/Phinx/Db/Action/RenameTable.php create mode 100644 vendor/robmorgan/phinx/src/Phinx/Db/Adapter/AbstractAdapter.php create mode 100644 vendor/robmorgan/phinx/src/Phinx/Db/Adapter/AdapterFactory.php create mode 100644 vendor/robmorgan/phinx/src/Phinx/Db/Adapter/AdapterInterface.php create mode 100644 vendor/robmorgan/phinx/src/Phinx/Db/Adapter/AdapterWrapper.php create mode 100644 vendor/robmorgan/phinx/src/Phinx/Db/Adapter/DirectActionInterface.php create mode 100644 vendor/robmorgan/phinx/src/Phinx/Db/Adapter/MysqlAdapter.php create mode 100644 vendor/robmorgan/phinx/src/Phinx/Db/Adapter/PdoAdapter.php create mode 100644 vendor/robmorgan/phinx/src/Phinx/Db/Adapter/PostgresAdapter.php create mode 100644 vendor/robmorgan/phinx/src/Phinx/Db/Adapter/ProxyAdapter.php create mode 100644 vendor/robmorgan/phinx/src/Phinx/Db/Adapter/SQLiteAdapter.php create mode 100644 vendor/robmorgan/phinx/src/Phinx/Db/Adapter/SqlServerAdapter.php create mode 100644 vendor/robmorgan/phinx/src/Phinx/Db/Adapter/TablePrefixAdapter.php create mode 100644 vendor/robmorgan/phinx/src/Phinx/Db/Adapter/TimedOutputAdapter.php create mode 100644 vendor/robmorgan/phinx/src/Phinx/Db/Adapter/UnsupportedColumnTypeException.php create mode 100644 vendor/robmorgan/phinx/src/Phinx/Db/Adapter/WrapperInterface.php create mode 100644 vendor/robmorgan/phinx/src/Phinx/Db/Plan/AlterTable.php create mode 100644 vendor/robmorgan/phinx/src/Phinx/Db/Plan/Intent.php create mode 100644 vendor/robmorgan/phinx/src/Phinx/Db/Plan/NewTable.php create mode 100644 vendor/robmorgan/phinx/src/Phinx/Db/Plan/Plan.php create mode 100644 vendor/robmorgan/phinx/src/Phinx/Db/Plan/Solver/ActionSplitter.php create mode 100644 vendor/robmorgan/phinx/src/Phinx/Db/Table.php create mode 100644 vendor/robmorgan/phinx/src/Phinx/Db/Table/Column.php create mode 100644 vendor/robmorgan/phinx/src/Phinx/Db/Table/ForeignKey.php create mode 100644 vendor/robmorgan/phinx/src/Phinx/Db/Table/Index.php create mode 100644 vendor/robmorgan/phinx/src/Phinx/Db/Table/Table.php create mode 100644 vendor/robmorgan/phinx/src/Phinx/Db/Util/AlterInstructions.php create mode 100644 vendor/robmorgan/phinx/src/Phinx/Migration/AbstractMigration.php create mode 100644 vendor/robmorgan/phinx/src/Phinx/Migration/AbstractTemplateCreation.php create mode 100644 vendor/robmorgan/phinx/src/Phinx/Migration/CreationInterface.php create mode 100644 vendor/robmorgan/phinx/src/Phinx/Migration/IrreversibleMigrationException.php create mode 100644 vendor/robmorgan/phinx/src/Phinx/Migration/Manager.php create mode 100644 vendor/robmorgan/phinx/src/Phinx/Migration/Manager/Environment.php create mode 100644 vendor/robmorgan/phinx/src/Phinx/Migration/Migration.change.template.php.dist create mode 100644 vendor/robmorgan/phinx/src/Phinx/Migration/Migration.up_down.template.php.dist create mode 100644 vendor/robmorgan/phinx/src/Phinx/Migration/MigrationInterface.php create mode 100644 vendor/robmorgan/phinx/src/Phinx/Seed/AbstractSeed.php create mode 100644 vendor/robmorgan/phinx/src/Phinx/Seed/Seed.template.php.dist create mode 100644 vendor/robmorgan/phinx/src/Phinx/Seed/SeedInterface.php create mode 100644 vendor/robmorgan/phinx/src/Phinx/Util/Expression.php create mode 100644 vendor/robmorgan/phinx/src/Phinx/Util/Literal.php create mode 100644 vendor/robmorgan/phinx/src/Phinx/Util/Util.php create mode 100644 vendor/robmorgan/phinx/src/Phinx/Wrapper/TextWrapper.php create mode 100644 vendor/robmorgan/phinx/src/composer_autoloader.php create mode 100644 vendor/symfony/config/Builder/ClassBuilder.php create mode 100644 vendor/symfony/config/Builder/ConfigBuilderGenerator.php create mode 100644 vendor/symfony/config/Builder/ConfigBuilderGeneratorInterface.php create mode 100644 vendor/symfony/config/Builder/ConfigBuilderInterface.php create mode 100644 vendor/symfony/config/Builder/Method.php create mode 100644 vendor/symfony/config/Builder/Property.php create mode 100644 vendor/symfony/config/CHANGELOG.md create mode 100644 vendor/symfony/config/ConfigCache.php create mode 100644 vendor/symfony/config/ConfigCacheFactory.php create mode 100644 vendor/symfony/config/ConfigCacheFactoryInterface.php create mode 100644 vendor/symfony/config/ConfigCacheInterface.php create mode 100644 vendor/symfony/config/Definition/ArrayNode.php create mode 100644 vendor/symfony/config/Definition/BaseNode.php create mode 100644 vendor/symfony/config/Definition/BooleanNode.php create mode 100644 vendor/symfony/config/Definition/Builder/ArrayNodeDefinition.php create mode 100644 vendor/symfony/config/Definition/Builder/BooleanNodeDefinition.php create mode 100644 vendor/symfony/config/Definition/Builder/BuilderAwareInterface.php create mode 100644 vendor/symfony/config/Definition/Builder/EnumNodeDefinition.php create mode 100644 vendor/symfony/config/Definition/Builder/ExprBuilder.php create mode 100644 vendor/symfony/config/Definition/Builder/FloatNodeDefinition.php create mode 100644 vendor/symfony/config/Definition/Builder/IntegerNodeDefinition.php create mode 100644 vendor/symfony/config/Definition/Builder/MergeBuilder.php create mode 100644 vendor/symfony/config/Definition/Builder/NodeBuilder.php create mode 100644 vendor/symfony/config/Definition/Builder/NodeDefinition.php create mode 100644 vendor/symfony/config/Definition/Builder/NodeParentInterface.php create mode 100644 vendor/symfony/config/Definition/Builder/NormalizationBuilder.php create mode 100644 vendor/symfony/config/Definition/Builder/NumericNodeDefinition.php create mode 100644 vendor/symfony/config/Definition/Builder/ParentNodeDefinitionInterface.php create mode 100644 vendor/symfony/config/Definition/Builder/ScalarNodeDefinition.php create mode 100644 vendor/symfony/config/Definition/Builder/TreeBuilder.php create mode 100644 vendor/symfony/config/Definition/Builder/ValidationBuilder.php create mode 100644 vendor/symfony/config/Definition/Builder/VariableNodeDefinition.php create mode 100644 vendor/symfony/config/Definition/ConfigurationInterface.php create mode 100644 vendor/symfony/config/Definition/Dumper/XmlReferenceDumper.php create mode 100644 vendor/symfony/config/Definition/Dumper/YamlReferenceDumper.php create mode 100644 vendor/symfony/config/Definition/EnumNode.php create mode 100644 vendor/symfony/config/Definition/Exception/DuplicateKeyException.php create mode 100644 vendor/symfony/config/Definition/Exception/Exception.php create mode 100644 vendor/symfony/config/Definition/Exception/ForbiddenOverwriteException.php create mode 100644 vendor/symfony/config/Definition/Exception/InvalidConfigurationException.php create mode 100644 vendor/symfony/config/Definition/Exception/InvalidDefinitionException.php create mode 100644 vendor/symfony/config/Definition/Exception/InvalidTypeException.php create mode 100644 vendor/symfony/config/Definition/Exception/UnsetKeyException.php create mode 100644 vendor/symfony/config/Definition/FloatNode.php create mode 100644 vendor/symfony/config/Definition/IntegerNode.php create mode 100644 vendor/symfony/config/Definition/NodeInterface.php create mode 100644 vendor/symfony/config/Definition/NumericNode.php create mode 100644 vendor/symfony/config/Definition/Processor.php create mode 100644 vendor/symfony/config/Definition/PrototypeNodeInterface.php create mode 100644 vendor/symfony/config/Definition/PrototypedArrayNode.php create mode 100644 vendor/symfony/config/Definition/ScalarNode.php create mode 100644 vendor/symfony/config/Definition/VariableNode.php create mode 100644 vendor/symfony/config/Exception/FileLoaderImportCircularReferenceException.php create mode 100644 vendor/symfony/config/Exception/FileLocatorFileNotFoundException.php create mode 100644 vendor/symfony/config/Exception/LoaderLoadException.php create mode 100644 vendor/symfony/config/FileLocator.php create mode 100644 vendor/symfony/config/FileLocatorInterface.php create mode 100644 vendor/symfony/config/LICENSE create mode 100644 vendor/symfony/config/Loader/DelegatingLoader.php create mode 100644 vendor/symfony/config/Loader/FileLoader.php create mode 100644 vendor/symfony/config/Loader/GlobFileLoader.php create mode 100644 vendor/symfony/config/Loader/Loader.php create mode 100644 vendor/symfony/config/Loader/LoaderInterface.php create mode 100644 vendor/symfony/config/Loader/LoaderResolver.php create mode 100644 vendor/symfony/config/Loader/LoaderResolverInterface.php create mode 100644 vendor/symfony/config/Loader/ParamConfigurator.php create mode 100644 vendor/symfony/config/README.md create mode 100644 vendor/symfony/config/Resource/ClassExistenceResource.php create mode 100644 vendor/symfony/config/Resource/ComposerResource.php create mode 100644 vendor/symfony/config/Resource/DirectoryResource.php create mode 100644 vendor/symfony/config/Resource/FileExistenceResource.php create mode 100644 vendor/symfony/config/Resource/FileResource.php create mode 100644 vendor/symfony/config/Resource/GlobResource.php create mode 100644 vendor/symfony/config/Resource/ReflectionClassResource.php create mode 100644 vendor/symfony/config/Resource/ResourceInterface.php create mode 100644 vendor/symfony/config/Resource/SelfCheckingResourceChecker.php create mode 100644 vendor/symfony/config/Resource/SelfCheckingResourceInterface.php create mode 100644 vendor/symfony/config/ResourceCheckerConfigCache.php create mode 100644 vendor/symfony/config/ResourceCheckerConfigCacheFactory.php create mode 100644 vendor/symfony/config/ResourceCheckerInterface.php create mode 100644 vendor/symfony/config/Util/Exception/InvalidXmlException.php create mode 100644 vendor/symfony/config/Util/Exception/XmlParsingException.php create mode 100644 vendor/symfony/config/Util/XmlUtils.php create mode 100644 vendor/symfony/config/composer.json create mode 100644 vendor/symfony/filesystem/CHANGELOG.md create mode 100644 vendor/symfony/filesystem/Exception/ExceptionInterface.php create mode 100644 vendor/symfony/filesystem/Exception/FileNotFoundException.php create mode 100644 vendor/symfony/filesystem/Exception/IOException.php create mode 100644 vendor/symfony/filesystem/Exception/IOExceptionInterface.php create mode 100644 vendor/symfony/filesystem/Exception/InvalidArgumentException.php create mode 100644 vendor/symfony/filesystem/Exception/RuntimeException.php create mode 100644 vendor/symfony/filesystem/Filesystem.php create mode 100644 vendor/symfony/filesystem/LICENSE create mode 100644 vendor/symfony/filesystem/Path.php create mode 100644 vendor/symfony/filesystem/README.md create mode 100644 vendor/symfony/filesystem/composer.json create mode 100644 vendor/symfony/polyfill-php81/LICENSE create mode 100644 vendor/symfony/polyfill-php81/Php81.php create mode 100644 vendor/symfony/polyfill-php81/README.md create mode 100644 vendor/symfony/polyfill-php81/Resources/stubs/CURLStringFile.php create mode 100644 vendor/symfony/polyfill-php81/Resources/stubs/ReturnTypeWillChange.php create mode 100644 vendor/symfony/polyfill-php81/bootstrap.php create mode 100644 vendor/symfony/polyfill-php81/composer.json delete mode 100644 vendor/webman-tech/debugbar/.gitignore delete mode 100644 vendor/webman-tech/debugbar/README.md delete mode 100644 vendor/webman-tech/debugbar/composer.json delete mode 100644 vendor/webman-tech/debugbar/src/Bootstrap/LaravelQuery.php delete mode 100644 vendor/webman-tech/debugbar/src/Bootstrap/LaravelRedisExec.php delete mode 100644 vendor/webman-tech/debugbar/src/DataCollector/LaravelQueryCollector.php delete mode 100644 vendor/webman-tech/debugbar/src/DataCollector/LaravelRedisCollector.php delete mode 100644 vendor/webman-tech/debugbar/src/DataCollector/MemoryCollector.php delete mode 100644 vendor/webman-tech/debugbar/src/DataCollector/PhpInfoCollector.php delete mode 100644 vendor/webman-tech/debugbar/src/DataCollector/RequestDataCollector.php delete mode 100644 vendor/webman-tech/debugbar/src/DataCollector/RouteCollector.php delete mode 100644 vendor/webman-tech/debugbar/src/DataCollector/SessionCollector.php delete mode 100644 vendor/webman-tech/debugbar/src/DataCollector/ThinkPdoCollector.php delete mode 100644 vendor/webman-tech/debugbar/src/DataCollector/TimeDataCollector.php delete mode 100644 vendor/webman-tech/debugbar/src/DataCollector/WebmanCollector.php delete mode 100644 vendor/webman-tech/debugbar/src/DebugBar.php delete mode 100644 vendor/webman-tech/debugbar/src/Ext/HttpExt.php delete mode 100644 vendor/webman-tech/debugbar/src/Helper/ArrayHelper.php delete mode 100644 vendor/webman-tech/debugbar/src/Helper/StringHelper.php delete mode 100644 vendor/webman-tech/debugbar/src/Install.php delete mode 100644 vendor/webman-tech/debugbar/src/Laravel/DataCollector/QueryCollector.php delete mode 100644 vendor/webman-tech/debugbar/src/Laravel/DataFormatter/QueryFormatter.php delete mode 100644 vendor/webman-tech/debugbar/src/Laravel/README.md delete mode 100644 vendor/webman-tech/debugbar/src/Laravel/Resources/sqlqueries/widget.js delete mode 100644 vendor/webman-tech/debugbar/src/Middleware/DebugBarMiddleware.php delete mode 100644 vendor/webman-tech/debugbar/src/Resources/webman-debugbar.css delete mode 100644 vendor/webman-tech/debugbar/src/Storage/AutoCleanFileStorage.php delete mode 100644 vendor/webman-tech/debugbar/src/Storage/FileStorage.php delete mode 100644 vendor/webman-tech/debugbar/src/Traits/DebugBarOverwrite.php delete mode 100644 vendor/webman-tech/debugbar/src/WebmanDebugBar.php delete mode 100644 vendor/webman-tech/debugbar/src/WebmanHttpDriver.php delete mode 100644 vendor/webman-tech/debugbar/src/WebmanJavascriptRenderer.php delete mode 100644 vendor/webman-tech/debugbar/src/config/plugin/webman-tech/debugbar/app.php delete mode 100644 vendor/webman-tech/debugbar/src/config/plugin/webman-tech/debugbar/bootstrap.php delete mode 100644 vendor/webman-tech/debugbar/src/config/plugin/webman-tech/debugbar/middleware.php delete mode 100644 vendor/webman-tech/debugbar/src/config/plugin/webman-tech/debugbar/route.php diff --git a/app/controller/IndexController.php b/app/controller/IndexController.php index a3d3d2d..e416e7f 100644 --- a/app/controller/IndexController.php +++ b/app/controller/IndexController.php @@ -24,7 +24,7 @@ class IndexController public function domain(Request $request) { View::assign('userinfo', $request->session()->get('userinfo')); - return view('index'); + return view('domain'); } public function json(Request $request) { diff --git a/app/view/domain.html b/app/view/domain.html new file mode 100644 index 0000000..cc9930b --- /dev/null +++ b/app/view/domain.html @@ -0,0 +1,112 @@ + + + +
+ + +

域名列表

+ + + + + 添加新域名 + +
+
+
+
域名列表
+
+
+ 如遇需更改账号,请先以新账号添加用户,再删除旧账号 +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
头像姓名邮箱账号密码操作
头像姓名邮箱账号密码操作
新用户管理员admin@admin.comadminStart dateSalary
+
+
+
+
+ + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/composer.json b/composer.json index 0527677..b48b417 100644 --- a/composer.json +++ b/composer.json @@ -32,11 +32,15 @@ "geoip2/geoip2": "~2.0", "illuminate/redis": "^9.45", "symfony/cache": "^6.0", - "illuminate/events": "^9.45", + "illuminate/events": "^9.52", "yzh52521/webman-throttle": "^1.0", "workerman/validation": "^3.0", "yzh52521/easyhttp": "^1.0", - "laysense/dns": "^0.1.0" + "laysense/dns": "^0.1.0", + "illuminate/database": "^9.52", + "illuminate/pagination": "^9.52", + "symfony/var-dumper": "^6.0", + "robmorgan/phinx": "^0.14.0" }, "suggest": { "ext-event": "For better performance. " @@ -63,8 +67,5 @@ "pre-package-uninstall": [ "support\\Plugin::uninstall" ] - }, - "require-dev": { - "webman-tech/debugbar": "^2.1" } } diff --git a/composer.lock b/composer.lock index 9f90148..98aaf20 100644 --- a/composer.lock +++ b/composer.lock @@ -4,8 +4,326 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "c056667084b6bb7fd68b4328dc947f0b", + "content-hash": "fe1282e812343c931593169d84dd03ec", "packages": [ + { + "name": "brick/math", + "version": "0.11.0", + "source": { + "type": "git", + "url": "https://github.com/brick/math.git", + "reference": "0ad82ce168c82ba30d1c01ec86116ab52f589478" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/brick/math/zipball/0ad82ce168c82ba30d1c01ec86116ab52f589478", + "reference": "0ad82ce168c82ba30d1c01ec86116ab52f589478", + "shasum": "", + "mirrors": [ + { + "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%", + "preferred": true + } + ] + }, + "require": { + "php": "^8.0" + }, + "require-dev": { + "php-coveralls/php-coveralls": "^2.2", + "phpunit/phpunit": "^9.0", + "vimeo/psalm": "5.0.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Brick\\Math\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "Arbitrary-precision arithmetic library", + "keywords": [ + "Arbitrary-precision", + "BigInteger", + "BigRational", + "arithmetic", + "bigdecimal", + "bignum", + "brick", + "math" + ], + "support": { + "issues": "https://github.com/brick/math/issues", + "source": "https://github.com/brick/math/tree/0.11.0" + }, + "funding": [ + { + "url": "https://github.com/BenMorel", + "type": "github" + } + ], + "time": "2023-01-15T23:15:59+00:00" + }, + { + "name": "cakephp/core", + "version": "4.5.3", + "source": { + "type": "git", + "url": "https://github.com/cakephp/core.git", + "reference": "c2f4dff110d41e475d1041f2abe236f1c62d0cd0" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/cakephp/core/zipball/c2f4dff110d41e475d1041f2abe236f1c62d0cd0", + "reference": "c2f4dff110d41e475d1041f2abe236f1c62d0cd0", + "shasum": "", + "mirrors": [ + { + "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%", + "preferred": true + } + ] + }, + "require": { + "cakephp/utility": "^4.0", + "php": ">=7.4.0" + }, + "provide": { + "psr/container-implementation": "^1.0 || ^2.0" + }, + "suggest": { + "cakephp/cache": "To use Configure::store() and restore().", + "cakephp/event": "To use PluginApplicationInterface or plugin applications.", + "league/container": "To use Container and ServiceProvider classes" + }, + "type": "library", + "autoload": { + "files": [ + "functions.php" + ], + "psr-4": { + "Cake\\Core\\": "." + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "CakePHP Community", + "homepage": "https://github.com/cakephp/core/graphs/contributors" + } + ], + "description": "CakePHP Framework Core classes", + "homepage": "https://cakephp.org", + "keywords": [ + "cakephp", + "core", + "framework" + ], + "support": { + "forum": "https://stackoverflow.com/tags/cakephp", + "irc": "irc://irc.freenode.org/cakephp", + "issues": "https://github.com/cakephp/cakephp/issues", + "source": "https://github.com/cakephp/core" + }, + "time": "2023-10-21T13:30:46+00:00" + }, + { + "name": "cakephp/database", + "version": "4.5.3", + "source": { + "type": "git", + "url": "https://github.com/cakephp/database.git", + "reference": "317739cc32060ef19b6c19c87ac6b64848d78e27" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/cakephp/database/zipball/317739cc32060ef19b6c19c87ac6b64848d78e27", + "reference": "317739cc32060ef19b6c19c87ac6b64848d78e27", + "shasum": "", + "mirrors": [ + { + "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%", + "preferred": true + } + ] + }, + "require": { + "cakephp/core": "^4.0", + "cakephp/datasource": "^4.0", + "php": ">=7.4.0" + }, + "suggest": { + "cakephp/i18n": "If you are using locale-aware datetime formats or Chronos types.", + "cakephp/log": "If you want to use query logging without providing a logger yourself." + }, + "type": "library", + "autoload": { + "psr-4": { + "Cake\\Database\\": "." + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "CakePHP Community", + "homepage": "https://github.com/cakephp/database/graphs/contributors" + } + ], + "description": "Flexible and powerful Database abstraction library with a familiar PDO-like API", + "homepage": "https://cakephp.org", + "keywords": [ + "abstraction", + "cakephp", + "database", + "database abstraction", + "pdo" + ], + "support": { + "forum": "https://stackoverflow.com/tags/cakephp", + "irc": "irc://irc.freenode.org/cakephp", + "issues": "https://github.com/cakephp/cakephp/issues", + "source": "https://github.com/cakephp/database" + }, + "time": "2023-12-07T12:23:54+00:00" + }, + { + "name": "cakephp/datasource", + "version": "4.5.3", + "source": { + "type": "git", + "url": "https://github.com/cakephp/datasource.git", + "reference": "5d11a35ffc09dee744faaab7f758aeb42c17cfec" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/cakephp/datasource/zipball/5d11a35ffc09dee744faaab7f758aeb42c17cfec", + "reference": "5d11a35ffc09dee744faaab7f758aeb42c17cfec", + "shasum": "", + "mirrors": [ + { + "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%", + "preferred": true + } + ] + }, + "require": { + "cakephp/core": "^4.0", + "php": ">=7.4.0", + "psr/log": "^1.0 || ^2.0", + "psr/simple-cache": "^1.0 || ^2.0" + }, + "suggest": { + "cakephp/cache": "If you decide to use Query caching.", + "cakephp/collection": "If you decide to use ResultSetInterface.", + "cakephp/utility": "If you decide to use EntityTrait." + }, + "type": "library", + "autoload": { + "psr-4": { + "Cake\\Datasource\\": "." + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "CakePHP Community", + "homepage": "https://github.com/cakephp/datasource/graphs/contributors" + } + ], + "description": "Provides connection managing and traits for Entities and Queries that can be reused for different datastores", + "homepage": "https://cakephp.org", + "keywords": [ + "cakephp", + "connection management", + "datasource", + "entity", + "query" + ], + "support": { + "forum": "https://stackoverflow.com/tags/cakephp", + "irc": "irc://irc.freenode.org/cakephp", + "issues": "https://github.com/cakephp/cakephp/issues", + "source": "https://github.com/cakephp/datasource" + }, + "time": "2023-11-05T07:32:10+00:00" + }, + { + "name": "cakephp/utility", + "version": "4.5.3", + "source": { + "type": "git", + "url": "https://github.com/cakephp/utility.git", + "reference": "9fb72974e91e81f1545a15a6d45f50c82cd77def" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/cakephp/utility/zipball/9fb72974e91e81f1545a15a6d45f50c82cd77def", + "reference": "9fb72974e91e81f1545a15a6d45f50c82cd77def", + "shasum": "", + "mirrors": [ + { + "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%", + "preferred": true + } + ] + }, + "require": { + "cakephp/core": "^4.0", + "php": ">=7.4.0" + }, + "suggest": { + "ext-intl": "To use Text::transliterate() or Text::slug()", + "lib-ICU": "To use Text::transliterate() or Text::slug()" + }, + "type": "library", + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Cake\\Utility\\": "." + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "CakePHP Community", + "homepage": "https://github.com/cakephp/utility/graphs/contributors" + } + ], + "description": "CakePHP Utility classes such as Inflector, String, Hash, and Security", + "homepage": "https://cakephp.org", + "keywords": [ + "cakephp", + "hash", + "inflector", + "security", + "string", + "utility" + ], + "support": { + "forum": "https://stackoverflow.com/tags/cakephp", + "irc": "irc://irc.freenode.org/cakephp", + "issues": "https://github.com/cakephp/cakephp/issues", + "source": "https://github.com/cakephp/utility" + }, + "time": "2023-04-11T21:22:06+00:00" + }, { "name": "carbonphp/carbon-doctrine-types", "version": "2.1.0", @@ -18,7 +336,13 @@ "type": "zip", "url": "https://api.github.com/repos/CarbonPHP/carbon-doctrine-types/zipball/99f76ffa36cce3b70a4a6abce41dba15ca2e84cb", "reference": "99f76ffa36cce3b70a4a6abce41dba15ca2e84cb", - "shasum": "" + "shasum": "", + "mirrors": [ + { + "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%", + "preferred": true + } + ] }, "require": { "php": "^7.4 || ^8.0" @@ -153,17 +477,23 @@ }, { "name": "doctrine/inflector", - "version": "2.0.9", + "version": "2.0.8", "source": { "type": "git", "url": "https://github.com/doctrine/inflector.git", - "reference": "2930cd5ef353871c821d5c43ed030d39ac8cfe65" + "reference": "f9301a5b2fb1216b2b08f02ba04dc45423db6bff" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/inflector/zipball/2930cd5ef353871c821d5c43ed030d39ac8cfe65", - "reference": "2930cd5ef353871c821d5c43ed030d39ac8cfe65", - "shasum": "" + "url": "https://api.github.com/repos/doctrine/inflector/zipball/f9301a5b2fb1216b2b08f02ba04dc45423db6bff", + "reference": "f9301a5b2fb1216b2b08f02ba04dc45423db6bff", + "shasum": "", + "mirrors": [ + { + "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%", + "preferred": true + } + ] }, "require": { "php": "^7.2 || ^8.0" @@ -224,7 +554,7 @@ ], "support": { "issues": "https://github.com/doctrine/inflector/issues", - "source": "https://github.com/doctrine/inflector/tree/2.0.9" + "source": "https://github.com/doctrine/inflector/tree/2.0.8" }, "funding": [ { @@ -240,7 +570,7 @@ "type": "tidelift" } ], - "time": "2024-01-15T18:05:13+00:00" + "time": "2023-06-16T13:40:37+00:00" }, { "name": "geoip2/geoip2", @@ -633,7 +963,13 @@ "type": "zip", "url": "https://api.github.com/repos/illuminate/bus/zipball/4c719a19c3d8c34b2494a7206f8ffde3eff3f983", "reference": "4c719a19c3d8c34b2494a7206f8ffde3eff3f983", - "shasum": "" + "shasum": "", + "mirrors": [ + { + "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%", + "preferred": true + } + ] }, "require": { "illuminate/collections": "^9.0", @@ -686,7 +1022,13 @@ "type": "zip", "url": "https://api.github.com/repos/illuminate/collections/zipball/d3710b0b244bfc62c288c1a87eaa62dd28352d1f", "reference": "d3710b0b244bfc62c288c1a87eaa62dd28352d1f", - "shasum": "" + "shasum": "", + "mirrors": [ + { + "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%", + "preferred": true + } + ] }, "require": { "illuminate/conditionable": "^9.0", @@ -741,7 +1083,13 @@ "type": "zip", "url": "https://api.github.com/repos/illuminate/conditionable/zipball/bea24daa0fa84b7e7b0d5b84f62c71b7e2dc3364", "reference": "bea24daa0fa84b7e7b0d5b84f62c71b7e2dc3364", - "shasum": "" + "shasum": "", + "mirrors": [ + { + "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%", + "preferred": true + } + ] }, "require": { "php": "^8.0.2" @@ -787,7 +1135,13 @@ "type": "zip", "url": "https://api.github.com/repos/illuminate/container/zipball/1641dda2d0750b68bb1264a3b37ff3973f2e6265", "reference": "1641dda2d0750b68bb1264a3b37ff3973f2e6265", - "shasum": "" + "shasum": "", + "mirrors": [ + { + "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%", + "preferred": true + } + ] }, "require": { "illuminate/contracts": "^9.0", @@ -838,7 +1192,13 @@ "type": "zip", "url": "https://api.github.com/repos/illuminate/contracts/zipball/44f65d723b13823baa02ff69751a5948bde60c22", "reference": "44f65d723b13823baa02ff69751a5948bde60c22", - "shasum": "" + "shasum": "", + "mirrors": [ + { + "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%", + "preferred": true + } + ] }, "require": { "php": "^8.0.2", @@ -874,6 +1234,82 @@ }, "time": "2023-02-08T14:36:30+00:00" }, + { + "name": "illuminate/database", + "version": "v9.52.16", + "source": { + "type": "git", + "url": "https://github.com/illuminate/database.git", + "reference": "93cfc8e1f9ac147e6a2851ecabe8d8f21ad85182" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/illuminate/database/zipball/93cfc8e1f9ac147e6a2851ecabe8d8f21ad85182", + "reference": "93cfc8e1f9ac147e6a2851ecabe8d8f21ad85182", + "shasum": "", + "mirrors": [ + { + "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%", + "preferred": true + } + ] + }, + "require": { + "brick/math": "^0.9.3|^0.10.2|^0.11", + "ext-pdo": "*", + "illuminate/collections": "^9.0", + "illuminate/container": "^9.0", + "illuminate/contracts": "^9.0", + "illuminate/macroable": "^9.0", + "illuminate/support": "^9.0", + "php": "^8.0.2", + "symfony/console": "^6.0.9" + }, + "suggest": { + "doctrine/dbal": "Required to rename columns and drop SQLite columns (^2.13.3|^3.1.4).", + "ext-filter": "Required to use the Postgres database driver.", + "fakerphp/faker": "Required to use the eloquent factory builder (^1.21).", + "illuminate/console": "Required to use the database commands (^9.0).", + "illuminate/events": "Required to use the observers with Eloquent (^9.0).", + "illuminate/filesystem": "Required to use the migrations (^9.0).", + "illuminate/pagination": "Required to paginate the result set (^9.0).", + "symfony/finder": "Required to use Eloquent model factories (^6.0)." + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "9.x-dev" + } + }, + "autoload": { + "psr-4": { + "Illuminate\\Database\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Taylor Otwell", + "email": "taylor@laravel.com" + } + ], + "description": "The Illuminate Database package.", + "homepage": "https://laravel.com", + "keywords": [ + "database", + "laravel", + "orm", + "sql" + ], + "support": { + "issues": "https://github.com/laravel/framework/issues", + "source": "https://github.com/laravel/framework" + }, + "time": "2023-06-11T21:17:10+00:00" + }, { "name": "illuminate/events", "version": "v9.52.16", @@ -886,7 +1322,13 @@ "type": "zip", "url": "https://api.github.com/repos/illuminate/events/zipball/8e534676bac23bc17925f5c74c128f9c09b98f69", "reference": "8e534676bac23bc17925f5c74c128f9c09b98f69", - "shasum": "" + "shasum": "", + "mirrors": [ + { + "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%", + "preferred": true + } + ] }, "require": { "illuminate/bus": "^9.0", @@ -941,7 +1383,13 @@ "type": "zip", "url": "https://api.github.com/repos/illuminate/macroable/zipball/e3bfaf6401742a9c6abca61b9b10e998e5b6449a", "reference": "e3bfaf6401742a9c6abca61b9b10e998e5b6449a", - "shasum": "" + "shasum": "", + "mirrors": [ + { + "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%", + "preferred": true + } + ] }, "require": { "php": "^8.0.2" @@ -975,6 +1423,62 @@ }, "time": "2022-08-09T13:29:29+00:00" }, + { + "name": "illuminate/pagination", + "version": "v9.52.16", + "source": { + "type": "git", + "url": "https://github.com/illuminate/pagination.git", + "reference": "0c913d6af303ae0060d94d74d68d537637f7e6d4" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/illuminate/pagination/zipball/0c913d6af303ae0060d94d74d68d537637f7e6d4", + "reference": "0c913d6af303ae0060d94d74d68d537637f7e6d4", + "shasum": "", + "mirrors": [ + { + "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%", + "preferred": true + } + ] + }, + "require": { + "ext-filter": "*", + "illuminate/collections": "^9.0", + "illuminate/contracts": "^9.0", + "illuminate/support": "^9.0", + "php": "^8.0.2" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "9.x-dev" + } + }, + "autoload": { + "psr-4": { + "Illuminate\\Pagination\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Taylor Otwell", + "email": "taylor@laravel.com" + } + ], + "description": "The Illuminate Pagination package.", + "homepage": "https://laravel.com", + "support": { + "issues": "https://github.com/laravel/framework/issues", + "source": "https://github.com/laravel/framework" + }, + "time": "2023-02-06T02:52:41+00:00" + }, { "name": "illuminate/pipeline", "version": "v9.52.16", @@ -987,7 +1491,13 @@ "type": "zip", "url": "https://api.github.com/repos/illuminate/pipeline/zipball/e0be3f3f79f8235ad7334919ca4094d5074e02f6", "reference": "e0be3f3f79f8235ad7334919ca4094d5074e02f6", - "shasum": "" + "shasum": "", + "mirrors": [ + { + "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%", + "preferred": true + } + ] }, "require": { "illuminate/contracts": "^9.0", @@ -1089,7 +1599,13 @@ "type": "zip", "url": "https://api.github.com/repos/illuminate/support/zipball/223c608dbca27232df6213f776bfe7bdeec24874", "reference": "223c608dbca27232df6213f776bfe7bdeec24874", - "shasum": "" + "shasum": "", + "mirrors": [ + { + "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%", + "preferred": true + } + ] }, "require": { "doctrine/inflector": "^2.0", @@ -1385,17 +1901,23 @@ }, { "name": "nesbot/carbon", - "version": "2.72.2", + "version": "2.72.3", "source": { "type": "git", "url": "https://github.com/briannesbitt/Carbon.git", - "reference": "3e7edc41b58d65509baeb0d4a14c8fa41d627130" + "reference": "0c6fd108360c562f6e4fd1dedb8233b423e91c83" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/briannesbitt/Carbon/zipball/3e7edc41b58d65509baeb0d4a14c8fa41d627130", - "reference": "3e7edc41b58d65509baeb0d4a14c8fa41d627130", - "shasum": "" + "url": "https://api.github.com/repos/briannesbitt/Carbon/zipball/0c6fd108360c562f6e4fd1dedb8233b423e91c83", + "reference": "0c6fd108360c562f6e4fd1dedb8233b423e91c83", + "shasum": "", + "mirrors": [ + { + "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%", + "preferred": true + } + ] }, "require": { "carbonphp/carbon-doctrine-types": "*", @@ -1488,7 +2010,7 @@ "type": "tidelift" } ], - "time": "2024-01-19T00:21:53+00:00" + "time": "2024-01-25T10:35:09+00:00" }, { "name": "nikic/fast-route", @@ -1552,7 +2074,13 @@ "type": "zip", "url": "https://api.github.com/repos/php-fig/cache/zipball/aa5030cfa5405eccfdcb1083ce040c2cb8d253bf", "reference": "aa5030cfa5405eccfdcb1083ce040c2cb8d253bf", - "shasum": "" + "shasum": "", + "mirrors": [ + { + "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%", + "preferred": true + } + ] }, "require": { "php": ">=8.0.0" @@ -1601,7 +2129,13 @@ "type": "zip", "url": "https://api.github.com/repos/php-fig/clock/zipball/e41a24703d4560fd0acb709162f73b8adfc3aa0d", "reference": "e41a24703d4560fd0acb709162f73b8adfc3aa0d", - "shasum": "" + "shasum": "", + "mirrors": [ + { + "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%", + "preferred": true + } + ] }, "require": { "php": "^7.0 || ^8.0" @@ -1649,7 +2183,13 @@ "type": "zip", "url": "https://api.github.com/repos/php-fig/container/zipball/c71ecc56dfe541dbd90c5360474fbc405f8d5963", "reference": "c71ecc56dfe541dbd90c5360474fbc405f8d5963", - "shasum": "" + "shasum": "", + "mirrors": [ + { + "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%", + "preferred": true + } + ] }, "require": { "php": ">=7.4.0" @@ -1852,17 +2392,23 @@ }, { "name": "psr/log", - "version": "3.0.0", + "version": "2.0.0", "source": { "type": "git", "url": "https://github.com/php-fig/log.git", - "reference": "fe5ea303b0887d5caefd3d431c3e61ad47037001" + "reference": "ef29f6d262798707a9edd554e2b82517ef3a9376" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/php-fig/log/zipball/fe5ea303b0887d5caefd3d431c3e61ad47037001", - "reference": "fe5ea303b0887d5caefd3d431c3e61ad47037001", - "shasum": "" + "url": "https://api.github.com/repos/php-fig/log/zipball/ef29f6d262798707a9edd554e2b82517ef3a9376", + "reference": "ef29f6d262798707a9edd554e2b82517ef3a9376", + "shasum": "", + "mirrors": [ + { + "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%", + "preferred": true + } + ] }, "require": { "php": ">=8.0.0" @@ -1870,7 +2416,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "3.x-dev" + "dev-master": "2.0.x-dev" } }, "autoload": { @@ -1896,23 +2442,29 @@ "psr-3" ], "support": { - "source": "https://github.com/php-fig/log/tree/3.0.0" + "source": "https://github.com/php-fig/log/tree/2.0.0" }, - "time": "2021-07-14T16:46:02+00:00" + "time": "2021-07-14T16:41:46+00:00" }, { "name": "psr/simple-cache", - "version": "3.0.0", + "version": "2.0.0", "source": { "type": "git", "url": "https://github.com/php-fig/simple-cache.git", - "reference": "764e0b3939f5ca87cb904f570ef9be2d78a07865" + "reference": "8707bf3cea6f710bf6ef05491234e3ab06f6432a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/php-fig/simple-cache/zipball/764e0b3939f5ca87cb904f570ef9be2d78a07865", - "reference": "764e0b3939f5ca87cb904f570ef9be2d78a07865", - "shasum": "" + "url": "https://api.github.com/repos/php-fig/simple-cache/zipball/8707bf3cea6f710bf6ef05491234e3ab06f6432a", + "reference": "8707bf3cea6f710bf6ef05491234e3ab06f6432a", + "shasum": "", + "mirrors": [ + { + "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%", + "preferred": true + } + ] }, "require": { "php": ">=8.0.0" @@ -1920,7 +2472,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "3.0.x-dev" + "dev-master": "2.0.x-dev" } }, "autoload": { @@ -1947,9 +2499,9 @@ "simple-cache" ], "support": { - "source": "https://github.com/php-fig/simple-cache/tree/3.0.0" + "source": "https://github.com/php-fig/simple-cache/tree/2.0.0" }, - "time": "2021-10-29T13:26:27+00:00" + "time": "2021-10-29T13:22:09+00:00" }, { "name": "ralouphie/getallheaders", @@ -2049,6 +2601,98 @@ }, "time": "2017-12-29T19:39:25+00:00" }, + { + "name": "robmorgan/phinx", + "version": "0.14.0", + "source": { + "type": "git", + "url": "https://github.com/cakephp/phinx.git", + "reference": "7bc24bae664b2124f3d5b8d1e98fdb8abaf70e87" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/cakephp/phinx/zipball/7bc24bae664b2124f3d5b8d1e98fdb8abaf70e87", + "reference": "7bc24bae664b2124f3d5b8d1e98fdb8abaf70e87", + "shasum": "", + "mirrors": [ + { + "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%", + "preferred": true + } + ] + }, + "require": { + "cakephp/database": "^4.0", + "php-64bit": ">=7.3", + "psr/container": "^1.0 || ^2.0", + "symfony/config": "^3.4|^4.0|^5.0|^6.0", + "symfony/console": "^3.4|^4.0|^5.0|^6.0" + }, + "require-dev": { + "cakephp/cakephp-codesniffer": "^4.0", + "ext-json": "*", + "ext-pdo": "*", + "phpunit/phpunit": "^9.5", + "sebastian/comparator": ">=1.2.3", + "symfony/yaml": "^3.4|^4.0|^5.0" + }, + "suggest": { + "ext-json": "Install if using JSON configuration format", + "ext-pdo": "PDO extension is needed", + "symfony/yaml": "Install if using YAML configuration format" + }, + "bin": [ + "bin/phinx" + ], + "type": "library", + "autoload": { + "psr-4": { + "Phinx\\": "src/Phinx/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Rob Morgan", + "email": "robbym@gmail.com", + "homepage": "https://robmorgan.id.au", + "role": "Lead Developer" + }, + { + "name": "Woody Gilk", + "email": "woody.gilk@gmail.com", + "homepage": "https://shadowhand.me", + "role": "Developer" + }, + { + "name": "Richard Quadling", + "email": "rquadling@gmail.com", + "role": "Developer" + }, + { + "name": "CakePHP Community", + "homepage": "https://github.com/cakephp/phinx/graphs/contributors", + "role": "Developer" + } + ], + "description": "Phinx makes it ridiculously easy to manage the database migrations for your PHP app.", + "homepage": "https://phinx.org", + "keywords": [ + "database", + "database migrations", + "db", + "migrations", + "phinx" + ], + "support": { + "issues": "https://github.com/cakephp/phinx/issues", + "source": "https://github.com/cakephp/phinx/tree/0.14.0" + }, + "time": "2023-09-07T14:26:14+00:00" + }, { "name": "symfony/cache", "version": "v6.0.19", @@ -2154,7 +2798,13 @@ "type": "zip", "url": "https://api.github.com/repos/symfony/cache-contracts/zipball/1c0a181c9ee221afe4fa55b2d13fc63c5ae14348", "reference": "1c0a181c9ee221afe4fa55b2d13fc63c5ae14348", - "shasum": "" + "shasum": "", + "mirrors": [ + { + "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%", + "preferred": true + } + ] }, "require": { "php": ">=8.0.2", @@ -2221,6 +2871,90 @@ ], "time": "2022-01-02T09:55:41+00:00" }, + { + "name": "symfony/config", + "version": "v6.0.19", + "source": { + "type": "git", + "url": "https://github.com/symfony/config.git", + "reference": "db4fc45c24e0c3e2198e68ada9d7f90daa1f97e3" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/config/zipball/db4fc45c24e0c3e2198e68ada9d7f90daa1f97e3", + "reference": "db4fc45c24e0c3e2198e68ada9d7f90daa1f97e3", + "shasum": "", + "mirrors": [ + { + "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%", + "preferred": true + } + ] + }, + "require": { + "php": ">=8.0.2", + "symfony/deprecation-contracts": "^2.1|^3", + "symfony/filesystem": "^5.4|^6.0", + "symfony/polyfill-ctype": "~1.8", + "symfony/polyfill-php81": "^1.22" + }, + "conflict": { + "symfony/finder": "<4.4" + }, + "require-dev": { + "symfony/event-dispatcher": "^5.4|^6.0", + "symfony/finder": "^5.4|^6.0", + "symfony/messenger": "^5.4|^6.0", + "symfony/service-contracts": "^1.1|^2|^3", + "symfony/yaml": "^5.4|^6.0" + }, + "suggest": { + "symfony/yaml": "To use the yaml reference dumper" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\Config\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Helps you find, load, combine, autofill and validate configuration values of any kind", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/config/tree/v6.0.19" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2023-01-09T04:36:00+00:00" + }, { "name": "symfony/console", "version": "v6.0.19", @@ -2233,7 +2967,13 @@ "type": "zip", "url": "https://api.github.com/repos/symfony/console/zipball/c3ebc83d031b71c39da318ca8b7a07ecc67507ed", "reference": "c3ebc83d031b71c39da318ca8b7a07ecc67507ed", - "shasum": "" + "shasum": "", + "mirrors": [ + { + "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%", + "preferred": true + } + ] }, "require": { "php": ">=8.0.2", @@ -2328,7 +3068,13 @@ "type": "zip", "url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/26954b3d62a6c5fd0ea8a2a00c0353a14978d05c", "reference": "26954b3d62a6c5fd0ea8a2a00c0353a14978d05c", - "shasum": "" + "shasum": "", + "mirrors": [ + { + "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%", + "preferred": true + } + ] }, "require": { "php": ">=8.0.2" @@ -2383,6 +3129,75 @@ ], "time": "2022-01-02T09:55:41+00:00" }, + { + "name": "symfony/filesystem", + "version": "v6.0.19", + "source": { + "type": "git", + "url": "https://github.com/symfony/filesystem.git", + "reference": "3d49eec03fda1f0fc19b7349fbbe55ebc1004214" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/filesystem/zipball/3d49eec03fda1f0fc19b7349fbbe55ebc1004214", + "reference": "3d49eec03fda1f0fc19b7349fbbe55ebc1004214", + "shasum": "", + "mirrors": [ + { + "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%", + "preferred": true + } + ] + }, + "require": { + "php": ">=8.0.2", + "symfony/polyfill-ctype": "~1.8", + "symfony/polyfill-mbstring": "~1.8" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\Filesystem\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Provides basic utilities for the filesystem", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/filesystem/tree/v6.0.19" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2023-01-20T17:44:14+00:00" + }, { "name": "symfony/polyfill-ctype", "version": "v1.28.0", @@ -2395,7 +3210,13 @@ "type": "zip", "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/ea208ce43cbb04af6867b4fdddb1bdbf84cc28cb", "reference": "ea208ce43cbb04af6867b4fdddb1bdbf84cc28cb", - "shasum": "" + "shasum": "", + "mirrors": [ + { + "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%", + "preferred": true + } + ] }, "require": { "php": ">=7.1" @@ -2477,7 +3298,13 @@ "type": "zip", "url": "https://api.github.com/repos/symfony/polyfill-intl-grapheme/zipball/875e90aeea2777b6f135677f618529449334a612", "reference": "875e90aeea2777b6f135677f618529449334a612", - "shasum": "" + "shasum": "", + "mirrors": [ + { + "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%", + "preferred": true + } + ] }, "require": { "php": ">=7.1" @@ -2558,7 +3385,13 @@ "type": "zip", "url": "https://api.github.com/repos/symfony/polyfill-intl-normalizer/zipball/8c4ad05dd0120b6a53c1ca374dca2ad0a1c4ed92", "reference": "8c4ad05dd0120b6a53c1ca374dca2ad0a1c4ed92", - "shasum": "" + "shasum": "", + "mirrors": [ + { + "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%", + "preferred": true + } + ] }, "require": { "php": ">=7.1" @@ -2642,7 +3475,13 @@ "type": "zip", "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/42292d99c55abe617799667f454222c54c60e229", "reference": "42292d99c55abe617799667f454222c54c60e229", - "shasum": "" + "shasum": "", + "mirrors": [ + { + "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%", + "preferred": true + } + ] }, "require": { "php": ">=7.1" @@ -2725,7 +3564,13 @@ "type": "zip", "url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/6caa57379c4aec19c0a12a38b59b26487dcfe4b5", "reference": "6caa57379c4aec19c0a12a38b59b26487dcfe4b5", - "shasum": "" + "shasum": "", + "mirrors": [ + { + "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%", + "preferred": true + } + ] }, "require": { "php": ">=7.1" @@ -2796,6 +3641,91 @@ ], "time": "2023-01-26T09:26:14+00:00" }, + { + "name": "symfony/polyfill-php81", + "version": "v1.28.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-php81.git", + "reference": "7581cd600fa9fd681b797d00b02f068e2f13263b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-php81/zipball/7581cd600fa9fd681b797d00b02f068e2f13263b", + "reference": "7581cd600fa9fd681b797d00b02f068e2f13263b", + "shasum": "", + "mirrors": [ + { + "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%", + "preferred": true + } + ] + }, + "require": { + "php": ">=7.1" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "1.28-dev" + }, + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Php81\\": "" + }, + "classmap": [ + "Resources/stubs" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill backporting some PHP 8.1+ features to lower PHP versions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "polyfill", + "portable", + "shim" + ], + "support": { + "source": "https://github.com/symfony/polyfill-php81/tree/v1.28.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2023-01-26T09:26:14+00:00" + }, { "name": "symfony/service-contracts", "version": "v3.0.2", @@ -2808,7 +3738,13 @@ "type": "zip", "url": "https://api.github.com/repos/symfony/service-contracts/zipball/d78d39c1599bd1188b8e26bb341da52c3c6d8a66", "reference": "d78d39c1599bd1188b8e26bb341da52c3c6d8a66", - "shasum": "" + "shasum": "", + "mirrors": [ + { + "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%", + "preferred": true + } + ] }, "require": { "php": ">=8.0.2", @@ -2890,7 +3826,13 @@ "type": "zip", "url": "https://api.github.com/repos/symfony/string/zipball/d9e72497367c23e08bf94176d2be45b00a9d232a", "reference": "d9e72497367c23e08bf94176d2be45b00a9d232a", - "shasum": "" + "shasum": "", + "mirrors": [ + { + "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%", + "preferred": true + } + ] }, "require": { "php": ">=8.0.2", @@ -2975,7 +3917,13 @@ "type": "zip", "url": "https://api.github.com/repos/symfony/translation/zipball/9c24b3fdbbe9fb2ef3a6afd8bbaadfd72dad681f", "reference": "9c24b3fdbbe9fb2ef3a6afd8bbaadfd72dad681f", - "shasum": "" + "shasum": "", + "mirrors": [ + { + "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%", + "preferred": true + } + ] }, "require": { "php": ">=8.0.2", @@ -3070,7 +4018,13 @@ "type": "zip", "url": "https://api.github.com/repos/symfony/translation-contracts/zipball/acbfbb274e730e5a0236f619b6168d9dedb3e282", "reference": "acbfbb274e730e5a0236f619b6168d9dedb3e282", - "shasum": "" + "shasum": "", + "mirrors": [ + { + "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%", + "preferred": true + } + ] }, "require": { "php": ">=8.0.2" @@ -3136,6 +4090,100 @@ ], "time": "2022-06-27T17:10:44+00:00" }, + { + "name": "symfony/var-dumper", + "version": "v6.0.19", + "source": { + "type": "git", + "url": "https://github.com/symfony/var-dumper.git", + "reference": "eb980457fa6899840fe1687e8627a03a7d8a3d52" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/var-dumper/zipball/eb980457fa6899840fe1687e8627a03a7d8a3d52", + "reference": "eb980457fa6899840fe1687e8627a03a7d8a3d52", + "shasum": "", + "mirrors": [ + { + "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%", + "preferred": true + } + ] + }, + "require": { + "php": ">=8.0.2", + "symfony/polyfill-mbstring": "~1.0" + }, + "conflict": { + "phpunit/phpunit": "<5.4.3", + "symfony/console": "<5.4" + }, + "require-dev": { + "ext-iconv": "*", + "symfony/console": "^5.4|^6.0", + "symfony/process": "^5.4|^6.0", + "symfony/uid": "^5.4|^6.0", + "twig/twig": "^2.13|^3.0.4" + }, + "suggest": { + "ext-iconv": "To convert non-UTF-8 strings to UTF-8 (or symfony/polyfill-iconv in case ext-iconv cannot be used).", + "ext-intl": "To show region name in time zone dump", + "symfony/console": "To use the ServerDumpCommand and/or the bin/var-dump-server script" + }, + "bin": [ + "Resources/bin/var-dump-server" + ], + "type": "library", + "autoload": { + "files": [ + "Resources/functions/dump.php" + ], + "psr-4": { + "Symfony\\Component\\VarDumper\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Provides mechanisms for walking through any arbitrary PHP variable", + "homepage": "https://symfony.com", + "keywords": [ + "debug", + "dump" + ], + "support": { + "source": "https://github.com/symfony/var-dumper/tree/v6.0.19" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2023-01-20T17:44:14+00:00" + }, { "name": "symfony/var-exporter", "version": "v6.0.19", @@ -3220,7 +4268,13 @@ "type": "zip", "url": "https://api.github.com/repos/voku/portable-ascii/zipball/b56450eed252f6801410d810c8e1727224ae0743", "reference": "b56450eed252f6801410d810c8e1727224ae0743", - "shasum": "" + "shasum": "", + "mirrors": [ + { + "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%", + "preferred": true + } + ] }, "require": { "php": ">=7.0.0" @@ -3627,205 +4681,7 @@ "time": "2023-09-13T01:21:14+00:00" } ], - "packages-dev": [ - { - "name": "maximebf/debugbar", - "version": "v1.19.1", - "source": { - "type": "git", - "url": "https://github.com/maximebf/php-debugbar.git", - "reference": "03dd40a1826f4d585ef93ef83afa2a9874a00523" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/maximebf/php-debugbar/zipball/03dd40a1826f4d585ef93ef83afa2a9874a00523", - "reference": "03dd40a1826f4d585ef93ef83afa2a9874a00523", - "shasum": "" - }, - "require": { - "php": "^7.1|^8", - "psr/log": "^1|^2|^3", - "symfony/var-dumper": "^4|^5|^6" - }, - "require-dev": { - "phpunit/phpunit": ">=7.5.20 <10.0", - "twig/twig": "^1.38|^2.7|^3.0" - }, - "suggest": { - "kriswallsmith/assetic": "The best way to manage assets", - "monolog/monolog": "Log using Monolog", - "predis/predis": "Redis storage" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.18-dev" - } - }, - "autoload": { - "psr-4": { - "DebugBar\\": "src/DebugBar/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Maxime Bouroumeau-Fuseau", - "email": "maxime.bouroumeau@gmail.com", - "homepage": "http://maximebf.com" - }, - { - "name": "Barry vd. Heuvel", - "email": "barryvdh@gmail.com" - } - ], - "description": "Debug bar in the browser for php application", - "homepage": "https://github.com/maximebf/php-debugbar", - "keywords": [ - "debug", - "debugbar" - ], - "support": { - "issues": "https://github.com/maximebf/php-debugbar/issues", - "source": "https://github.com/maximebf/php-debugbar/tree/v1.19.1" - }, - "time": "2023-10-12T08:10:52+00:00" - }, - { - "name": "symfony/var-dumper", - "version": "v6.0.19", - "source": { - "type": "git", - "url": "https://github.com/symfony/var-dumper.git", - "reference": "eb980457fa6899840fe1687e8627a03a7d8a3d52" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/var-dumper/zipball/eb980457fa6899840fe1687e8627a03a7d8a3d52", - "reference": "eb980457fa6899840fe1687e8627a03a7d8a3d52", - "shasum": "" - }, - "require": { - "php": ">=8.0.2", - "symfony/polyfill-mbstring": "~1.0" - }, - "conflict": { - "phpunit/phpunit": "<5.4.3", - "symfony/console": "<5.4" - }, - "require-dev": { - "ext-iconv": "*", - "symfony/console": "^5.4|^6.0", - "symfony/process": "^5.4|^6.0", - "symfony/uid": "^5.4|^6.0", - "twig/twig": "^2.13|^3.0.4" - }, - "suggest": { - "ext-iconv": "To convert non-UTF-8 strings to UTF-8 (or symfony/polyfill-iconv in case ext-iconv cannot be used).", - "ext-intl": "To show region name in time zone dump", - "symfony/console": "To use the ServerDumpCommand and/or the bin/var-dump-server script" - }, - "bin": [ - "Resources/bin/var-dump-server" - ], - "type": "library", - "autoload": { - "files": [ - "Resources/functions/dump.php" - ], - "psr-4": { - "Symfony\\Component\\VarDumper\\": "" - }, - "exclude-from-classmap": [ - "/Tests/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Nicolas Grekas", - "email": "p@tchwork.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Provides mechanisms for walking through any arbitrary PHP variable", - "homepage": "https://symfony.com", - "keywords": [ - "debug", - "dump" - ], - "support": { - "source": "https://github.com/symfony/var-dumper/tree/v6.0.19" - }, - "funding": [ - { - "url": "https://symfony.com/sponsor", - "type": "custom" - }, - { - "url": "https://github.com/fabpot", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", - "type": "tidelift" - } - ], - "time": "2023-01-20T17:44:14+00:00" - }, - { - "name": "webman-tech/debugbar", - "version": "v2.2.1", - "source": { - "type": "git", - "url": "https://github.com/webman-tech/debugbar.git", - "reference": "f448183bb2a2fe3dce8c4de59f5668611e4e2e8b" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/webman-tech/debugbar/zipball/f448183bb2a2fe3dce8c4de59f5668611e4e2e8b", - "reference": "f448183bb2a2fe3dce8c4de59f5668611e4e2e8b", - "shasum": "" - }, - "require": { - "maximebf/debugbar": "^1.18", - "php": ">=7.2" - }, - "require-dev": { - "illuminate/database": "^8.83", - "illuminate/events": "^8.83", - "illuminate/redis": "^8.83", - "symfony/finder": "^5.4", - "topthink/think-orm": "^2.0", - "workerman/webman-framework": "^1.4" - }, - "type": "library", - "autoload": { - "psr-4": { - "WebmanTech\\Debugbar\\": "src" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "description": "Webman plugin webman-tech/debugbar", - "support": { - "issues": "https://github.com/webman-tech/debugbar/issues", - "source": "https://github.com/webman-tech/debugbar/tree/v2.2.1" - }, - "time": "2024-01-10T09:23:31+00:00" - } - ], + "packages-dev": [], "aliases": [], "minimum-stability": "stable", "stability-flags": [], diff --git a/config/plugin/webman-tech/debugbar/app.php b/config/plugin/webman-tech/debugbar/app.php deleted file mode 100644 index 0027d71..0000000 --- a/config/plugin/webman-tech/debugbar/app.php +++ /dev/null @@ -1,13 +0,0 @@ - $enable, - /** - * @see \WebmanTech\Debugbar\WebmanDebugBar::$config - */ - 'debugbar' => [ - 'enable' => $enable, - ], -]; diff --git a/config/plugin/webman-tech/debugbar/bootstrap.php b/config/plugin/webman-tech/debugbar/bootstrap.php deleted file mode 100644 index 1b921d2..0000000 --- a/config/plugin/webman-tech/debugbar/bootstrap.php +++ /dev/null @@ -1,9 +0,0 @@ - [ - DebugBarMiddleware::class, - ], -]; diff --git a/config/plugin/webman-tech/debugbar/route.php b/config/plugin/webman-tech/debugbar/route.php deleted file mode 100644 index 9844079..0000000 --- a/config/plugin/webman-tech/debugbar/route.php +++ /dev/null @@ -1,5 +0,0 @@ -registerRoute(); diff --git a/database/migrations/20240204114015_my_new_migration.php b/database/migrations/20240204114015_my_new_migration.php new file mode 100644 index 0000000..4f8e494 --- /dev/null +++ b/database/migrations/20240204114015_my_new_migration.php @@ -0,0 +1,24 @@ + [ + "migrations" => "database/migrations", + "seeds" => "database/seeds" + ], + "environments" => [ + "default_migration_table" => "phinxlog", + "default_database" => "dev", + "default_environment" => "dev", + "dev" => [ + "adapter" => "DB_CONNECTION", + "host" => "DB_HOST", + "name" => "DB_DATABASE", + "user" => "DB_USERNAME", + "pass" => "DB_PASSWORD", + "port" => "DB_PORT", + "charset" => "utf8" + ] + ] +]; \ No newline at end of file diff --git a/vendor/bin/phinx b/vendor/bin/phinx new file mode 100755 index 0000000..9942549 --- /dev/null +++ b/vendor/bin/phinx @@ -0,0 +1,120 @@ +#!/usr/bin/env php +realpath = realpath($opened_path) ?: $opened_path; + $opened_path = $this->realpath; + $this->handle = fopen($this->realpath, $mode); + $this->position = 0; + + return (bool) $this->handle; + } + + public function stream_read($count) + { + $data = fread($this->handle, $count); + + if ($this->position === 0) { + $data = preg_replace('{^#!.*\r?\n}', '', $data); + } + + $this->position += strlen($data); + + return $data; + } + + public function stream_cast($castAs) + { + return $this->handle; + } + + public function stream_close() + { + fclose($this->handle); + } + + public function stream_lock($operation) + { + return $operation ? flock($this->handle, $operation) : true; + } + + public function stream_seek($offset, $whence) + { + if (0 === fseek($this->handle, $offset, $whence)) { + $this->position = ftell($this->handle); + return true; + } + + return false; + } + + public function stream_tell() + { + return $this->position; + } + + public function stream_eof() + { + return feof($this->handle); + } + + public function stream_stat() + { + return array(); + } + + public function stream_set_option($option, $arg1, $arg2) + { + return true; + } + + public function url_stat($path, $flags) + { + $path = substr($path, 17); + if (file_exists($path)) { + return stat($path); + } + + return false; + } + } + } + + if ( + (function_exists('stream_get_wrappers') && in_array('phpvfscomposer', stream_get_wrappers(), true)) + || (function_exists('stream_wrapper_register') && stream_wrapper_register('phpvfscomposer', 'Composer\BinProxyWrapper')) + ) { + include("phpvfscomposer://" . __DIR__ . '/..'.'/robmorgan/phinx/bin/phinx'); + exit(0); + } +} + +include __DIR__ . '/..'.'/robmorgan/phinx/bin/phinx'; diff --git a/vendor/bin/phinx.bat b/vendor/bin/phinx.bat new file mode 100755 index 0000000..022652f --- /dev/null +++ b/vendor/bin/phinx.bat @@ -0,0 +1,5 @@ +@ECHO OFF +setlocal DISABLEDELAYEDEXPANSION +SET BIN_TARGET=%~dp0/phinx +SET COMPOSER_RUNTIME_BIN_DIR=%~dp0 +php "%BIN_TARGET%" %* diff --git a/vendor/brick/math/CHANGELOG.md b/vendor/brick/math/CHANGELOG.md new file mode 100644 index 0000000..17cea8d --- /dev/null +++ b/vendor/brick/math/CHANGELOG.md @@ -0,0 +1,445 @@ +# Changelog + +All notable changes to this project will be documented in this file. + +## [0.11.0](https://github.com/brick/math/releases/tag/0.11.0) - 2023-01-16 + +💥 **Breaking changes** + +- Minimum PHP version is now 8.0 +- Methods accepting a union of types are now strongly typed* +- `MathException` now extends `Exception` instead of `RuntimeException` + +* You may now run into type errors if you were passing `Stringable` objects to `of()` or any of the methods +internally calling `of()`, with `strict_types` enabled. You can fix this by casting `Stringable` objects to `string` +first. + +## [0.10.2](https://github.com/brick/math/releases/tag/0.10.2) - 2022-08-11 + +👌 **Improvements** + +- `BigRational::toFloat()` now simplifies the fraction before performing division (#73) thanks to @olsavmic + +## [0.10.1](https://github.com/brick/math/releases/tag/0.10.1) - 2022-08-02 + +✨ **New features** + +- `BigInteger::gcdMultiple()` returns the GCD of multiple `BigInteger` numbers + +## [0.10.0](https://github.com/brick/math/releases/tag/0.10.0) - 2022-06-18 + +💥 **Breaking changes** + +- Minimum PHP version is now 7.4 + +## [0.9.3](https://github.com/brick/math/releases/tag/0.9.3) - 2021-08-15 + +🚀 **Compatibility with PHP 8.1** + +- Support for custom object serialization; this removes a warning on PHP 8.1 due to the `Serializable` interface being deprecated (#60) thanks @TRowbotham + +## [0.9.2](https://github.com/brick/math/releases/tag/0.9.2) - 2021-01-20 + +🐛 **Bug fix** + +- Incorrect results could be returned when using the BCMath calculator, with a default scale set with `bcscale()`, on PHP >= 7.2 (#55). + +## [0.9.1](https://github.com/brick/math/releases/tag/0.9.1) - 2020-08-19 + +✨ **New features** + +- `BigInteger::not()` returns the bitwise `NOT` value + +🐛 **Bug fixes** + +- `BigInteger::toBytes()` could return an incorrect binary representation for some numbers +- The bitwise operations `and()`, `or()`, `xor()` on `BigInteger` could return an incorrect result when the GMP extension is not available + +## [0.9.0](https://github.com/brick/math/releases/tag/0.9.0) - 2020-08-18 + +👌 **Improvements** + +- `BigNumber::of()` now accepts `.123` and `123.` formats, both of which return a `BigDecimal` + +💥 **Breaking changes** + +- Deprecated method `BigInteger::powerMod()` has been removed - use `modPow()` instead +- Deprecated method `BigInteger::parse()` has been removed - use `fromBase()` instead + +## [0.8.17](https://github.com/brick/math/releases/tag/0.8.17) - 2020-08-19 + +🐛 **Bug fix** + +- `BigInteger::toBytes()` could return an incorrect binary representation for some numbers +- The bitwise operations `and()`, `or()`, `xor()` on `BigInteger` could return an incorrect result when the GMP extension is not available + +## [0.8.16](https://github.com/brick/math/releases/tag/0.8.16) - 2020-08-18 + +🚑 **Critical fix** + +- This version reintroduces the deprecated `BigInteger::parse()` method, that has been removed by mistake in version `0.8.9` and should have lasted for the whole `0.8` release cycle. + +✨ **New features** + +- `BigInteger::modInverse()` calculates a modular multiplicative inverse +- `BigInteger::fromBytes()` creates a `BigInteger` from a byte string +- `BigInteger::toBytes()` converts a `BigInteger` to a byte string +- `BigInteger::randomBits()` creates a pseudo-random `BigInteger` of a given bit length +- `BigInteger::randomRange()` creates a pseudo-random `BigInteger` between two bounds + +💩 **Deprecations** + +- `BigInteger::powerMod()` is now deprecated in favour of `modPow()` + +## [0.8.15](https://github.com/brick/math/releases/tag/0.8.15) - 2020-04-15 + +🐛 **Fixes** + +- added missing `ext-json` requirement, due to `BigNumber` implementing `JsonSerializable` + +⚡️ **Optimizations** + +- additional optimization in `BigInteger::remainder()` + +## [0.8.14](https://github.com/brick/math/releases/tag/0.8.14) - 2020-02-18 + +✨ **New features** + +- `BigInteger::getLowestSetBit()` returns the index of the rightmost one bit + +## [0.8.13](https://github.com/brick/math/releases/tag/0.8.13) - 2020-02-16 + +✨ **New features** + +- `BigInteger::isEven()` tests whether the number is even +- `BigInteger::isOdd()` tests whether the number is odd +- `BigInteger::testBit()` tests if a bit is set +- `BigInteger::getBitLength()` returns the number of bits in the minimal representation of the number + +## [0.8.12](https://github.com/brick/math/releases/tag/0.8.12) - 2020-02-03 + +🛠️ **Maintenance release** + +Classes are now annotated for better static analysis with [psalm](https://psalm.dev/). + +This is a maintenance release: no bug fixes, no new features, no breaking changes. + +## [0.8.11](https://github.com/brick/math/releases/tag/0.8.11) - 2020-01-23 + +✨ **New feature** + +`BigInteger::powerMod()` performs a power-with-modulo operation. Useful for crypto. + +## [0.8.10](https://github.com/brick/math/releases/tag/0.8.10) - 2020-01-21 + +✨ **New feature** + +`BigInteger::mod()` returns the **modulo** of two numbers. The *modulo* differs from the *remainder* when the signs of the operands are different. + +## [0.8.9](https://github.com/brick/math/releases/tag/0.8.9) - 2020-01-08 + +⚡️ **Performance improvements** + +A few additional optimizations in `BigInteger` and `BigDecimal` when one of the operands can be returned as is. Thanks to @tomtomsen in #24. + +## [0.8.8](https://github.com/brick/math/releases/tag/0.8.8) - 2019-04-25 + +🐛 **Bug fixes** + +- `BigInteger::toBase()` could return an empty string for zero values (BCMath & Native calculators only, GMP calculator unaffected) + +✨ **New features** + +- `BigInteger::toArbitraryBase()` converts a number to an arbitrary base, using a custom alphabet +- `BigInteger::fromArbitraryBase()` converts a string in an arbitrary base, using a custom alphabet, back to a number + +These methods can be used as the foundation to convert strings between different bases/alphabets, using BigInteger as an intermediate representation. + +💩 **Deprecations** + +- `BigInteger::parse()` is now deprecated in favour of `fromBase()` + +`BigInteger::fromBase()` works the same way as `parse()`, with 2 minor differences: + +- the `$base` parameter is required, it does not default to `10` +- it throws a `NumberFormatException` instead of an `InvalidArgumentException` when the number is malformed + +## [0.8.7](https://github.com/brick/math/releases/tag/0.8.7) - 2019-04-20 + +**Improvements** + +- Safer conversion from `float` when using custom locales +- **Much faster** `NativeCalculator` implementation 🚀 + +You can expect **at least a 3x performance improvement** for common arithmetic operations when using the library on systems without GMP or BCMath; it gets exponentially faster on multiplications with a high number of digits. This is due to calculations now being performed on whole blocks of digits (the block size depending on the platform, 32-bit or 64-bit) instead of digit-by-digit as before. + +## [0.8.6](https://github.com/brick/math/releases/tag/0.8.6) - 2019-04-11 + +**New method** + +`BigNumber::sum()` returns the sum of one or more numbers. + +## [0.8.5](https://github.com/brick/math/releases/tag/0.8.5) - 2019-02-12 + +**Bug fix**: `of()` factory methods could fail when passing a `float` in environments using a `LC_NUMERIC` locale with a decimal separator other than `'.'` (#20). + +Thanks @manowark 👍 + +## [0.8.4](https://github.com/brick/math/releases/tag/0.8.4) - 2018-12-07 + +**New method** + +`BigDecimal::sqrt()` calculates the square root of a decimal number, to a given scale. + +## [0.8.3](https://github.com/brick/math/releases/tag/0.8.3) - 2018-12-06 + +**New method** + +`BigInteger::sqrt()` calculates the square root of a number (thanks @peter279k). + +**New exception** + +`NegativeNumberException` is thrown when calling `sqrt()` on a negative number. + +## [0.8.2](https://github.com/brick/math/releases/tag/0.8.2) - 2018-11-08 + +**Performance update** + +- Further improvement of `toInt()` performance +- `NativeCalculator` can now perform some multiplications more efficiently + +## [0.8.1](https://github.com/brick/math/releases/tag/0.8.1) - 2018-11-07 + +Performance optimization of `toInt()` methods. + +## [0.8.0](https://github.com/brick/math/releases/tag/0.8.0) - 2018-10-13 + +**Breaking changes** + +The following deprecated methods have been removed. Use the new method name instead: + +| Method removed | Replacement method | +| --- | --- | +| `BigDecimal::getIntegral()` | `BigDecimal::getIntegralPart()` | +| `BigDecimal::getFraction()` | `BigDecimal::getFractionalPart()` | + +--- + +**New features** + +`BigInteger` has been augmented with 5 new methods for bitwise operations: + +| New method | Description | +| --- | --- | +| `and()` | performs a bitwise `AND` operation on two numbers | +| `or()` | performs a bitwise `OR` operation on two numbers | +| `xor()` | performs a bitwise `XOR` operation on two numbers | +| `shiftedLeft()` | returns the number shifted left by a number of bits | +| `shiftedRight()` | returns the number shifted right by a number of bits | + +Thanks to @DASPRiD 👍 + +## [0.7.3](https://github.com/brick/math/releases/tag/0.7.3) - 2018-08-20 + +**New method:** `BigDecimal::hasNonZeroFractionalPart()` + +**Renamed/deprecated methods:** + +- `BigDecimal::getIntegral()` has been renamed to `getIntegralPart()` and is now deprecated +- `BigDecimal::getFraction()` has been renamed to `getFractionalPart()` and is now deprecated + +## [0.7.2](https://github.com/brick/math/releases/tag/0.7.2) - 2018-07-21 + +**Performance update** + +`BigInteger::parse()` and `toBase()` now use GMP's built-in base conversion features when available. + +## [0.7.1](https://github.com/brick/math/releases/tag/0.7.1) - 2018-03-01 + +This is a maintenance release, no code has been changed. + +- When installed with `--no-dev`, the autoloader does not autoload tests anymore +- Tests and other files unnecessary for production are excluded from the dist package + +This will help make installations more compact. + +## [0.7.0](https://github.com/brick/math/releases/tag/0.7.0) - 2017-10-02 + +Methods renamed: + +- `BigNumber:sign()` has been renamed to `getSign()` +- `BigDecimal::unscaledValue()` has been renamed to `getUnscaledValue()` +- `BigDecimal::scale()` has been renamed to `getScale()` +- `BigDecimal::integral()` has been renamed to `getIntegral()` +- `BigDecimal::fraction()` has been renamed to `getFraction()` +- `BigRational::numerator()` has been renamed to `getNumerator()` +- `BigRational::denominator()` has been renamed to `getDenominator()` + +Classes renamed: + +- `ArithmeticException` has been renamed to `MathException` + +## [0.6.2](https://github.com/brick/math/releases/tag/0.6.2) - 2017-10-02 + +The base class for all exceptions is now `MathException`. +`ArithmeticException` has been deprecated, and will be removed in 0.7.0. + +## [0.6.1](https://github.com/brick/math/releases/tag/0.6.1) - 2017-10-02 + +A number of methods have been renamed: + +- `BigNumber:sign()` is deprecated; use `getSign()` instead +- `BigDecimal::unscaledValue()` is deprecated; use `getUnscaledValue()` instead +- `BigDecimal::scale()` is deprecated; use `getScale()` instead +- `BigDecimal::integral()` is deprecated; use `getIntegral()` instead +- `BigDecimal::fraction()` is deprecated; use `getFraction()` instead +- `BigRational::numerator()` is deprecated; use `getNumerator()` instead +- `BigRational::denominator()` is deprecated; use `getDenominator()` instead + +The old methods will be removed in version 0.7.0. + +## [0.6.0](https://github.com/brick/math/releases/tag/0.6.0) - 2017-08-25 + +- Minimum PHP version is now [7.1](https://gophp71.org/); for PHP 5.6 and PHP 7.0 support, use version `0.5` +- Deprecated method `BigDecimal::withScale()` has been removed; use `toScale()` instead +- Method `BigNumber::toInteger()` has been renamed to `toInt()` + +## [0.5.4](https://github.com/brick/math/releases/tag/0.5.4) - 2016-10-17 + +`BigNumber` classes now implement [JsonSerializable](http://php.net/manual/en/class.jsonserializable.php). +The JSON output is always a string. + +## [0.5.3](https://github.com/brick/math/releases/tag/0.5.3) - 2016-03-31 + +This is a bugfix release. Dividing by a negative power of 1 with the same scale as the dividend could trigger an incorrect optimization which resulted in a wrong result. See #6. + +## [0.5.2](https://github.com/brick/math/releases/tag/0.5.2) - 2015-08-06 + +The `$scale` parameter of `BigDecimal::dividedBy()` is now optional again. + +## [0.5.1](https://github.com/brick/math/releases/tag/0.5.1) - 2015-07-05 + +**New method: `BigNumber::toScale()`** + +This allows to convert any `BigNumber` to a `BigDecimal` with a given scale, using rounding if necessary. + +## [0.5.0](https://github.com/brick/math/releases/tag/0.5.0) - 2015-07-04 + +**New features** +- Common `BigNumber` interface for all classes, with the following methods: + - `sign()` and derived methods (`isZero()`, `isPositive()`, ...) + - `compareTo()` and derived methods (`isEqualTo()`, `isGreaterThan()`, ...) that work across different `BigNumber` types + - `toBigInteger()`, `toBigDecimal()`, `toBigRational`() conversion methods + - `toInteger()` and `toFloat()` conversion methods to native types +- Unified `of()` behaviour: every class now accepts any type of number, provided that it can be safely converted to the current type +- New method: `BigDecimal::exactlyDividedBy()`; this method automatically computes the scale of the result, provided that the division yields a finite number of digits +- New methods: `BigRational::quotient()` and `remainder()` +- Fine-grained exceptions: `DivisionByZeroException`, `RoundingNecessaryException`, `NumberFormatException` +- Factory methods `zero()`, `one()` and `ten()` available in all classes +- Rounding mode reintroduced in `BigInteger::dividedBy()` + +This release also comes with many performance improvements. + +--- + +**Breaking changes** +- `BigInteger`: + - `getSign()` is renamed to `sign()` + - `toString()` is renamed to `toBase()` + - `BigInteger::dividedBy()` now throws an exception by default if the remainder is not zero; use `quotient()` to get the previous behaviour +- `BigDecimal`: + - `getSign()` is renamed to `sign()` + - `getUnscaledValue()` is renamed to `unscaledValue()` + - `getScale()` is renamed to `scale()` + - `getIntegral()` is renamed to `integral()` + - `getFraction()` is renamed to `fraction()` + - `divideAndRemainder()` is renamed to `quotientAndRemainder()` + - `dividedBy()` now takes a **mandatory** `$scale` parameter **before** the rounding mode + - `toBigInteger()` does not accept a `$roundingMode` parameter anymore + - `toBigRational()` does not simplify the fraction anymore; explicitly add `->simplified()` to get the previous behaviour +- `BigRational`: + - `getSign()` is renamed to `sign()` + - `getNumerator()` is renamed to `numerator()` + - `getDenominator()` is renamed to `denominator()` + - `of()` is renamed to `nd()`, while `parse()` is renamed to `of()` +- Miscellaneous: + - `ArithmeticException` is moved to an `Exception\` sub-namespace + - `of()` factory methods now throw `NumberFormatException` instead of `InvalidArgumentException` + +## [0.4.3](https://github.com/brick/math/releases/tag/0.4.3) - 2016-03-31 + +Backport of two bug fixes from the 0.5 branch: +- `BigInteger::parse()` did not always throw `InvalidArgumentException` as expected +- Dividing by a negative power of 1 with the same scale as the dividend could trigger an incorrect optimization which resulted in a wrong result. See #6. + +## [0.4.2](https://github.com/brick/math/releases/tag/0.4.2) - 2015-06-16 + +New method: `BigDecimal::stripTrailingZeros()` + +## [0.4.1](https://github.com/brick/math/releases/tag/0.4.1) - 2015-06-12 + +Introducing a `BigRational` class, to perform calculations on fractions of any size. + +## [0.4.0](https://github.com/brick/math/releases/tag/0.4.0) - 2015-06-12 + +Rounding modes have been removed from `BigInteger`, and are now a concept specific to `BigDecimal`. + +`BigInteger::dividedBy()` now always returns the quotient of the division. + +## [0.3.5](https://github.com/brick/math/releases/tag/0.3.5) - 2016-03-31 + +Backport of two bug fixes from the 0.5 branch: + +- `BigInteger::parse()` did not always throw `InvalidArgumentException` as expected +- Dividing by a negative power of 1 with the same scale as the dividend could trigger an incorrect optimization which resulted in a wrong result. See #6. + +## [0.3.4](https://github.com/brick/math/releases/tag/0.3.4) - 2015-06-11 + +New methods: +- `BigInteger::remainder()` returns the remainder of a division only +- `BigInteger::gcd()` returns the greatest common divisor of two numbers + +## [0.3.3](https://github.com/brick/math/releases/tag/0.3.3) - 2015-06-07 + +Fix `toString()` not handling negative numbers. + +## [0.3.2](https://github.com/brick/math/releases/tag/0.3.2) - 2015-06-07 + +`BigInteger` and `BigDecimal` now have a `getSign()` method that returns: +- `-1` if the number is negative +- `0` if the number is zero +- `1` if the number is positive + +## [0.3.1](https://github.com/brick/math/releases/tag/0.3.1) - 2015-06-05 + +Minor performance improvements + +## [0.3.0](https://github.com/brick/math/releases/tag/0.3.0) - 2015-06-04 + +The `$roundingMode` and `$scale` parameters have been swapped in `BigDecimal::dividedBy()`. + +## [0.2.2](https://github.com/brick/math/releases/tag/0.2.2) - 2015-06-04 + +Stronger immutability guarantee for `BigInteger` and `BigDecimal`. + +So far, it would have been possible to break immutability of these classes by calling the `unserialize()` internal function. This release fixes that. + +## [0.2.1](https://github.com/brick/math/releases/tag/0.2.1) - 2015-06-02 + +Added `BigDecimal::divideAndRemainder()` + +## [0.2.0](https://github.com/brick/math/releases/tag/0.2.0) - 2015-05-22 + +- `min()` and `max()` do not accept an `array` anymore, but a variable number of parameters +- **minimum PHP version is now 5.6** +- continuous integration with PHP 7 + +## [0.1.1](https://github.com/brick/math/releases/tag/0.1.1) - 2014-09-01 + +- Added `BigInteger::power()` +- Added HHVM support + +## [0.1.0](https://github.com/brick/math/releases/tag/0.1.0) - 2014-08-31 + +First beta release. + diff --git a/vendor/brick/math/LICENSE b/vendor/brick/math/LICENSE new file mode 100644 index 0000000..f9b724f --- /dev/null +++ b/vendor/brick/math/LICENSE @@ -0,0 +1,20 @@ +The MIT License (MIT) + +Copyright (c) 2013-present Benjamin Morel + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software is furnished to do so, +subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/vendor/brick/math/composer.json b/vendor/brick/math/composer.json new file mode 100644 index 0000000..ed817bd --- /dev/null +++ b/vendor/brick/math/composer.json @@ -0,0 +1,34 @@ +{ + "name": "brick/math", + "description": "Arbitrary-precision arithmetic library", + "type": "library", + "keywords": [ + "Brick", + "Math", + "Arbitrary-precision", + "Arithmetic", + "BigInteger", + "BigDecimal", + "BigRational", + "Bignum" + ], + "license": "MIT", + "require": { + "php": "^8.0" + }, + "require-dev": { + "phpunit/phpunit": "^9.0", + "php-coveralls/php-coveralls": "^2.2", + "vimeo/psalm": "5.0.0" + }, + "autoload": { + "psr-4": { + "Brick\\Math\\": "src/" + } + }, + "autoload-dev": { + "psr-4": { + "Brick\\Math\\Tests\\": "tests/" + } + } +} diff --git a/vendor/brick/math/src/BigDecimal.php b/vendor/brick/math/src/BigDecimal.php new file mode 100644 index 0000000..02fc656 --- /dev/null +++ b/vendor/brick/math/src/BigDecimal.php @@ -0,0 +1,786 @@ +value = $value; + $this->scale = $scale; + } + + /** + * Creates a BigDecimal of the given value. + * + * @throws MathException If the value cannot be converted to a BigDecimal. + * + * @psalm-pure + */ + public static function of(BigNumber|int|float|string $value) : BigDecimal + { + return parent::of($value)->toBigDecimal(); + } + + /** + * Creates a BigDecimal from an unscaled value and a scale. + * + * Example: `(12345, 3)` will result in the BigDecimal `12.345`. + * + * @param BigNumber|int|float|string $value The unscaled value. Must be convertible to a BigInteger. + * @param int $scale The scale of the number, positive or zero. + * + * @throws \InvalidArgumentException If the scale is negative. + * + * @psalm-pure + */ + public static function ofUnscaledValue(BigNumber|int|float|string $value, int $scale = 0) : BigDecimal + { + if ($scale < 0) { + throw new \InvalidArgumentException('The scale cannot be negative.'); + } + + return new BigDecimal((string) BigInteger::of($value), $scale); + } + + /** + * Returns a BigDecimal representing zero, with a scale of zero. + * + * @psalm-pure + */ + public static function zero() : BigDecimal + { + /** + * @psalm-suppress ImpureStaticVariable + * @var BigDecimal|null $zero + */ + static $zero; + + if ($zero === null) { + $zero = new BigDecimal('0'); + } + + return $zero; + } + + /** + * Returns a BigDecimal representing one, with a scale of zero. + * + * @psalm-pure + */ + public static function one() : BigDecimal + { + /** + * @psalm-suppress ImpureStaticVariable + * @var BigDecimal|null $one + */ + static $one; + + if ($one === null) { + $one = new BigDecimal('1'); + } + + return $one; + } + + /** + * Returns a BigDecimal representing ten, with a scale of zero. + * + * @psalm-pure + */ + public static function ten() : BigDecimal + { + /** + * @psalm-suppress ImpureStaticVariable + * @var BigDecimal|null $ten + */ + static $ten; + + if ($ten === null) { + $ten = new BigDecimal('10'); + } + + return $ten; + } + + /** + * Returns the sum of this number and the given one. + * + * The result has a scale of `max($this->scale, $that->scale)`. + * + * @param BigNumber|int|float|string $that The number to add. Must be convertible to a BigDecimal. + * + * @throws MathException If the number is not valid, or is not convertible to a BigDecimal. + */ + public function plus(BigNumber|int|float|string $that) : BigDecimal + { + $that = BigDecimal::of($that); + + if ($that->value === '0' && $that->scale <= $this->scale) { + return $this; + } + + if ($this->value === '0' && $this->scale <= $that->scale) { + return $that; + } + + [$a, $b] = $this->scaleValues($this, $that); + + $value = Calculator::get()->add($a, $b); + $scale = $this->scale > $that->scale ? $this->scale : $that->scale; + + return new BigDecimal($value, $scale); + } + + /** + * Returns the difference of this number and the given one. + * + * The result has a scale of `max($this->scale, $that->scale)`. + * + * @param BigNumber|int|float|string $that The number to subtract. Must be convertible to a BigDecimal. + * + * @throws MathException If the number is not valid, or is not convertible to a BigDecimal. + */ + public function minus(BigNumber|int|float|string $that) : BigDecimal + { + $that = BigDecimal::of($that); + + if ($that->value === '0' && $that->scale <= $this->scale) { + return $this; + } + + [$a, $b] = $this->scaleValues($this, $that); + + $value = Calculator::get()->sub($a, $b); + $scale = $this->scale > $that->scale ? $this->scale : $that->scale; + + return new BigDecimal($value, $scale); + } + + /** + * Returns the product of this number and the given one. + * + * The result has a scale of `$this->scale + $that->scale`. + * + * @param BigNumber|int|float|string $that The multiplier. Must be convertible to a BigDecimal. + * + * @throws MathException If the multiplier is not a valid number, or is not convertible to a BigDecimal. + */ + public function multipliedBy(BigNumber|int|float|string $that) : BigDecimal + { + $that = BigDecimal::of($that); + + if ($that->value === '1' && $that->scale === 0) { + return $this; + } + + if ($this->value === '1' && $this->scale === 0) { + return $that; + } + + $value = Calculator::get()->mul($this->value, $that->value); + $scale = $this->scale + $that->scale; + + return new BigDecimal($value, $scale); + } + + /** + * Returns the result of the division of this number by the given one, at the given scale. + * + * @param BigNumber|int|float|string $that The divisor. + * @param int|null $scale The desired scale, or null to use the scale of this number. + * @param int $roundingMode An optional rounding mode. + * + * @throws \InvalidArgumentException If the scale or rounding mode is invalid. + * @throws MathException If the number is invalid, is zero, or rounding was necessary. + */ + public function dividedBy(BigNumber|int|float|string $that, ?int $scale = null, int $roundingMode = RoundingMode::UNNECESSARY) : BigDecimal + { + $that = BigDecimal::of($that); + + if ($that->isZero()) { + throw DivisionByZeroException::divisionByZero(); + } + + if ($scale === null) { + $scale = $this->scale; + } elseif ($scale < 0) { + throw new \InvalidArgumentException('Scale cannot be negative.'); + } + + if ($that->value === '1' && $that->scale === 0 && $scale === $this->scale) { + return $this; + } + + $p = $this->valueWithMinScale($that->scale + $scale); + $q = $that->valueWithMinScale($this->scale - $scale); + + $result = Calculator::get()->divRound($p, $q, $roundingMode); + + return new BigDecimal($result, $scale); + } + + /** + * Returns the exact result of the division of this number by the given one. + * + * The scale of the result is automatically calculated to fit all the fraction digits. + * + * @param BigNumber|int|float|string $that The divisor. Must be convertible to a BigDecimal. + * + * @throws MathException If the divisor is not a valid number, is not convertible to a BigDecimal, is zero, + * or the result yields an infinite number of digits. + */ + public function exactlyDividedBy(BigNumber|int|float|string $that) : BigDecimal + { + $that = BigDecimal::of($that); + + if ($that->value === '0') { + throw DivisionByZeroException::divisionByZero(); + } + + [, $b] = $this->scaleValues($this, $that); + + $d = \rtrim($b, '0'); + $scale = \strlen($b) - \strlen($d); + + $calculator = Calculator::get(); + + foreach ([5, 2] as $prime) { + for (;;) { + $lastDigit = (int) $d[-1]; + + if ($lastDigit % $prime !== 0) { + break; + } + + $d = $calculator->divQ($d, (string) $prime); + $scale++; + } + } + + return $this->dividedBy($that, $scale)->stripTrailingZeros(); + } + + /** + * Returns this number exponentiated to the given value. + * + * The result has a scale of `$this->scale * $exponent`. + * + * @throws \InvalidArgumentException If the exponent is not in the range 0 to 1,000,000. + */ + public function power(int $exponent) : BigDecimal + { + if ($exponent === 0) { + return BigDecimal::one(); + } + + if ($exponent === 1) { + return $this; + } + + if ($exponent < 0 || $exponent > Calculator::MAX_POWER) { + throw new \InvalidArgumentException(\sprintf( + 'The exponent %d is not in the range 0 to %d.', + $exponent, + Calculator::MAX_POWER + )); + } + + return new BigDecimal(Calculator::get()->pow($this->value, $exponent), $this->scale * $exponent); + } + + /** + * Returns the quotient of the division of this number by this given one. + * + * The quotient has a scale of `0`. + * + * @param BigNumber|int|float|string $that The divisor. Must be convertible to a BigDecimal. + * + * @throws MathException If the divisor is not a valid decimal number, or is zero. + */ + public function quotient(BigNumber|int|float|string $that) : BigDecimal + { + $that = BigDecimal::of($that); + + if ($that->isZero()) { + throw DivisionByZeroException::divisionByZero(); + } + + $p = $this->valueWithMinScale($that->scale); + $q = $that->valueWithMinScale($this->scale); + + $quotient = Calculator::get()->divQ($p, $q); + + return new BigDecimal($quotient, 0); + } + + /** + * Returns the remainder of the division of this number by this given one. + * + * The remainder has a scale of `max($this->scale, $that->scale)`. + * + * @param BigNumber|int|float|string $that The divisor. Must be convertible to a BigDecimal. + * + * @throws MathException If the divisor is not a valid decimal number, or is zero. + */ + public function remainder(BigNumber|int|float|string $that) : BigDecimal + { + $that = BigDecimal::of($that); + + if ($that->isZero()) { + throw DivisionByZeroException::divisionByZero(); + } + + $p = $this->valueWithMinScale($that->scale); + $q = $that->valueWithMinScale($this->scale); + + $remainder = Calculator::get()->divR($p, $q); + + $scale = $this->scale > $that->scale ? $this->scale : $that->scale; + + return new BigDecimal($remainder, $scale); + } + + /** + * Returns the quotient and remainder of the division of this number by the given one. + * + * The quotient has a scale of `0`, and the remainder has a scale of `max($this->scale, $that->scale)`. + * + * @param BigNumber|int|float|string $that The divisor. Must be convertible to a BigDecimal. + * + * @return BigDecimal[] An array containing the quotient and the remainder. + * + * @throws MathException If the divisor is not a valid decimal number, or is zero. + */ + public function quotientAndRemainder(BigNumber|int|float|string $that) : array + { + $that = BigDecimal::of($that); + + if ($that->isZero()) { + throw DivisionByZeroException::divisionByZero(); + } + + $p = $this->valueWithMinScale($that->scale); + $q = $that->valueWithMinScale($this->scale); + + [$quotient, $remainder] = Calculator::get()->divQR($p, $q); + + $scale = $this->scale > $that->scale ? $this->scale : $that->scale; + + $quotient = new BigDecimal($quotient, 0); + $remainder = new BigDecimal($remainder, $scale); + + return [$quotient, $remainder]; + } + + /** + * Returns the square root of this number, rounded down to the given number of decimals. + * + * @throws \InvalidArgumentException If the scale is negative. + * @throws NegativeNumberException If this number is negative. + */ + public function sqrt(int $scale) : BigDecimal + { + if ($scale < 0) { + throw new \InvalidArgumentException('Scale cannot be negative.'); + } + + if ($this->value === '0') { + return new BigDecimal('0', $scale); + } + + if ($this->value[0] === '-') { + throw new NegativeNumberException('Cannot calculate the square root of a negative number.'); + } + + $value = $this->value; + $addDigits = 2 * $scale - $this->scale; + + if ($addDigits > 0) { + // add zeros + $value .= \str_repeat('0', $addDigits); + } elseif ($addDigits < 0) { + // trim digits + if (-$addDigits >= \strlen($this->value)) { + // requesting a scale too low, will always yield a zero result + return new BigDecimal('0', $scale); + } + + $value = \substr($value, 0, $addDigits); + } + + $value = Calculator::get()->sqrt($value); + + return new BigDecimal($value, $scale); + } + + /** + * Returns a copy of this BigDecimal with the decimal point moved $n places to the left. + */ + public function withPointMovedLeft(int $n) : BigDecimal + { + if ($n === 0) { + return $this; + } + + if ($n < 0) { + return $this->withPointMovedRight(-$n); + } + + return new BigDecimal($this->value, $this->scale + $n); + } + + /** + * Returns a copy of this BigDecimal with the decimal point moved $n places to the right. + */ + public function withPointMovedRight(int $n) : BigDecimal + { + if ($n === 0) { + return $this; + } + + if ($n < 0) { + return $this->withPointMovedLeft(-$n); + } + + $value = $this->value; + $scale = $this->scale - $n; + + if ($scale < 0) { + if ($value !== '0') { + $value .= \str_repeat('0', -$scale); + } + $scale = 0; + } + + return new BigDecimal($value, $scale); + } + + /** + * Returns a copy of this BigDecimal with any trailing zeros removed from the fractional part. + */ + public function stripTrailingZeros() : BigDecimal + { + if ($this->scale === 0) { + return $this; + } + + $trimmedValue = \rtrim($this->value, '0'); + + if ($trimmedValue === '') { + return BigDecimal::zero(); + } + + $trimmableZeros = \strlen($this->value) - \strlen($trimmedValue); + + if ($trimmableZeros === 0) { + return $this; + } + + if ($trimmableZeros > $this->scale) { + $trimmableZeros = $this->scale; + } + + $value = \substr($this->value, 0, -$trimmableZeros); + $scale = $this->scale - $trimmableZeros; + + return new BigDecimal($value, $scale); + } + + /** + * Returns the absolute value of this number. + */ + public function abs() : BigDecimal + { + return $this->isNegative() ? $this->negated() : $this; + } + + /** + * Returns the negated value of this number. + */ + public function negated() : BigDecimal + { + return new BigDecimal(Calculator::get()->neg($this->value), $this->scale); + } + + public function compareTo(BigNumber|int|float|string $that) : int + { + $that = BigNumber::of($that); + + if ($that instanceof BigInteger) { + $that = $that->toBigDecimal(); + } + + if ($that instanceof BigDecimal) { + [$a, $b] = $this->scaleValues($this, $that); + + return Calculator::get()->cmp($a, $b); + } + + return - $that->compareTo($this); + } + + public function getSign() : int + { + return ($this->value === '0') ? 0 : (($this->value[0] === '-') ? -1 : 1); + } + + public function getUnscaledValue() : BigInteger + { + return self::newBigInteger($this->value); + } + + public function getScale() : int + { + return $this->scale; + } + + /** + * Returns a string representing the integral part of this decimal number. + * + * Example: `-123.456` => `-123`. + */ + public function getIntegralPart() : string + { + if ($this->scale === 0) { + return $this->value; + } + + $value = $this->getUnscaledValueWithLeadingZeros(); + + return \substr($value, 0, -$this->scale); + } + + /** + * Returns a string representing the fractional part of this decimal number. + * + * If the scale is zero, an empty string is returned. + * + * Examples: `-123.456` => '456', `123` => ''. + */ + public function getFractionalPart() : string + { + if ($this->scale === 0) { + return ''; + } + + $value = $this->getUnscaledValueWithLeadingZeros(); + + return \substr($value, -$this->scale); + } + + /** + * Returns whether this decimal number has a non-zero fractional part. + */ + public function hasNonZeroFractionalPart() : bool + { + return $this->getFractionalPart() !== \str_repeat('0', $this->scale); + } + + public function toBigInteger() : BigInteger + { + $zeroScaleDecimal = $this->scale === 0 ? $this : $this->dividedBy(1, 0); + + return self::newBigInteger($zeroScaleDecimal->value); + } + + public function toBigDecimal() : BigDecimal + { + return $this; + } + + public function toBigRational() : BigRational + { + $numerator = self::newBigInteger($this->value); + $denominator = self::newBigInteger('1' . \str_repeat('0', $this->scale)); + + return self::newBigRational($numerator, $denominator, false); + } + + public function toScale(int $scale, int $roundingMode = RoundingMode::UNNECESSARY) : BigDecimal + { + if ($scale === $this->scale) { + return $this; + } + + return $this->dividedBy(BigDecimal::one(), $scale, $roundingMode); + } + + public function toInt() : int + { + return $this->toBigInteger()->toInt(); + } + + public function toFloat() : float + { + return (float) (string) $this; + } + + public function __toString() : string + { + if ($this->scale === 0) { + return $this->value; + } + + $value = $this->getUnscaledValueWithLeadingZeros(); + + return \substr($value, 0, -$this->scale) . '.' . \substr($value, -$this->scale); + } + + /** + * This method is required for serializing the object and SHOULD NOT be accessed directly. + * + * @internal + * + * @return array{value: string, scale: int} + */ + public function __serialize(): array + { + return ['value' => $this->value, 'scale' => $this->scale]; + } + + /** + * This method is only here to allow unserializing the object and cannot be accessed directly. + * + * @internal + * @psalm-suppress RedundantPropertyInitializationCheck + * + * @param array{value: string, scale: int} $data + * + * @throws \LogicException + */ + public function __unserialize(array $data): void + { + if (isset($this->value)) { + throw new \LogicException('__unserialize() is an internal function, it must not be called directly.'); + } + + $this->value = $data['value']; + $this->scale = $data['scale']; + } + + /** + * This method is required by interface Serializable and SHOULD NOT be accessed directly. + * + * @internal + */ + public function serialize() : string + { + return $this->value . ':' . $this->scale; + } + + /** + * This method is only here to implement interface Serializable and cannot be accessed directly. + * + * @internal + * @psalm-suppress RedundantPropertyInitializationCheck + * + * @throws \LogicException + */ + public function unserialize($value) : void + { + if (isset($this->value)) { + throw new \LogicException('unserialize() is an internal function, it must not be called directly.'); + } + + [$value, $scale] = \explode(':', $value); + + $this->value = $value; + $this->scale = (int) $scale; + } + + /** + * Puts the internal values of the given decimal numbers on the same scale. + * + * @return array{string, string} The scaled integer values of $x and $y. + */ + private function scaleValues(BigDecimal $x, BigDecimal $y) : array + { + $a = $x->value; + $b = $y->value; + + if ($b !== '0' && $x->scale > $y->scale) { + $b .= \str_repeat('0', $x->scale - $y->scale); + } elseif ($a !== '0' && $x->scale < $y->scale) { + $a .= \str_repeat('0', $y->scale - $x->scale); + } + + return [$a, $b]; + } + + private function valueWithMinScale(int $scale) : string + { + $value = $this->value; + + if ($this->value !== '0' && $scale > $this->scale) { + $value .= \str_repeat('0', $scale - $this->scale); + } + + return $value; + } + + /** + * Adds leading zeros if necessary to the unscaled value to represent the full decimal number. + */ + private function getUnscaledValueWithLeadingZeros() : string + { + $value = $this->value; + $targetLength = $this->scale + 1; + $negative = ($value[0] === '-'); + $length = \strlen($value); + + if ($negative) { + $length--; + } + + if ($length >= $targetLength) { + return $this->value; + } + + if ($negative) { + $value = \substr($value, 1); + } + + $value = \str_pad($value, $targetLength, '0', STR_PAD_LEFT); + + if ($negative) { + $value = '-' . $value; + } + + return $value; + } +} diff --git a/vendor/brick/math/src/BigInteger.php b/vendor/brick/math/src/BigInteger.php new file mode 100644 index 0000000..4356793 --- /dev/null +++ b/vendor/brick/math/src/BigInteger.php @@ -0,0 +1,1079 @@ +value = $value; + } + + /** + * Creates a BigInteger of the given value. + * + * @throws MathException If the value cannot be converted to a BigInteger. + * + * @psalm-pure + */ + public static function of(BigNumber|int|float|string $value) : BigInteger + { + return parent::of($value)->toBigInteger(); + } + + /** + * Creates a number from a string in a given base. + * + * The string can optionally be prefixed with the `+` or `-` sign. + * + * Bases greater than 36 are not supported by this method, as there is no clear consensus on which of the lowercase + * or uppercase characters should come first. Instead, this method accepts any base up to 36, and does not + * differentiate lowercase and uppercase characters, which are considered equal. + * + * For bases greater than 36, and/or custom alphabets, use the fromArbitraryBase() method. + * + * @param string $number The number to convert, in the given base. + * @param int $base The base of the number, between 2 and 36. + * + * @throws NumberFormatException If the number is empty, or contains invalid chars for the given base. + * @throws \InvalidArgumentException If the base is out of range. + * + * @psalm-pure + */ + public static function fromBase(string $number, int $base) : BigInteger + { + if ($number === '') { + throw new NumberFormatException('The number cannot be empty.'); + } + + if ($base < 2 || $base > 36) { + throw new \InvalidArgumentException(\sprintf('Base %d is not in range 2 to 36.', $base)); + } + + if ($number[0] === '-') { + $sign = '-'; + $number = \substr($number, 1); + } elseif ($number[0] === '+') { + $sign = ''; + $number = \substr($number, 1); + } else { + $sign = ''; + } + + if ($number === '') { + throw new NumberFormatException('The number cannot be empty.'); + } + + $number = \ltrim($number, '0'); + + if ($number === '') { + // The result will be the same in any base, avoid further calculation. + return BigInteger::zero(); + } + + if ($number === '1') { + // The result will be the same in any base, avoid further calculation. + return new BigInteger($sign . '1'); + } + + $pattern = '/[^' . \substr(Calculator::ALPHABET, 0, $base) . ']/'; + + if (\preg_match($pattern, \strtolower($number), $matches) === 1) { + throw new NumberFormatException(\sprintf('"%s" is not a valid character in base %d.', $matches[0], $base)); + } + + if ($base === 10) { + // The number is usable as is, avoid further calculation. + return new BigInteger($sign . $number); + } + + $result = Calculator::get()->fromBase($number, $base); + + return new BigInteger($sign . $result); + } + + /** + * Parses a string containing an integer in an arbitrary base, using a custom alphabet. + * + * Because this method accepts an alphabet with any character, including dash, it does not handle negative numbers. + * + * @param string $number The number to parse. + * @param string $alphabet The alphabet, for example '01' for base 2, or '01234567' for base 8. + * + * @throws NumberFormatException If the given number is empty or contains invalid chars for the given alphabet. + * @throws \InvalidArgumentException If the alphabet does not contain at least 2 chars. + * + * @psalm-pure + */ + public static function fromArbitraryBase(string $number, string $alphabet) : BigInteger + { + if ($number === '') { + throw new NumberFormatException('The number cannot be empty.'); + } + + $base = \strlen($alphabet); + + if ($base < 2) { + throw new \InvalidArgumentException('The alphabet must contain at least 2 chars.'); + } + + $pattern = '/[^' . \preg_quote($alphabet, '/') . ']/'; + + if (\preg_match($pattern, $number, $matches) === 1) { + throw NumberFormatException::charNotInAlphabet($matches[0]); + } + + $number = Calculator::get()->fromArbitraryBase($number, $alphabet, $base); + + return new BigInteger($number); + } + + /** + * Translates a string of bytes containing the binary representation of a BigInteger into a BigInteger. + * + * The input string is assumed to be in big-endian byte-order: the most significant byte is in the zeroth element. + * + * If `$signed` is true, the input is assumed to be in two's-complement representation, and the leading bit is + * interpreted as a sign bit. If `$signed` is false, the input is interpreted as an unsigned number, and the + * resulting BigInteger will always be positive or zero. + * + * This method can be used to retrieve a number exported by `toBytes()`, as long as the `$signed` flags match. + * + * @param string $value The byte string. + * @param bool $signed Whether to interpret as a signed number in two's-complement representation with a leading + * sign bit. + * + * @throws NumberFormatException If the string is empty. + */ + public static function fromBytes(string $value, bool $signed = true) : BigInteger + { + if ($value === '') { + throw new NumberFormatException('The byte string must not be empty.'); + } + + $twosComplement = false; + + if ($signed) { + $x = \ord($value[0]); + + if (($twosComplement = ($x >= 0x80))) { + $value = ~$value; + } + } + + $number = self::fromBase(\bin2hex($value), 16); + + if ($twosComplement) { + return $number->plus(1)->negated(); + } + + return $number; + } + + /** + * Generates a pseudo-random number in the range 0 to 2^numBits - 1. + * + * Using the default random bytes generator, this method is suitable for cryptographic use. + * + * @psalm-param (callable(int): string)|null $randomBytesGenerator + * + * @param int $numBits The number of bits. + * @param callable|null $randomBytesGenerator A function that accepts a number of bytes as an integer, and returns a + * string of random bytes of the given length. Defaults to the + * `random_bytes()` function. + * + * @throws \InvalidArgumentException If $numBits is negative. + */ + public static function randomBits(int $numBits, ?callable $randomBytesGenerator = null) : BigInteger + { + if ($numBits < 0) { + throw new \InvalidArgumentException('The number of bits cannot be negative.'); + } + + if ($numBits === 0) { + return BigInteger::zero(); + } + + if ($randomBytesGenerator === null) { + $randomBytesGenerator = 'random_bytes'; + } + + $byteLength = \intdiv($numBits - 1, 8) + 1; + + $extraBits = ($byteLength * 8 - $numBits); + $bitmask = \chr(0xFF >> $extraBits); + + $randomBytes = $randomBytesGenerator($byteLength); + $randomBytes[0] = $randomBytes[0] & $bitmask; + + return self::fromBytes($randomBytes, false); + } + + /** + * Generates a pseudo-random number between `$min` and `$max`. + * + * Using the default random bytes generator, this method is suitable for cryptographic use. + * + * @psalm-param (callable(int): string)|null $randomBytesGenerator + * + * @param BigNumber|int|float|string $min The lower bound. Must be convertible to a BigInteger. + * @param BigNumber|int|float|string $max The upper bound. Must be convertible to a BigInteger. + * @param callable|null $randomBytesGenerator A function that accepts a number of bytes as an integer, + * and returns a string of random bytes of the given length. + * Defaults to the `random_bytes()` function. + * + * @throws MathException If one of the parameters cannot be converted to a BigInteger, + * or `$min` is greater than `$max`. + */ + public static function randomRange( + BigNumber|int|float|string $min, + BigNumber|int|float|string $max, + ?callable $randomBytesGenerator = null + ) : BigInteger { + $min = BigInteger::of($min); + $max = BigInteger::of($max); + + if ($min->isGreaterThan($max)) { + throw new MathException('$min cannot be greater than $max.'); + } + + if ($min->isEqualTo($max)) { + return $min; + } + + $diff = $max->minus($min); + $bitLength = $diff->getBitLength(); + + // try until the number is in range (50% to 100% chance of success) + do { + $randomNumber = self::randomBits($bitLength, $randomBytesGenerator); + } while ($randomNumber->isGreaterThan($diff)); + + return $randomNumber->plus($min); + } + + /** + * Returns a BigInteger representing zero. + * + * @psalm-pure + */ + public static function zero() : BigInteger + { + /** + * @psalm-suppress ImpureStaticVariable + * @var BigInteger|null $zero + */ + static $zero; + + if ($zero === null) { + $zero = new BigInteger('0'); + } + + return $zero; + } + + /** + * Returns a BigInteger representing one. + * + * @psalm-pure + */ + public static function one() : BigInteger + { + /** + * @psalm-suppress ImpureStaticVariable + * @var BigInteger|null $one + */ + static $one; + + if ($one === null) { + $one = new BigInteger('1'); + } + + return $one; + } + + /** + * Returns a BigInteger representing ten. + * + * @psalm-pure + */ + public static function ten() : BigInteger + { + /** + * @psalm-suppress ImpureStaticVariable + * @var BigInteger|null $ten + */ + static $ten; + + if ($ten === null) { + $ten = new BigInteger('10'); + } + + return $ten; + } + + public static function gcdMultiple(BigInteger $a, BigInteger ...$n): BigInteger + { + $result = $a; + + foreach ($n as $next) { + $result = $result->gcd($next); + + if ($result->isEqualTo(1)) { + return $result; + } + } + + return $result; + } + + /** + * Returns the sum of this number and the given one. + * + * @param BigNumber|int|float|string $that The number to add. Must be convertible to a BigInteger. + * + * @throws MathException If the number is not valid, or is not convertible to a BigInteger. + */ + public function plus(BigNumber|int|float|string $that) : BigInteger + { + $that = BigInteger::of($that); + + if ($that->value === '0') { + return $this; + } + + if ($this->value === '0') { + return $that; + } + + $value = Calculator::get()->add($this->value, $that->value); + + return new BigInteger($value); + } + + /** + * Returns the difference of this number and the given one. + * + * @param BigNumber|int|float|string $that The number to subtract. Must be convertible to a BigInteger. + * + * @throws MathException If the number is not valid, or is not convertible to a BigInteger. + */ + public function minus(BigNumber|int|float|string $that) : BigInteger + { + $that = BigInteger::of($that); + + if ($that->value === '0') { + return $this; + } + + $value = Calculator::get()->sub($this->value, $that->value); + + return new BigInteger($value); + } + + /** + * Returns the product of this number and the given one. + * + * @param BigNumber|int|float|string $that The multiplier. Must be convertible to a BigInteger. + * + * @throws MathException If the multiplier is not a valid number, or is not convertible to a BigInteger. + */ + public function multipliedBy(BigNumber|int|float|string $that) : BigInteger + { + $that = BigInteger::of($that); + + if ($that->value === '1') { + return $this; + } + + if ($this->value === '1') { + return $that; + } + + $value = Calculator::get()->mul($this->value, $that->value); + + return new BigInteger($value); + } + + /** + * Returns the result of the division of this number by the given one. + * + * @param BigNumber|int|float|string $that The divisor. Must be convertible to a BigInteger. + * @param int $roundingMode An optional rounding mode. + * + * @throws MathException If the divisor is not a valid number, is not convertible to a BigInteger, is zero, + * or RoundingMode::UNNECESSARY is used and the remainder is not zero. + */ + public function dividedBy(BigNumber|int|float|string $that, int $roundingMode = RoundingMode::UNNECESSARY) : BigInteger + { + $that = BigInteger::of($that); + + if ($that->value === '1') { + return $this; + } + + if ($that->value === '0') { + throw DivisionByZeroException::divisionByZero(); + } + + $result = Calculator::get()->divRound($this->value, $that->value, $roundingMode); + + return new BigInteger($result); + } + + /** + * Returns this number exponentiated to the given value. + * + * @throws \InvalidArgumentException If the exponent is not in the range 0 to 1,000,000. + */ + public function power(int $exponent) : BigInteger + { + if ($exponent === 0) { + return BigInteger::one(); + } + + if ($exponent === 1) { + return $this; + } + + if ($exponent < 0 || $exponent > Calculator::MAX_POWER) { + throw new \InvalidArgumentException(\sprintf( + 'The exponent %d is not in the range 0 to %d.', + $exponent, + Calculator::MAX_POWER + )); + } + + return new BigInteger(Calculator::get()->pow($this->value, $exponent)); + } + + /** + * Returns the quotient of the division of this number by the given one. + * + * @param BigNumber|int|float|string $that The divisor. Must be convertible to a BigInteger. + * + * @throws DivisionByZeroException If the divisor is zero. + */ + public function quotient(BigNumber|int|float|string $that) : BigInteger + { + $that = BigInteger::of($that); + + if ($that->value === '1') { + return $this; + } + + if ($that->value === '0') { + throw DivisionByZeroException::divisionByZero(); + } + + $quotient = Calculator::get()->divQ($this->value, $that->value); + + return new BigInteger($quotient); + } + + /** + * Returns the remainder of the division of this number by the given one. + * + * The remainder, when non-zero, has the same sign as the dividend. + * + * @param BigNumber|int|float|string $that The divisor. Must be convertible to a BigInteger. + * + * @throws DivisionByZeroException If the divisor is zero. + */ + public function remainder(BigNumber|int|float|string $that) : BigInteger + { + $that = BigInteger::of($that); + + if ($that->value === '1') { + return BigInteger::zero(); + } + + if ($that->value === '0') { + throw DivisionByZeroException::divisionByZero(); + } + + $remainder = Calculator::get()->divR($this->value, $that->value); + + return new BigInteger($remainder); + } + + /** + * Returns the quotient and remainder of the division of this number by the given one. + * + * @param BigNumber|int|float|string $that The divisor. Must be convertible to a BigInteger. + * + * @return BigInteger[] An array containing the quotient and the remainder. + * + * @throws DivisionByZeroException If the divisor is zero. + */ + public function quotientAndRemainder(BigNumber|int|float|string $that) : array + { + $that = BigInteger::of($that); + + if ($that->value === '0') { + throw DivisionByZeroException::divisionByZero(); + } + + [$quotient, $remainder] = Calculator::get()->divQR($this->value, $that->value); + + return [ + new BigInteger($quotient), + new BigInteger($remainder) + ]; + } + + /** + * Returns the modulo of this number and the given one. + * + * The modulo operation yields the same result as the remainder operation when both operands are of the same sign, + * and may differ when signs are different. + * + * The result of the modulo operation, when non-zero, has the same sign as the divisor. + * + * @param BigNumber|int|float|string $that The divisor. Must be convertible to a BigInteger. + * + * @throws DivisionByZeroException If the divisor is zero. + */ + public function mod(BigNumber|int|float|string $that) : BigInteger + { + $that = BigInteger::of($that); + + if ($that->value === '0') { + throw DivisionByZeroException::modulusMustNotBeZero(); + } + + $value = Calculator::get()->mod($this->value, $that->value); + + return new BigInteger($value); + } + + /** + * Returns the modular multiplicative inverse of this BigInteger modulo $m. + * + * @throws DivisionByZeroException If $m is zero. + * @throws NegativeNumberException If $m is negative. + * @throws MathException If this BigInteger has no multiplicative inverse mod m (that is, this BigInteger + * is not relatively prime to m). + */ + public function modInverse(BigInteger $m) : BigInteger + { + if ($m->value === '0') { + throw DivisionByZeroException::modulusMustNotBeZero(); + } + + if ($m->isNegative()) { + throw new NegativeNumberException('Modulus must not be negative.'); + } + + if ($m->value === '1') { + return BigInteger::zero(); + } + + $value = Calculator::get()->modInverse($this->value, $m->value); + + if ($value === null) { + throw new MathException('Unable to compute the modInverse for the given modulus.'); + } + + return new BigInteger($value); + } + + /** + * Returns this number raised into power with modulo. + * + * This operation only works on positive numbers. + * + * @param BigNumber|int|float|string $exp The exponent. Must be positive or zero. + * @param BigNumber|int|float|string $mod The modulus. Must be strictly positive. + * + * @throws NegativeNumberException If any of the operands is negative. + * @throws DivisionByZeroException If the modulus is zero. + */ + public function modPow(BigNumber|int|float|string $exp, BigNumber|int|float|string $mod) : BigInteger + { + $exp = BigInteger::of($exp); + $mod = BigInteger::of($mod); + + if ($this->isNegative() || $exp->isNegative() || $mod->isNegative()) { + throw new NegativeNumberException('The operands cannot be negative.'); + } + + if ($mod->isZero()) { + throw DivisionByZeroException::modulusMustNotBeZero(); + } + + $result = Calculator::get()->modPow($this->value, $exp->value, $mod->value); + + return new BigInteger($result); + } + + /** + * Returns the greatest common divisor of this number and the given one. + * + * The GCD is always positive, unless both operands are zero, in which case it is zero. + * + * @param BigNumber|int|float|string $that The operand. Must be convertible to an integer number. + */ + public function gcd(BigNumber|int|float|string $that) : BigInteger + { + $that = BigInteger::of($that); + + if ($that->value === '0' && $this->value[0] !== '-') { + return $this; + } + + if ($this->value === '0' && $that->value[0] !== '-') { + return $that; + } + + $value = Calculator::get()->gcd($this->value, $that->value); + + return new BigInteger($value); + } + + /** + * Returns the integer square root number of this number, rounded down. + * + * The result is the largest x such that x² ≤ n. + * + * @throws NegativeNumberException If this number is negative. + */ + public function sqrt() : BigInteger + { + if ($this->value[0] === '-') { + throw new NegativeNumberException('Cannot calculate the square root of a negative number.'); + } + + $value = Calculator::get()->sqrt($this->value); + + return new BigInteger($value); + } + + /** + * Returns the absolute value of this number. + */ + public function abs() : BigInteger + { + return $this->isNegative() ? $this->negated() : $this; + } + + /** + * Returns the inverse of this number. + */ + public function negated() : BigInteger + { + return new BigInteger(Calculator::get()->neg($this->value)); + } + + /** + * Returns the integer bitwise-and combined with another integer. + * + * This method returns a negative BigInteger if and only if both operands are negative. + * + * @param BigNumber|int|float|string $that The operand. Must be convertible to an integer number. + */ + public function and(BigNumber|int|float|string $that) : BigInteger + { + $that = BigInteger::of($that); + + return new BigInteger(Calculator::get()->and($this->value, $that->value)); + } + + /** + * Returns the integer bitwise-or combined with another integer. + * + * This method returns a negative BigInteger if and only if either of the operands is negative. + * + * @param BigNumber|int|float|string $that The operand. Must be convertible to an integer number. + */ + public function or(BigNumber|int|float|string $that) : BigInteger + { + $that = BigInteger::of($that); + + return new BigInteger(Calculator::get()->or($this->value, $that->value)); + } + + /** + * Returns the integer bitwise-xor combined with another integer. + * + * This method returns a negative BigInteger if and only if exactly one of the operands is negative. + * + * @param BigNumber|int|float|string $that The operand. Must be convertible to an integer number. + */ + public function xor(BigNumber|int|float|string $that) : BigInteger + { + $that = BigInteger::of($that); + + return new BigInteger(Calculator::get()->xor($this->value, $that->value)); + } + + /** + * Returns the bitwise-not of this BigInteger. + */ + public function not() : BigInteger + { + return $this->negated()->minus(1); + } + + /** + * Returns the integer left shifted by a given number of bits. + */ + public function shiftedLeft(int $distance) : BigInteger + { + if ($distance === 0) { + return $this; + } + + if ($distance < 0) { + return $this->shiftedRight(- $distance); + } + + return $this->multipliedBy(BigInteger::of(2)->power($distance)); + } + + /** + * Returns the integer right shifted by a given number of bits. + */ + public function shiftedRight(int $distance) : BigInteger + { + if ($distance === 0) { + return $this; + } + + if ($distance < 0) { + return $this->shiftedLeft(- $distance); + } + + $operand = BigInteger::of(2)->power($distance); + + if ($this->isPositiveOrZero()) { + return $this->quotient($operand); + } + + return $this->dividedBy($operand, RoundingMode::UP); + } + + /** + * Returns the number of bits in the minimal two's-complement representation of this BigInteger, excluding a sign bit. + * + * For positive BigIntegers, this is equivalent to the number of bits in the ordinary binary representation. + * Computes (ceil(log2(this < 0 ? -this : this+1))). + */ + public function getBitLength() : int + { + if ($this->value === '0') { + return 0; + } + + if ($this->isNegative()) { + return $this->abs()->minus(1)->getBitLength(); + } + + return \strlen($this->toBase(2)); + } + + /** + * Returns the index of the rightmost (lowest-order) one bit in this BigInteger. + * + * Returns -1 if this BigInteger contains no one bits. + */ + public function getLowestSetBit() : int + { + $n = $this; + $bitLength = $this->getBitLength(); + + for ($i = 0; $i <= $bitLength; $i++) { + if ($n->isOdd()) { + return $i; + } + + $n = $n->shiftedRight(1); + } + + return -1; + } + + /** + * Returns whether this number is even. + */ + public function isEven() : bool + { + return \in_array($this->value[-1], ['0', '2', '4', '6', '8'], true); + } + + /** + * Returns whether this number is odd. + */ + public function isOdd() : bool + { + return \in_array($this->value[-1], ['1', '3', '5', '7', '9'], true); + } + + /** + * Returns true if and only if the designated bit is set. + * + * Computes ((this & (1<shiftedRight($n)->isOdd(); + } + + public function compareTo(BigNumber|int|float|string $that) : int + { + $that = BigNumber::of($that); + + if ($that instanceof BigInteger) { + return Calculator::get()->cmp($this->value, $that->value); + } + + return - $that->compareTo($this); + } + + public function getSign() : int + { + return ($this->value === '0') ? 0 : (($this->value[0] === '-') ? -1 : 1); + } + + public function toBigInteger() : BigInteger + { + return $this; + } + + public function toBigDecimal() : BigDecimal + { + return self::newBigDecimal($this->value); + } + + public function toBigRational() : BigRational + { + return self::newBigRational($this, BigInteger::one(), false); + } + + public function toScale(int $scale, int $roundingMode = RoundingMode::UNNECESSARY) : BigDecimal + { + return $this->toBigDecimal()->toScale($scale, $roundingMode); + } + + public function toInt() : int + { + $intValue = (int) $this->value; + + if ($this->value !== (string) $intValue) { + throw IntegerOverflowException::toIntOverflow($this); + } + + return $intValue; + } + + public function toFloat() : float + { + return (float) $this->value; + } + + /** + * Returns a string representation of this number in the given base. + * + * The output will always be lowercase for bases greater than 10. + * + * @throws \InvalidArgumentException If the base is out of range. + */ + public function toBase(int $base) : string + { + if ($base === 10) { + return $this->value; + } + + if ($base < 2 || $base > 36) { + throw new \InvalidArgumentException(\sprintf('Base %d is out of range [2, 36]', $base)); + } + + return Calculator::get()->toBase($this->value, $base); + } + + /** + * Returns a string representation of this number in an arbitrary base with a custom alphabet. + * + * Because this method accepts an alphabet with any character, including dash, it does not handle negative numbers; + * a NegativeNumberException will be thrown when attempting to call this method on a negative number. + * + * @param string $alphabet The alphabet, for example '01' for base 2, or '01234567' for base 8. + * + * @throws NegativeNumberException If this number is negative. + * @throws \InvalidArgumentException If the given alphabet does not contain at least 2 chars. + */ + public function toArbitraryBase(string $alphabet) : string + { + $base = \strlen($alphabet); + + if ($base < 2) { + throw new \InvalidArgumentException('The alphabet must contain at least 2 chars.'); + } + + if ($this->value[0] === '-') { + throw new NegativeNumberException(__FUNCTION__ . '() does not support negative numbers.'); + } + + return Calculator::get()->toArbitraryBase($this->value, $alphabet, $base); + } + + /** + * Returns a string of bytes containing the binary representation of this BigInteger. + * + * The string is in big-endian byte-order: the most significant byte is in the zeroth element. + * + * If `$signed` is true, the output will be in two's-complement representation, and a sign bit will be prepended to + * the output. If `$signed` is false, no sign bit will be prepended, and this method will throw an exception if the + * number is negative. + * + * The string will contain the minimum number of bytes required to represent this BigInteger, including a sign bit + * if `$signed` is true. + * + * This representation is compatible with the `fromBytes()` factory method, as long as the `$signed` flags match. + * + * @param bool $signed Whether to output a signed number in two's-complement representation with a leading sign bit. + * + * @throws NegativeNumberException If $signed is false, and the number is negative. + */ + public function toBytes(bool $signed = true) : string + { + if (! $signed && $this->isNegative()) { + throw new NegativeNumberException('Cannot convert a negative number to a byte string when $signed is false.'); + } + + $hex = $this->abs()->toBase(16); + + if (\strlen($hex) % 2 !== 0) { + $hex = '0' . $hex; + } + + $baseHexLength = \strlen($hex); + + if ($signed) { + if ($this->isNegative()) { + $bin = \hex2bin($hex); + assert($bin !== false); + + $hex = \bin2hex(~$bin); + $hex = self::fromBase($hex, 16)->plus(1)->toBase(16); + + $hexLength = \strlen($hex); + + if ($hexLength < $baseHexLength) { + $hex = \str_repeat('0', $baseHexLength - $hexLength) . $hex; + } + + if ($hex[0] < '8') { + $hex = 'FF' . $hex; + } + } else { + if ($hex[0] >= '8') { + $hex = '00' . $hex; + } + } + } + + return \hex2bin($hex); + } + + public function __toString() : string + { + return $this->value; + } + + /** + * This method is required for serializing the object and SHOULD NOT be accessed directly. + * + * @internal + * + * @return array{value: string} + */ + public function __serialize(): array + { + return ['value' => $this->value]; + } + + /** + * This method is only here to allow unserializing the object and cannot be accessed directly. + * + * @internal + * @psalm-suppress RedundantPropertyInitializationCheck + * + * @param array{value: string} $data + * + * @throws \LogicException + */ + public function __unserialize(array $data): void + { + if (isset($this->value)) { + throw new \LogicException('__unserialize() is an internal function, it must not be called directly.'); + } + + $this->value = $data['value']; + } + + /** + * This method is required by interface Serializable and SHOULD NOT be accessed directly. + * + * @internal + */ + public function serialize() : string + { + return $this->value; + } + + /** + * This method is only here to implement interface Serializable and cannot be accessed directly. + * + * @internal + * @psalm-suppress RedundantPropertyInitializationCheck + * + * @throws \LogicException + */ + public function unserialize($value) : void + { + if (isset($this->value)) { + throw new \LogicException('unserialize() is an internal function, it must not be called directly.'); + } + + $this->value = $value; + } +} diff --git a/vendor/brick/math/src/BigNumber.php b/vendor/brick/math/src/BigNumber.php new file mode 100644 index 0000000..80146d2 --- /dev/null +++ b/vendor/brick/math/src/BigNumber.php @@ -0,0 +1,512 @@ +[\-\+])?' . + '(?:' . + '(?:' . + '(?[0-9]+)?' . + '(?\.)?' . + '(?[0-9]+)?' . + '(?:[eE](?[\-\+]?[0-9]+))?' . + ')|(?:' . + '(?[0-9]+)' . + '\/?' . + '(?[0-9]+)' . + ')' . + ')' . + '$/'; + + /** + * Creates a BigNumber of the given value. + * + * The concrete return type is dependent on the given value, with the following rules: + * + * - BigNumber instances are returned as is + * - integer numbers are returned as BigInteger + * - floating point numbers are converted to a string then parsed as such + * - strings containing a `/` character are returned as BigRational + * - strings containing a `.` character or using an exponential notation are returned as BigDecimal + * - strings containing only digits with an optional leading `+` or `-` sign are returned as BigInteger + * + * @throws NumberFormatException If the format of the number is not valid. + * @throws DivisionByZeroException If the value represents a rational number with a denominator of zero. + * + * @psalm-pure + */ + public static function of(BigNumber|int|float|string $value) : BigNumber + { + if ($value instanceof BigNumber) { + return $value; + } + + if (\is_int($value)) { + return new BigInteger((string) $value); + } + + $value = \is_float($value) ? self::floatToString($value) : $value; + + $throw = static function() use ($value) : void { + throw new NumberFormatException(\sprintf( + 'The given value "%s" does not represent a valid number.', + $value + )); + }; + + if (\preg_match(self::PARSE_REGEXP, $value, $matches) !== 1) { + $throw(); + } + + $getMatch = static fn(string $value): ?string => (($matches[$value] ?? '') !== '') ? $matches[$value] : null; + + $sign = $getMatch('sign'); + $numerator = $getMatch('numerator'); + $denominator = $getMatch('denominator'); + + if ($numerator !== null) { + assert($denominator !== null); + + if ($sign !== null) { + $numerator = $sign . $numerator; + } + + $numerator = self::cleanUp($numerator); + $denominator = self::cleanUp($denominator); + + if ($denominator === '0') { + throw DivisionByZeroException::denominatorMustNotBeZero(); + } + + return new BigRational( + new BigInteger($numerator), + new BigInteger($denominator), + false + ); + } + + $point = $getMatch('point'); + $integral = $getMatch('integral'); + $fractional = $getMatch('fractional'); + $exponent = $getMatch('exponent'); + + if ($integral === null && $fractional === null) { + $throw(); + } + + if ($integral === null) { + $integral = '0'; + } + + if ($point !== null || $exponent !== null) { + $fractional = ($fractional ?? ''); + $exponent = ($exponent !== null) ? (int) $exponent : 0; + + if ($exponent === PHP_INT_MIN || $exponent === PHP_INT_MAX) { + throw new NumberFormatException('Exponent too large.'); + } + + $unscaledValue = self::cleanUp(($sign ?? ''). $integral . $fractional); + + $scale = \strlen($fractional) - $exponent; + + if ($scale < 0) { + if ($unscaledValue !== '0') { + $unscaledValue .= \str_repeat('0', - $scale); + } + $scale = 0; + } + + return new BigDecimal($unscaledValue, $scale); + } + + $integral = self::cleanUp(($sign ?? '') . $integral); + + return new BigInteger($integral); + } + + /** + * Safely converts float to string, avoiding locale-dependent issues. + * + * @see https://github.com/brick/math/pull/20 + * + * @psalm-pure + * @psalm-suppress ImpureFunctionCall + */ + private static function floatToString(float $float) : string + { + $currentLocale = \setlocale(LC_NUMERIC, '0'); + \setlocale(LC_NUMERIC, 'C'); + + $result = (string) $float; + + \setlocale(LC_NUMERIC, $currentLocale); + + return $result; + } + + /** + * Proxy method to access BigInteger's protected constructor from sibling classes. + * + * @internal + * @psalm-pure + */ + protected function newBigInteger(string $value) : BigInteger + { + return new BigInteger($value); + } + + /** + * Proxy method to access BigDecimal's protected constructor from sibling classes. + * + * @internal + * @psalm-pure + */ + protected function newBigDecimal(string $value, int $scale = 0) : BigDecimal + { + return new BigDecimal($value, $scale); + } + + /** + * Proxy method to access BigRational's protected constructor from sibling classes. + * + * @internal + * @psalm-pure + */ + protected function newBigRational(BigInteger $numerator, BigInteger $denominator, bool $checkDenominator) : BigRational + { + return new BigRational($numerator, $denominator, $checkDenominator); + } + + /** + * Returns the minimum of the given values. + * + * @param BigNumber|int|float|string ...$values The numbers to compare. All the numbers need to be convertible + * to an instance of the class this method is called on. + * + * @throws \InvalidArgumentException If no values are given. + * @throws MathException If an argument is not valid. + * + * @psalm-suppress LessSpecificReturnStatement + * @psalm-suppress MoreSpecificReturnType + * @psalm-pure + */ + public static function min(BigNumber|int|float|string ...$values) : static + { + $min = null; + + foreach ($values as $value) { + $value = static::of($value); + + if ($min === null || $value->isLessThan($min)) { + $min = $value; + } + } + + if ($min === null) { + throw new \InvalidArgumentException(__METHOD__ . '() expects at least one value.'); + } + + return $min; + } + + /** + * Returns the maximum of the given values. + * + * @param BigNumber|int|float|string ...$values The numbers to compare. All the numbers need to be convertible + * to an instance of the class this method is called on. + * + * @throws \InvalidArgumentException If no values are given. + * @throws MathException If an argument is not valid. + * + * @psalm-suppress LessSpecificReturnStatement + * @psalm-suppress MoreSpecificReturnType + * @psalm-pure + */ + public static function max(BigNumber|int|float|string ...$values) : static + { + $max = null; + + foreach ($values as $value) { + $value = static::of($value); + + if ($max === null || $value->isGreaterThan($max)) { + $max = $value; + } + } + + if ($max === null) { + throw new \InvalidArgumentException(__METHOD__ . '() expects at least one value.'); + } + + return $max; + } + + /** + * Returns the sum of the given values. + * + * @param BigNumber|int|float|string ...$values The numbers to add. All the numbers need to be convertible + * to an instance of the class this method is called on. + * + * @throws \InvalidArgumentException If no values are given. + * @throws MathException If an argument is not valid. + * + * @psalm-pure + */ + public static function sum(BigNumber|int|float|string ...$values) : static + { + /** @var static|null $sum */ + $sum = null; + + foreach ($values as $value) { + $value = static::of($value); + + $sum = $sum === null ? $value : self::add($sum, $value); + } + + if ($sum === null) { + throw new \InvalidArgumentException(__METHOD__ . '() expects at least one value.'); + } + + return $sum; + } + + /** + * Adds two BigNumber instances in the correct order to avoid a RoundingNecessaryException. + * + * @todo This could be better resolved by creating an abstract protected method in BigNumber, and leaving to + * concrete classes the responsibility to perform the addition themselves or delegate it to the given number, + * depending on their ability to perform the operation. This will also require a version bump because we're + * potentially breaking custom BigNumber implementations (if any...) + * + * @psalm-pure + */ + private static function add(BigNumber $a, BigNumber $b) : BigNumber + { + if ($a instanceof BigRational) { + return $a->plus($b); + } + + if ($b instanceof BigRational) { + return $b->plus($a); + } + + if ($a instanceof BigDecimal) { + return $a->plus($b); + } + + if ($b instanceof BigDecimal) { + return $b->plus($a); + } + + /** @var BigInteger $a */ + + return $a->plus($b); + } + + /** + * Removes optional leading zeros and + sign from the given number. + * + * @param string $number The number, validated as a non-empty string of digits with optional leading sign. + * + * @psalm-pure + */ + private static function cleanUp(string $number) : string + { + $firstChar = $number[0]; + + if ($firstChar === '+' || $firstChar === '-') { + $number = \substr($number, 1); + } + + $number = \ltrim($number, '0'); + + if ($number === '') { + return '0'; + } + + if ($firstChar === '-') { + return '-' . $number; + } + + return $number; + } + + /** + * Checks if this number is equal to the given one. + */ + public function isEqualTo(BigNumber|int|float|string $that) : bool + { + return $this->compareTo($that) === 0; + } + + /** + * Checks if this number is strictly lower than the given one. + */ + public function isLessThan(BigNumber|int|float|string $that) : bool + { + return $this->compareTo($that) < 0; + } + + /** + * Checks if this number is lower than or equal to the given one. + */ + public function isLessThanOrEqualTo(BigNumber|int|float|string $that) : bool + { + return $this->compareTo($that) <= 0; + } + + /** + * Checks if this number is strictly greater than the given one. + */ + public function isGreaterThan(BigNumber|int|float|string $that) : bool + { + return $this->compareTo($that) > 0; + } + + /** + * Checks if this number is greater than or equal to the given one. + */ + public function isGreaterThanOrEqualTo(BigNumber|int|float|string $that) : bool + { + return $this->compareTo($that) >= 0; + } + + /** + * Checks if this number equals zero. + */ + public function isZero() : bool + { + return $this->getSign() === 0; + } + + /** + * Checks if this number is strictly negative. + */ + public function isNegative() : bool + { + return $this->getSign() < 0; + } + + /** + * Checks if this number is negative or zero. + */ + public function isNegativeOrZero() : bool + { + return $this->getSign() <= 0; + } + + /** + * Checks if this number is strictly positive. + */ + public function isPositive() : bool + { + return $this->getSign() > 0; + } + + /** + * Checks if this number is positive or zero. + */ + public function isPositiveOrZero() : bool + { + return $this->getSign() >= 0; + } + + /** + * Returns the sign of this number. + * + * @return int -1 if the number is negative, 0 if zero, 1 if positive. + */ + abstract public function getSign() : int; + + /** + * Compares this number to the given one. + * + * @return int [-1,0,1] If `$this` is lower than, equal to, or greater than `$that`. + * + * @throws MathException If the number is not valid. + */ + abstract public function compareTo(BigNumber|int|float|string $that) : int; + + /** + * Converts this number to a BigInteger. + * + * @throws RoundingNecessaryException If this number cannot be converted to a BigInteger without rounding. + */ + abstract public function toBigInteger() : BigInteger; + + /** + * Converts this number to a BigDecimal. + * + * @throws RoundingNecessaryException If this number cannot be converted to a BigDecimal without rounding. + */ + abstract public function toBigDecimal() : BigDecimal; + + /** + * Converts this number to a BigRational. + */ + abstract public function toBigRational() : BigRational; + + /** + * Converts this number to a BigDecimal with the given scale, using rounding if necessary. + * + * @param int $scale The scale of the resulting `BigDecimal`. + * @param int $roundingMode A `RoundingMode` constant. + * + * @throws RoundingNecessaryException If this number cannot be converted to the given scale without rounding. + * This only applies when RoundingMode::UNNECESSARY is used. + */ + abstract public function toScale(int $scale, int $roundingMode = RoundingMode::UNNECESSARY) : BigDecimal; + + /** + * Returns the exact value of this number as a native integer. + * + * If this number cannot be converted to a native integer without losing precision, an exception is thrown. + * Note that the acceptable range for an integer depends on the platform and differs for 32-bit and 64-bit. + * + * @throws MathException If this number cannot be exactly converted to a native integer. + */ + abstract public function toInt() : int; + + /** + * Returns an approximation of this number as a floating-point value. + * + * Note that this method can discard information as the precision of a floating-point value + * is inherently limited. + * + * If the number is greater than the largest representable floating point number, positive infinity is returned. + * If the number is less than the smallest representable floating point number, negative infinity is returned. + */ + abstract public function toFloat() : float; + + /** + * Returns a string representation of this number. + * + * The output of this method can be parsed by the `of()` factory method; + * this will yield an object equal to this one, without any information loss. + */ + abstract public function __toString() : string; + + public function jsonSerialize() : string + { + return $this->__toString(); + } +} diff --git a/vendor/brick/math/src/BigRational.php b/vendor/brick/math/src/BigRational.php new file mode 100644 index 0000000..31f2904 --- /dev/null +++ b/vendor/brick/math/src/BigRational.php @@ -0,0 +1,445 @@ +isZero()) { + throw DivisionByZeroException::denominatorMustNotBeZero(); + } + + if ($denominator->isNegative()) { + $numerator = $numerator->negated(); + $denominator = $denominator->negated(); + } + } + + $this->numerator = $numerator; + $this->denominator = $denominator; + } + + /** + * Creates a BigRational of the given value. + * + * @throws MathException If the value cannot be converted to a BigRational. + * + * @psalm-pure + */ + public static function of(BigNumber|int|float|string $value) : BigRational + { + return parent::of($value)->toBigRational(); + } + + /** + * Creates a BigRational out of a numerator and a denominator. + * + * If the denominator is negative, the signs of both the numerator and the denominator + * will be inverted to ensure that the denominator is always positive. + * + * @param BigNumber|int|float|string $numerator The numerator. Must be convertible to a BigInteger. + * @param BigNumber|int|float|string $denominator The denominator. Must be convertible to a BigInteger. + * + * @throws NumberFormatException If an argument does not represent a valid number. + * @throws RoundingNecessaryException If an argument represents a non-integer number. + * @throws DivisionByZeroException If the denominator is zero. + * + * @psalm-pure + */ + public static function nd( + BigNumber|int|float|string $numerator, + BigNumber|int|float|string $denominator, + ) : BigRational { + $numerator = BigInteger::of($numerator); + $denominator = BigInteger::of($denominator); + + return new BigRational($numerator, $denominator, true); + } + + /** + * Returns a BigRational representing zero. + * + * @psalm-pure + */ + public static function zero() : BigRational + { + /** + * @psalm-suppress ImpureStaticVariable + * @var BigRational|null $zero + */ + static $zero; + + if ($zero === null) { + $zero = new BigRational(BigInteger::zero(), BigInteger::one(), false); + } + + return $zero; + } + + /** + * Returns a BigRational representing one. + * + * @psalm-pure + */ + public static function one() : BigRational + { + /** + * @psalm-suppress ImpureStaticVariable + * @var BigRational|null $one + */ + static $one; + + if ($one === null) { + $one = new BigRational(BigInteger::one(), BigInteger::one(), false); + } + + return $one; + } + + /** + * Returns a BigRational representing ten. + * + * @psalm-pure + */ + public static function ten() : BigRational + { + /** + * @psalm-suppress ImpureStaticVariable + * @var BigRational|null $ten + */ + static $ten; + + if ($ten === null) { + $ten = new BigRational(BigInteger::ten(), BigInteger::one(), false); + } + + return $ten; + } + + public function getNumerator() : BigInteger + { + return $this->numerator; + } + + public function getDenominator() : BigInteger + { + return $this->denominator; + } + + /** + * Returns the quotient of the division of the numerator by the denominator. + */ + public function quotient() : BigInteger + { + return $this->numerator->quotient($this->denominator); + } + + /** + * Returns the remainder of the division of the numerator by the denominator. + */ + public function remainder() : BigInteger + { + return $this->numerator->remainder($this->denominator); + } + + /** + * Returns the quotient and remainder of the division of the numerator by the denominator. + * + * @return BigInteger[] + */ + public function quotientAndRemainder() : array + { + return $this->numerator->quotientAndRemainder($this->denominator); + } + + /** + * Returns the sum of this number and the given one. + * + * @param BigNumber|int|float|string $that The number to add. + * + * @throws MathException If the number is not valid. + */ + public function plus(BigNumber|int|float|string $that) : BigRational + { + $that = BigRational::of($that); + + $numerator = $this->numerator->multipliedBy($that->denominator); + $numerator = $numerator->plus($that->numerator->multipliedBy($this->denominator)); + $denominator = $this->denominator->multipliedBy($that->denominator); + + return new BigRational($numerator, $denominator, false); + } + + /** + * Returns the difference of this number and the given one. + * + * @param BigNumber|int|float|string $that The number to subtract. + * + * @throws MathException If the number is not valid. + */ + public function minus(BigNumber|int|float|string $that) : BigRational + { + $that = BigRational::of($that); + + $numerator = $this->numerator->multipliedBy($that->denominator); + $numerator = $numerator->minus($that->numerator->multipliedBy($this->denominator)); + $denominator = $this->denominator->multipliedBy($that->denominator); + + return new BigRational($numerator, $denominator, false); + } + + /** + * Returns the product of this number and the given one. + * + * @param BigNumber|int|float|string $that The multiplier. + * + * @throws MathException If the multiplier is not a valid number. + */ + public function multipliedBy(BigNumber|int|float|string $that) : BigRational + { + $that = BigRational::of($that); + + $numerator = $this->numerator->multipliedBy($that->numerator); + $denominator = $this->denominator->multipliedBy($that->denominator); + + return new BigRational($numerator, $denominator, false); + } + + /** + * Returns the result of the division of this number by the given one. + * + * @param BigNumber|int|float|string $that The divisor. + * + * @throws MathException If the divisor is not a valid number, or is zero. + */ + public function dividedBy(BigNumber|int|float|string $that) : BigRational + { + $that = BigRational::of($that); + + $numerator = $this->numerator->multipliedBy($that->denominator); + $denominator = $this->denominator->multipliedBy($that->numerator); + + return new BigRational($numerator, $denominator, true); + } + + /** + * Returns this number exponentiated to the given value. + * + * @throws \InvalidArgumentException If the exponent is not in the range 0 to 1,000,000. + */ + public function power(int $exponent) : BigRational + { + if ($exponent === 0) { + $one = BigInteger::one(); + + return new BigRational($one, $one, false); + } + + if ($exponent === 1) { + return $this; + } + + return new BigRational( + $this->numerator->power($exponent), + $this->denominator->power($exponent), + false + ); + } + + /** + * Returns the reciprocal of this BigRational. + * + * The reciprocal has the numerator and denominator swapped. + * + * @throws DivisionByZeroException If the numerator is zero. + */ + public function reciprocal() : BigRational + { + return new BigRational($this->denominator, $this->numerator, true); + } + + /** + * Returns the absolute value of this BigRational. + */ + public function abs() : BigRational + { + return new BigRational($this->numerator->abs(), $this->denominator, false); + } + + /** + * Returns the negated value of this BigRational. + */ + public function negated() : BigRational + { + return new BigRational($this->numerator->negated(), $this->denominator, false); + } + + /** + * Returns the simplified value of this BigRational. + */ + public function simplified() : BigRational + { + $gcd = $this->numerator->gcd($this->denominator); + + $numerator = $this->numerator->quotient($gcd); + $denominator = $this->denominator->quotient($gcd); + + return new BigRational($numerator, $denominator, false); + } + + public function compareTo(BigNumber|int|float|string $that) : int + { + return $this->minus($that)->getSign(); + } + + public function getSign() : int + { + return $this->numerator->getSign(); + } + + public function toBigInteger() : BigInteger + { + $simplified = $this->simplified(); + + if (! $simplified->denominator->isEqualTo(1)) { + throw new RoundingNecessaryException('This rational number cannot be represented as an integer value without rounding.'); + } + + return $simplified->numerator; + } + + public function toBigDecimal() : BigDecimal + { + return $this->numerator->toBigDecimal()->exactlyDividedBy($this->denominator); + } + + public function toBigRational() : BigRational + { + return $this; + } + + public function toScale(int $scale, int $roundingMode = RoundingMode::UNNECESSARY) : BigDecimal + { + return $this->numerator->toBigDecimal()->dividedBy($this->denominator, $scale, $roundingMode); + } + + public function toInt() : int + { + return $this->toBigInteger()->toInt(); + } + + public function toFloat() : float + { + $simplified = $this->simplified(); + return $simplified->numerator->toFloat() / $simplified->denominator->toFloat(); + } + + public function __toString() : string + { + $numerator = (string) $this->numerator; + $denominator = (string) $this->denominator; + + if ($denominator === '1') { + return $numerator; + } + + return $this->numerator . '/' . $this->denominator; + } + + /** + * This method is required for serializing the object and SHOULD NOT be accessed directly. + * + * @internal + * + * @return array{numerator: BigInteger, denominator: BigInteger} + */ + public function __serialize(): array + { + return ['numerator' => $this->numerator, 'denominator' => $this->denominator]; + } + + /** + * This method is only here to allow unserializing the object and cannot be accessed directly. + * + * @internal + * @psalm-suppress RedundantPropertyInitializationCheck + * + * @param array{numerator: BigInteger, denominator: BigInteger} $data + * + * @throws \LogicException + */ + public function __unserialize(array $data): void + { + if (isset($this->numerator)) { + throw new \LogicException('__unserialize() is an internal function, it must not be called directly.'); + } + + $this->numerator = $data['numerator']; + $this->denominator = $data['denominator']; + } + + /** + * This method is required by interface Serializable and SHOULD NOT be accessed directly. + * + * @internal + */ + public function serialize() : string + { + return $this->numerator . '/' . $this->denominator; + } + + /** + * This method is only here to implement interface Serializable and cannot be accessed directly. + * + * @internal + * @psalm-suppress RedundantPropertyInitializationCheck + * + * @throws \LogicException + */ + public function unserialize($value) : void + { + if (isset($this->numerator)) { + throw new \LogicException('unserialize() is an internal function, it must not be called directly.'); + } + + [$numerator, $denominator] = \explode('/', $value); + + $this->numerator = BigInteger::of($numerator); + $this->denominator = BigInteger::of($denominator); + } +} diff --git a/vendor/brick/math/src/Exception/DivisionByZeroException.php b/vendor/brick/math/src/Exception/DivisionByZeroException.php new file mode 100644 index 0000000..ce7769a --- /dev/null +++ b/vendor/brick/math/src/Exception/DivisionByZeroException.php @@ -0,0 +1,35 @@ + 126) { + $char = \strtoupper(\dechex($ord)); + + if ($ord < 10) { + $char = '0' . $char; + } + } else { + $char = '"' . $char . '"'; + } + + return new self(sprintf('Char %s is not a valid character in the given alphabet.', $char)); + } +} diff --git a/vendor/brick/math/src/Exception/RoundingNecessaryException.php b/vendor/brick/math/src/Exception/RoundingNecessaryException.php new file mode 100644 index 0000000..57bfcd8 --- /dev/null +++ b/vendor/brick/math/src/Exception/RoundingNecessaryException.php @@ -0,0 +1,19 @@ +init($a, $b); + + if ($aNeg && ! $bNeg) { + return -1; + } + + if ($bNeg && ! $aNeg) { + return 1; + } + + $aLen = \strlen($aDig); + $bLen = \strlen($bDig); + + if ($aLen < $bLen) { + $result = -1; + } elseif ($aLen > $bLen) { + $result = 1; + } else { + $result = $aDig <=> $bDig; + } + + return $aNeg ? -$result : $result; + } + + /** + * Adds two numbers. + */ + abstract public function add(string $a, string $b) : string; + + /** + * Subtracts two numbers. + */ + abstract public function sub(string $a, string $b) : string; + + /** + * Multiplies two numbers. + */ + abstract public function mul(string $a, string $b) : string; + + /** + * Returns the quotient of the division of two numbers. + * + * @param string $a The dividend. + * @param string $b The divisor, must not be zero. + * + * @return string The quotient. + */ + abstract public function divQ(string $a, string $b) : string; + + /** + * Returns the remainder of the division of two numbers. + * + * @param string $a The dividend. + * @param string $b The divisor, must not be zero. + * + * @return string The remainder. + */ + abstract public function divR(string $a, string $b) : string; + + /** + * Returns the quotient and remainder of the division of two numbers. + * + * @param string $a The dividend. + * @param string $b The divisor, must not be zero. + * + * @return array{string, string} An array containing the quotient and remainder. + */ + abstract public function divQR(string $a, string $b) : array; + + /** + * Exponentiates a number. + * + * @param string $a The base number. + * @param int $e The exponent, validated as an integer between 0 and MAX_POWER. + * + * @return string The power. + */ + abstract public function pow(string $a, int $e) : string; + + /** + * @param string $b The modulus; must not be zero. + */ + public function mod(string $a, string $b) : string + { + return $this->divR($this->add($this->divR($a, $b), $b), $b); + } + + /** + * Returns the modular multiplicative inverse of $x modulo $m. + * + * If $x has no multiplicative inverse mod m, this method must return null. + * + * This method can be overridden by the concrete implementation if the underlying library has built-in support. + * + * @param string $m The modulus; must not be negative or zero. + */ + public function modInverse(string $x, string $m) : ?string + { + if ($m === '1') { + return '0'; + } + + $modVal = $x; + + if ($x[0] === '-' || ($this->cmp($this->abs($x), $m) >= 0)) { + $modVal = $this->mod($x, $m); + } + + [$g, $x] = $this->gcdExtended($modVal, $m); + + if ($g !== '1') { + return null; + } + + return $this->mod($this->add($this->mod($x, $m), $m), $m); + } + + /** + * Raises a number into power with modulo. + * + * @param string $base The base number; must be positive or zero. + * @param string $exp The exponent; must be positive or zero. + * @param string $mod The modulus; must be strictly positive. + */ + abstract public function modPow(string $base, string $exp, string $mod) : string; + + /** + * Returns the greatest common divisor of the two numbers. + * + * This method can be overridden by the concrete implementation if the underlying library + * has built-in support for GCD calculations. + * + * @return string The GCD, always positive, or zero if both arguments are zero. + */ + public function gcd(string $a, string $b) : string + { + if ($a === '0') { + return $this->abs($b); + } + + if ($b === '0') { + return $this->abs($a); + } + + return $this->gcd($b, $this->divR($a, $b)); + } + + /** + * @return array{string, string, string} GCD, X, Y + */ + private function gcdExtended(string $a, string $b) : array + { + if ($a === '0') { + return [$b, '0', '1']; + } + + [$gcd, $x1, $y1] = $this->gcdExtended($this->mod($b, $a), $a); + + $x = $this->sub($y1, $this->mul($this->divQ($b, $a), $x1)); + $y = $x1; + + return [$gcd, $x, $y]; + } + + /** + * Returns the square root of the given number, rounded down. + * + * The result is the largest x such that x² ≤ n. + * The input MUST NOT be negative. + */ + abstract public function sqrt(string $n) : string; + + /** + * Converts a number from an arbitrary base. + * + * This method can be overridden by the concrete implementation if the underlying library + * has built-in support for base conversion. + * + * @param string $number The number, positive or zero, non-empty, case-insensitively validated for the given base. + * @param int $base The base of the number, validated from 2 to 36. + * + * @return string The converted number, following the Calculator conventions. + */ + public function fromBase(string $number, int $base) : string + { + return $this->fromArbitraryBase(\strtolower($number), self::ALPHABET, $base); + } + + /** + * Converts a number to an arbitrary base. + * + * This method can be overridden by the concrete implementation if the underlying library + * has built-in support for base conversion. + * + * @param string $number The number to convert, following the Calculator conventions. + * @param int $base The base to convert to, validated from 2 to 36. + * + * @return string The converted number, lowercase. + */ + public function toBase(string $number, int $base) : string + { + $negative = ($number[0] === '-'); + + if ($negative) { + $number = \substr($number, 1); + } + + $number = $this->toArbitraryBase($number, self::ALPHABET, $base); + + if ($negative) { + return '-' . $number; + } + + return $number; + } + + /** + * Converts a non-negative number in an arbitrary base using a custom alphabet, to base 10. + * + * @param string $number The number to convert, validated as a non-empty string, + * containing only chars in the given alphabet/base. + * @param string $alphabet The alphabet that contains every digit, validated as 2 chars minimum. + * @param int $base The base of the number, validated from 2 to alphabet length. + * + * @return string The number in base 10, following the Calculator conventions. + */ + final public function fromArbitraryBase(string $number, string $alphabet, int $base) : string + { + // remove leading "zeros" + $number = \ltrim($number, $alphabet[0]); + + if ($number === '') { + return '0'; + } + + // optimize for "one" + if ($number === $alphabet[1]) { + return '1'; + } + + $result = '0'; + $power = '1'; + + $base = (string) $base; + + for ($i = \strlen($number) - 1; $i >= 0; $i--) { + $index = \strpos($alphabet, $number[$i]); + + if ($index !== 0) { + $result = $this->add($result, ($index === 1) + ? $power + : $this->mul($power, (string) $index) + ); + } + + if ($i !== 0) { + $power = $this->mul($power, $base); + } + } + + return $result; + } + + /** + * Converts a non-negative number to an arbitrary base using a custom alphabet. + * + * @param string $number The number to convert, positive or zero, following the Calculator conventions. + * @param string $alphabet The alphabet that contains every digit, validated as 2 chars minimum. + * @param int $base The base to convert to, validated from 2 to alphabet length. + * + * @return string The converted number in the given alphabet. + */ + final public function toArbitraryBase(string $number, string $alphabet, int $base) : string + { + if ($number === '0') { + return $alphabet[0]; + } + + $base = (string) $base; + $result = ''; + + while ($number !== '0') { + [$number, $remainder] = $this->divQR($number, $base); + $remainder = (int) $remainder; + + $result .= $alphabet[$remainder]; + } + + return \strrev($result); + } + + /** + * Performs a rounded division. + * + * Rounding is performed when the remainder of the division is not zero. + * + * @param string $a The dividend. + * @param string $b The divisor, must not be zero. + * @param int $roundingMode The rounding mode. + * + * @throws \InvalidArgumentException If the rounding mode is invalid. + * @throws RoundingNecessaryException If RoundingMode::UNNECESSARY is provided but rounding is necessary. + * + * @psalm-suppress ImpureFunctionCall + */ + final public function divRound(string $a, string $b, int $roundingMode) : string + { + [$quotient, $remainder] = $this->divQR($a, $b); + + $hasDiscardedFraction = ($remainder !== '0'); + $isPositiveOrZero = ($a[0] === '-') === ($b[0] === '-'); + + $discardedFractionSign = function() use ($remainder, $b) : int { + $r = $this->abs($this->mul($remainder, '2')); + $b = $this->abs($b); + + return $this->cmp($r, $b); + }; + + $increment = false; + + switch ($roundingMode) { + case RoundingMode::UNNECESSARY: + if ($hasDiscardedFraction) { + throw RoundingNecessaryException::roundingNecessary(); + } + break; + + case RoundingMode::UP: + $increment = $hasDiscardedFraction; + break; + + case RoundingMode::DOWN: + break; + + case RoundingMode::CEILING: + $increment = $hasDiscardedFraction && $isPositiveOrZero; + break; + + case RoundingMode::FLOOR: + $increment = $hasDiscardedFraction && ! $isPositiveOrZero; + break; + + case RoundingMode::HALF_UP: + $increment = $discardedFractionSign() >= 0; + break; + + case RoundingMode::HALF_DOWN: + $increment = $discardedFractionSign() > 0; + break; + + case RoundingMode::HALF_CEILING: + $increment = $isPositiveOrZero ? $discardedFractionSign() >= 0 : $discardedFractionSign() > 0; + break; + + case RoundingMode::HALF_FLOOR: + $increment = $isPositiveOrZero ? $discardedFractionSign() > 0 : $discardedFractionSign() >= 0; + break; + + case RoundingMode::HALF_EVEN: + $lastDigit = (int) $quotient[-1]; + $lastDigitIsEven = ($lastDigit % 2 === 0); + $increment = $lastDigitIsEven ? $discardedFractionSign() > 0 : $discardedFractionSign() >= 0; + break; + + default: + throw new \InvalidArgumentException('Invalid rounding mode.'); + } + + if ($increment) { + return $this->add($quotient, $isPositiveOrZero ? '1' : '-1'); + } + + return $quotient; + } + + /** + * Calculates bitwise AND of two numbers. + * + * This method can be overridden by the concrete implementation if the underlying library + * has built-in support for bitwise operations. + */ + public function and(string $a, string $b) : string + { + return $this->bitwise('and', $a, $b); + } + + /** + * Calculates bitwise OR of two numbers. + * + * This method can be overridden by the concrete implementation if the underlying library + * has built-in support for bitwise operations. + */ + public function or(string $a, string $b) : string + { + return $this->bitwise('or', $a, $b); + } + + /** + * Calculates bitwise XOR of two numbers. + * + * This method can be overridden by the concrete implementation if the underlying library + * has built-in support for bitwise operations. + */ + public function xor(string $a, string $b) : string + { + return $this->bitwise('xor', $a, $b); + } + + /** + * Performs a bitwise operation on a decimal number. + * + * @param 'and'|'or'|'xor' $operator The operator to use. + * @param string $a The left operand. + * @param string $b The right operand. + */ + private function bitwise(string $operator, string $a, string $b) : string + { + [$aNeg, $bNeg, $aDig, $bDig] = $this->init($a, $b); + + $aBin = $this->toBinary($aDig); + $bBin = $this->toBinary($bDig); + + $aLen = \strlen($aBin); + $bLen = \strlen($bBin); + + if ($aLen > $bLen) { + $bBin = \str_repeat("\x00", $aLen - $bLen) . $bBin; + } elseif ($bLen > $aLen) { + $aBin = \str_repeat("\x00", $bLen - $aLen) . $aBin; + } + + if ($aNeg) { + $aBin = $this->twosComplement($aBin); + } + if ($bNeg) { + $bBin = $this->twosComplement($bBin); + } + + switch ($operator) { + case 'and': + $value = $aBin & $bBin; + $negative = ($aNeg and $bNeg); + break; + + case 'or': + $value = $aBin | $bBin; + $negative = ($aNeg or $bNeg); + break; + + case 'xor': + $value = $aBin ^ $bBin; + $negative = ($aNeg xor $bNeg); + break; + + // @codeCoverageIgnoreStart + default: + throw new \InvalidArgumentException('Invalid bitwise operator.'); + // @codeCoverageIgnoreEnd + } + + if ($negative) { + $value = $this->twosComplement($value); + } + + $result = $this->toDecimal($value); + + return $negative ? $this->neg($result) : $result; + } + + /** + * @param string $number A positive, binary number. + */ + private function twosComplement(string $number) : string + { + $xor = \str_repeat("\xff", \strlen($number)); + + $number ^= $xor; + + for ($i = \strlen($number) - 1; $i >= 0; $i--) { + $byte = \ord($number[$i]); + + if (++$byte !== 256) { + $number[$i] = \chr($byte); + break; + } + + $number[$i] = "\x00"; + + if ($i === 0) { + $number = "\x01" . $number; + } + } + + return $number; + } + + /** + * Converts a decimal number to a binary string. + * + * @param string $number The number to convert, positive or zero, only digits. + */ + private function toBinary(string $number) : string + { + $result = ''; + + while ($number !== '0') { + [$number, $remainder] = $this->divQR($number, '256'); + $result .= \chr((int) $remainder); + } + + return \strrev($result); + } + + /** + * Returns the positive decimal representation of a binary number. + * + * @param string $bytes The bytes representing the number. + */ + private function toDecimal(string $bytes) : string + { + $result = '0'; + $power = '1'; + + for ($i = \strlen($bytes) - 1; $i >= 0; $i--) { + $index = \ord($bytes[$i]); + + if ($index !== 0) { + $result = $this->add($result, ($index === 1) + ? $power + : $this->mul($power, (string) $index) + ); + } + + if ($i !== 0) { + $power = $this->mul($power, '256'); + } + } + + return $result; + } +} diff --git a/vendor/brick/math/src/Internal/Calculator/BcMathCalculator.php b/vendor/brick/math/src/Internal/Calculator/BcMathCalculator.php new file mode 100644 index 0000000..5457a3c --- /dev/null +++ b/vendor/brick/math/src/Internal/Calculator/BcMathCalculator.php @@ -0,0 +1,75 @@ +maxDigits = 9; + break; + + case 8: + $this->maxDigits = 18; + break; + + default: + throw new \RuntimeException('The platform is not 32-bit or 64-bit as expected.'); + } + } + + public function add(string $a, string $b) : string + { + /** + * @psalm-var numeric-string $a + * @psalm-var numeric-string $b + */ + $result = $a + $b; + + if (is_int($result)) { + return (string) $result; + } + + if ($a === '0') { + return $b; + } + + if ($b === '0') { + return $a; + } + + [$aNeg, $bNeg, $aDig, $bDig] = $this->init($a, $b); + + $result = $aNeg === $bNeg ? $this->doAdd($aDig, $bDig) : $this->doSub($aDig, $bDig); + + if ($aNeg) { + $result = $this->neg($result); + } + + return $result; + } + + public function sub(string $a, string $b) : string + { + return $this->add($a, $this->neg($b)); + } + + public function mul(string $a, string $b) : string + { + /** + * @psalm-var numeric-string $a + * @psalm-var numeric-string $b + */ + $result = $a * $b; + + if (is_int($result)) { + return (string) $result; + } + + if ($a === '0' || $b === '0') { + return '0'; + } + + if ($a === '1') { + return $b; + } + + if ($b === '1') { + return $a; + } + + if ($a === '-1') { + return $this->neg($b); + } + + if ($b === '-1') { + return $this->neg($a); + } + + [$aNeg, $bNeg, $aDig, $bDig] = $this->init($a, $b); + + $result = $this->doMul($aDig, $bDig); + + if ($aNeg !== $bNeg) { + $result = $this->neg($result); + } + + return $result; + } + + public function divQ(string $a, string $b) : string + { + return $this->divQR($a, $b)[0]; + } + + public function divR(string $a, string $b): string + { + return $this->divQR($a, $b)[1]; + } + + public function divQR(string $a, string $b) : array + { + if ($a === '0') { + return ['0', '0']; + } + + if ($a === $b) { + return ['1', '0']; + } + + if ($b === '1') { + return [$a, '0']; + } + + if ($b === '-1') { + return [$this->neg($a), '0']; + } + + /** @psalm-var numeric-string $a */ + $na = $a * 1; // cast to number + + if (is_int($na)) { + /** @psalm-var numeric-string $b */ + $nb = $b * 1; + + if (is_int($nb)) { + // the only division that may overflow is PHP_INT_MIN / -1, + // which cannot happen here as we've already handled a divisor of -1 above. + $r = $na % $nb; + $q = ($na - $r) / $nb; + + assert(is_int($q)); + + return [ + (string) $q, + (string) $r + ]; + } + } + + [$aNeg, $bNeg, $aDig, $bDig] = $this->init($a, $b); + + [$q, $r] = $this->doDiv($aDig, $bDig); + + if ($aNeg !== $bNeg) { + $q = $this->neg($q); + } + + if ($aNeg) { + $r = $this->neg($r); + } + + return [$q, $r]; + } + + public function pow(string $a, int $e) : string + { + if ($e === 0) { + return '1'; + } + + if ($e === 1) { + return $a; + } + + $odd = $e % 2; + $e -= $odd; + + $aa = $this->mul($a, $a); + + /** @psalm-suppress PossiblyInvalidArgument We're sure that $e / 2 is an int now */ + $result = $this->pow($aa, $e / 2); + + if ($odd === 1) { + $result = $this->mul($result, $a); + } + + return $result; + } + + /** + * Algorithm from: https://www.geeksforgeeks.org/modular-exponentiation-power-in-modular-arithmetic/ + */ + public function modPow(string $base, string $exp, string $mod) : string + { + // special case: the algorithm below fails with 0 power 0 mod 1 (returns 1 instead of 0) + if ($base === '0' && $exp === '0' && $mod === '1') { + return '0'; + } + + // special case: the algorithm below fails with power 0 mod 1 (returns 1 instead of 0) + if ($exp === '0' && $mod === '1') { + return '0'; + } + + $x = $base; + + $res = '1'; + + // numbers are positive, so we can use remainder instead of modulo + $x = $this->divR($x, $mod); + + while ($exp !== '0') { + if (in_array($exp[-1], ['1', '3', '5', '7', '9'])) { // odd + $res = $this->divR($this->mul($res, $x), $mod); + } + + $exp = $this->divQ($exp, '2'); + $x = $this->divR($this->mul($x, $x), $mod); + } + + return $res; + } + + /** + * Adapted from https://cp-algorithms.com/num_methods/roots_newton.html + */ + public function sqrt(string $n) : string + { + if ($n === '0') { + return '0'; + } + + // initial approximation + $x = \str_repeat('9', \intdiv(\strlen($n), 2) ?: 1); + + $decreased = false; + + for (;;) { + $nx = $this->divQ($this->add($x, $this->divQ($n, $x)), '2'); + + if ($x === $nx || $this->cmp($nx, $x) > 0 && $decreased) { + break; + } + + $decreased = $this->cmp($nx, $x) < 0; + $x = $nx; + } + + return $x; + } + + /** + * Performs the addition of two non-signed large integers. + */ + private function doAdd(string $a, string $b) : string + { + [$a, $b, $length] = $this->pad($a, $b); + + $carry = 0; + $result = ''; + + for ($i = $length - $this->maxDigits;; $i -= $this->maxDigits) { + $blockLength = $this->maxDigits; + + if ($i < 0) { + $blockLength += $i; + /** @psalm-suppress LoopInvalidation */ + $i = 0; + } + + /** @psalm-var numeric-string $blockA */ + $blockA = \substr($a, $i, $blockLength); + + /** @psalm-var numeric-string $blockB */ + $blockB = \substr($b, $i, $blockLength); + + $sum = (string) ($blockA + $blockB + $carry); + $sumLength = \strlen($sum); + + if ($sumLength > $blockLength) { + $sum = \substr($sum, 1); + $carry = 1; + } else { + if ($sumLength < $blockLength) { + $sum = \str_repeat('0', $blockLength - $sumLength) . $sum; + } + $carry = 0; + } + + $result = $sum . $result; + + if ($i === 0) { + break; + } + } + + if ($carry === 1) { + $result = '1' . $result; + } + + return $result; + } + + /** + * Performs the subtraction of two non-signed large integers. + */ + private function doSub(string $a, string $b) : string + { + if ($a === $b) { + return '0'; + } + + // Ensure that we always subtract to a positive result: biggest minus smallest. + $cmp = $this->doCmp($a, $b); + + $invert = ($cmp === -1); + + if ($invert) { + $c = $a; + $a = $b; + $b = $c; + } + + [$a, $b, $length] = $this->pad($a, $b); + + $carry = 0; + $result = ''; + + $complement = 10 ** $this->maxDigits; + + for ($i = $length - $this->maxDigits;; $i -= $this->maxDigits) { + $blockLength = $this->maxDigits; + + if ($i < 0) { + $blockLength += $i; + /** @psalm-suppress LoopInvalidation */ + $i = 0; + } + + /** @psalm-var numeric-string $blockA */ + $blockA = \substr($a, $i, $blockLength); + + /** @psalm-var numeric-string $blockB */ + $blockB = \substr($b, $i, $blockLength); + + $sum = $blockA - $blockB - $carry; + + if ($sum < 0) { + $sum += $complement; + $carry = 1; + } else { + $carry = 0; + } + + $sum = (string) $sum; + $sumLength = \strlen($sum); + + if ($sumLength < $blockLength) { + $sum = \str_repeat('0', $blockLength - $sumLength) . $sum; + } + + $result = $sum . $result; + + if ($i === 0) { + break; + } + } + + // Carry cannot be 1 when the loop ends, as a > b + assert($carry === 0); + + $result = \ltrim($result, '0'); + + if ($invert) { + $result = $this->neg($result); + } + + return $result; + } + + /** + * Performs the multiplication of two non-signed large integers. + */ + private function doMul(string $a, string $b) : string + { + $x = \strlen($a); + $y = \strlen($b); + + $maxDigits = \intdiv($this->maxDigits, 2); + $complement = 10 ** $maxDigits; + + $result = '0'; + + for ($i = $x - $maxDigits;; $i -= $maxDigits) { + $blockALength = $maxDigits; + + if ($i < 0) { + $blockALength += $i; + /** @psalm-suppress LoopInvalidation */ + $i = 0; + } + + $blockA = (int) \substr($a, $i, $blockALength); + + $line = ''; + $carry = 0; + + for ($j = $y - $maxDigits;; $j -= $maxDigits) { + $blockBLength = $maxDigits; + + if ($j < 0) { + $blockBLength += $j; + /** @psalm-suppress LoopInvalidation */ + $j = 0; + } + + $blockB = (int) \substr($b, $j, $blockBLength); + + $mul = $blockA * $blockB + $carry; + $value = $mul % $complement; + $carry = ($mul - $value) / $complement; + + $value = (string) $value; + $value = \str_pad($value, $maxDigits, '0', STR_PAD_LEFT); + + $line = $value . $line; + + if ($j === 0) { + break; + } + } + + if ($carry !== 0) { + $line = $carry . $line; + } + + $line = \ltrim($line, '0'); + + if ($line !== '') { + $line .= \str_repeat('0', $x - $blockALength - $i); + $result = $this->add($result, $line); + } + + if ($i === 0) { + break; + } + } + + return $result; + } + + /** + * Performs the division of two non-signed large integers. + * + * @return string[] The quotient and remainder. + */ + private function doDiv(string $a, string $b) : array + { + $cmp = $this->doCmp($a, $b); + + if ($cmp === -1) { + return ['0', $a]; + } + + $x = \strlen($a); + $y = \strlen($b); + + // we now know that a >= b && x >= y + + $q = '0'; // quotient + $r = $a; // remainder + $z = $y; // focus length, always $y or $y+1 + + for (;;) { + $focus = \substr($a, 0, $z); + + $cmp = $this->doCmp($focus, $b); + + if ($cmp === -1) { + if ($z === $x) { // remainder < dividend + break; + } + + $z++; + } + + $zeros = \str_repeat('0', $x - $z); + + $q = $this->add($q, '1' . $zeros); + $a = $this->sub($a, $b . $zeros); + + $r = $a; + + if ($r === '0') { // remainder == 0 + break; + } + + $x = \strlen($a); + + if ($x < $y) { // remainder < dividend + break; + } + + $z = $y; + } + + return [$q, $r]; + } + + /** + * Compares two non-signed large numbers. + * + * @return int [-1, 0, 1] + */ + private function doCmp(string $a, string $b) : int + { + $x = \strlen($a); + $y = \strlen($b); + + $cmp = $x <=> $y; + + if ($cmp !== 0) { + return $cmp; + } + + return \strcmp($a, $b) <=> 0; // enforce [-1, 0, 1] + } + + /** + * Pads the left of one of the given numbers with zeros if necessary to make both numbers the same length. + * + * The numbers must only consist of digits, without leading minus sign. + * + * @return array{string, string, int} + */ + private function pad(string $a, string $b) : array + { + $x = \strlen($a); + $y = \strlen($b); + + if ($x > $y) { + $b = \str_repeat('0', $x - $y) . $b; + + return [$a, $b, $x]; + } + + if ($x < $y) { + $a = \str_repeat('0', $y - $x) . $a; + + return [$a, $b, $y]; + } + + return [$a, $b, $x]; + } +} diff --git a/vendor/brick/math/src/RoundingMode.php b/vendor/brick/math/src/RoundingMode.php new file mode 100644 index 0000000..06936d8 --- /dev/null +++ b/vendor/brick/math/src/RoundingMode.php @@ -0,0 +1,107 @@ += 0.5; otherwise, behaves as for DOWN. + * Note that this is the rounding mode commonly taught at school. + */ + public const HALF_UP = 5; + + /** + * Rounds towards "nearest neighbor" unless both neighbors are equidistant, in which case round down. + * + * Behaves as for UP if the discarded fraction is > 0.5; otherwise, behaves as for DOWN. + */ + public const HALF_DOWN = 6; + + /** + * Rounds towards "nearest neighbor" unless both neighbors are equidistant, in which case round towards positive infinity. + * + * If the result is positive, behaves as for HALF_UP; if negative, behaves as for HALF_DOWN. + */ + public const HALF_CEILING = 7; + + /** + * Rounds towards "nearest neighbor" unless both neighbors are equidistant, in which case round towards negative infinity. + * + * If the result is positive, behaves as for HALF_DOWN; if negative, behaves as for HALF_UP. + */ + public const HALF_FLOOR = 8; + + /** + * Rounds towards the "nearest neighbor" unless both neighbors are equidistant, in which case rounds towards the even neighbor. + * + * Behaves as for HALF_UP if the digit to the left of the discarded fraction is odd; + * behaves as for HALF_DOWN if it's even. + * + * Note that this is the rounding mode that statistically minimizes + * cumulative error when applied repeatedly over a sequence of calculations. + * It is sometimes known as "Banker's rounding", and is chiefly used in the USA. + */ + public const HALF_EVEN = 9; +} diff --git a/vendor/cakephp/core/App.php b/vendor/cakephp/core/App.php new file mode 100644 index 0000000..3f5c9a0 --- /dev/null +++ b/vendor/cakephp/core/App.php @@ -0,0 +1,269 @@ + + * @link https://book.cakephp.org/4/en/core-libraries/app.html#finding-paths-to-namespaces + */ + public static function path(string $type, ?string $plugin = null): array + { + if ($plugin === null && $type[0] === strtolower($type[0])) { + return (array)Configure::read('App.paths.' . $type); + } + + if ($type === 'templates') { + /** @psalm-suppress PossiblyNullArgument */ + return [Plugin::templatePath($plugin)]; + } + + if ($type === 'locales') { + /** @psalm-suppress PossiblyNullArgument */ + return [Plugin::path($plugin) . 'resources' . DIRECTORY_SEPARATOR . 'locales' . DIRECTORY_SEPARATOR]; + } + + deprecationWarning( + 'App::path() is deprecated for class path.' + . ' Use \Cake\Core\App::classPath() or \Cake\Core\Plugin::classPath() instead.' + ); + + return static::classPath($type, $plugin); + } + + /** + * Gets the path to a class type in the application or a plugin. + * + * Example: + * + * ``` + * App::classPath('Model/Table'); + * ``` + * + * Will return the path for tables - e.g. `src/Model/Table/`. + * + * ``` + * App::classPath('Model/Table', 'My/Plugin'); + * ``` + * + * Will return the plugin based path for those. + * + * @param string $type Package type. + * @param string|null $plugin Plugin name. + * @return array + */ + public static function classPath(string $type, ?string $plugin = null): array + { + if ($plugin !== null) { + return [ + Plugin::classPath($plugin) . $type . DIRECTORY_SEPARATOR, + ]; + } + + return [APP . $type . DIRECTORY_SEPARATOR]; + } + + /** + * Returns the full path to a package inside the CakePHP core + * + * Usage: + * + * ``` + * App::core('Cache/Engine'); + * ``` + * + * Will return the full path to the cache engines package. + * + * @param string $type Package type. + * @return array Full path to package + */ + public static function core(string $type): array + { + if ($type === 'templates') { + return [CORE_PATH . 'templates' . DIRECTORY_SEPARATOR]; + } + + return [CAKE . str_replace('/', DIRECTORY_SEPARATOR, $type) . DIRECTORY_SEPARATOR]; + } +} diff --git a/vendor/cakephp/core/BasePlugin.php b/vendor/cakephp/core/BasePlugin.php new file mode 100644 index 0000000..a748be3 --- /dev/null +++ b/vendor/cakephp/core/BasePlugin.php @@ -0,0 +1,305 @@ + $options Options + */ + public function __construct(array $options = []) + { + foreach (static::VALID_HOOKS as $key) { + if (isset($options[$key])) { + $this->{"{$key}Enabled"} = (bool)$options[$key]; + } + } + foreach (['name', 'path', 'classPath', 'configPath', 'templatePath'] as $path) { + if (isset($options[$path])) { + $this->{$path} = $options[$path]; + } + } + + $this->initialize(); + } + + /** + * Initialization hook called from constructor. + * + * @return void + */ + public function initialize(): void + { + } + + /** + * @inheritDoc + */ + public function getName(): string + { + if ($this->name) { + return $this->name; + } + $parts = explode('\\', static::class); + array_pop($parts); + $this->name = implode('/', $parts); + + return $this->name; + } + + /** + * @inheritDoc + */ + public function getPath(): string + { + if ($this->path) { + return $this->path; + } + $reflection = new ReflectionClass($this); + $path = dirname($reflection->getFileName()); + + // Trim off src + if (substr($path, -3) === 'src') { + $path = substr($path, 0, -3); + } + $this->path = rtrim($path, DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR; + + return $this->path; + } + + /** + * @inheritDoc + */ + public function getConfigPath(): string + { + if ($this->configPath) { + return $this->configPath; + } + $path = $this->getPath(); + + return $path . 'config' . DIRECTORY_SEPARATOR; + } + + /** + * @inheritDoc + */ + public function getClassPath(): string + { + if ($this->classPath) { + return $this->classPath; + } + $path = $this->getPath(); + + return $path . 'src' . DIRECTORY_SEPARATOR; + } + + /** + * @inheritDoc + */ + public function getTemplatePath(): string + { + if ($this->templatePath) { + return $this->templatePath; + } + $path = $this->getPath(); + + return $this->templatePath = $path . 'templates' . DIRECTORY_SEPARATOR; + } + + /** + * @inheritDoc + */ + public function enable(string $hook) + { + $this->checkHook($hook); + $this->{"{$hook}Enabled"} = true; + + return $this; + } + + /** + * @inheritDoc + */ + public function disable(string $hook) + { + $this->checkHook($hook); + $this->{"{$hook}Enabled"} = false; + + return $this; + } + + /** + * @inheritDoc + */ + public function isEnabled(string $hook): bool + { + $this->checkHook($hook); + + return $this->{"{$hook}Enabled"} === true; + } + + /** + * Check if a hook name is valid + * + * @param string $hook The hook name to check + * @throws \InvalidArgumentException on invalid hooks + * @return void + */ + protected function checkHook(string $hook): void + { + if (!in_array($hook, static::VALID_HOOKS, true)) { + throw new InvalidArgumentException( + "`$hook` is not a valid hook name. Must be one of " . implode(', ', static::VALID_HOOKS) + ); + } + } + + /** + * @inheritDoc + */ + public function routes(RouteBuilder $routes): void + { + $path = $this->getConfigPath() . 'routes.php'; + if (is_file($path)) { + $return = require $path; + if ($return instanceof Closure) { + $return($routes); + } + } + } + + /** + * @inheritDoc + */ + public function bootstrap(PluginApplicationInterface $app): void + { + $bootstrap = $this->getConfigPath() . 'bootstrap.php'; + if (is_file($bootstrap)) { + require $bootstrap; + } + } + + /** + * @inheritDoc + */ + public function console(CommandCollection $commands): CommandCollection + { + return $commands->addMany($commands->discoverPlugin($this->getName())); + } + + /** + * @inheritDoc + */ + public function middleware(MiddlewareQueue $middlewareQueue): MiddlewareQueue + { + return $middlewareQueue; + } + + /** + * Register container services for this plugin. + * + * @param \Cake\Core\ContainerInterface $container The container to add services to. + * @return void + */ + public function services(ContainerInterface $container): void + { + } +} diff --git a/vendor/cakephp/core/ClassLoader.php b/vendor/cakephp/core/ClassLoader.php new file mode 100644 index 0000000..e2a7525 --- /dev/null +++ b/vendor/cakephp/core/ClassLoader.php @@ -0,0 +1,139 @@ + + */ + protected $_prefixes = []; + + /** + * Register loader with SPL autoloader stack. + * + * @return void + */ + public function register(): void + { + /** @var callable $callable */ + $callable = [$this, 'loadClass']; + spl_autoload_register($callable); + } + + /** + * Adds a base directory for a namespace prefix. + * + * @param string $prefix The namespace prefix. + * @param string $baseDir A base directory for class files in the + * namespace. + * @param bool $prepend If true, prepend the base directory to the stack + * instead of appending it; this causes it to be searched first rather + * than last. + * @return void + */ + public function addNamespace(string $prefix, string $baseDir, bool $prepend = false): void + { + $prefix = trim($prefix, '\\') . '\\'; + + $baseDir = rtrim($baseDir, '/') . DIRECTORY_SEPARATOR; + $baseDir = rtrim($baseDir, DIRECTORY_SEPARATOR) . '/'; + + $this->_prefixes[$prefix] = $this->_prefixes[$prefix] ?? []; + + if ($prepend) { + array_unshift($this->_prefixes[$prefix], $baseDir); + } else { + $this->_prefixes[$prefix][] = $baseDir; + } + } + + /** + * Loads the class file for a given class name. + * + * @param string $class The fully-qualified class name. + * @return string|false The mapped file name on success, or boolean false on + * failure. + */ + public function loadClass(string $class) + { + $prefix = $class; + + while (($pos = strrpos($prefix, '\\')) !== false) { + $prefix = substr($class, 0, $pos + 1); + $relativeClass = substr($class, $pos + 1); + + $mappedFile = $this->_loadMappedFile($prefix, $relativeClass); + if ($mappedFile) { + return $mappedFile; + } + + $prefix = rtrim($prefix, '\\'); + } + + return false; + } + + /** + * Load the mapped file for a namespace prefix and relative class. + * + * @param string $prefix The namespace prefix. + * @param string $relativeClass The relative class name. + * @return string|false Boolean false if no mapped file can be loaded, or the + * name of the mapped file that was loaded. + */ + protected function _loadMappedFile(string $prefix, string $relativeClass) + { + if (!isset($this->_prefixes[$prefix])) { + return false; + } + + foreach ($this->_prefixes[$prefix] as $baseDir) { + $file = $baseDir . str_replace('\\', DIRECTORY_SEPARATOR, $relativeClass) . '.php'; + + if ($this->_requireFile($file)) { + return $file; + } + } + + return false; + } + + /** + * If a file exists, require it from the file system. + * + * @param string $file The file to require. + * @return bool True if the file exists, false if not. + */ + protected function _requireFile(string $file): bool + { + if (file_exists($file)) { + require $file; + + return true; + } + + return false; + } +} diff --git a/vendor/cakephp/core/Configure.php b/vendor/cakephp/core/Configure.php new file mode 100644 index 0000000..99e8259 --- /dev/null +++ b/vendor/cakephp/core/Configure.php @@ -0,0 +1,498 @@ + + */ + protected static $_values = [ + 'debug' => false, + ]; + + /** + * Configured engine classes, used to load config files from resources + * + * @see \Cake\Core\Configure::load() + * @var array<\Cake\Core\Configure\ConfigEngineInterface> + */ + protected static $_engines = []; + + /** + * Flag to track whether ini_set exists. + * + * @var bool|null + */ + protected static $_hasIniSet; + + /** + * Used to store a dynamic variable in Configure. + * + * Usage: + * ``` + * Configure::write('One.key1', 'value of the Configure::One[key1]'); + * Configure::write(['One.key1' => 'value of the Configure::One[key1]']); + * Configure::write('One', [ + * 'key1' => 'value of the Configure::One[key1]', + * 'key2' => 'value of the Configure::One[key2]' + * ]); + * + * Configure::write([ + * 'One.key1' => 'value of the Configure::One[key1]', + * 'One.key2' => 'value of the Configure::One[key2]' + * ]); + * ``` + * + * @param array|string $config The key to write, can be a dot notation value. + * Alternatively can be an array containing key(s) and value(s). + * @param mixed $value Value to set for the given key. + * @return void + * @link https://book.cakephp.org/4/en/development/configuration.html#writing-configuration-data + */ + public static function write($config, $value = null): void + { + if (!is_array($config)) { + $config = [$config => $value]; + } + + foreach ($config as $name => $valueToInsert) { + static::$_values = Hash::insert(static::$_values, $name, $valueToInsert); + } + + if (isset($config['debug'])) { + if (static::$_hasIniSet === null) { + static::$_hasIniSet = function_exists('ini_set'); + } + if (static::$_hasIniSet) { + ini_set('display_errors', $config['debug'] ? '1' : '0'); + } + } + } + + /** + * Used to read information stored in Configure. It's not + * possible to store `null` values in Configure. + * + * Usage: + * ``` + * Configure::read('Name'); will return all values for Name + * Configure::read('Name.key'); will return only the value of Configure::Name[key] + * ``` + * + * @param string|null $var Variable to obtain. Use '.' to access array elements. + * @param mixed $default The return value when the configure does not exist + * @return mixed Value stored in configure, or null. + * @link https://book.cakephp.org/4/en/development/configuration.html#reading-configuration-data + */ + public static function read(?string $var = null, $default = null) + { + if ($var === null) { + return static::$_values; + } + + return Hash::get(static::$_values, $var, $default); + } + + /** + * Returns true if given variable is set in Configure. + * + * @param string $var Variable name to check for + * @return bool True if variable is there + */ + public static function check(string $var): bool + { + if (empty($var)) { + return false; + } + + return static::read($var) !== null; + } + + /** + * Used to get information stored in Configure. It's not + * possible to store `null` values in Configure. + * + * Acts as a wrapper around Configure::read() and Configure::check(). + * The configure key/value pair fetched via this method is expected to exist. + * In case it does not an exception will be thrown. + * + * Usage: + * ``` + * Configure::readOrFail('Name'); will return all values for Name + * Configure::readOrFail('Name.key'); will return only the value of Configure::Name[key] + * ``` + * + * @param string $var Variable to obtain. Use '.' to access array elements. + * @return mixed Value stored in configure. + * @throws \RuntimeException if the requested configuration is not set. + * @link https://book.cakephp.org/4/en/development/configuration.html#reading-configuration-data + */ + public static function readOrFail(string $var) + { + if (!static::check($var)) { + throw new RuntimeException(sprintf('Expected configuration key "%s" not found.', $var)); + } + + return static::read($var); + } + + /** + * Used to delete a variable from Configure. + * + * Usage: + * ``` + * Configure::delete('Name'); will delete the entire Configure::Name + * Configure::delete('Name.key'); will delete only the Configure::Name[key] + * ``` + * + * @param string $var the var to be deleted + * @return void + * @link https://book.cakephp.org/4/en/development/configuration.html#deleting-configuration-data + */ + public static function delete(string $var): void + { + static::$_values = Hash::remove(static::$_values, $var); + } + + /** + * Used to consume information stored in Configure. It's not + * possible to store `null` values in Configure. + * + * Acts as a wrapper around Configure::consume() and Configure::check(). + * The configure key/value pair consumed via this method is expected to exist. + * In case it does not an exception will be thrown. + * + * @param string $var Variable to consume. Use '.' to access array elements. + * @return mixed Value stored in configure. + * @throws \RuntimeException if the requested configuration is not set. + * @since 3.6.0 + */ + public static function consumeOrFail(string $var) + { + if (!static::check($var)) { + throw new RuntimeException(sprintf('Expected configuration key "%s" not found.', $var)); + } + + return static::consume($var); + } + + /** + * Used to read and delete a variable from Configure. + * + * This is primarily used during bootstrapping to move configuration data + * out of configure into the various other classes in CakePHP. + * + * @param string $var The key to read and remove. + * @return array|string|null + */ + public static function consume(string $var) + { + if (strpos($var, '.') === false) { + if (!isset(static::$_values[$var])) { + return null; + } + $value = static::$_values[$var]; + unset(static::$_values[$var]); + + return $value; + } + $value = Hash::get(static::$_values, $var); + static::delete($var); + + return $value; + } + + /** + * Add a new engine to Configure. Engines allow you to read configuration + * files in various formats/storage locations. CakePHP comes with two built-in engines + * PhpConfig and IniConfig. You can also implement your own engine classes in your application. + * + * To add a new engine to Configure: + * + * ``` + * Configure::config('ini', new IniConfig()); + * ``` + * + * @param string $name The name of the engine being configured. This alias is used later to + * read values from a specific engine. + * @param \Cake\Core\Configure\ConfigEngineInterface $engine The engine to append. + * @return void + */ + public static function config(string $name, ConfigEngineInterface $engine): void + { + static::$_engines[$name] = $engine; + } + + /** + * Returns true if the Engine objects is configured. + * + * @param string $name Engine name. + * @return bool + */ + public static function isConfigured(string $name): bool + { + return isset(static::$_engines[$name]); + } + + /** + * Gets the names of the configured Engine objects. + * + * @return array + */ + public static function configured(): array + { + $engines = array_keys(static::$_engines); + + return array_map(function ($key) { + return (string)$key; + }, $engines); + } + + /** + * Remove a configured engine. This will unset the engine + * and make any future attempts to use it cause an Exception. + * + * @param string $name Name of the engine to drop. + * @return bool Success + */ + public static function drop(string $name): bool + { + if (!isset(static::$_engines[$name])) { + return false; + } + unset(static::$_engines[$name]); + + return true; + } + + /** + * Loads stored configuration information from a resource. You can add + * config file resource engines with `Configure::config()`. + * + * Loaded configuration information will be merged with the current + * runtime configuration. You can load configuration files from plugins + * by preceding the filename with the plugin name. + * + * `Configure::load('Users.user', 'default')` + * + * Would load the 'user' config file using the default config engine. You can load + * app config files by giving the name of the resource you want loaded. + * + * ``` + * Configure::load('setup', 'default'); + * ``` + * + * If using `default` config and no engine has been configured for it yet, + * one will be automatically created using PhpConfig + * + * @param string $key name of configuration resource to load. + * @param string $config Name of the configured engine to use to read the resource identified by $key. + * @param bool $merge if config files should be merged instead of simply overridden + * @return bool True if load successful. + * @throws \Cake\Core\Exception\CakeException if the $config engine is not found + * @link https://book.cakephp.org/4/en/development/configuration.html#reading-and-writing-configuration-files + */ + public static function load(string $key, string $config = 'default', bool $merge = true): bool + { + $engine = static::_getEngine($config); + if (!$engine) { + throw new CakeException( + sprintf( + 'Config %s engine not found when attempting to load %s.', + $config, + $key + ) + ); + } + + $values = $engine->read($key); + + if ($merge) { + $values = Hash::merge(static::$_values, $values); + } + + static::write($values); + + return true; + } + + /** + * Dump data currently in Configure into $key. The serialization format + * is decided by the config engine attached as $config. For example, if the + * 'default' adapter is a PhpConfig, the generated file will be a PHP + * configuration file loadable by the PhpConfig. + * + * ### Usage + * + * Given that the 'default' engine is an instance of PhpConfig. + * Save all data in Configure to the file `my_config.php`: + * + * ``` + * Configure::dump('my_config', 'default'); + * ``` + * + * Save only the error handling configuration: + * + * ``` + * Configure::dump('error', 'default', ['Error', 'Exception']; + * ``` + * + * @param string $key The identifier to create in the config adapter. + * This could be a filename or a cache key depending on the adapter being used. + * @param string $config The name of the configured adapter to dump data with. + * @param array $keys The name of the top-level keys you want to dump. + * This allows you save only some data stored in Configure. + * @return bool Success + * @throws \Cake\Core\Exception\CakeException if the adapter does not implement a `dump` method. + */ + public static function dump(string $key, string $config = 'default', array $keys = []): bool + { + $engine = static::_getEngine($config); + if (!$engine) { + throw new CakeException(sprintf('There is no "%s" config engine.', $config)); + } + $values = static::$_values; + if (!empty($keys)) { + $values = array_intersect_key($values, array_flip($keys)); + } + + return $engine->dump($key, $values); + } + + /** + * Get the configured engine. Internally used by `Configure::load()` and `Configure::dump()` + * Will create new PhpConfig for default if not configured yet. + * + * @param string $config The name of the configured adapter + * @return \Cake\Core\Configure\ConfigEngineInterface|null Engine instance or null + */ + protected static function _getEngine(string $config): ?ConfigEngineInterface + { + if (!isset(static::$_engines[$config])) { + if ($config !== 'default') { + return null; + } + static::config($config, new PhpConfig()); + } + + return static::$_engines[$config]; + } + + /** + * Used to determine the current version of CakePHP. + * + * Usage + * ``` + * Configure::version(); + * ``` + * + * @return string Current version of CakePHP + */ + public static function version(): string + { + $version = static::read('Cake.version'); + if ($version !== null) { + return $version; + } + + $path = dirname(dirname(__DIR__)) . DIRECTORY_SEPARATOR . 'config/config.php'; + if (is_file($path)) { + $config = require $path; + static::write($config); + + return static::read('Cake.version'); + } + + return 'unknown'; + } + + /** + * Used to write runtime configuration into Cache. Stored runtime configuration can be + * restored using `Configure::restore()`. These methods can be used to enable configuration managers + * frontends, or other GUI type interfaces for configuration. + * + * @param string $name The storage name for the saved configuration. + * @param string $cacheConfig The cache configuration to save into. Defaults to 'default' + * @param array|null $data Either an array of data to store, or leave empty to store all values. + * @return bool Success + * @throws \RuntimeException + */ + public static function store(string $name, string $cacheConfig = 'default', ?array $data = null): bool + { + if ($data === null) { + $data = static::$_values; + } + if (!class_exists(Cache::class)) { + throw new RuntimeException('You must install cakephp/cache to use Configure::store()'); + } + + return Cache::write($name, $data, $cacheConfig); + } + + /** + * Restores configuration data stored in the Cache into configure. Restored + * values will overwrite existing ones. + * + * @param string $name Name of the stored config file to load. + * @param string $cacheConfig Name of the Cache configuration to read from. + * @return bool Success. + * @throws \RuntimeException + */ + public static function restore(string $name, string $cacheConfig = 'default'): bool + { + if (!class_exists(Cache::class)) { + throw new RuntimeException('You must install cakephp/cache to use Configure::restore()'); + } + $values = Cache::read($name, $cacheConfig); + if ($values) { + static::write($values); + + return true; + } + + return false; + } + + /** + * Clear all values stored in Configure. + * + * @return void + */ + public static function clear(): void + { + static::$_values = []; + } +} diff --git a/vendor/cakephp/core/Configure/ConfigEngineInterface.php b/vendor/cakephp/core/Configure/ConfigEngineInterface.php new file mode 100644 index 0000000..a8f59ad --- /dev/null +++ b/vendor/cakephp/core/Configure/ConfigEngineInterface.php @@ -0,0 +1,44 @@ + ['password' => 'secret']]` + * + * You can nest properties as deeply as needed using `.`'s. In addition to using `.` you + * can use standard ini section notation to create nested structures: + * + * ``` + * [section] + * key = value + * ``` + * + * Once loaded into Configure, the above would be accessed using: + * + * `Configure::read('section.key'); + * + * You can also use `.` separated values in section names to create more deeply + * nested structures. + * + * IniConfig also manipulates how the special ini values of + * 'yes', 'no', 'on', 'off', 'null' are handled. These values will be + * converted to their boolean equivalents. + * + * @see https://secure.php.net/parse_ini_file + */ +class IniConfig implements ConfigEngineInterface +{ + use FileConfigTrait; + + /** + * File extension. + * + * @var string + */ + protected $_extension = '.ini'; + + /** + * The section to read, if null all sections will be read. + * + * @var string|null + */ + protected $_section; + + /** + * Build and construct a new ini file parser. The parser can be used to read + * ini files that are on the filesystem. + * + * @param string|null $path Path to load ini config files from. Defaults to CONFIG. + * @param string|null $section Only get one section, leave null to parse and fetch + * all sections in the ini file. + */ + public function __construct(?string $path = null, ?string $section = null) + { + if ($path === null) { + $path = CONFIG; + } + $this->_path = $path; + $this->_section = $section; + } + + /** + * Read an ini file and return the results as an array. + * + * @param string $key The identifier to read from. If the key has a . it will be treated + * as a plugin prefix. The chosen file must be on the engine's path. + * @return array Parsed configuration values. + * @throws \Cake\Core\Exception\CakeException when files don't exist. + * Or when files contain '..' as this could lead to abusive reads. + */ + public function read(string $key): array + { + $file = $this->_getFilePath($key, true); + + $contents = parse_ini_file($file, true); + if ($this->_section && isset($contents[$this->_section])) { + $values = $this->_parseNestedValues($contents[$this->_section]); + } else { + $values = []; + foreach ($contents as $section => $attribs) { + if (is_array($attribs)) { + $values[$section] = $this->_parseNestedValues($attribs); + } else { + $parse = $this->_parseNestedValues([$attribs]); + $values[$section] = array_shift($parse); + } + } + } + + return $values; + } + + /** + * parses nested values out of keys. + * + * @param array $values Values to be exploded. + * @return array Array of values exploded + */ + protected function _parseNestedValues(array $values): array + { + foreach ($values as $key => $value) { + if ($value === '1') { + $value = true; + } + if ($value === '') { + $value = false; + } + unset($values[$key]); + if (strpos((string)$key, '.') !== false) { + $values = Hash::insert($values, $key, $value); + } else { + $values[$key] = $value; + } + } + + return $values; + } + + /** + * Dumps the state of Configure data into an ini formatted string. + * + * @param string $key The identifier to write to. If the key has a . it will be treated + * as a plugin prefix. + * @param array $data The data to convert to ini file. + * @return bool Success. + */ + public function dump(string $key, array $data): bool + { + $result = []; + foreach ($data as $k => $value) { + $isSection = false; + /** @psalm-suppress InvalidArrayAccess */ + if ($k[0] !== '[') { + $result[] = "[$k]"; + $isSection = true; + } + if (is_array($value)) { + $kValues = Hash::flatten($value, '.'); + foreach ($kValues as $k2 => $v) { + $result[] = "$k2 = " . $this->_value($v); + } + } + if ($isSection) { + $result[] = ''; + } + } + $contents = trim(implode("\n", $result)); + + $filename = $this->_getFilePath($key); + + return file_put_contents($filename, $contents) > 0; + } + + /** + * Converts a value into the ini equivalent + * + * @param mixed $value Value to export. + * @return string String value for ini file. + */ + protected function _value($value): string + { + if ($value === null) { + return 'null'; + } + if ($value === true) { + return 'true'; + } + if ($value === false) { + return 'false'; + } + + return (string)$value; + } +} diff --git a/vendor/cakephp/core/Configure/Engine/JsonConfig.php b/vendor/cakephp/core/Configure/Engine/JsonConfig.php new file mode 100644 index 0000000..66e8a90 --- /dev/null +++ b/vendor/cakephp/core/Configure/Engine/JsonConfig.php @@ -0,0 +1,115 @@ +_path = $path; + } + + /** + * Read a config file and return its contents. + * + * Files with `.` in the name will be treated as values in plugins. Instead of + * reading from the initialized path, plugin keys will be located using Plugin::path(). + * + * @param string $key The identifier to read from. If the key has a . it will be treated + * as a plugin prefix. + * @return array Parsed configuration values. + * @throws \Cake\Core\Exception\CakeException When files don't exist or when + * files contain '..' (as this could lead to abusive reads) or when there + * is an error parsing the JSON string. + */ + public function read(string $key): array + { + $file = $this->_getFilePath($key, true); + + $values = json_decode(file_get_contents($file), true); + if (json_last_error() !== JSON_ERROR_NONE) { + throw new CakeException(sprintf( + 'Error parsing JSON string fetched from config file "%s.json": %s', + $key, + json_last_error_msg() + )); + } + if (!is_array($values)) { + throw new CakeException(sprintf( + 'Decoding JSON config file "%s.json" did not return an array', + $key + )); + } + + return $values; + } + + /** + * Converts the provided $data into a JSON string that can be used saved + * into a file and loaded later. + * + * @param string $key The identifier to write to. If the key has a . it will + * be treated as a plugin prefix. + * @param array $data Data to dump. + * @return bool Success + */ + public function dump(string $key, array $data): bool + { + $filename = $this->_getFilePath($key); + + return file_put_contents($filename, json_encode($data, JSON_PRETTY_PRINT)) > 0; + } +} diff --git a/vendor/cakephp/core/Configure/Engine/PhpConfig.php b/vendor/cakephp/core/Configure/Engine/PhpConfig.php new file mode 100644 index 0000000..6bdf3a4 --- /dev/null +++ b/vendor/cakephp/core/Configure/Engine/PhpConfig.php @@ -0,0 +1,114 @@ + false, + * 'Security' => [ + * 'salt' => 'its-secret' + * ], + * 'App' => [ + * 'namespace' => 'App' + * ] + * ]; + * ``` + * + * @see \Cake\Core\Configure::load() for how to load custom configuration files. + */ +class PhpConfig implements ConfigEngineInterface +{ + use FileConfigTrait; + + /** + * File extension. + * + * @var string + */ + protected $_extension = '.php'; + + /** + * Constructor for PHP Config file reading. + * + * @param string|null $path The path to read config files from. Defaults to CONFIG. + */ + public function __construct(?string $path = null) + { + if ($path === null) { + $path = CONFIG; + } + $this->_path = $path; + } + + /** + * Read a config file and return its contents. + * + * Files with `.` in the name will be treated as values in plugins. Instead of + * reading from the initialized path, plugin keys will be located using Plugin::path(). + * + * @param string $key The identifier to read from. If the key has a . it will be treated + * as a plugin prefix. + * @return array Parsed configuration values. + * @throws \Cake\Core\Exception\CakeException when files don't exist or they don't contain `$config`. + * Or when files contain '..' as this could lead to abusive reads. + */ + public function read(string $key): array + { + $file = $this->_getFilePath($key, true); + + $config = null; + + $return = include $file; + if (is_array($return)) { + return $return; + } + + throw new CakeException(sprintf('Config file "%s" did not return an array', $key . '.php')); + } + + /** + * Converts the provided $data into a string of PHP code that can + * be used saved into a file and loaded later. + * + * @param string $key The identifier to write to. If the key has a . it will be treated + * as a plugin prefix. + * @param array $data Data to dump. + * @return bool Success + */ + public function dump(string $key, array $data): bool + { + $contents = '_getFilePath($key); + + return file_put_contents($filename, $contents) > 0; + } +} diff --git a/vendor/cakephp/core/Configure/FileConfigTrait.php b/vendor/cakephp/core/Configure/FileConfigTrait.php new file mode 100644 index 0000000..79bcdea --- /dev/null +++ b/vendor/cakephp/core/Configure/FileConfigTrait.php @@ -0,0 +1,72 @@ +_path . $key; + } + + $file .= $this->_extension; + + if (!$checkExists || is_file($file)) { + return $file; + } + + $realPath = realpath($file); + if ($realPath !== false && is_file($realPath)) { + return $realPath; + } + + throw new CakeException(sprintf('Could not load configuration file: %s', $file)); + } +} diff --git a/vendor/cakephp/core/ConsoleApplicationInterface.php b/vendor/cakephp/core/ConsoleApplicationInterface.php new file mode 100644 index 0000000..b2a532a --- /dev/null +++ b/vendor/cakephp/core/ConsoleApplicationInterface.php @@ -0,0 +1,42 @@ +_attributes = $message; + $message = vsprintf($this->_messageTemplate, $message); + } + parent::__construct($message, $code ?? $this->_defaultCode, $previous); + } + + /** + * Get the passed in attributes + * + * @return array + */ + public function getAttributes(): array + { + return $this->_attributes; + } + + /** + * Get/set the response header to be used + * + * See also {@link \Cake\Http\Response::withHeader()} + * + * @param array|string|null $header A single header string or an associative + * array of "header name" => "header value" + * @param string|null $value The header value. + * @return array|null + * @deprecated 4.2.0 Use `HttpException::setHeaders()` instead. Response headers + * should be set for HttpException only. + */ + public function responseHeader($header = null, $value = null): ?array + { + if ($header === null) { + return $this->_responseHeaders; + } + + deprecationWarning( + 'Setting HTTP response headers from Exception directly is deprecated. ' . + 'If your exceptions extend Exception, they must now extend HttpException. ' . + 'You should only set HTTP headers on HttpException instances via the `setHeaders()` method.' + ); + if (is_array($header)) { + return $this->_responseHeaders = $header; + } + + return $this->_responseHeaders = [$header => $value]; + } +} + +// phpcs:disable +class_alias( + 'Cake\Core\Exception\CakeException', + 'Cake\Core\Exception\Exception' +); +// phpcs:enable diff --git a/vendor/cakephp/core/Exception/Exception.php b/vendor/cakephp/core/Exception/Exception.php new file mode 100644 index 0000000..bd93c50 --- /dev/null +++ b/vendor/cakephp/core/Exception/Exception.php @@ -0,0 +1,21 @@ + + */ + protected $_config = []; + + /** + * Whether the config property has already been configured with defaults + * + * @var bool + */ + protected $_configInitialized = false; + + /** + * Sets the config. + * + * ### Usage + * + * Setting a specific value: + * + * ``` + * $this->setConfig('key', $value); + * ``` + * + * Setting a nested value: + * + * ``` + * $this->setConfig('some.nested.key', $value); + * ``` + * + * Updating multiple config settings at the same time: + * + * ``` + * $this->setConfig(['one' => 'value', 'another' => 'value']); + * ``` + * + * @param array|string $key The key to set, or a complete array of configs. + * @param mixed|null $value The value to set. + * @param bool $merge Whether to recursively merge or overwrite existing config, defaults to true. + * @return $this + * @throws \Cake\Core\Exception\CakeException When trying to set a key that is invalid. + */ + public function setConfig($key, $value = null, $merge = true) + { + if (!$this->_configInitialized) { + $this->_config = $this->_defaultConfig; + $this->_configInitialized = true; + } + + $this->_configWrite($key, $value, $merge); + + return $this; + } + + /** + * Returns the config. + * + * ### Usage + * + * Reading the whole config: + * + * ``` + * $this->getConfig(); + * ``` + * + * Reading a specific value: + * + * ``` + * $this->getConfig('key'); + * ``` + * + * Reading a nested value: + * + * ``` + * $this->getConfig('some.nested.key'); + * ``` + * + * Reading with default value: + * + * ``` + * $this->getConfig('some-key', 'default-value'); + * ``` + * + * @param string|null $key The key to get or null for the whole config. + * @param mixed $default The return value when the key does not exist. + * @return mixed Configuration data at the named key or null if the key does not exist. + */ + public function getConfig(?string $key = null, $default = null) + { + if (!$this->_configInitialized) { + $this->_config = $this->_defaultConfig; + $this->_configInitialized = true; + } + + $return = $this->_configRead($key); + + return $return ?? $default; + } + + /** + * Returns the config for this specific key. + * + * The config value for this key must exist, it can never be null. + * + * @param string $key The key to get. + * @return mixed Configuration data at the named key + * @throws \InvalidArgumentException + */ + public function getConfigOrFail(string $key) + { + $config = $this->getConfig($key); + if ($config === null) { + throw new InvalidArgumentException(sprintf('Expected configuration `%s` not found.', $key)); + } + + return $config; + } + + /** + * Merge provided config with existing config. Unlike `config()` which does + * a recursive merge for nested keys, this method does a simple merge. + * + * Setting a specific value: + * + * ``` + * $this->configShallow('key', $value); + * ``` + * + * Setting a nested value: + * + * ``` + * $this->configShallow('some.nested.key', $value); + * ``` + * + * Updating multiple config settings at the same time: + * + * ``` + * $this->configShallow(['one' => 'value', 'another' => 'value']); + * ``` + * + * @param array|string $key The key to set, or a complete array of configs. + * @param mixed|null $value The value to set. + * @return $this + */ + public function configShallow($key, $value = null) + { + if (!$this->_configInitialized) { + $this->_config = $this->_defaultConfig; + $this->_configInitialized = true; + } + + $this->_configWrite($key, $value, 'shallow'); + + return $this; + } + + /** + * Reads a config key. + * + * @param string|null $key Key to read. + * @return mixed + */ + protected function _configRead(?string $key) + { + if ($key === null) { + return $this->_config; + } + + if (strpos($key, '.') === false) { + return $this->_config[$key] ?? null; + } + + $return = $this->_config; + + foreach (explode('.', $key) as $k) { + if (!is_array($return) || !isset($return[$k])) { + $return = null; + break; + } + + $return = $return[$k]; + } + + return $return; + } + + /** + * Writes a config key. + * + * @param array|string $key Key to write to. + * @param mixed $value Value to write. + * @param string|bool $merge True to merge recursively, 'shallow' for simple merge, + * false to overwrite, defaults to false. + * @return void + * @throws \Cake\Core\Exception\CakeException if attempting to clobber existing config + */ + protected function _configWrite($key, $value, $merge = false): void + { + if (is_string($key) && $value === null) { + $this->_configDelete($key); + + return; + } + + if ($merge) { + $update = is_array($key) ? $key : [$key => $value]; + if ($merge === 'shallow') { + $this->_config = array_merge($this->_config, Hash::expand($update)); + } else { + $this->_config = Hash::merge($this->_config, Hash::expand($update)); + } + + return; + } + + if (is_array($key)) { + foreach ($key as $k => $val) { + $this->_configWrite($k, $val); + } + + return; + } + + if (strpos($key, '.') === false) { + $this->_config[$key] = $value; + + return; + } + + $update = &$this->_config; + $stack = explode('.', $key); + + foreach ($stack as $k) { + if (!is_array($update)) { + throw new CakeException(sprintf('Cannot set %s value', $key)); + } + + $update[$k] = $update[$k] ?? []; + + $update = &$update[$k]; + } + + $update = $value; + } + + /** + * Deletes a single config key. + * + * @param string $key Key to delete. + * @return void + * @throws \Cake\Core\Exception\CakeException if attempting to clobber existing config + */ + protected function _configDelete(string $key): void + { + if (strpos($key, '.') === false) { + unset($this->_config[$key]); + + return; + } + + $update = &$this->_config; + $stack = explode('.', $key); + $length = count($stack); + + foreach ($stack as $i => $k) { + if (!is_array($update)) { + throw new CakeException(sprintf('Cannot unset %s value', $key)); + } + + if (!isset($update[$k])) { + break; + } + + if ($i === $length - 1) { + unset($update[$k]); + break; + } + + $update = &$update[$k]; + } + } +} diff --git a/vendor/cakephp/core/LICENSE.txt b/vendor/cakephp/core/LICENSE.txt new file mode 100644 index 0000000..b938c9e --- /dev/null +++ b/vendor/cakephp/core/LICENSE.txt @@ -0,0 +1,22 @@ +The MIT License (MIT) + +CakePHP(tm) : The Rapid Development PHP Framework (https://cakephp.org) +Copyright (c) 2005-2020, Cake Software Foundation, Inc. (https://cakefoundation.org) + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/vendor/cakephp/core/ObjectRegistry.php b/vendor/cakephp/core/ObjectRegistry.php new file mode 100644 index 0000000..25b8d16 --- /dev/null +++ b/vendor/cakephp/core/ObjectRegistry.php @@ -0,0 +1,416 @@ + + */ +abstract class ObjectRegistry implements Countable, IteratorAggregate +{ + /** + * Map of loaded objects. + * + * @var array + * @psalm-var array + */ + protected $_loaded = []; + + /** + * Loads/constructs an object instance. + * + * Will return the instance in the registry if it already exists. + * If a subclass provides event support, you can use `$config['enabled'] = false` + * to exclude constructed objects from being registered for events. + * + * Using {@link \Cake\Controller\Component::$components} as an example. You can alias + * an object by setting the 'className' key, i.e., + * + * ``` + * protected $components = [ + * 'Email' => [ + * 'className' => 'App\Controller\Component\AliasedEmailComponent' + * ]; + * ]; + * ``` + * + * All calls to the `Email` component would use `AliasedEmail` instead. + * + * @param string $name The name/class of the object to load. + * @param array $config Additional settings to use when loading the object. + * @return mixed + * @psalm-return TObject + * @throws \Exception If the class cannot be found. + */ + public function load(string $name, array $config = []) + { + if (isset($config['className'])) { + $objName = $name; + $name = $config['className']; + } else { + [, $objName] = pluginSplit($name); + } + + $loaded = isset($this->_loaded[$objName]); + if ($loaded && !empty($config)) { + $this->_checkDuplicate($objName, $config); + } + if ($loaded) { + return $this->_loaded[$objName]; + } + + $className = $name; + if (is_string($name)) { + $className = $this->_resolveClassName($name); + if ($className === null) { + [$plugin, $name] = pluginSplit($name); + $this->_throwMissingClassError($name, $plugin); + } + } + + /** + * @psalm-var TObject $instance + * @psalm-suppress PossiblyNullArgument + **/ + $instance = $this->_create($className, $objName, $config); + $this->_loaded[$objName] = $instance; + + return $instance; + } + + /** + * Check for duplicate object loading. + * + * If a duplicate is being loaded and has different configuration, that is + * bad and an exception will be raised. + * + * An exception is raised, as replacing the object will not update any + * references other objects may have. Additionally, simply updating the runtime + * configuration is not a good option as we may be missing important constructor + * logic dependent on the configuration. + * + * @param string $name The name of the alias in the registry. + * @param array $config The config data for the new instance. + * @return void + * @throws \RuntimeException When a duplicate is found. + */ + protected function _checkDuplicate(string $name, array $config): void + { + $existing = $this->_loaded[$name]; + $msg = sprintf('The "%s" alias has already been loaded.', $name); + $hasConfig = method_exists($existing, 'getConfig'); + if (!$hasConfig) { + throw new RuntimeException($msg); + } + if (empty($config)) { + return; + } + $existingConfig = $existing->getConfig(); + unset($config['enabled'], $existingConfig['enabled']); + + $failure = null; + foreach ($config as $key => $value) { + if (!array_key_exists($key, $existingConfig)) { + $failure = " The `{$key}` was not defined in the previous configuration data."; + break; + } + if (isset($existingConfig[$key]) && $existingConfig[$key] !== $value) { + $failure = sprintf( + ' The `%s` key has a value of `%s` but previously had a value of `%s`', + $key, + json_encode($value), + json_encode($existingConfig[$key]) + ); + break; + } + } + if ($failure) { + throw new RuntimeException($msg . $failure); + } + } + + /** + * Should resolve the classname for a given object type. + * + * @param string $class The class to resolve. + * @return string|null The resolved name or null for failure. + * @psalm-return class-string|null + */ + abstract protected function _resolveClassName(string $class): ?string; + + /** + * Throw an exception when the requested object name is missing. + * + * @param string $class The class that is missing. + * @param string|null $plugin The plugin $class is missing from. + * @return void + * @throws \Exception + */ + abstract protected function _throwMissingClassError(string $class, ?string $plugin): void; + + /** + * Create an instance of a given classname. + * + * This method should construct and do any other initialization logic + * required. + * + * @param object|string $class The class to build. + * @param string $alias The alias of the object. + * @param array $config The Configuration settings for construction + * @return object + * @psalm-param TObject|string $class + * @psalm-return TObject + */ + abstract protected function _create($class, string $alias, array $config); + + /** + * Get the list of loaded objects. + * + * @return array List of object names. + */ + public function loaded(): array + { + return array_keys($this->_loaded); + } + + /** + * Check whether a given object is loaded. + * + * @param string $name The object name to check for. + * @return bool True is object is loaded else false. + */ + public function has(string $name): bool + { + return isset($this->_loaded[$name]); + } + + /** + * Get loaded object instance. + * + * @param string $name Name of object. + * @return object Object instance. + * @throws \RuntimeException If not loaded or found. + * @psalm-return TObject + */ + public function get(string $name) + { + if (!isset($this->_loaded[$name])) { + throw new RuntimeException(sprintf('Unknown object "%s"', $name)); + } + + return $this->_loaded[$name]; + } + + /** + * Provide public read access to the loaded objects + * + * @param string $name Name of property to read + * @return object|null + * @psalm-return TObject|null + */ + public function __get(string $name) + { + return $this->_loaded[$name] ?? null; + } + + /** + * Provide isset access to _loaded + * + * @param string $name Name of object being checked. + * @return bool + */ + public function __isset(string $name): bool + { + return $this->has($name); + } + + /** + * Sets an object. + * + * @param string $name Name of a property to set. + * @param object $object Object to set. + * @psalm-param TObject $object + * @return void + */ + public function __set(string $name, $object): void + { + $this->set($name, $object); + } + + /** + * Unsets an object. + * + * @param string $name Name of a property to unset. + * @return void + */ + public function __unset(string $name): void + { + $this->unload($name); + } + + /** + * Normalizes an object array, creates an array that makes lazy loading + * easier + * + * @param array $objects Array of child objects to normalize. + * @return array Array of normalized objects. + */ + public function normalizeArray(array $objects): array + { + $normal = []; + foreach ($objects as $i => $objectName) { + $config = []; + if (!is_int($i)) { + $config = (array)$objectName; + $objectName = $i; + } + [, $name] = pluginSplit($objectName); + if (isset($config['class'])) { + $normal[$name] = $config + ['config' => []]; + } else { + $normal[$name] = ['class' => $objectName, 'config' => $config]; + } + } + + return $normal; + } + + /** + * Clear loaded instances in the registry. + * + * If the registry subclass has an event manager, the objects will be detached from events as well. + * + * @return $this + */ + public function reset() + { + foreach (array_keys($this->_loaded) as $name) { + $this->unload((string)$name); + } + + return $this; + } + + /** + * Set an object directly into the registry by name. + * + * If this collection implements events, the passed object will + * be attached into the event manager + * + * @param string $name The name of the object to set in the registry. + * @param object $object instance to store in the registry + * @return $this + * @psalm-param TObject $object + */ + public function set(string $name, object $object) + { + [, $objName] = pluginSplit($name); + + // Just call unload if the object was loaded before + if (array_key_exists($name, $this->_loaded)) { + $this->unload($name); + } + if ($this instanceof EventDispatcherInterface && $object instanceof EventListenerInterface) { + $this->getEventManager()->on($object); + } + $this->_loaded[$objName] = $object; + + return $this; + } + + /** + * Remove an object from the registry. + * + * If this registry has an event manager, the object will be detached from any events as well. + * + * @param string $name The name of the object to remove from the registry. + * @return $this + */ + public function unload(string $name) + { + if (empty($this->_loaded[$name])) { + [$plugin, $name] = pluginSplit($name); + $this->_throwMissingClassError($name, $plugin); + } + + $object = $this->_loaded[$name]; + if ($this instanceof EventDispatcherInterface && $object instanceof EventListenerInterface) { + $this->getEventManager()->off($object); + } + unset($this->_loaded[$name]); + + return $this; + } + + /** + * Returns an array iterator. + * + * @return \Traversable + * @psalm-return \Traversable + */ + public function getIterator(): Traversable + { + return new ArrayIterator($this->_loaded); + } + + /** + * Returns the number of loaded objects. + * + * @return int + */ + public function count(): int + { + return count($this->_loaded); + } + + /** + * Debug friendly object properties. + * + * @return array + */ + public function __debugInfo(): array + { + $properties = get_object_vars($this); + if (isset($properties['_loaded'])) { + $properties['_loaded'] = array_keys($properties['_loaded']); + } + + return $properties; + } +} diff --git a/vendor/cakephp/core/Plugin.php b/vendor/cakephp/core/Plugin.php new file mode 100644 index 0000000..67e1a63 --- /dev/null +++ b/vendor/cakephp/core/Plugin.php @@ -0,0 +1,136 @@ +get($name); + + return $plugin->getPath(); + } + + /** + * Returns the filesystem path for plugin's folder containing class files. + * + * @param string $name name of the plugin in CamelCase format. + * @return string Path to the plugin folder containing class files. + * @throws \Cake\Core\Exception\MissingPluginException If plugin has not been loaded. + */ + public static function classPath(string $name): string + { + $plugin = static::getCollection()->get($name); + + return $plugin->getClassPath(); + } + + /** + * Returns the filesystem path for plugin's folder containing config files. + * + * @param string $name name of the plugin in CamelCase format. + * @return string Path to the plugin folder containing config files. + * @throws \Cake\Core\Exception\MissingPluginException If plugin has not been loaded. + */ + public static function configPath(string $name): string + { + $plugin = static::getCollection()->get($name); + + return $plugin->getConfigPath(); + } + + /** + * Returns the filesystem path for plugin's folder containing template files. + * + * @param string $name name of the plugin in CamelCase format. + * @return string Path to the plugin folder containing template files. + * @throws \Cake\Core\Exception\MissingPluginException If plugin has not been loaded. + */ + public static function templatePath(string $name): string + { + $plugin = static::getCollection()->get($name); + + return $plugin->getTemplatePath(); + } + + /** + * Returns true if the plugin $plugin is already loaded. + * + * @param string $plugin Plugin name. + * @return bool + * @since 3.7.0 + */ + public static function isLoaded(string $plugin): bool + { + return static::getCollection()->has($plugin); + } + + /** + * Return a list of loaded plugins. + * + * @return array A list of plugins that have been loaded + */ + public static function loaded(): array + { + $names = []; + foreach (static::getCollection() as $plugin) { + $names[] = $plugin->getName(); + } + sort($names); + + return $names; + } + + /** + * Get the shared plugin collection. + * + * This method should generally not be used during application + * runtime as plugins should be set during Application startup. + * + * @return \Cake\Core\PluginCollection + */ + public static function getCollection(): PluginCollection + { + if (!isset(static::$plugins)) { + static::$plugins = new PluginCollection(); + } + + return static::$plugins; + } +} diff --git a/vendor/cakephp/core/PluginApplicationInterface.php b/vendor/cakephp/core/PluginApplicationInterface.php new file mode 100644 index 0000000..0ba0771 --- /dev/null +++ b/vendor/cakephp/core/PluginApplicationInterface.php @@ -0,0 +1,75 @@ + $config The configuration data for the plugin if using a string for $name + * @return $this + */ + public function addPlugin($name, array $config = []); + + /** + * Run bootstrap logic for loaded plugins. + * + * @return void + */ + public function pluginBootstrap(): void; + + /** + * Run routes hooks for loaded plugins + * + * @param \Cake\Routing\RouteBuilder $routes The route builder to use. + * @return \Cake\Routing\RouteBuilder + */ + public function pluginRoutes(RouteBuilder $routes): RouteBuilder; + + /** + * Run middleware hooks for plugins + * + * @param \Cake\Http\MiddlewareQueue $middleware The MiddlewareQueue to use. + * @return \Cake\Http\MiddlewareQueue + */ + public function pluginMiddleware(MiddlewareQueue $middleware): MiddlewareQueue; + + /** + * Run console hooks for plugins + * + * @param \Cake\Console\CommandCollection $commands The CommandCollection to use. + * @return \Cake\Console\CommandCollection + */ + public function pluginConsole(CommandCollection $commands): CommandCollection; +} diff --git a/vendor/cakephp/core/PluginCollection.php b/vendor/cakephp/core/PluginCollection.php new file mode 100644 index 0000000..a9fc4a1 --- /dev/null +++ b/vendor/cakephp/core/PluginCollection.php @@ -0,0 +1,363 @@ + + */ +class PluginCollection implements Iterator, Countable +{ + /** + * Plugin list + * + * @var array<\Cake\Core\PluginInterface> + */ + protected $plugins = []; + + /** + * Names of plugins + * + * @var array + */ + protected $names = []; + + /** + * Iterator position stack. + * + * @var array + */ + protected $positions = []; + + /** + * Loop depth + * + * @var int + */ + protected $loopDepth = -1; + + /** + * Constructor + * + * @param array<\Cake\Core\PluginInterface> $plugins The map of plugins to add to the collection. + */ + public function __construct(array $plugins = []) + { + foreach ($plugins as $plugin) { + $this->add($plugin); + } + $this->loadConfig(); + } + + /** + * Load the path information stored in vendor/cakephp-plugins.php + * + * This file is generated by the cakephp/plugin-installer package and used + * to locate plugins on the filesystem as applications can use `extra.plugin-paths` + * in their composer.json file to move plugin outside of vendor/ + * + * @internal + * @return void + */ + protected function loadConfig(): void + { + if (Configure::check('plugins')) { + return; + } + $vendorFile = dirname(dirname(__DIR__)) . DIRECTORY_SEPARATOR . 'cakephp-plugins.php'; + if (!is_file($vendorFile)) { + $vendorFile = dirname(dirname(dirname(dirname(__DIR__)))) . DIRECTORY_SEPARATOR . 'cakephp-plugins.php'; + if (!is_file($vendorFile)) { + Configure::write(['plugins' => []]); + + return; + } + } + + $config = require $vendorFile; + Configure::write($config); + } + + /** + * Locate a plugin path by looking at configuration data. + * + * This will use the `plugins` Configure key, and fallback to enumerating `App::path('plugins')` + * + * This method is not part of the official public API as plugins with + * no plugin class are being phased out. + * + * @param string $name The plugin name to locate a path for. + * @return string + * @throws \Cake\Core\Exception\MissingPluginException when a plugin path cannot be resolved. + * @internal + */ + public function findPath(string $name): string + { + // Ensure plugin config is loaded each time. This is necessary primarily + // for testing because the Configure::clear() call in TestCase::tearDown() + // wipes out all configuration including plugin paths config. + $this->loadConfig(); + + $path = Configure::read('plugins.' . $name); + if ($path) { + return $path; + } + + $pluginPath = str_replace('/', DIRECTORY_SEPARATOR, $name); + $paths = App::path('plugins'); + foreach ($paths as $path) { + if (is_dir($path . $pluginPath)) { + return $path . $pluginPath . DIRECTORY_SEPARATOR; + } + } + + throw new MissingPluginException(['plugin' => $name]); + } + + /** + * Add a plugin to the collection + * + * Plugins will be keyed by their names. + * + * @param \Cake\Core\PluginInterface $plugin The plugin to load. + * @return $this + */ + public function add(PluginInterface $plugin) + { + $name = $plugin->getName(); + $this->plugins[$name] = $plugin; + $this->names = array_keys($this->plugins); + + return $this; + } + + /** + * Remove a plugin from the collection if it exists. + * + * @param string $name The named plugin. + * @return $this + */ + public function remove(string $name) + { + unset($this->plugins[$name]); + $this->names = array_keys($this->plugins); + + return $this; + } + + /** + * Remove all plugins from the collection + * + * @return $this + */ + public function clear() + { + $this->plugins = []; + $this->names = []; + $this->positions = []; + $this->loopDepth = -1; + + return $this; + } + + /** + * Check whether the named plugin exists in the collection. + * + * @param string $name The named plugin. + * @return bool + */ + public function has(string $name): bool + { + return isset($this->plugins[$name]); + } + + /** + * Get the a plugin by name. + * + * If a plugin isn't already loaded it will be autoloaded on first access + * and that plugins loaded this way may miss some hook methods. + * + * @param string $name The plugin to get. + * @return \Cake\Core\PluginInterface The plugin. + * @throws \Cake\Core\Exception\MissingPluginException when unknown plugins are fetched. + */ + public function get(string $name): PluginInterface + { + if ($this->has($name)) { + return $this->plugins[$name]; + } + + $plugin = $this->create($name); + $this->add($plugin); + + return $plugin; + } + + /** + * Create a plugin instance from a name/classname and configuration. + * + * @param string $name The plugin name or classname + * @param array $config Configuration options for the plugin. + * @return \Cake\Core\PluginInterface + * @throws \Cake\Core\Exception\MissingPluginException When plugin instance could not be created. + */ + public function create(string $name, array $config = []): PluginInterface + { + if ($name === '') { + throw new CakeException('Cannot create a plugin with empty name'); + } + + if (strpos($name, '\\') !== false) { + /** @var \Cake\Core\PluginInterface */ + return new $name($config); + } + + $config += ['name' => $name]; + $namespace = str_replace('/', '\\', $name); + + $className = $namespace . '\\' . 'Plugin'; + // Check for [Vendor/]Foo/Plugin class + if (!class_exists($className)) { + $pos = strpos($name, '/'); + if ($pos === false) { + $className = $namespace . '\\' . $name . 'Plugin'; + } else { + $className = $namespace . '\\' . substr($name, $pos + 1) . 'Plugin'; + } + + // Check for [Vendor/]Foo/FooPlugin + if (!class_exists($className)) { + $className = BasePlugin::class; + if (empty($config['path'])) { + $config['path'] = $this->findPath($name); + } + } + } + + /** @var class-string<\Cake\Core\PluginInterface> $className */ + return new $className($config); + } + + /** + * Implementation of Countable. + * + * Get the number of plugins in the collection. + * + * @return int + */ + public function count(): int + { + return count($this->plugins); + } + + /** + * Part of Iterator Interface + * + * @return void + */ + public function next(): void + { + $this->positions[$this->loopDepth]++; + } + + /** + * Part of Iterator Interface + * + * @return string + */ + public function key(): string + { + return $this->names[$this->positions[$this->loopDepth]]; + } + + /** + * Part of Iterator Interface + * + * @return \Cake\Core\PluginInterface + */ + public function current(): PluginInterface + { + $position = $this->positions[$this->loopDepth]; + $name = $this->names[$position]; + + return $this->plugins[$name]; + } + + /** + * Part of Iterator Interface + * + * @return void + */ + public function rewind(): void + { + $this->positions[] = 0; + $this->loopDepth += 1; + } + + /** + * Part of Iterator Interface + * + * @return bool + */ + public function valid(): bool + { + $valid = isset($this->names[$this->positions[$this->loopDepth]]); + if (!$valid) { + array_pop($this->positions); + $this->loopDepth -= 1; + } + + return $valid; + } + + /** + * Filter the plugins to those with the named hook enabled. + * + * @param string $hook The hook to filter plugins by + * @return \Generator<\Cake\Core\PluginInterface> A generator containing matching plugins. + * @throws \InvalidArgumentException on invalid hooks + */ + public function with(string $hook): Generator + { + if (!in_array($hook, PluginInterface::VALID_HOOKS, true)) { + throw new InvalidArgumentException("The `{$hook}` hook is not a known plugin hook."); + } + foreach ($this as $plugin) { + if ($plugin->isEnabled($hook)) { + yield $plugin; + } + } + } +} diff --git a/vendor/cakephp/core/PluginInterface.php b/vendor/cakephp/core/PluginInterface.php new file mode 100644 index 0000000..e251cdf --- /dev/null +++ b/vendor/cakephp/core/PluginInterface.php @@ -0,0 +1,135 @@ + + */ + public const VALID_HOOKS = ['bootstrap', 'console', 'middleware', 'routes', 'services']; + + /** + * Get the name of this plugin. + * + * @return string + */ + public function getName(): string; + + /** + * Get the filesystem path to this plugin + * + * @return string + */ + public function getPath(): string; + + /** + * Get the filesystem path to configuration for this plugin + * + * @return string + */ + public function getConfigPath(): string; + + /** + * Get the filesystem path to configuration for this plugin + * + * @return string + */ + public function getClassPath(): string; + + /** + * Get the filesystem path to templates for this plugin + * + * @return string + */ + public function getTemplatePath(): string; + + /** + * Load all the application configuration and bootstrap logic. + * + * The default implementation of this method will include the `config/bootstrap.php` in the plugin if it exist. You + * can override this method to replace that behavior. + * + * The host application is provided as an argument. This allows you to load additional + * plugin dependencies, or attach events. + * + * @param \Cake\Core\PluginApplicationInterface $app The host application + * @return void + */ + public function bootstrap(PluginApplicationInterface $app): void; + + /** + * Add console commands for the plugin. + * + * @param \Cake\Console\CommandCollection $commands The command collection to update + * @return \Cake\Console\CommandCollection + */ + public function console(CommandCollection $commands): CommandCollection; + + /** + * Add middleware for the plugin. + * + * @param \Cake\Http\MiddlewareQueue $middlewareQueue The middleware queue to update. + * @return \Cake\Http\MiddlewareQueue + */ + public function middleware(MiddlewareQueue $middlewareQueue): MiddlewareQueue; + + /** + * Add routes for the plugin. + * + * The default implementation of this method will include the `config/routes.php` in the plugin if it exists. You + * can override this method to replace that behavior. + * + * @param \Cake\Routing\RouteBuilder $routes The route builder to update. + * @return void + */ + public function routes(RouteBuilder $routes): void; + + /** + * Disables the named hook + * + * @param string $hook The hook to disable + * @return $this + */ + public function disable(string $hook); + + /** + * Enables the named hook + * + * @param string $hook The hook to disable + * @return $this + */ + public function enable(string $hook); + + /** + * Check if the named hook is enabled + * + * @param string $hook The hook to check + * @return bool + */ + public function isEnabled(string $hook): bool; +} diff --git a/vendor/cakephp/core/README.md b/vendor/cakephp/core/README.md new file mode 100644 index 0000000..f26cba6 --- /dev/null +++ b/vendor/cakephp/core/README.md @@ -0,0 +1,37 @@ +[![Total Downloads](https://img.shields.io/packagist/dt/cakephp/core.svg?style=flat-square)](https://packagist.org/packages/cakephp/core) +[![License](https://img.shields.io/badge/license-MIT-blue.svg?style=flat-square)](LICENSE.txt) + +# CakePHP Core Classes + +A set of classes used for configuration files reading and storing. +This repository contains the classes that are used as glue for creating the CakePHP framework. + +## Usage + +You can use the `Configure` class to store arbitrary configuration data: + +```php +use Cake\Core\Configure; +use Cake\Core\Configure\Engine\PhpConfig; + +Configure::write('Company.name','Pizza, Inc.'); +Configure::read('Company.name'); // Returns: 'Pizza, Inc.' +``` + +It also possible to load configuration from external files: + +```php +Configure::config('default', new PhpConfig('/path/to/config/folder')); +Configure::load('app', 'default', false); +Configure::load('other_config', 'default'); +``` + +And write the configuration back into files: + +```php +Configure::dump('my_config', 'default'); +``` + +## Documentation + +Please make sure you check the [official documentation](https://book.cakephp.org/4/en/development/configuration.html) diff --git a/vendor/cakephp/core/Retry/CommandRetry.php b/vendor/cakephp/core/Retry/CommandRetry.php new file mode 100644 index 0000000..1211695 --- /dev/null +++ b/vendor/cakephp/core/Retry/CommandRetry.php @@ -0,0 +1,94 @@ +strategy = $strategy; + $this->maxRetries = $maxRetries; + } + + /** + * The number of retries to perform in case of failure + * + * @param callable $action The callable action to execute with a retry strategy + * @return mixed The return value of the passed action callable + * @throws \Exception + */ + public function run(callable $action) + { + $this->numRetries = 0; + while (true) { + try { + return $action(); + } catch (Exception $e) { + if ( + $this->numRetries < $this->maxRetries && + $this->strategy->shouldRetry($e, $this->numRetries) + ) { + $this->numRetries++; + continue; + } + + throw $e; + } + } + } + + /** + * Returns the last number of retry attemps. + * + * @return int + */ + public function getRetries(): int + { + return $this->numRetries; + } +} diff --git a/vendor/cakephp/core/Retry/RetryStrategyInterface.php b/vendor/cakephp/core/Retry/RetryStrategyInterface.php new file mode 100644 index 0000000..e2ef9e2 --- /dev/null +++ b/vendor/cakephp/core/Retry/RetryStrategyInterface.php @@ -0,0 +1,35 @@ + + * @see ServiceProvider::provides() + */ + protected $provides = []; + + /** + * Get the container. + * + * This method's actual return type and documented return type differ + * because PHP 7.2 doesn't support return type narrowing. + * + * @return \Cake\Core\ContainerInterface + */ + public function getContainer(): DefinitionContainerInterface + { + $container = parent::getContainer(); + + if (!($container instanceof ContainerInterface)) { + $message = sprintf( + 'Unexpected container type. Expected `%s` got `%s` instead.', + ContainerInterface::class, + getTypeName($container) + ); + throw new RuntimeException($message); + } + + return $container; + } + + /** + * Delegate to the bootstrap() method + * + * This method wraps the league/container function so users + * only need to use the CakePHP bootstrap() interface. + * + * @return void + */ + public function boot(): void + { + $this->bootstrap($this->getContainer()); + } + + /** + * Bootstrap hook for ServiceProviders + * + * This hook should be implemented if your service provider + * needs to register additional service providers, load configuration + * files or do any other work when the service provider is added to the + * container. + * + * @param \Cake\Core\ContainerInterface $container The container to add services to. + * @return void + */ + public function bootstrap(ContainerInterface $container): void + { + } + + /** + * Call the abstract services() method. + * + * This method primarily exists as a shim between the interface + * that league/container has and the one we want to offer in CakePHP. + * + * @return void + */ + public function register(): void + { + $this->services($this->getContainer()); + } + + /** + * The provides method is a way to let the container know that a service + * is provided by this service provider. + * + * Every service that is registered via this service provider must have an + * alias added to this array or it will be ignored. + * + * @param string $id Identifier. + * @return bool + */ + public function provides(string $id): bool + { + return in_array($id, $this->provides, true); + } + + /** + * Register the services in a provider. + * + * All services registered in this method should also be included in the $provides + * property so that services can be located. + * + * @param \Cake\Core\ContainerInterface $container The container to add services to. + * @return void + */ + abstract public function services(ContainerInterface $container): void; +} diff --git a/vendor/cakephp/core/StaticConfigTrait.php b/vendor/cakephp/core/StaticConfigTrait.php new file mode 100644 index 0000000..2db8624 --- /dev/null +++ b/vendor/cakephp/core/StaticConfigTrait.php @@ -0,0 +1,325 @@ + + */ + protected static $_config = []; + + /** + * This method can be used to define configuration adapters for an application. + * + * To change an adapter's configuration at runtime, first drop the adapter and then + * reconfigure it. + * + * Adapters will not be constructed until the first operation is done. + * + * ### Usage + * + * Assuming that the class' name is `Cache` the following scenarios + * are supported: + * + * Setting a cache engine up. + * + * ``` + * Cache::setConfig('default', $settings); + * ``` + * + * Injecting a constructed adapter in: + * + * ``` + * Cache::setConfig('default', $instance); + * ``` + * + * Configure multiple adapters at once: + * + * ``` + * Cache::setConfig($arrayOfConfig); + * ``` + * + * @param array|string $key The name of the configuration, or an array of multiple configs. + * @param mixed $config Configuration value. Generally an array of name => configuration data for adapter. + * @throws \BadMethodCallException When trying to modify an existing config. + * @throws \LogicException When trying to store an invalid structured config array. + * @return void + */ + public static function setConfig($key, $config = null): void + { + if ($config === null) { + if (!is_array($key)) { + throw new LogicException('If config is null, key must be an array.'); + } + foreach ($key as $name => $settings) { + static::setConfig($name, $settings); + } + + return; + } + + if (isset(static::$_config[$key])) { + /** @psalm-suppress PossiblyInvalidArgument */ + throw new BadMethodCallException(sprintf('Cannot reconfigure existing key "%s"', $key)); + } + + if (is_object($config)) { + $config = ['className' => $config]; + } + + if (is_array($config) && isset($config['url'])) { + $parsed = static::parseDsn($config['url']); + unset($config['url']); + $config = $parsed + $config; + } + + if (isset($config['engine']) && empty($config['className'])) { + $config['className'] = $config['engine']; + unset($config['engine']); + } + /** @psalm-suppress InvalidPropertyAssignmentValue */ + static::$_config[$key] = $config; + } + + /** + * Reads existing configuration. + * + * @param string $key The name of the configuration. + * @return mixed|null Configuration data at the named key or null if the key does not exist. + */ + public static function getConfig(string $key) + { + return static::$_config[$key] ?? null; + } + + /** + * Reads existing configuration for a specific key. + * + * The config value for this key must exist, it can never be null. + * + * @param string $key The name of the configuration. + * @return mixed Configuration data at the named key. + * @throws \InvalidArgumentException If value does not exist. + */ + public static function getConfigOrFail(string $key) + { + if (!isset(static::$_config[$key])) { + throw new InvalidArgumentException(sprintf('Expected configuration `%s` not found.', $key)); + } + + return static::$_config[$key]; + } + + /** + * Drops a constructed adapter. + * + * If you wish to modify an existing configuration, you should drop it, + * change configuration and then re-add it. + * + * If the implementing objects supports a `$_registry` object the named configuration + * will also be unloaded from the registry. + * + * @param string $config An existing configuration you wish to remove. + * @return bool Success of the removal, returns false when the config does not exist. + */ + public static function drop(string $config): bool + { + if (!isset(static::$_config[$config])) { + return false; + } + /** @psalm-suppress RedundantPropertyInitializationCheck */ + if (isset(static::$_registry)) { + static::$_registry->unload($config); + } + unset(static::$_config[$config]); + + return true; + } + + /** + * Returns an array containing the named configurations + * + * @return array Array of configurations. + */ + public static function configured(): array + { + $configurations = array_keys(static::$_config); + + return array_map(function ($key) { + return (string)$key; + }, $configurations); + } + + /** + * Parses a DSN into a valid connection configuration + * + * This method allows setting a DSN using formatting similar to that used by PEAR::DB. + * The following is an example of its usage: + * + * ``` + * $dsn = 'mysql://user:pass@localhost/database?'; + * $config = ConnectionManager::parseDsn($dsn); + * + * $dsn = 'Cake\Log\Engine\FileLog://?types=notice,info,debug&file=debug&path=LOGS'; + * $config = Log::parseDsn($dsn); + * + * $dsn = 'smtp://user:secret@localhost:25?timeout=30&client=null&tls=null'; + * $config = Email::parseDsn($dsn); + * + * $dsn = 'file:///?className=\My\Cache\Engine\FileEngine'; + * $config = Cache::parseDsn($dsn); + * + * $dsn = 'File://?prefix=myapp_cake_core_&serialize=true&duration=+2 minutes&path=/tmp/persistent/'; + * $config = Cache::parseDsn($dsn); + * ``` + * + * For all classes, the value of `scheme` is set as the value of both the `className` + * unless they have been otherwise specified. + * + * Note that querystring arguments are also parsed and set as values in the returned configuration. + * + * @param string $dsn The DSN string to convert to a configuration array + * @return array The configuration array to be stored after parsing the DSN + * @throws \InvalidArgumentException If not passed a string, or passed an invalid string + */ + public static function parseDsn(string $dsn): array + { + if (empty($dsn)) { + return []; + } + + $pattern = <<<'REGEXP' +{ + ^ + (?P<_scheme> + (?P[\w\\\\]+):// + ) + (?P<_username> + (?P.*?) + (?P<_password> + :(?P.*?) + )? + @ + )? + (?P<_host> + (?P[^?#/:@]+) + (?P<_port> + :(?P\d+) + )? + )? + (?P<_path> + (?P/[^?#]*) + )? + (?P<_query> + \?(?P[^#]*) + )? + (?P<_fragment> + \#(?P.*) + )? + $ +}x +REGEXP; + + preg_match($pattern, $dsn, $parsed); + + if (!$parsed) { + throw new InvalidArgumentException("The DSN string '{$dsn}' could not be parsed."); + } + + $exists = []; + foreach ($parsed as $k => $v) { + if (is_int($k)) { + unset($parsed[$k]); + } elseif (strpos($k, '_') === 0) { + $exists[substr($k, 1)] = ($v !== ''); + unset($parsed[$k]); + } elseif ($v === '' && !$exists[$k]) { + unset($parsed[$k]); + } + } + + $query = ''; + + if (isset($parsed['query'])) { + $query = $parsed['query']; + unset($parsed['query']); + } + + parse_str($query, $queryArgs); + + foreach ($queryArgs as $key => $value) { + if ($value === 'true') { + $queryArgs[$key] = true; + } elseif ($value === 'false') { + $queryArgs[$key] = false; + } elseif ($value === 'null') { + $queryArgs[$key] = null; + } + } + + $parsed = $queryArgs + $parsed; + + if (empty($parsed['className'])) { + $classMap = static::getDsnClassMap(); + + $parsed['className'] = $parsed['scheme']; + if (isset($classMap[$parsed['scheme']])) { + /** @psalm-suppress PossiblyNullArrayOffset */ + $parsed['className'] = $classMap[$parsed['scheme']]; + } + } + + return $parsed; + } + + /** + * Updates the DSN class map for this class. + * + * @param array $map Additions/edits to the class map to apply. + * @return void + * @psalm-param array $map + */ + public static function setDsnClassMap(array $map): void + { + static::$_dsnClassMap = $map + static::$_dsnClassMap; + } + + /** + * Returns the DSN class map for this class. + * + * @return array + * @psalm-return array + */ + public static function getDsnClassMap(): array + { + return static::$_dsnClassMap; + } +} diff --git a/vendor/cakephp/core/TestSuite/ContainerStubTrait.php b/vendor/cakephp/core/TestSuite/ContainerStubTrait.php new file mode 100644 index 0000000..9c6ae1e --- /dev/null +++ b/vendor/cakephp/core/TestSuite/ContainerStubTrait.php @@ -0,0 +1,181 @@ +|class-string<\Cake\Core\ConsoleApplicationInterface>|null + * @var string|null + */ + protected $_appClass; + + /** + * The customized application constructor arguments. + * + * @var array|null + */ + protected $_appArgs; + + /** + * The collection of container services. + * + * @var array + */ + private $containerServices = []; + + /** + * Configure the application class to use in integration tests. + * + * @param string $class The application class name. + * @param array|null $constructorArgs The constructor arguments for your application class. + * @return void + * @psalm-param class-string<\Cake\Core\HttpApplicationInterface>|class-string<\Cake\Core\ConsoleApplicationInterface> $class + */ + public function configApplication(string $class, ?array $constructorArgs): void + { + $this->_appClass = $class; + $this->_appArgs = $constructorArgs; + } + + /** + * Create an application instance. + * + * Uses the configuration set in `configApplication()`. + * + * @return \Cake\Core\HttpApplicationInterface|\Cake\Core\ConsoleApplicationInterface + */ + protected function createApp() + { + if ($this->_appClass) { + $appClass = $this->_appClass; + } else { + /** @psalm-var class-string<\Cake\Http\BaseApplication> */ + $appClass = Configure::read('App.namespace') . '\Application'; + } + if (!class_exists($appClass)) { + throw new LogicException("Cannot load `{$appClass}` for use in integration testing."); + } + $appArgs = $this->_appArgs ?: [CONFIG]; + + $app = new $appClass(...$appArgs); + if (!empty($this->containerServices) && method_exists($app, 'getEventManager')) { + $app->getEventManager()->on('Application.buildContainer', [$this, 'modifyContainer']); + } + + return $app; + } + + /** + * Add a mocked service to the container. + * + * When the container is created the provided classname + * will be mapped to the factory function. The factory + * function will be used to create mocked services. + * + * @param string $class The class or interface you want to define. + * @param \Closure $factory The factory function for mocked services. + * @return $this + */ + public function mockService(string $class, Closure $factory) + { + $this->containerServices[$class] = $factory; + + return $this; + } + + /** + * Remove a mocked service to the container. + * + * @param string $class The class or interface you want to remove. + * @return $this + */ + public function removeMockService(string $class) + { + unset($this->containerServices[$class]); + + return $this; + } + + /** + * Wrap the application's container with one containing mocks. + * + * If any mocked services are defined, the application's container + * will be replaced with one containing mocks. The original + * container will be set as a delegate to the mock container. + * + * @param \Cake\Event\EventInterface $event The event + * @param \Cake\Core\ContainerInterface $container The container to wrap. + * @return \Cake\Core\ContainerInterface|null + */ + public function modifyContainer(EventInterface $event, ContainerInterface $container): ?ContainerInterface + { + if (empty($this->containerServices)) { + return null; + } + foreach ($this->containerServices as $key => $factory) { + if ($container->has($key)) { + try { + $container->extend($key)->setConcrete($factory); + } catch (NotFoundException $e) { + $container->add($key, $factory); + } + } else { + $container->add($key, $factory); + } + } + + return $container; + } + + /** + * Clears any mocks that were defined and cleans + * up application class configuration. + * + * @after + * @return void + */ + public function cleanupContainer(): void + { + $this->_appArgs = null; + $this->_appClass = null; + $this->containerServices = []; + } +} + +// phpcs:disable +class_alias( + 'Cake\Core\TestSuite\ContainerStubTrait', + 'Cake\TestSuite\ContainerStubTrait' +); +// phpcs:enable diff --git a/vendor/cakephp/core/composer.json b/vendor/cakephp/core/composer.json new file mode 100644 index 0000000..d5d4cf7 --- /dev/null +++ b/vendor/cakephp/core/composer.json @@ -0,0 +1,44 @@ +{ + "name": "cakephp/core", + "description": "CakePHP Framework Core classes", + "type": "library", + "keywords": [ + "cakephp", + "framework", + "core" + ], + "homepage": "https://cakephp.org", + "license": "MIT", + "authors": [ + { + "name": "CakePHP Community", + "homepage": "https://github.com/cakephp/core/graphs/contributors" + } + ], + "support": { + "issues": "https://github.com/cakephp/cakephp/issues", + "forum": "https://stackoverflow.com/tags/cakephp", + "irc": "irc://irc.freenode.org/cakephp", + "source": "https://github.com/cakephp/core" + }, + "require": { + "php": ">=7.4.0", + "cakephp/utility": "^4.0" + }, + "provide": { + "psr/container-implementation": "^1.0 || ^2.0" + }, + "suggest": { + "cakephp/event": "To use PluginApplicationInterface or plugin applications.", + "cakephp/cache": "To use Configure::store() and restore().", + "league/container": "To use Container and ServiceProvider classes" + }, + "autoload": { + "psr-4": { + "Cake\\Core\\": "." + }, + "files": [ + "functions.php" + ] + } +} diff --git a/vendor/cakephp/core/functions.php b/vendor/cakephp/core/functions.php new file mode 100644 index 0000000..af2d2b6 --- /dev/null +++ b/vendor/cakephp/core/functions.php @@ -0,0 +1,340 @@ + $t) { + $texts[$k] = h($t, $double, $charset); + } + + return $texts; + } elseif (is_object($text)) { + if (method_exists($text, '__toString')) { + $text = $text->__toString(); + } else { + $text = '(object)' . get_class($text); + } + } elseif ($text === null || is_scalar($text)) { + return $text; + } + + static $defaultCharset = false; + if ($defaultCharset === false) { + $defaultCharset = mb_internal_encoding() ?: 'UTF-8'; + } + + return htmlspecialchars($text, ENT_QUOTES | ENT_SUBSTITUTE, $charset ?: $defaultCharset, $double); + } +} + +if (!function_exists('Cake\Core\pluginSplit')) { + /** + * Splits a dot syntax plugin name into its plugin and class name. + * If $name does not have a dot, then index 0 will be null. + * + * Commonly used like + * ``` + * list($plugin, $name) = pluginSplit($name); + * ``` + * + * @param string $name The name you want to plugin split. + * @param bool $dotAppend Set to true if you want the plugin to have a '.' appended to it. + * @param string|null $plugin Optional default plugin to use if no plugin is found. Defaults to null. + * @return array Array with 2 indexes. 0 => plugin name, 1 => class name. + * @link https://book.cakephp.org/4/en/core-libraries/global-constants-and-functions.html#pluginSplit + * @psalm-return array{string|null, string} + */ + function pluginSplit(string $name, bool $dotAppend = false, ?string $plugin = null): array + { + if (strpos($name, '.') !== false) { + $parts = explode('.', $name, 2); + if ($dotAppend) { + $parts[0] .= '.'; + } + + /** @psalm-var array{string, string} */ + return $parts; + } + + return [$plugin, $name]; + } +} + +if (!function_exists('Cake\Core\namespaceSplit')) { + /** + * Split the namespace from the classname. + * + * Commonly used like `list($namespace, $className) = namespaceSplit($class);`. + * + * @param string $class The full class name, ie `Cake\Core\App`. + * @return array Array with 2 indexes. 0 => namespace, 1 => classname. + */ + function namespaceSplit(string $class): array + { + $pos = strrpos($class, '\\'); + if ($pos === false) { + return ['', $class]; + } + + return [substr($class, 0, $pos), substr($class, $pos + 1)]; + } +} + +if (!function_exists('Cake\Core\pr')) { + /** + * print_r() convenience function. + * + * In terminals this will act similar to using print_r() directly, when not run on CLI + * print_r() will also wrap `
` tags around the output of given variable. Similar to debug().
+     *
+     * This function returns the same variable that was passed.
+     *
+     * @param mixed $var Variable to print out.
+     * @return mixed the same $var that was passed to this function
+     * @link https://book.cakephp.org/4/en/core-libraries/global-constants-and-functions.html#pr
+     * @see debug()
+     */
+    function pr($var)
+    {
+        if (!Configure::read('debug')) {
+            return $var;
+        }
+
+        $template = PHP_SAPI !== 'cli' && PHP_SAPI !== 'phpdbg' ? '
%s
' : "\n%s\n\n"; + printf($template, trim(print_r($var, true))); + + return $var; + } +} + +if (!function_exists('Cake\Core\pj')) { + /** + * JSON pretty print convenience function. + * + * In terminals this will act similar to using json_encode() with JSON_PRETTY_PRINT directly, when not run on CLI + * will also wrap `
` tags around the output of given variable. Similar to pr().
+     *
+     * This function returns the same variable that was passed.
+     *
+     * @param mixed $var Variable to print out.
+     * @return mixed the same $var that was passed to this function
+     * @see pr()
+     * @link https://book.cakephp.org/4/en/core-libraries/global-constants-and-functions.html#pj
+     */
+    function pj($var)
+    {
+        if (!Configure::read('debug')) {
+            return $var;
+        }
+
+        $template = PHP_SAPI !== 'cli' && PHP_SAPI !== 'phpdbg' ? '
%s
' : "\n%s\n\n"; + printf($template, trim(json_encode($var, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES))); + + return $var; + } +} + +if (!function_exists('Cake\Core\env')) { + /** + * Gets an environment variable from available sources, and provides emulation + * for unsupported or inconsistent environment variables (i.e. DOCUMENT_ROOT on + * IIS, or SCRIPT_NAME in CGI mode). Also exposes some additional custom + * environment information. + * + * @param string $key Environment variable name. + * @param string|bool|null $default Specify a default value in case the environment variable is not defined. + * @return string|bool|null Environment variable setting. + * @link https://book.cakephp.org/4/en/core-libraries/global-constants-and-functions.html#env + */ + function env(string $key, $default = null) + { + if ($key === 'HTTPS') { + if (isset($_SERVER['HTTPS'])) { + return !empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off'; + } + + return strpos((string)env('SCRIPT_URI'), 'https://') === 0; + } + + if ($key === 'SCRIPT_NAME' && env('CGI_MODE') && isset($_ENV['SCRIPT_URL'])) { + $key = 'SCRIPT_URL'; + } + + /** @var string|null $val */ + $val = $_SERVER[$key] ?? $_ENV[$key] ?? null; + if ($val == null && getenv($key) !== false) { + /** @var string|false $val */ + $val = getenv($key); + } + + if ($key === 'REMOTE_ADDR' && $val === env('SERVER_ADDR')) { + $addr = env('HTTP_PC_REMOTE_ADDR'); + if ($addr !== null) { + $val = $addr; + } + } + + if ($val !== null) { + return $val; + } + + switch ($key) { + case 'DOCUMENT_ROOT': + $name = (string)env('SCRIPT_NAME'); + $filename = (string)env('SCRIPT_FILENAME'); + $offset = 0; + if (!strpos($name, '.php')) { + $offset = 4; + } + + return substr($filename, 0, -(strlen($name) + $offset)); + case 'PHP_SELF': + return str_replace((string)env('DOCUMENT_ROOT'), '', (string)env('SCRIPT_FILENAME')); + case 'CGI_MODE': + return PHP_SAPI === 'cgi'; + } + + return $default; + } +} + +if (!function_exists('Cake\Core\triggerWarning')) { + /** + * Triggers an E_USER_WARNING. + * + * @param string $message The warning message. + * @return void + */ + function triggerWarning(string $message): void + { + $trace = debug_backtrace(); + if (isset($trace[1])) { + $frame = $trace[1]; + $frame += ['file' => '[internal]', 'line' => '??']; + $message = sprintf( + '%s - %s, line: %s', + $message, + $frame['file'], + $frame['line'] + ); + } + trigger_error($message, E_USER_WARNING); + } +} + +if (!function_exists('Cake\Core\deprecationWarning')) { + /** + * Helper method for outputting deprecation warnings + * + * @param string $message The message to output as a deprecation warning. + * @param int $stackFrame The stack frame to include in the error. Defaults to 1 + * as that should point to application/plugin code. + * @return void + */ + function deprecationWarning(string $message, int $stackFrame = 1): void + { + if (!(error_reporting() & E_USER_DEPRECATED)) { + return; + } + + $trace = debug_backtrace(); + if (isset($trace[$stackFrame])) { + $frame = $trace[$stackFrame]; + $frame += ['file' => '[internal]', 'line' => '??']; + + // Assuming we're installed in vendor/cakephp/cakephp/src/Core/functions.php + $root = dirname(__DIR__, 5); + if (defined('ROOT')) { + $root = ROOT; + } + $relative = str_replace( + DIRECTORY_SEPARATOR, + '/', + substr($frame['file'], strlen($root) + 1) + ); + $patterns = (array)Configure::read('Error.ignoredDeprecationPaths'); + foreach ($patterns as $pattern) { + $pattern = str_replace(DIRECTORY_SEPARATOR, '/', $pattern); + if (fnmatch($pattern, $relative)) { + return; + } + } + + $message = sprintf( + "%s\n%s, line: %s\n" . 'You can disable all deprecation warnings by setting `Error.errorLevel` to ' . + '`E_ALL & ~E_USER_DEPRECATED`. Adding `%s` to `Error.ignoredDeprecationPaths` ' . + 'in your `config/app.php` config will mute deprecations from that file only.', + $message, + $frame['file'], + $frame['line'], + $relative + ); + } + + static $errors = []; + $checksum = md5($message); + $duplicate = (bool)Configure::read('Error.allowDuplicateDeprecations', false); + if (isset($errors[$checksum]) && !$duplicate) { + return; + } + if (!$duplicate) { + $errors[$checksum] = true; + } + + trigger_error($message, E_USER_DEPRECATED); + } +} + +if (!function_exists('Cake\Core\getTypeName')) { + /** + * Returns the objects class or var type of it's not an object + * + * @param mixed $var Variable to check + * @return string Returns the class name or variable type + */ + function getTypeName($var): string + { + return is_object($var) ? get_class($var) : gettype($var); + } +} + +/** + * Include global functions. + */ +if (!getenv('CAKE_DISABLE_GLOBAL_FUNCS')) { + include 'functions_global.php'; +} diff --git a/vendor/cakephp/core/functions_global.php b/vendor/cakephp/core/functions_global.php new file mode 100644 index 0000000..bb2a714 --- /dev/null +++ b/vendor/cakephp/core/functions_global.php @@ -0,0 +1,190 @@ + plugin name, 1 => class name. + * @link https://book.cakephp.org/4/en/core-libraries/global-constants-and-functions.html#pluginSplit + * @psalm-return array{string|null, string} + */ + function pluginSplit(string $name, bool $dotAppend = false, ?string $plugin = null): array + { + return cakePluginSplit($name, $dotAppend, $plugin); + } +} + +if (!function_exists('namespaceSplit')) { + /** + * Split the namespace from the classname. + * + * Commonly used like `list($namespace, $className) = namespaceSplit($class);`. + * + * @param string $class The full class name, ie `Cake\Core\App`. + * @return array Array with 2 indexes. 0 => namespace, 1 => classname. + */ + function namespaceSplit(string $class): array + { + return cakeNamespaceSplit($class); + } +} + +if (!function_exists('pr')) { + /** + * print_r() convenience function. + * + * In terminals this will act similar to using print_r() directly, when not run on CLI + * print_r() will also wrap `
` tags around the output of given variable. Similar to debug().
+     *
+     * This function returns the same variable that was passed.
+     *
+     * @param mixed $var Variable to print out.
+     * @return mixed the same $var that was passed to this function
+     * @link https://book.cakephp.org/4/en/core-libraries/global-constants-and-functions.html#pr
+     * @see debug()
+     */
+    function pr($var)
+    {
+        return cakePr($var);
+    }
+}
+
+if (!function_exists('pj')) {
+    /**
+     * JSON pretty print convenience function.
+     *
+     * In terminals this will act similar to using json_encode() with JSON_PRETTY_PRINT directly, when not run on CLI
+     * will also wrap `
` tags around the output of given variable. Similar to pr().
+     *
+     * This function returns the same variable that was passed.
+     *
+     * @param mixed $var Variable to print out.
+     * @return mixed the same $var that was passed to this function
+     * @see pr()
+     * @link https://book.cakephp.org/4/en/core-libraries/global-constants-and-functions.html#pj
+     */
+    function pj($var)
+    {
+        return cakePj($var);
+    }
+}
+
+if (!function_exists('env')) {
+    /**
+     * Gets an environment variable from available sources, and provides emulation
+     * for unsupported or inconsistent environment variables (i.e. DOCUMENT_ROOT on
+     * IIS, or SCRIPT_NAME in CGI mode). Also exposes some additional custom
+     * environment information.
+     *
+     * @param string $key Environment variable name.
+     * @param string|bool|null $default Specify a default value in case the environment variable is not defined.
+     * @return string|bool|null Environment variable setting.
+     * @link https://book.cakephp.org/4/en/core-libraries/global-constants-and-functions.html#env
+     */
+    function env(string $key, $default = null)
+    {
+        return cakeEnv($key, $default);
+    }
+}
+
+if (!function_exists('triggerWarning')) {
+    /**
+     * Triggers an E_USER_WARNING.
+     *
+     * @param string $message The warning message.
+     * @return void
+     */
+    function triggerWarning(string $message): void
+    {
+        cakeTriggerWarning($message);
+    }
+}
+
+if (!function_exists('deprecationWarning')) {
+    /**
+     * Helper method for outputting deprecation warnings
+     *
+     * @param string $message The message to output as a deprecation warning.
+     * @param int $stackFrame The stack frame to include in the error. Defaults to 1
+     *   as that should point to application/plugin code.
+     * @return void
+     */
+    function deprecationWarning(string $message, int $stackFrame = 1): void
+    {
+        cakeDeprecationWarning($message, $stackFrame + 1);
+    }
+}
+
+if (!function_exists('getTypeName')) {
+    /**
+     * Returns the objects class or var type of it's not an object
+     *
+     * @param mixed $var Variable to check
+     * @return string Returns the class name or variable type
+     */
+    function getTypeName($var): string
+    {
+        return cakeGetTypeName($var);
+    }
+}
diff --git a/vendor/cakephp/database/Connection.php b/vendor/cakephp/database/Connection.php
new file mode 100644
index 0000000..83777d7
--- /dev/null
+++ b/vendor/cakephp/database/Connection.php
@@ -0,0 +1,1197 @@
+
+     */
+    protected $_config;
+
+    /**
+     * @var \Cake\Database\DriverInterface
+     */
+    protected DriverInterface $readDriver;
+
+    /**
+     * @var \Cake\Database\DriverInterface
+     */
+    protected DriverInterface $writeDriver;
+
+    /**
+     * Contains how many nested transactions have been started.
+     *
+     * @var int
+     */
+    protected $_transactionLevel = 0;
+
+    /**
+     * Whether a transaction is active in this connection.
+     *
+     * @var bool
+     */
+    protected $_transactionStarted = false;
+
+    /**
+     * Whether this connection can and should use savepoints for nested
+     * transactions.
+     *
+     * @var bool
+     */
+    protected $_useSavePoints = false;
+
+    /**
+     * Whether to log queries generated during this connection.
+     *
+     * @var bool
+     */
+    protected $_logQueries = false;
+
+    /**
+     * Logger object instance.
+     *
+     * @var \Psr\Log\LoggerInterface|null
+     */
+    protected $_logger;
+
+    /**
+     * Cacher object instance.
+     *
+     * @var \Psr\SimpleCache\CacheInterface|null
+     */
+    protected $cacher;
+
+    /**
+     * The schema collection object
+     *
+     * @var \Cake\Database\Schema\CollectionInterface|null
+     */
+    protected $_schemaCollection;
+
+    /**
+     * NestedTransactionRollbackException object instance, will be stored if
+     * the rollback method is called in some nested transaction.
+     *
+     * @var \Cake\Database\Exception\NestedTransactionRollbackException|null
+     */
+    protected $nestedTransactionRollbackException;
+
+    /**
+     * Constructor.
+     *
+     * ### Available options:
+     *
+     * - `driver` Sort name or FCQN for driver.
+     * - `log` Boolean indicating whether to use query logging.
+     * - `name` Connection name.
+     * - `cacheMetaData` Boolean indicating whether metadata (datasource schemas) should be cached.
+     *    If set to a string it will be used as the name of cache config to use.
+     * - `cacheKeyPrefix` Custom prefix to use when generation cache keys. Defaults to connection name.
+     *
+     * @param array $config Configuration array.
+     */
+    public function __construct(array $config)
+    {
+        $this->_config = $config;
+        [self::ROLE_READ => $this->readDriver, self::ROLE_WRITE => $this->writeDriver] = $this->createDrivers($config);
+
+        if (!empty($config['log'])) {
+            $this->enableQueryLogging((bool)$config['log']);
+        }
+    }
+
+    /**
+     * Creates read and write drivers.
+     *
+     * @param array $config Connection config
+     * @return array
+     * @psalm-return array{read: \Cake\Database\DriverInterface, write: \Cake\Database\DriverInterface}
+     */
+    protected function createDrivers(array $config): array
+    {
+        $driver = $config['driver'] ?? '';
+        if (!is_string($driver)) {
+            /** @var \Cake\Database\DriverInterface $driver */
+            if (!$driver->enabled()) {
+                throw new MissingExtensionException(['driver' => get_class($driver), 'name' => $this->configName()]);
+            }
+
+            // Legacy support for setting instance instead of driver class
+            return [self::ROLE_READ => $driver, self::ROLE_WRITE => $driver];
+        }
+
+        /** @var class-string<\Cake\Database\DriverInterface>|null $driverClass */
+        $driverClass = App::className($driver, 'Database/Driver');
+        if ($driverClass === null) {
+            throw new MissingDriverException(['driver' => $driver, 'connection' => $this->configName()]);
+        }
+
+        $sharedConfig = array_diff_key($config, array_flip([
+            'name',
+            'driver',
+            'log',
+            'cacheMetaData',
+            'cacheKeyPrefix',
+        ]));
+
+        $writeConfig = $config['write'] ?? [] + $sharedConfig;
+        $readConfig = $config['read'] ?? [] + $sharedConfig;
+        if ($readConfig == $writeConfig) {
+            $readDriver = $writeDriver = new $driverClass(['_role' => self::ROLE_WRITE] + $writeConfig);
+        } else {
+            $readDriver = new $driverClass(['_role' => self::ROLE_READ] + $readConfig);
+            $writeDriver = new $driverClass(['_role' => self::ROLE_WRITE] + $writeConfig);
+        }
+
+        if (!$writeDriver->enabled()) {
+            throw new MissingExtensionException(['driver' => get_class($writeDriver), 'name' => $this->configName()]);
+        }
+
+        return [self::ROLE_READ => $readDriver, self::ROLE_WRITE => $writeDriver];
+    }
+
+    /**
+     * Destructor
+     *
+     * Disconnects the driver to release the connection.
+     */
+    public function __destruct()
+    {
+        if ($this->_transactionStarted && class_exists(Log::class)) {
+            Log::warning('The connection is going to be closed but there is an active transaction.');
+        }
+    }
+
+    /**
+     * @inheritDoc
+     */
+    public function config(): array
+    {
+        return $this->_config;
+    }
+
+    /**
+     * @inheritDoc
+     */
+    public function configName(): string
+    {
+        return $this->_config['name'] ?? '';
+    }
+
+    /**
+     * Returns the connection role: read or write.
+     *
+     * @return string
+     */
+    public function role(): string
+    {
+        return preg_match('/:read$/', $this->configName()) === 1 ? static::ROLE_READ : static::ROLE_WRITE;
+    }
+
+    /**
+     * Sets the driver instance. If a string is passed it will be treated
+     * as a class name and will be instantiated.
+     *
+     * @param \Cake\Database\DriverInterface|string $driver The driver instance to use.
+     * @param array $config Config for a new driver.
+     * @throws \Cake\Database\Exception\MissingDriverException When a driver class is missing.
+     * @throws \Cake\Database\Exception\MissingExtensionException When a driver's PHP extension is missing.
+     * @return $this
+     * @deprecated 4.4.0 Setting the driver is deprecated. Use the connection config instead.
+     */
+    public function setDriver($driver, $config = [])
+    {
+        deprecationWarning('Setting the driver is deprecated. Use the connection config instead.');
+
+        $driver = $this->createDriver($driver, $config);
+        $this->readDriver = $this->writeDriver = $driver;
+
+        return $this;
+    }
+
+    /**
+     * Creates driver from name, class name or instance.
+     *
+     * @param \Cake\Database\DriverInterface|string $name Driver name, class name or instance.
+     * @param array $config Driver config if $name is not an instance.
+     * @return \Cake\Database\DriverInterface
+     * @throws \Cake\Database\Exception\MissingDriverException When a driver class is missing.
+     * @throws \Cake\Database\Exception\MissingExtensionException When a driver's PHP extension is missing.
+     */
+    protected function createDriver($name, array $config): DriverInterface
+    {
+        $driver = $name;
+        if (is_string($driver)) {
+            /** @psalm-var class-string<\Cake\Database\DriverInterface>|null $className */
+            $className = App::className($driver, 'Database/Driver');
+            if ($className === null) {
+                throw new MissingDriverException(['driver' => $driver, 'connection' => $this->configName()]);
+            }
+            $driver = new $className(['_role' => self::ROLE_WRITE] + $config);
+        }
+
+        if (!$driver->enabled()) {
+            throw new MissingExtensionException(['driver' => get_class($driver), 'name' => $this->configName()]);
+        }
+
+        return $driver;
+    }
+
+    /**
+     * Get the retry wrapper object that is allows recovery from server disconnects
+     * while performing certain database actions, such as executing a query.
+     *
+     * @return \Cake\Core\Retry\CommandRetry The retry wrapper
+     */
+    public function getDisconnectRetry(): CommandRetry
+    {
+        return new CommandRetry(new ReconnectStrategy($this));
+    }
+
+    /**
+     * Gets the driver instance.
+     *
+     * @param string $role Connection role ('read' or 'write')
+     * @return \Cake\Database\DriverInterface
+     */
+    public function getDriver(string $role = self::ROLE_WRITE): DriverInterface
+    {
+        assert($role === self::ROLE_READ || $role === self::ROLE_WRITE);
+
+        return $role === self::ROLE_READ ? $this->readDriver : $this->writeDriver;
+    }
+
+    /**
+     * Connects to the configured database.
+     *
+     * @throws \Cake\Database\Exception\MissingConnectionException If database connection could not be established.
+     * @return bool true, if the connection was already established or the attempt was successful.
+     * @deprecated 4.5.0 Use getDriver()->connect() instead.
+     */
+    public function connect(): bool
+    {
+        deprecationWarning(
+            'If you cannot use automatic connection management, use $connection->getDriver()->connect() instead.'
+        );
+
+        $connected = true;
+        foreach ([self::ROLE_READ, self::ROLE_WRITE] as $role) {
+            try {
+                $connected = $connected && $this->getDriver($role)->connect();
+            } catch (MissingConnectionException $e) {
+                throw $e;
+            } catch (Throwable $e) {
+                throw new MissingConnectionException(
+                    [
+                        'driver' => App::shortName(get_class($this->getDriver($role)), 'Database/Driver'),
+                        'reason' => $e->getMessage(),
+                    ],
+                    null,
+                    $e
+                );
+            }
+        }
+
+        return $connected;
+    }
+
+    /**
+     * Disconnects from database server.
+     *
+     * @return void
+     * @deprecated 4.5.0 Use getDriver()->disconnect() instead.
+     */
+    public function disconnect(): void
+    {
+        deprecationWarning(
+            'If you cannot use automatic connection management, use $connection->getDriver()->disconnect() instead.'
+        );
+
+        $this->getDriver(self::ROLE_READ)->disconnect();
+        $this->getDriver(self::ROLE_WRITE)->disconnect();
+    }
+
+    /**
+     * Returns whether connection to database server was already established.
+     *
+     * @return bool
+     * @deprecated 4.5.0 Use getDriver()->isConnected() instead.
+     */
+    public function isConnected(): bool
+    {
+        deprecationWarning('Use $connection->getDriver()->isConnected() instead.');
+
+        return $this->getDriver(self::ROLE_READ)->isConnected() && $this->getDriver(self::ROLE_WRITE)->isConnected();
+    }
+
+    /**
+     * Prepares a SQL statement to be executed.
+     *
+     * @param \Cake\Database\Query|string $query The SQL to convert into a prepared statement.
+     * @return \Cake\Database\StatementInterface
+     * @deprecated 4.5.0 Use getDriver()->prepare() instead.
+     */
+    public function prepare($query): StatementInterface
+    {
+        $role = $query instanceof Query ? $query->getConnectionRole() : self::ROLE_WRITE;
+
+        return $this->getDisconnectRetry()->run(function () use ($query, $role) {
+            $statement = $this->getDriver($role)->prepare($query);
+
+            if ($this->_logQueries) {
+                $statement = $this->_newLogger($statement);
+            }
+
+            return $statement;
+        });
+    }
+
+    /**
+     * Executes a query using $params for interpolating values and $types as a hint for each
+     * those params.
+     *
+     * @param string $sql SQL to be executed and interpolated with $params
+     * @param array $params list or associative array of params to be interpolated in $sql as values
+     * @param array $types list or associative array of types to be used for casting values in query
+     * @return \Cake\Database\StatementInterface executed statement
+     */
+    public function execute(string $sql, array $params = [], array $types = []): StatementInterface
+    {
+        return $this->getDisconnectRetry()->run(function () use ($sql, $params, $types) {
+            $statement = $this->prepare($sql);
+            if (!empty($params)) {
+                $statement->bind($params, $types);
+            }
+            $statement->execute();
+
+            return $statement;
+        });
+    }
+
+    /**
+     * Compiles a Query object into a SQL string according to the dialect for this
+     * connection's driver
+     *
+     * @param \Cake\Database\Query $query The query to be compiled
+     * @param \Cake\Database\ValueBinder $binder Value binder
+     * @return string
+     * @deprecated 4.5.0 Use getDriver()->compileQuery() instead.
+     */
+    public function compileQuery(Query $query, ValueBinder $binder): string
+    {
+        deprecationWarning('Use getDriver()->compileQuery() instead.');
+
+        return $this->getDriver($query->getConnectionRole())->compileQuery($query, $binder)[1];
+    }
+
+    /**
+     * Executes the provided query after compiling it for the specific driver
+     * dialect and returns the executed Statement object.
+     *
+     * @param \Cake\Database\Query $query The query to be executed
+     * @return \Cake\Database\StatementInterface executed statement
+     */
+    public function run(Query $query): StatementInterface
+    {
+        return $this->getDisconnectRetry()->run(function () use ($query) {
+            $statement = $this->prepare($query);
+            $query->getValueBinder()->attachTo($statement);
+            $statement->execute();
+
+            return $statement;
+        });
+    }
+
+    /**
+     * Create a new SelectQuery instance for this connection.
+     *
+     * @param \Cake\Database\ExpressionInterface|callable|array|string $fields fields to be added to the list.
+     * @param array|string $table The table or list of tables to query.
+     * @param array $types Associative array containing the types to be used for casting.
+     * @return \Cake\Database\Query\SelectQuery
+     */
+    public function selectQuery(
+        $fields = [],
+        $table = [],
+        array $types = []
+    ): SelectQuery {
+        $query = new SelectQuery($this);
+        if ($table) {
+            $query->from($table);
+        }
+        if ($fields) {
+            $query->select($fields, false);
+        }
+        $query->setDefaultTypes($types);
+
+        return $query;
+    }
+
+    /**
+     * Executes a SQL statement and returns the Statement object as result.
+     *
+     * @param string $sql The SQL query to execute.
+     * @return \Cake\Database\StatementInterface
+     * @deprecated 4.5.0 Use either `selectQuery`, `insertQuery`, `deleteQuery`, `updateQuery` instead.
+     */
+    public function query(string $sql): StatementInterface
+    {
+        deprecationWarning('Use either `selectQuery`, `insertQuery`, `deleteQuery`, `updateQuery` instead.');
+
+        return $this->getDisconnectRetry()->run(function () use ($sql) {
+            $statement = $this->prepare($sql);
+            $statement->execute();
+
+            return $statement;
+        });
+    }
+
+    /**
+     * Create a new Query instance for this connection.
+     *
+     * @return \Cake\Database\Query
+     * @deprecated 4.5.0 Use `insertQuery()`, `deleteQuery()`, `selectQuery()` or `updateQuery()` instead.
+     */
+    public function newQuery(): Query
+    {
+        deprecationWarning(
+            'As of 4.5.0, using newQuery() is deprecated. Instead, use `insertQuery()`, ' .
+            '`deleteQuery()`, `selectQuery()` or `updateQuery()`. The query objects ' .
+            'returned by these methods will emit deprecations that will become fatal errors in 5.0.' .
+            'See https://book.cakephp.org/4/en/appendices/4-5-migration-guide.html for more information.'
+        );
+
+        return new Query($this);
+    }
+
+    /**
+     * Sets a Schema\Collection object for this connection.
+     *
+     * @param \Cake\Database\Schema\CollectionInterface $collection The schema collection object
+     * @return $this
+     */
+    public function setSchemaCollection(SchemaCollectionInterface $collection)
+    {
+        $this->_schemaCollection = $collection;
+
+        return $this;
+    }
+
+    /**
+     * Gets a Schema\Collection object for this connection.
+     *
+     * @return \Cake\Database\Schema\CollectionInterface
+     */
+    public function getSchemaCollection(): SchemaCollectionInterface
+    {
+        if ($this->_schemaCollection !== null) {
+            return $this->_schemaCollection;
+        }
+
+        if (!empty($this->_config['cacheMetadata'])) {
+            return $this->_schemaCollection = new CachedCollection(
+                new SchemaCollection($this),
+                empty($this->_config['cacheKeyPrefix']) ? $this->configName() : $this->_config['cacheKeyPrefix'],
+                $this->getCacher()
+            );
+        }
+
+        return $this->_schemaCollection = new SchemaCollection($this);
+    }
+
+    /**
+     * Executes an INSERT query on the specified table.
+     *
+     * @param string $table the table to insert values in
+     * @param array $values values to be inserted
+     * @param array $types Array containing the types to be used for casting
+     * @return \Cake\Database\StatementInterface
+     */
+    public function insert(string $table, array $values, array $types = []): StatementInterface
+    {
+        return $this->getDisconnectRetry()->run(function () use ($table, $values, $types) {
+            return $this->insertQuery($table, $values, $types)->execute();
+        });
+    }
+
+    /**
+     * Create a new InsertQuery instance for this connection.
+     *
+     * @param string|null $table The table to insert rows into.
+     * @param array $values Associative array of column => value to be inserted.
+     * @param array $types Associative array containing the types to be used for casting.
+     * @return \Cake\Database\Query\InsertQuery
+     */
+    public function insertQuery(?string $table = null, array $values = [], array $types = []): InsertQuery
+    {
+        $query = new InsertQuery($this);
+        if ($table) {
+            $query->into($table);
+        }
+        if ($values) {
+            $columns = array_keys($values);
+            $query->insert($columns, $types)
+                ->values($values);
+        }
+
+        return $query;
+    }
+
+    /**
+     * Executes an UPDATE statement on the specified table.
+     *
+     * @param string $table the table to update rows from
+     * @param array $values values to be updated
+     * @param array $conditions conditions to be set for update statement
+     * @param array $types list of associative array containing the types to be used for casting
+     * @return \Cake\Database\StatementInterface
+     */
+    public function update(string $table, array $values, array $conditions = [], array $types = []): StatementInterface
+    {
+        return $this->getDisconnectRetry()->run(function () use ($table, $values, $conditions, $types) {
+            return $this->updateQuery($table, $values, $conditions, $types)->execute();
+        });
+    }
+
+    /**
+     * Create a new UpdateQuery instance for this connection.
+     *
+     * @param \Cake\Database\ExpressionInterface|string|null $table The table to update rows of.
+     * @param array $values Values to be updated.
+     * @param array $conditions Conditions to be set for the update statement.
+     * @param array $types Associative array containing the types to be used for casting.
+     * @return \Cake\Database\Query\UpdateQuery
+     */
+    public function updateQuery(
+        $table = null,
+        array $values = [],
+        array $conditions = [],
+        array $types = []
+    ): UpdateQuery {
+        $query = new UpdateQuery($this);
+        if ($table) {
+            $query->update($table);
+        }
+        if ($values) {
+            $query->set($values, $types);
+        }
+        if ($conditions) {
+            $query->where($conditions, $types);
+        }
+
+        return $query;
+    }
+
+    /**
+     * Executes a DELETE statement on the specified table.
+     *
+     * @param string $table the table to delete rows from
+     * @param array $conditions conditions to be set for delete statement
+     * @param array $types list of associative array containing the types to be used for casting
+     * @return \Cake\Database\StatementInterface
+     */
+    public function delete(string $table, array $conditions = [], array $types = []): StatementInterface
+    {
+        return $this->getDisconnectRetry()->run(function () use ($table, $conditions, $types) {
+            return $this->deleteQuery($table, $conditions, $types)->execute();
+        });
+    }
+
+    /**
+     * Create a new DeleteQuery instance for this connection.
+     *
+     * @param string|null $table The table to delete rows from.
+     * @param array $conditions Conditions to be set for the delete statement.
+     * @param array $types Associative array containing the types to be used for casting.
+     * @return \Cake\Database\Query\DeleteQuery
+     */
+    public function deleteQuery(?string $table = null, array $conditions = [], array $types = []): DeleteQuery
+    {
+        $query = new DeleteQuery($this);
+        if ($table) {
+            $query->from($table);
+        }
+        if ($conditions) {
+            $query->where($conditions, $types);
+        }
+
+        return $query;
+    }
+
+    /**
+     * Starts a new transaction.
+     *
+     * @return void
+     */
+    public function begin(): void
+    {
+        if (!$this->_transactionStarted) {
+            if ($this->_logQueries) {
+                $this->log('BEGIN');
+            }
+
+            $this->getDisconnectRetry()->run(function (): void {
+                $this->getDriver()->beginTransaction();
+            });
+
+            $this->_transactionLevel = 0;
+            $this->_transactionStarted = true;
+            $this->nestedTransactionRollbackException = null;
+
+            return;
+        }
+
+        $this->_transactionLevel++;
+        if ($this->isSavePointsEnabled()) {
+            $this->createSavePoint((string)$this->_transactionLevel);
+        }
+    }
+
+    /**
+     * Commits current transaction.
+     *
+     * @return bool true on success, false otherwise
+     */
+    public function commit(): bool
+    {
+        if (!$this->_transactionStarted) {
+            return false;
+        }
+
+        if ($this->_transactionLevel === 0) {
+            if ($this->wasNestedTransactionRolledback()) {
+                /** @var \Cake\Database\Exception\NestedTransactionRollbackException $e */
+                $e = $this->nestedTransactionRollbackException;
+                $this->nestedTransactionRollbackException = null;
+                throw $e;
+            }
+
+            $this->_transactionStarted = false;
+            $this->nestedTransactionRollbackException = null;
+            if ($this->_logQueries) {
+                $this->log('COMMIT');
+            }
+
+            return $this->getDriver()->commitTransaction();
+        }
+        if ($this->isSavePointsEnabled()) {
+            $this->releaseSavePoint((string)$this->_transactionLevel);
+        }
+
+        $this->_transactionLevel--;
+
+        return true;
+    }
+
+    /**
+     * Rollback current transaction.
+     *
+     * @param bool|null $toBeginning Whether the transaction should be rolled back to the
+     * beginning of it. Defaults to false if using savepoints, or true if not.
+     * @return bool
+     */
+    public function rollback(?bool $toBeginning = null): bool
+    {
+        if (!$this->_transactionStarted) {
+            return false;
+        }
+
+        $useSavePoint = $this->isSavePointsEnabled();
+        if ($toBeginning === null) {
+            $toBeginning = !$useSavePoint;
+        }
+        if ($this->_transactionLevel === 0 || $toBeginning) {
+            $this->_transactionLevel = 0;
+            $this->_transactionStarted = false;
+            $this->nestedTransactionRollbackException = null;
+            if ($this->_logQueries) {
+                $this->log('ROLLBACK');
+            }
+            $this->getDriver()->rollbackTransaction();
+
+            return true;
+        }
+
+        $savePoint = $this->_transactionLevel--;
+        if ($useSavePoint) {
+            $this->rollbackSavepoint($savePoint);
+        } elseif ($this->nestedTransactionRollbackException === null) {
+            $this->nestedTransactionRollbackException = new NestedTransactionRollbackException();
+        }
+
+        return true;
+    }
+
+    /**
+     * Enables/disables the usage of savepoints, enables only if driver the allows it.
+     *
+     * If you are trying to enable this feature, make sure you check
+     * `isSavePointsEnabled()` to verify that savepoints were enabled successfully.
+     *
+     * @param bool $enable Whether save points should be used.
+     * @return $this
+     */
+    public function enableSavePoints(bool $enable = true)
+    {
+        if ($enable === false) {
+            $this->_useSavePoints = false;
+        } else {
+            $this->_useSavePoints = $this->getDriver()->supports(DriverInterface::FEATURE_SAVEPOINT);
+        }
+
+        return $this;
+    }
+
+    /**
+     * Disables the usage of savepoints.
+     *
+     * @return $this
+     */
+    public function disableSavePoints()
+    {
+        $this->_useSavePoints = false;
+
+        return $this;
+    }
+
+    /**
+     * Returns whether this connection is using savepoints for nested transactions
+     *
+     * @return bool true if enabled, false otherwise
+     */
+    public function isSavePointsEnabled(): bool
+    {
+        return $this->_useSavePoints;
+    }
+
+    /**
+     * Creates a new save point for nested transactions.
+     *
+     * @param string|int $name Save point name or id
+     * @return void
+     */
+    public function createSavePoint($name): void
+    {
+        $this->execute($this->getDriver()->savePointSQL($name))->closeCursor();
+    }
+
+    /**
+     * Releases a save point by its name.
+     *
+     * @param string|int $name Save point name or id
+     * @return void
+     */
+    public function releaseSavePoint($name): void
+    {
+        $sql = $this->getDriver()->releaseSavePointSQL($name);
+        if ($sql) {
+            $this->execute($sql)->closeCursor();
+        }
+    }
+
+    /**
+     * Rollback a save point by its name.
+     *
+     * @param string|int $name Save point name or id
+     * @return void
+     */
+    public function rollbackSavepoint($name): void
+    {
+        $this->execute($this->getDriver()->rollbackSavePointSQL($name))->closeCursor();
+    }
+
+    /**
+     * Run driver specific SQL to disable foreign key checks.
+     *
+     * @return void
+     */
+    public function disableForeignKeys(): void
+    {
+        $this->getDisconnectRetry()->run(function (): void {
+            $this->execute($this->getDriver()->disableForeignKeySQL())->closeCursor();
+        });
+    }
+
+    /**
+     * Run driver specific SQL to enable foreign key checks.
+     *
+     * @return void
+     */
+    public function enableForeignKeys(): void
+    {
+        $this->getDisconnectRetry()->run(function (): void {
+            $this->execute($this->getDriver()->enableForeignKeySQL())->closeCursor();
+        });
+    }
+
+    /**
+     * Returns whether the driver supports adding or dropping constraints
+     * to already created tables.
+     *
+     * @return bool true if driver supports dynamic constraints
+     * @deprecated 4.3.0 Fixtures no longer dynamically drop and create constraints.
+     */
+    public function supportsDynamicConstraints(): bool
+    {
+        return $this->getDriver()->supportsDynamicConstraints();
+    }
+
+    /**
+     * @inheritDoc
+     */
+    public function transactional(callable $callback)
+    {
+        $this->begin();
+
+        try {
+            $result = $callback($this);
+        } catch (Throwable $e) {
+            $this->rollback(false);
+            throw $e;
+        }
+
+        if ($result === false) {
+            $this->rollback(false);
+
+            return false;
+        }
+
+        try {
+            $this->commit();
+        } catch (NestedTransactionRollbackException $e) {
+            $this->rollback(false);
+            throw $e;
+        }
+
+        return $result;
+    }
+
+    /**
+     * Returns whether some nested transaction has been already rolled back.
+     *
+     * @return bool
+     */
+    protected function wasNestedTransactionRolledback(): bool
+    {
+        return $this->nestedTransactionRollbackException instanceof NestedTransactionRollbackException;
+    }
+
+    /**
+     * @inheritDoc
+     */
+    public function disableConstraints(callable $callback)
+    {
+        return $this->getDisconnectRetry()->run(function () use ($callback) {
+            $this->disableForeignKeys();
+
+            try {
+                $result = $callback($this);
+            } finally {
+                $this->enableForeignKeys();
+            }
+
+            return $result;
+        });
+    }
+
+    /**
+     * Checks if a transaction is running.
+     *
+     * @return bool True if a transaction is running else false.
+     */
+    public function inTransaction(): bool
+    {
+        return $this->_transactionStarted;
+    }
+
+    /**
+     * Quotes value to be used safely in database query.
+     *
+     * This uses `PDO::quote()` and requires `supportsQuoting()` to work.
+     *
+     * @param mixed $value The value to quote.
+     * @param \Cake\Database\TypeInterface|string|int $type Type to be used for determining kind of quoting to perform
+     * @return string Quoted value
+     * @deprecated 4.5.0 Use getDriver()->quote() instead.
+     */
+    public function quote($value, $type = 'string'): string
+    {
+        deprecationWarning('Use getDriver()->quote() instead.');
+        [$value, $type] = $this->cast($value, $type);
+
+        return $this->getDriver()->quote($value, $type);
+    }
+
+    /**
+     * Checks if using `quote()` is supported.
+     *
+     * This is not required to use `quoteIdentifier()`.
+     *
+     * @return bool
+     * @deprecated 4.5.0 Use getDriver()->supportsQuoting() instead.
+     */
+    public function supportsQuoting(): bool
+    {
+        deprecationWarning('Use getDriver()->supportsQuoting() instead.');
+
+        return $this->getDriver()->supports(DriverInterface::FEATURE_QUOTE);
+    }
+
+    /**
+     * Quotes a database identifier (a column name, table name, etc..) to
+     * be used safely in queries without the risk of using reserved words.
+     *
+     * This does not require `supportsQuoting()` to work.
+     *
+     * @param string $identifier The identifier to quote.
+     * @return string
+     * @deprecated 4.5.0 Use getDriver()->quoteIdentifier() instead.
+     */
+    public function quoteIdentifier(string $identifier): string
+    {
+        deprecationWarning('Use getDriver()->quoteIdentifier() instead.');
+
+        return $this->getDriver()->quoteIdentifier($identifier);
+    }
+
+    /**
+     * Enables or disables metadata caching for this connection
+     *
+     * Changing this setting will not modify existing schema collections objects.
+     *
+     * @param string|bool $cache Either boolean false to disable metadata caching, or
+     *   true to use `_cake_model_` or the name of the cache config to use.
+     * @return void
+     */
+    public function cacheMetadata($cache): void
+    {
+        $this->_schemaCollection = null;
+        $this->_config['cacheMetadata'] = $cache;
+        if (is_string($cache)) {
+            $this->cacher = null;
+        }
+    }
+
+    /**
+     * @inheritDoc
+     */
+    public function setCacher(CacheInterface $cacher)
+    {
+        $this->cacher = $cacher;
+
+        return $this;
+    }
+
+    /**
+     * @inheritDoc
+     */
+    public function getCacher(): CacheInterface
+    {
+        if ($this->cacher !== null) {
+            return $this->cacher;
+        }
+
+        $configName = $this->_config['cacheMetadata'] ?? '_cake_model_';
+        if (!is_string($configName)) {
+            $configName = '_cake_model_';
+        }
+
+        if (!class_exists(Cache::class)) {
+            throw new RuntimeException(
+                'To use caching you must either set a cacher using Connection::setCacher()' .
+                ' or require the cakephp/cache package in your composer config.'
+            );
+        }
+
+        return $this->cacher = Cache::pool($configName);
+    }
+
+    /**
+     * Enable/disable query logging
+     *
+     * @param bool $enable Enable/disable query logging
+     * @return $this
+     * @deprecated 4.5.0 Connection logging is moving to the driver in 5.x
+     */
+    public function enableQueryLogging(bool $enable = true)
+    {
+        $this->_logQueries = $enable;
+
+        return $this;
+    }
+
+    /**
+     * Disable query logging
+     *
+     * @return $this
+     * @deprecated 4.5.0 Connection logging is moving to the driver in 5.x
+     */
+    public function disableQueryLogging()
+    {
+        $this->_logQueries = false;
+
+        return $this;
+    }
+
+    /**
+     * Check if query logging is enabled.
+     *
+     * @return bool
+     * @deprecated 4.5.0 Connection logging is moving to the driver in 5.x
+     */
+    public function isQueryLoggingEnabled(): bool
+    {
+        return $this->_logQueries;
+    }
+
+    /**
+     * Sets a logger
+     *
+     * @param \Psr\Log\LoggerInterface $logger Logger object
+     * @return $this
+     * @psalm-suppress ImplementedReturnTypeMismatch
+     */
+    public function setLogger(LoggerInterface $logger)
+    {
+        $this->_logger = $logger;
+
+        return $this;
+    }
+
+    /**
+     * Gets the logger object
+     *
+     * @return \Psr\Log\LoggerInterface logger instance
+     */
+    public function getLogger(): LoggerInterface
+    {
+        if ($this->_logger !== null) {
+            return $this->_logger;
+        }
+
+        if (!class_exists(BaseLog::class)) {
+            throw new RuntimeException(
+                'For logging you must either set a logger using Connection::setLogger()' .
+                ' or require the cakephp/log package in your composer config.'
+            );
+        }
+
+        return $this->_logger = new QueryLogger(['connection' => $this->configName()]);
+    }
+
+    /**
+     * Logs a Query string using the configured logger object.
+     *
+     * @param string $sql string to be logged
+     * @return void
+     */
+    public function log(string $sql): void
+    {
+        $query = new LoggedQuery();
+        $query->query = $sql;
+        $this->getLogger()->debug((string)$query, ['query' => $query]);
+    }
+
+    /**
+     * Returns a new statement object that will log the activity
+     * for the passed original statement instance.
+     *
+     * @param \Cake\Database\StatementInterface $statement the instance to be decorated
+     * @return \Cake\Database\Log\LoggingStatement
+     */
+    protected function _newLogger(StatementInterface $statement): LoggingStatement
+    {
+        $log = new LoggingStatement($statement, $this->getDriver());
+        $log->setLogger($this->getLogger());
+
+        return $log;
+    }
+
+    /**
+     * Returns an array that can be used to describe the internal state of this
+     * object.
+     *
+     * @return array
+     */
+    public function __debugInfo(): array
+    {
+        $secrets = [
+            'password' => '*****',
+            'username' => '*****',
+            'host' => '*****',
+            'database' => '*****',
+            'port' => '*****',
+        ];
+        $replace = array_intersect_key($secrets, $this->_config);
+        $config = $replace + $this->_config;
+
+        if (isset($config['read'])) {
+            /** @psalm-suppress PossiblyInvalidArgument */
+            $config['read'] = array_intersect_key($secrets, $config['read']) + $config['read'];
+        }
+        if (isset($config['write'])) {
+            /** @psalm-suppress PossiblyInvalidArgument */
+            $config['write'] = array_intersect_key($secrets, $config['write']) + $config['write'];
+        }
+
+        return [
+            'config' => $config,
+            'readDriver' => $this->readDriver,
+            'writeDriver' => $this->writeDriver,
+            'transactionLevel' => $this->_transactionLevel,
+            'transactionStarted' => $this->_transactionStarted,
+            'useSavePoints' => $this->_useSavePoints,
+            'logQueries' => $this->_logQueries,
+            'logger' => $this->_logger,
+        ];
+    }
+}
diff --git a/vendor/cakephp/database/ConstraintsInterface.php b/vendor/cakephp/database/ConstraintsInterface.php
new file mode 100644
index 0000000..f1fe3c1
--- /dev/null
+++ b/vendor/cakephp/database/ConstraintsInterface.php
@@ -0,0 +1,49 @@
+  DB-specific error codes that allow connect retry
+     */
+    protected const RETRY_ERROR_CODES = [];
+
+    /**
+     * Instance of PDO.
+     *
+     * @var \PDO
+     */
+    protected $_connection;
+
+    /**
+     * Configuration data.
+     *
+     * @var array
+     */
+    protected $_config;
+
+    /**
+     * Base configuration that is merged into the user
+     * supplied configuration data.
+     *
+     * @var array
+     */
+    protected $_baseConfig = [];
+
+    /**
+     * Indicates whether the driver is doing automatic identifier quoting
+     * for all queries
+     *
+     * @var bool
+     */
+    protected $_autoQuoting = false;
+
+    /**
+     * The server version
+     *
+     * @var string|null
+     */
+    protected $_version;
+
+    /**
+     * The last number of connection retry attempts.
+     *
+     * @var int
+     */
+    protected $connectRetries = 0;
+
+    /**
+     * Constructor
+     *
+     * @param array $config The configuration for the driver.
+     * @throws \InvalidArgumentException
+     */
+    public function __construct(array $config = [])
+    {
+        if (empty($config['username']) && !empty($config['login'])) {
+            throw new InvalidArgumentException(
+                'Please pass "username" instead of "login" for connecting to the database'
+            );
+        }
+        $config += $this->_baseConfig;
+        $this->_config = $config;
+        if (!empty($config['quoteIdentifiers'])) {
+            $this->enableAutoQuoting();
+        }
+    }
+
+    /**
+     * Get the configuration data used to create the driver.
+     *
+     * @return array
+     */
+    public function config(): array
+    {
+        return $this->_config;
+    }
+
+    /**
+     * Establishes a connection to the database server
+     *
+     * @param string $dsn A Driver-specific PDO-DSN
+     * @param array $config configuration to be used for creating connection
+     * @return bool true on success
+     */
+    protected function _connect(string $dsn, array $config): bool
+    {
+        $action = function () use ($dsn, $config) {
+            $this->setConnection(new PDO(
+                $dsn,
+                $config['username'] ?: null,
+                $config['password'] ?: null,
+                $config['flags']
+            ));
+        };
+
+        $retry = new CommandRetry(new ErrorCodeWaitStrategy(static::RETRY_ERROR_CODES, 5), 4);
+        try {
+            $retry->run($action);
+        } catch (PDOException $e) {
+            throw new MissingConnectionException(
+                [
+                    'driver' => App::shortName(static::class, 'Database/Driver'),
+                    'reason' => $e->getMessage(),
+                ],
+                null,
+                $e
+            );
+        } finally {
+            $this->connectRetries = $retry->getRetries();
+        }
+
+        return true;
+    }
+
+    /**
+     * @inheritDoc
+     */
+    abstract public function connect(): bool;
+
+    /**
+     * @inheritDoc
+     */
+    public function disconnect(): void
+    {
+        /** @psalm-suppress PossiblyNullPropertyAssignmentValue */
+        $this->_connection = null;
+        $this->_version = null;
+    }
+
+    /**
+     * Returns connected server version.
+     *
+     * @return string
+     */
+    public function version(): string
+    {
+        if ($this->_version === null) {
+            $this->connect();
+            $this->_version = (string)$this->_connection->getAttribute(PDO::ATTR_SERVER_VERSION);
+        }
+
+        return $this->_version;
+    }
+
+    /**
+     * Get the internal PDO connection instance.
+     *
+     * @return \PDO
+     */
+    public function getConnection()
+    {
+        if ($this->_connection === null) {
+            throw new MissingConnectionException([
+                'driver' => App::shortName(static::class, 'Database/Driver'),
+                'reason' => 'Unknown',
+            ]);
+        }
+
+        return $this->_connection;
+    }
+
+    /**
+     * Set the internal PDO connection instance.
+     *
+     * @param \PDO $connection PDO instance.
+     * @return $this
+     * @psalm-suppress MoreSpecificImplementedParamType
+     */
+    public function setConnection($connection)
+    {
+        $this->_connection = $connection;
+
+        return $this;
+    }
+
+    /**
+     * @inheritDoc
+     */
+    abstract public function enabled(): bool;
+
+    /**
+     * @inheritDoc
+     */
+    public function prepare($query): StatementInterface
+    {
+        $this->connect();
+        $statement = $this->_connection->prepare($query instanceof Query ? $query->sql() : $query);
+
+        return new PDOStatement($statement, $this);
+    }
+
+    /**
+     * @inheritDoc
+     */
+    public function beginTransaction(): bool
+    {
+        $this->connect();
+        if ($this->_connection->inTransaction()) {
+            return true;
+        }
+
+        return $this->_connection->beginTransaction();
+    }
+
+    /**
+     * @inheritDoc
+     */
+    public function commitTransaction(): bool
+    {
+        $this->connect();
+        if (!$this->_connection->inTransaction()) {
+            return false;
+        }
+
+        return $this->_connection->commit();
+    }
+
+    /**
+     * @inheritDoc
+     */
+    public function rollbackTransaction(): bool
+    {
+        $this->connect();
+        if (!$this->_connection->inTransaction()) {
+            return false;
+        }
+
+        return $this->_connection->rollBack();
+    }
+
+    /**
+     * Returns whether a transaction is active for connection.
+     *
+     * @return bool
+     */
+    public function inTransaction(): bool
+    {
+        $this->connect();
+
+        return $this->_connection->inTransaction();
+    }
+
+    /**
+     * @inheritDoc
+     */
+    public function supportsSavePoints(): bool
+    {
+        deprecationWarning('Feature support checks are now implemented by `supports()` with FEATURE_* constants.');
+
+        return $this->supports(static::FEATURE_SAVEPOINT);
+    }
+
+    /**
+     * Returns true if the server supports common table expressions.
+     *
+     * @return bool
+     * @deprecated 4.3.0 Use `supports(DriverInterface::FEATURE_QUOTE)` instead
+     */
+    public function supportsCTEs(): bool
+    {
+        deprecationWarning('Feature support checks are now implemented by `supports()` with FEATURE_* constants.');
+
+        return $this->supports(static::FEATURE_CTE);
+    }
+
+    /**
+     * @inheritDoc
+     */
+    public function quote($value, $type = PDO::PARAM_STR): string
+    {
+        $this->connect();
+
+        return $this->_connection->quote((string)$value, $type);
+    }
+
+    /**
+     * Checks if the driver supports quoting, as PDO_ODBC does not support it.
+     *
+     * @return bool
+     * @deprecated 4.3.0 Use `supports(DriverInterface::FEATURE_QUOTE)` instead
+     */
+    public function supportsQuoting(): bool
+    {
+        deprecationWarning('Feature support checks are now implemented by `supports()` with FEATURE_* constants.');
+
+        return $this->supports(static::FEATURE_QUOTE);
+    }
+
+    /**
+     * @inheritDoc
+     */
+    abstract public function queryTranslator(string $type): Closure;
+
+    /**
+     * @inheritDoc
+     */
+    abstract public function schemaDialect(): SchemaDialect;
+
+    /**
+     * @inheritDoc
+     */
+    abstract public function quoteIdentifier(string $identifier): string;
+
+    /**
+     * @inheritDoc
+     */
+    public function schemaValue($value): string
+    {
+        if ($value === null) {
+            return 'NULL';
+        }
+        if ($value === false) {
+            return 'FALSE';
+        }
+        if ($value === true) {
+            return 'TRUE';
+        }
+        if (is_float($value)) {
+            return str_replace(',', '.', (string)$value);
+        }
+        /** @psalm-suppress InvalidArgument */
+        if (
+            (
+                is_int($value) ||
+                $value === '0'
+            ) ||
+            (
+                is_numeric($value) &&
+                strpos($value, ',') === false &&
+                substr($value, 0, 1) !== '0' &&
+                strpos($value, 'e') === false
+            )
+        ) {
+            return (string)$value;
+        }
+
+        return $this->_connection->quote((string)$value, PDO::PARAM_STR);
+    }
+
+    /**
+     * @inheritDoc
+     */
+    public function schema(): string
+    {
+        return $this->_config['schema'];
+    }
+
+    /**
+     * @inheritDoc
+     */
+    public function lastInsertId(?string $table = null, ?string $column = null)
+    {
+        $this->connect();
+
+        if ($this->_connection instanceof PDO) {
+            return $this->_connection->lastInsertId($table);
+        }
+
+        return $this->_connection->lastInsertId($table);
+    }
+
+    /**
+     * @inheritDoc
+     */
+    public function isConnected(): bool
+    {
+        if ($this->_connection === null) {
+            $connected = false;
+        } else {
+            try {
+                $connected = (bool)$this->_connection->query('SELECT 1');
+            } catch (PDOException $e) {
+                $connected = false;
+            }
+        }
+
+        return $connected;
+    }
+
+    /**
+     * @inheritDoc
+     */
+    public function enableAutoQuoting(bool $enable = true)
+    {
+        $this->_autoQuoting = $enable;
+
+        return $this;
+    }
+
+    /**
+     * @inheritDoc
+     */
+    public function disableAutoQuoting()
+    {
+        $this->_autoQuoting = false;
+
+        return $this;
+    }
+
+    /**
+     * @inheritDoc
+     */
+    public function isAutoQuotingEnabled(): bool
+    {
+        return $this->_autoQuoting;
+    }
+
+    /**
+     * Returns whether the driver supports the feature.
+     *
+     * Defaults to true for FEATURE_QUOTE and FEATURE_SAVEPOINT.
+     *
+     * @param string $feature Driver feature name
+     * @return bool
+     */
+    public function supports(string $feature): bool
+    {
+        switch ($feature) {
+            case static::FEATURE_DISABLE_CONSTRAINT_WITHOUT_TRANSACTION:
+            case static::FEATURE_QUOTE:
+            case static::FEATURE_SAVEPOINT:
+                return true;
+        }
+
+        return false;
+    }
+
+    /**
+     * @inheritDoc
+     */
+    public function compileQuery(Query $query, ValueBinder $binder): array
+    {
+        $processor = $this->newCompiler();
+        $translator = $this->queryTranslator($query->type());
+        $query = $translator($query);
+
+        return [$query, $processor->compile($query, $binder)];
+    }
+
+    /**
+     * @inheritDoc
+     */
+    public function newCompiler(): QueryCompiler
+    {
+        return new QueryCompiler();
+    }
+
+    /**
+     * @inheritDoc
+     */
+    public function newTableSchema(string $table, array $columns = []): TableSchema
+    {
+        $className = TableSchema::class;
+        if (isset($this->_config['tableSchema'])) {
+            /** @var class-string<\Cake\Database\Schema\TableSchema> $className */
+            $className = $this->_config['tableSchema'];
+        }
+
+        return new $className($table, $columns);
+    }
+
+    /**
+     * Returns the maximum alias length allowed.
+     * This can be different from the maximum identifier length for columns.
+     *
+     * @return int|null Maximum alias length or null if no limit
+     */
+    public function getMaxAliasLength(): ?int
+    {
+        return static::MAX_ALIAS_LENGTH;
+    }
+
+    /**
+     * Returns the number of connection retry attempts made.
+     *
+     * @return int
+     */
+    public function getConnectRetries(): int
+    {
+        return $this->connectRetries;
+    }
+
+    /**
+     * Returns the connection role this driver performs.
+     *
+     * @return string
+     */
+    public function getRole(): string
+    {
+        return $this->_config['_role'] ?? Connection::ROLE_WRITE;
+    }
+
+    /**
+     * Destructor
+     */
+    public function __destruct()
+    {
+        /** @psalm-suppress PossiblyNullPropertyAssignmentValue */
+        $this->_connection = null;
+    }
+
+    /**
+     * Returns an array that can be used to describe the internal state of this
+     * object.
+     *
+     * @return array
+     */
+    public function __debugInfo(): array
+    {
+        return [
+            'connected' => $this->_connection !== null,
+            'role' => $this->getRole(),
+        ];
+    }
+}
diff --git a/vendor/cakephp/database/Driver/Mysql.php b/vendor/cakephp/database/Driver/Mysql.php
new file mode 100644
index 0000000..b7d30b6
--- /dev/null
+++ b/vendor/cakephp/database/Driver/Mysql.php
@@ -0,0 +1,345 @@
+
+     */
+    protected $_baseConfig = [
+        'persistent' => true,
+        'host' => 'localhost',
+        'username' => 'root',
+        'password' => '',
+        'database' => 'cake',
+        'port' => '3306',
+        'flags' => [],
+        'encoding' => 'utf8mb4',
+        'timezone' => null,
+        'init' => [],
+    ];
+
+    /**
+     * The schema dialect for this driver
+     *
+     * @var \Cake\Database\Schema\MysqlSchemaDialect|null
+     */
+    protected $_schemaDialect;
+
+    /**
+     * String used to start a database identifier quoting to make it safe
+     *
+     * @var string
+     */
+    protected $_startQuote = '`';
+
+    /**
+     * String used to end a database identifier quoting to make it safe
+     *
+     * @var string
+     */
+    protected $_endQuote = '`';
+
+    /**
+     * Server type.
+     *
+     * If the underlying server is MariaDB, its value will get set to `'mariadb'`
+     * after `version()` method is called.
+     *
+     * @var string
+     */
+    protected $serverType = self::SERVER_TYPE_MYSQL;
+
+    /**
+     * Mapping of feature to db server version for feature availability checks.
+     *
+     * @var array>
+     */
+    protected $featureVersions = [
+        'mysql' => [
+            'json' => '5.7.0',
+            'cte' => '8.0.0',
+            'window' => '8.0.0',
+        ],
+        'mariadb' => [
+            'json' => '10.2.7',
+            'cte' => '10.2.1',
+            'window' => '10.2.0',
+        ],
+    ];
+
+    /**
+     * Establishes a connection to the database server
+     *
+     * @return bool true on success
+     */
+    public function connect(): bool
+    {
+        if ($this->_connection) {
+            return true;
+        }
+        $config = $this->_config;
+
+        if ($config['timezone'] === 'UTC') {
+            $config['timezone'] = '+0:00';
+        }
+
+        if (!empty($config['timezone'])) {
+            $config['init'][] = sprintf("SET time_zone = '%s'", $config['timezone']);
+        }
+
+        $config['flags'] += [
+            PDO::ATTR_PERSISTENT => $config['persistent'],
+            PDO::MYSQL_ATTR_USE_BUFFERED_QUERY => true,
+            PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
+        ];
+
+        if (!empty($config['ssl_key']) && !empty($config['ssl_cert'])) {
+            $config['flags'][PDO::MYSQL_ATTR_SSL_KEY] = $config['ssl_key'];
+            $config['flags'][PDO::MYSQL_ATTR_SSL_CERT] = $config['ssl_cert'];
+        }
+        if (!empty($config['ssl_ca'])) {
+            $config['flags'][PDO::MYSQL_ATTR_SSL_CA] = $config['ssl_ca'];
+        }
+
+        if (empty($config['unix_socket'])) {
+            $dsn = "mysql:host={$config['host']};port={$config['port']};dbname={$config['database']}";
+        } else {
+            $dsn = "mysql:unix_socket={$config['unix_socket']};dbname={$config['database']}";
+        }
+
+        if (!empty($config['encoding'])) {
+            $dsn .= ";charset={$config['encoding']}";
+        }
+
+        $this->_connect($dsn, $config);
+
+        if (!empty($config['init'])) {
+            $connection = $this->getConnection();
+            foreach ((array)$config['init'] as $command) {
+                $connection->exec($command);
+            }
+        }
+
+        return true;
+    }
+
+    /**
+     * Returns whether php is able to use this driver for connecting to database
+     *
+     * @return bool true if it is valid to use this driver
+     */
+    public function enabled(): bool
+    {
+        return in_array('mysql', PDO::getAvailableDrivers(), true);
+    }
+
+    /**
+     * Prepares a sql statement to be executed
+     *
+     * @param \Cake\Database\Query|string $query The query to prepare.
+     * @return \Cake\Database\StatementInterface
+     */
+    public function prepare($query): StatementInterface
+    {
+        $this->connect();
+        $isObject = $query instanceof Query;
+        /**
+         * @psalm-suppress PossiblyInvalidMethodCall
+         * @psalm-suppress PossiblyInvalidArgument
+         */
+        $statement = $this->_connection->prepare($isObject ? $query->sql() : $query);
+        $result = new MysqlStatement($statement, $this);
+        /** @psalm-suppress PossiblyInvalidMethodCall */
+        if ($isObject && $query->isBufferedResultsEnabled() === false) {
+            $result->bufferResults(false);
+        }
+
+        return $result;
+    }
+
+    /**
+     * @inheritDoc
+     */
+    public function schemaDialect(): SchemaDialect
+    {
+        if ($this->_schemaDialect === null) {
+            $this->_schemaDialect = new MysqlSchemaDialect($this);
+        }
+
+        return $this->_schemaDialect;
+    }
+
+    /**
+     * @inheritDoc
+     */
+    public function schema(): string
+    {
+        return $this->_config['database'];
+    }
+
+    /**
+     * @inheritDoc
+     */
+    public function disableForeignKeySQL(): string
+    {
+        return 'SET foreign_key_checks = 0';
+    }
+
+    /**
+     * @inheritDoc
+     */
+    public function enableForeignKeySQL(): string
+    {
+        return 'SET foreign_key_checks = 1';
+    }
+
+    /**
+     * @inheritDoc
+     */
+    public function supports(string $feature): bool
+    {
+        switch ($feature) {
+            case static::FEATURE_CTE:
+            case static::FEATURE_JSON:
+            case static::FEATURE_WINDOW:
+                return version_compare(
+                    $this->version(),
+                    $this->featureVersions[$this->serverType][$feature],
+                    '>='
+                );
+        }
+
+        return parent::supports($feature);
+    }
+
+    /**
+     * @inheritDoc
+     */
+    public function supportsDynamicConstraints(): bool
+    {
+        return true;
+    }
+
+    /**
+     * Returns true if the connected server is MariaDB.
+     *
+     * @return bool
+     */
+    public function isMariadb(): bool
+    {
+        $this->version();
+
+        return $this->serverType === static::SERVER_TYPE_MARIADB;
+    }
+
+    /**
+     * Returns connected server version.
+     *
+     * @return string
+     */
+    public function version(): string
+    {
+        if ($this->_version === null) {
+            $this->connect();
+            $this->_version = (string)$this->_connection->getAttribute(PDO::ATTR_SERVER_VERSION);
+
+            if (strpos($this->_version, 'MariaDB') !== false) {
+                $this->serverType = static::SERVER_TYPE_MARIADB;
+                preg_match('/^(?:5\.5\.5-)?(\d+\.\d+\.\d+.*-MariaDB[^:]*)/', $this->_version, $matches);
+                $this->_version = $matches[1];
+            }
+        }
+
+        return $this->_version;
+    }
+
+    /**
+     * Returns true if the server supports common table expressions.
+     *
+     * @return bool
+     * @deprecated 4.3.0 Use `supports(DriverInterface::FEATURE_CTE)` instead
+     */
+    public function supportsCTEs(): bool
+    {
+        deprecationWarning('Feature support checks are now implemented by `supports()` with FEATURE_* constants.');
+
+        return $this->supports(static::FEATURE_CTE);
+    }
+
+    /**
+     * Returns true if the server supports native JSON columns
+     *
+     * @return bool
+     * @deprecated 4.3.0 Use `supports(DriverInterface::FEATURE_JSON)` instead
+     */
+    public function supportsNativeJson(): bool
+    {
+        deprecationWarning('Feature support checks are now implemented by `supports()` with FEATURE_* constants.');
+
+        return $this->supports(static::FEATURE_JSON);
+    }
+
+    /**
+     * Returns true if the connected server supports window functions.
+     *
+     * @return bool
+     * @deprecated 4.3.0 Use `supports(DriverInterface::FEATURE_WINDOW)` instead
+     */
+    public function supportsWindowFunctions(): bool
+    {
+        deprecationWarning('Feature support checks are now implemented by `supports()` with FEATURE_* constants.');
+
+        return $this->supports(static::FEATURE_WINDOW);
+    }
+}
diff --git a/vendor/cakephp/database/Driver/Postgres.php b/vendor/cakephp/database/Driver/Postgres.php
new file mode 100644
index 0000000..2a32264
--- /dev/null
+++ b/vendor/cakephp/database/Driver/Postgres.php
@@ -0,0 +1,348 @@
+
+     */
+    protected $_baseConfig = [
+        'persistent' => true,
+        'host' => 'localhost',
+        'username' => 'root',
+        'password' => '',
+        'database' => 'cake',
+        'schema' => 'public',
+        'port' => 5432,
+        'encoding' => 'utf8',
+        'timezone' => null,
+        'flags' => [],
+        'init' => [],
+    ];
+
+    /**
+     * The schema dialect class for this driver
+     *
+     * @var \Cake\Database\Schema\PostgresSchemaDialect|null
+     */
+    protected $_schemaDialect;
+
+    /**
+     * String used to start a database identifier quoting to make it safe
+     *
+     * @var string
+     */
+    protected $_startQuote = '"';
+
+    /**
+     * String used to end a database identifier quoting to make it safe
+     *
+     * @var string
+     */
+    protected $_endQuote = '"';
+
+    /**
+     * Establishes a connection to the database server
+     *
+     * @return bool true on success
+     */
+    public function connect(): bool
+    {
+        if ($this->_connection) {
+            return true;
+        }
+        $config = $this->_config;
+        $config['flags'] += [
+            PDO::ATTR_PERSISTENT => $config['persistent'],
+            PDO::ATTR_EMULATE_PREPARES => false,
+            PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
+        ];
+        if (empty($config['unix_socket'])) {
+            $dsn = "pgsql:host={$config['host']};port={$config['port']};dbname={$config['database']}";
+        } else {
+            $dsn = "pgsql:dbname={$config['database']}";
+        }
+
+        $this->_connect($dsn, $config);
+        $this->_connection = $connection = $this->getConnection();
+        if (!empty($config['encoding'])) {
+            $this->setEncoding($config['encoding']);
+        }
+
+        if (!empty($config['schema'])) {
+            $this->setSchema($config['schema']);
+        }
+
+        if (!empty($config['timezone'])) {
+            $config['init'][] = sprintf('SET timezone = %s', $connection->quote($config['timezone']));
+        }
+
+        foreach ($config['init'] as $command) {
+            $connection->exec($command);
+        }
+
+        return true;
+    }
+
+    /**
+     * Returns whether php is able to use this driver for connecting to database
+     *
+     * @return bool true if it is valid to use this driver
+     */
+    public function enabled(): bool
+    {
+        return in_array('pgsql', PDO::getAvailableDrivers(), true);
+    }
+
+    /**
+     * @inheritDoc
+     */
+    public function schemaDialect(): SchemaDialect
+    {
+        if ($this->_schemaDialect === null) {
+            $this->_schemaDialect = new PostgresSchemaDialect($this);
+        }
+
+        return $this->_schemaDialect;
+    }
+
+    /**
+     * Sets connection encoding
+     *
+     * @param string $encoding The encoding to use.
+     * @return void
+     */
+    public function setEncoding(string $encoding): void
+    {
+        $this->connect();
+        $this->_connection->exec('SET NAMES ' . $this->_connection->quote($encoding));
+    }
+
+    /**
+     * Sets connection default schema, if any relation defined in a query is not fully qualified
+     * postgres will fallback to looking the relation into defined default schema
+     *
+     * @param string $schema The schema names to set `search_path` to.
+     * @return void
+     */
+    public function setSchema(string $schema): void
+    {
+        $this->connect();
+        $this->_connection->exec('SET search_path TO ' . $this->_connection->quote($schema));
+    }
+
+    /**
+     * @inheritDoc
+     */
+    public function disableForeignKeySQL(): string
+    {
+        return 'SET CONSTRAINTS ALL DEFERRED';
+    }
+
+    /**
+     * @inheritDoc
+     */
+    public function enableForeignKeySQL(): string
+    {
+        return 'SET CONSTRAINTS ALL IMMEDIATE';
+    }
+
+    /**
+     * @inheritDoc
+     */
+    public function supports(string $feature): bool
+    {
+        switch ($feature) {
+            case static::FEATURE_CTE:
+            case static::FEATURE_JSON:
+            case static::FEATURE_TRUNCATE_WITH_CONSTRAINTS:
+            case static::FEATURE_WINDOW:
+                return true;
+
+            case static::FEATURE_DISABLE_CONSTRAINT_WITHOUT_TRANSACTION:
+                return false;
+        }
+
+        return parent::supports($feature);
+    }
+
+    /**
+     * @inheritDoc
+     */
+    public function supportsDynamicConstraints(): bool
+    {
+        return true;
+    }
+
+    /**
+     * @inheritDoc
+     */
+    protected function _transformDistinct(Query $query): Query
+    {
+        return $query;
+    }
+
+    /**
+     * @inheritDoc
+     */
+    protected function _insertQueryTranslator(Query $query): Query
+    {
+        if (!$query->clause('epilog')) {
+            $query->epilog('RETURNING *');
+        }
+
+        return $query;
+    }
+
+    /**
+     * @inheritDoc
+     */
+    protected function _expressionTranslators(): array
+    {
+        return [
+            IdentifierExpression::class => '_transformIdentifierExpression',
+            FunctionExpression::class => '_transformFunctionExpression',
+            StringExpression::class => '_transformStringExpression',
+        ];
+    }
+
+    /**
+     * Changes identifer expression into postgresql format.
+     *
+     * @param \Cake\Database\Expression\IdentifierExpression $expression The expression to tranform.
+     * @return void
+     */
+    protected function _transformIdentifierExpression(IdentifierExpression $expression): void
+    {
+        $collation = $expression->getCollation();
+        if ($collation) {
+            // use trim() to work around expression being transformed multiple times
+            $expression->setCollation('"' . trim($collation, '"') . '"');
+        }
+    }
+
+    /**
+     * Receives a FunctionExpression and changes it so that it conforms to this
+     * SQL dialect.
+     *
+     * @param \Cake\Database\Expression\FunctionExpression $expression The function expression to convert
+     *   to postgres SQL.
+     * @return void
+     */
+    protected function _transformFunctionExpression(FunctionExpression $expression): void
+    {
+        switch ($expression->getName()) {
+            case 'CONCAT':
+                // CONCAT function is expressed as exp1 || exp2
+                $expression->setName('')->setConjunction(' ||');
+                break;
+            case 'DATEDIFF':
+                $expression
+                    ->setName('')
+                    ->setConjunction('-')
+                    ->iterateParts(function ($p) {
+                        if (is_string($p)) {
+                            $p = ['value' => [$p => 'literal'], 'type' => null];
+                        } else {
+                            $p['value'] = [$p['value']];
+                        }
+
+                        return new FunctionExpression('DATE', $p['value'], [$p['type']]);
+                    });
+                break;
+            case 'CURRENT_DATE':
+                $time = new FunctionExpression('LOCALTIMESTAMP', [' 0 ' => 'literal']);
+                $expression->setName('CAST')->setConjunction(' AS ')->add([$time, 'date' => 'literal']);
+                break;
+            case 'CURRENT_TIME':
+                $time = new FunctionExpression('LOCALTIMESTAMP', [' 0 ' => 'literal']);
+                $expression->setName('CAST')->setConjunction(' AS ')->add([$time, 'time' => 'literal']);
+                break;
+            case 'NOW':
+                $expression->setName('LOCALTIMESTAMP')->add([' 0 ' => 'literal']);
+                break;
+            case 'RAND':
+                $expression->setName('RANDOM');
+                break;
+            case 'DATE_ADD':
+                $expression
+                    ->setName('')
+                    ->setConjunction(' + INTERVAL')
+                    ->iterateParts(function ($p, $key) {
+                        if ($key === 1) {
+                            $p = sprintf("'%s'", $p);
+                        }
+
+                        return $p;
+                    });
+                break;
+            case 'DAYOFWEEK':
+                $expression
+                    ->setName('EXTRACT')
+                    ->setConjunction(' ')
+                    ->add(['DOW FROM' => 'literal'], [], true)
+                    ->add([') + (1' => 'literal']); // Postgres starts on index 0 but Sunday should be 1
+                break;
+        }
+    }
+
+    /**
+     * Changes string expression into postgresql format.
+     *
+     * @param \Cake\Database\Expression\StringExpression $expression The string expression to tranform.
+     * @return void
+     */
+    protected function _transformStringExpression(StringExpression $expression): void
+    {
+        // use trim() to work around expression being transformed multiple times
+        $expression->setCollation('"' . trim($expression->getCollation(), '"') . '"');
+    }
+
+    /**
+     * {@inheritDoc}
+     *
+     * @return \Cake\Database\PostgresCompiler
+     */
+    public function newCompiler(): QueryCompiler
+    {
+        return new PostgresCompiler();
+    }
+}
diff --git a/vendor/cakephp/database/Driver/SqlDialectTrait.php b/vendor/cakephp/database/Driver/SqlDialectTrait.php
new file mode 100644
index 0000000..94a5e88
--- /dev/null
+++ b/vendor/cakephp/database/Driver/SqlDialectTrait.php
@@ -0,0 +1,315 @@
+_startQuote . $identifier . $this->_endQuote;
+        }
+
+        // string.string
+        if (preg_match('/^[\w-]+\.[^ \*]*$/u', $identifier)) {
+            $items = explode('.', $identifier);
+
+            return $this->_startQuote . implode($this->_endQuote . '.' . $this->_startQuote, $items) . $this->_endQuote;
+        }
+
+        // string.*
+        if (preg_match('/^[\w-]+\.\*$/u', $identifier)) {
+            return $this->_startQuote . str_replace('.*', $this->_endQuote . '.*', $identifier);
+        }
+
+        // Functions
+        if (preg_match('/^([\w-]+)\((.*)\)$/', $identifier, $matches)) {
+            return $matches[1] . '(' . $this->quoteIdentifier($matches[2]) . ')';
+        }
+
+        // Alias.field AS thing
+        if (preg_match('/^([\w-]+(\.[\w\s-]+|\(.*\))*)\s+AS\s*([\w-]+)$/ui', $identifier, $matches)) {
+            return $this->quoteIdentifier($matches[1]) . ' AS ' . $this->quoteIdentifier($matches[3]);
+        }
+
+        // string.string with spaces
+        if (preg_match('/^([\w-]+\.[\w][\w\s-]*[\w])(.*)/u', $identifier, $matches)) {
+            $items = explode('.', $matches[1]);
+            $field = implode($this->_endQuote . '.' . $this->_startQuote, $items);
+
+            return $this->_startQuote . $field . $this->_endQuote . $matches[2];
+        }
+
+        if (preg_match('/^[\w\s-]*[\w-]+/u', $identifier)) {
+            return $this->_startQuote . $identifier . $this->_endQuote;
+        }
+
+        return $identifier;
+    }
+
+    /**
+     * Returns a callable function that will be used to transform a passed Query object.
+     * This function, in turn, will return an instance of a Query object that has been
+     * transformed to accommodate any specificities of the SQL dialect in use.
+     *
+     * @param string $type the type of query to be transformed
+     * (select, insert, update, delete)
+     * @return \Closure
+     */
+    public function queryTranslator(string $type): Closure
+    {
+        return function ($query) use ($type) {
+            if ($this->isAutoQuotingEnabled()) {
+                $query = (new IdentifierQuoter($this))->quote($query);
+            }
+
+            /** @var \Cake\ORM\Query $query */
+            $query = $this->{'_' . $type . 'QueryTranslator'}($query);
+            $translators = $this->_expressionTranslators();
+            if (!$translators) {
+                return $query;
+            }
+
+            $query->traverseExpressions(function ($expression) use ($translators, $query): void {
+                foreach ($translators as $class => $method) {
+                    if ($expression instanceof $class) {
+                        $this->{$method}($expression, $query);
+                    }
+                }
+            });
+
+            return $query;
+        };
+    }
+
+    /**
+     * Returns an associative array of methods that will transform Expression
+     * objects to conform with the specific SQL dialect. Keys are class names
+     * and values a method in this class.
+     *
+     * @psalm-return array
+     * @return array
+     */
+    protected function _expressionTranslators(): array
+    {
+        return [];
+    }
+
+    /**
+     * Apply translation steps to select queries.
+     *
+     * @param \Cake\Database\Query $query The query to translate
+     * @return \Cake\Database\Query The modified query
+     */
+    protected function _selectQueryTranslator(Query $query): Query
+    {
+        return $this->_transformDistinct($query);
+    }
+
+    /**
+     * Returns the passed query after rewriting the DISTINCT clause, so that drivers
+     * that do not support the "ON" part can provide the actual way it should be done
+     *
+     * @param \Cake\Database\Query $query The query to be transformed
+     * @return \Cake\Database\Query
+     */
+    protected function _transformDistinct(Query $query): Query
+    {
+        if (is_array($query->clause('distinct'))) {
+            $query->group($query->clause('distinct'), true);
+            $query->distinct(false);
+        }
+
+        return $query;
+    }
+
+    /**
+     * Apply translation steps to delete queries.
+     *
+     * Chops out aliases on delete query conditions as most database dialects do not
+     * support aliases in delete queries. This also removes aliases
+     * in table names as they frequently don't work either.
+     *
+     * We are intentionally not supporting deletes with joins as they have even poorer support.
+     *
+     * @param \Cake\Database\Query $query The query to translate
+     * @return \Cake\Database\Query The modified query
+     */
+    protected function _deleteQueryTranslator(Query $query): Query
+    {
+        $hadAlias = false;
+        $tables = [];
+        foreach ($query->clause('from') as $alias => $table) {
+            if (is_string($alias)) {
+                $hadAlias = true;
+            }
+            $tables[] = $table;
+        }
+        if ($hadAlias) {
+            $query->from($tables, true);
+        }
+
+        if (!$hadAlias) {
+            return $query;
+        }
+
+        return $this->_removeAliasesFromConditions($query);
+    }
+
+    /**
+     * Apply translation steps to update queries.
+     *
+     * Chops out aliases on update query conditions as not all database dialects do support
+     * aliases in update queries.
+     *
+     * Just like for delete queries, joins are currently not supported for update queries.
+     *
+     * @param \Cake\Database\Query $query The query to translate
+     * @return \Cake\Database\Query The modified query
+     */
+    protected function _updateQueryTranslator(Query $query): Query
+    {
+        return $this->_removeAliasesFromConditions($query);
+    }
+
+    /**
+     * Removes aliases from the `WHERE` clause of a query.
+     *
+     * @param \Cake\Database\Query $query The query to process.
+     * @return \Cake\Database\Query The modified query.
+     * @throws \RuntimeException In case the processed query contains any joins, as removing
+     *  aliases from the conditions can break references to the joined tables.
+     */
+    protected function _removeAliasesFromConditions(Query $query): Query
+    {
+        if ($query->clause('join')) {
+            throw new RuntimeException(
+                'Aliases are being removed from conditions for UPDATE/DELETE queries, ' .
+                'this can break references to joined tables.'
+            );
+        }
+
+        $conditions = $query->clause('where');
+        if ($conditions) {
+            $conditions->traverse(function ($expression) {
+                if ($expression instanceof ComparisonExpression) {
+                    $field = $expression->getField();
+                    if (
+                        is_string($field) &&
+                        strpos($field, '.') !== false
+                    ) {
+                        [, $unaliasedField] = explode('.', $field, 2);
+                        $expression->setField($unaliasedField);
+                    }
+
+                    return $expression;
+                }
+
+                if ($expression instanceof IdentifierExpression) {
+                    $identifier = $expression->getIdentifier();
+                    if (strpos($identifier, '.') !== false) {
+                        [, $unaliasedIdentifier] = explode('.', $identifier, 2);
+                        $expression->setIdentifier($unaliasedIdentifier);
+                    }
+
+                    return $expression;
+                }
+
+                return $expression;
+            });
+        }
+
+        return $query;
+    }
+
+    /**
+     * Apply translation steps to insert queries.
+     *
+     * @param \Cake\Database\Query $query The query to translate
+     * @return \Cake\Database\Query The modified query
+     */
+    protected function _insertQueryTranslator(Query $query): Query
+    {
+        return $query;
+    }
+
+    /**
+     * Returns a SQL snippet for creating a new transaction savepoint
+     *
+     * @param string|int $name save point name
+     * @return string
+     */
+    public function savePointSQL($name): string
+    {
+        return 'SAVEPOINT LEVEL' . $name;
+    }
+
+    /**
+     * Returns a SQL snippet for releasing a previously created save point
+     *
+     * @param string|int $name save point name
+     * @return string
+     */
+    public function releaseSavePointSQL($name): string
+    {
+        return 'RELEASE SAVEPOINT LEVEL' . $name;
+    }
+
+    /**
+     * Returns a SQL snippet for rollbacking a previously created save point
+     *
+     * @param string|int $name save point name
+     * @return string
+     */
+    public function rollbackSavePointSQL($name): string
+    {
+        return 'ROLLBACK TO SAVEPOINT LEVEL' . $name;
+    }
+}
+
+// phpcs:disable
+class_alias(
+    'Cake\Database\Driver\SqlDialectTrait',
+    'Cake\Database\SqlDialectTrait'
+);
+// phpcs:enable
diff --git a/vendor/cakephp/database/Driver/Sqlite.php b/vendor/cakephp/database/Driver/Sqlite.php
new file mode 100644
index 0000000..65c3e7a
--- /dev/null
+++ b/vendor/cakephp/database/Driver/Sqlite.php
@@ -0,0 +1,385 @@
+
+     */
+    protected $_baseConfig = [
+        'persistent' => false,
+        'username' => null,
+        'password' => null,
+        'database' => ':memory:',
+        'encoding' => 'utf8',
+        'mask' => 0644,
+        'cache' => null,
+        'mode' => null,
+        'flags' => [],
+        'init' => [],
+    ];
+
+    /**
+     * The schema dialect class for this driver
+     *
+     * @var \Cake\Database\Schema\SqliteSchemaDialect|null
+     */
+    protected $_schemaDialect;
+
+    /**
+     * Whether the connected server supports window functions.
+     *
+     * @var bool|null
+     */
+    protected $_supportsWindowFunctions;
+
+    /**
+     * String used to start a database identifier quoting to make it safe
+     *
+     * @var string
+     */
+    protected $_startQuote = '"';
+
+    /**
+     * String used to end a database identifier quoting to make it safe
+     *
+     * @var string
+     */
+    protected $_endQuote = '"';
+
+    /**
+     * Mapping of date parts.
+     *
+     * @var array
+     */
+    protected $_dateParts = [
+        'day' => 'd',
+        'hour' => 'H',
+        'month' => 'm',
+        'minute' => 'M',
+        'second' => 'S',
+        'week' => 'W',
+        'year' => 'Y',
+    ];
+
+    /**
+     * Mapping of feature to db server version for feature availability checks.
+     *
+     * @var array
+     */
+    protected $featureVersions = [
+        'cte' => '3.8.3',
+        'window' => '3.28.0',
+    ];
+
+    /**
+     * Establishes a connection to the database server
+     *
+     * @return bool true on success
+     */
+    public function connect(): bool
+    {
+        if ($this->_connection) {
+            return true;
+        }
+        $config = $this->_config;
+        $config['flags'] += [
+            PDO::ATTR_PERSISTENT => $config['persistent'],
+            PDO::ATTR_EMULATE_PREPARES => false,
+            PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
+        ];
+        if (!is_string($config['database']) || $config['database'] === '') {
+            $name = $config['name'] ?? 'unknown';
+            throw new InvalidArgumentException(
+                "The `database` key for the `{$name}` SQLite connection needs to be a non-empty string."
+            );
+        }
+
+        $chmodFile = false;
+        if ($config['database'] !== ':memory:' && $config['mode'] !== 'memory') {
+            $chmodFile = !file_exists($config['database']);
+        }
+
+        $params = [];
+        if ($config['cache']) {
+            $params[] = 'cache=' . $config['cache'];
+        }
+        if ($config['mode']) {
+            $params[] = 'mode=' . $config['mode'];
+        }
+
+        if ($params) {
+            if (PHP_VERSION_ID < 80100) {
+                throw new RuntimeException('SQLite URI support requires PHP 8.1.');
+            }
+            $dsn = 'sqlite:file:' . $config['database'] . '?' . implode('&', $params);
+        } else {
+            $dsn = 'sqlite:' . $config['database'];
+        }
+
+        $this->_connect($dsn, $config);
+        if ($chmodFile) {
+            // phpcs:disable
+            @chmod($config['database'], $config['mask']);
+            // phpcs:enable
+        }
+
+        if (!empty($config['init'])) {
+            foreach ((array)$config['init'] as $command) {
+                $this->getConnection()->exec($command);
+            }
+        }
+
+        return true;
+    }
+
+    /**
+     * Returns whether php is able to use this driver for connecting to database
+     *
+     * @return bool true if it is valid to use this driver
+     */
+    public function enabled(): bool
+    {
+        return in_array('sqlite', PDO::getAvailableDrivers(), true);
+    }
+
+    /**
+     * Prepares a sql statement to be executed
+     *
+     * @param \Cake\Database\Query|string $query The query to prepare.
+     * @return \Cake\Database\StatementInterface
+     */
+    public function prepare($query): StatementInterface
+    {
+        $this->connect();
+        $isObject = $query instanceof Query;
+        /**
+         * @psalm-suppress PossiblyInvalidMethodCall
+         * @psalm-suppress PossiblyInvalidArgument
+         */
+        $statement = $this->_connection->prepare($isObject ? $query->sql() : $query);
+        $result = new SqliteStatement(new PDOStatement($statement, $this), $this);
+        /** @psalm-suppress PossiblyInvalidMethodCall */
+        if ($isObject && $query->isBufferedResultsEnabled() === false) {
+            $result->bufferResults(false);
+        }
+
+        return $result;
+    }
+
+    /**
+     * @inheritDoc
+     */
+    public function disableForeignKeySQL(): string
+    {
+        return 'PRAGMA foreign_keys = OFF';
+    }
+
+    /**
+     * @inheritDoc
+     */
+    public function enableForeignKeySQL(): string
+    {
+        return 'PRAGMA foreign_keys = ON';
+    }
+
+    /**
+     * @inheritDoc
+     */
+    public function supports(string $feature): bool
+    {
+        switch ($feature) {
+            case static::FEATURE_CTE:
+            case static::FEATURE_WINDOW:
+                return version_compare(
+                    $this->version(),
+                    $this->featureVersions[$feature],
+                    '>='
+                );
+
+            case static::FEATURE_TRUNCATE_WITH_CONSTRAINTS:
+                return true;
+        }
+
+        return parent::supports($feature);
+    }
+
+    /**
+     * @inheritDoc
+     */
+    public function supportsDynamicConstraints(): bool
+    {
+        return false;
+    }
+
+    /**
+     * @inheritDoc
+     */
+    public function schemaDialect(): SchemaDialect
+    {
+        if ($this->_schemaDialect === null) {
+            $this->_schemaDialect = new SqliteSchemaDialect($this);
+        }
+
+        return $this->_schemaDialect;
+    }
+
+    /**
+     * @inheritDoc
+     */
+    public function newCompiler(): QueryCompiler
+    {
+        return new SqliteCompiler();
+    }
+
+    /**
+     * @inheritDoc
+     */
+    protected function _expressionTranslators(): array
+    {
+        return [
+            FunctionExpression::class => '_transformFunctionExpression',
+            TupleComparison::class => '_transformTupleComparison',
+        ];
+    }
+
+    /**
+     * Receives a FunctionExpression and changes it so that it conforms to this
+     * SQL dialect.
+     *
+     * @param \Cake\Database\Expression\FunctionExpression $expression The function expression to convert to TSQL.
+     * @return void
+     */
+    protected function _transformFunctionExpression(FunctionExpression $expression): void
+    {
+        switch ($expression->getName()) {
+            case 'CONCAT':
+                // CONCAT function is expressed as exp1 || exp2
+                $expression->setName('')->setConjunction(' ||');
+                break;
+            case 'DATEDIFF':
+                $expression
+                    ->setName('ROUND')
+                    ->setConjunction('-')
+                    ->iterateParts(function ($p) {
+                        return new FunctionExpression('JULIANDAY', [$p['value']], [$p['type']]);
+                    });
+                break;
+            case 'NOW':
+                $expression->setName('DATETIME')->add(["'now'" => 'literal']);
+                break;
+            case 'RAND':
+                $expression
+                    ->setName('ABS')
+                    ->add(['RANDOM() % 1' => 'literal'], [], true);
+                break;
+            case 'CURRENT_DATE':
+                $expression->setName('DATE')->add(["'now'" => 'literal']);
+                break;
+            case 'CURRENT_TIME':
+                $expression->setName('TIME')->add(["'now'" => 'literal']);
+                break;
+            case 'EXTRACT':
+                $expression
+                    ->setName('STRFTIME')
+                    ->setConjunction(' ,')
+                    ->iterateParts(function ($p, $key) {
+                        if ($key === 0) {
+                            $value = rtrim(strtolower($p), 's');
+                            if (isset($this->_dateParts[$value])) {
+                                $p = ['value' => '%' . $this->_dateParts[$value], 'type' => null];
+                            }
+                        }
+
+                        return $p;
+                    });
+                break;
+            case 'DATE_ADD':
+                $expression
+                    ->setName('DATE')
+                    ->setConjunction(',')
+                    ->iterateParts(function ($p, $key) {
+                        if ($key === 1) {
+                            $p = ['value' => $p, 'type' => null];
+                        }
+
+                        return $p;
+                    });
+                break;
+            case 'DAYOFWEEK':
+                $expression
+                    ->setName('STRFTIME')
+                    ->setConjunction(' ')
+                    ->add(["'%w', " => 'literal'], [], true)
+                    ->add([') + (1' => 'literal']); // Sqlite starts on index 0 but Sunday should be 1
+                break;
+        }
+    }
+
+    /**
+     * Returns true if the server supports common table expressions.
+     *
+     * @return bool
+     * @deprecated 4.3.0 Use `supports(DriverInterface::FEATURE_CTE)` instead
+     */
+    public function supportsCTEs(): bool
+    {
+        deprecationWarning('Feature support checks are now implemented by `supports()` with FEATURE_* constants.');
+
+        return $this->supports(static::FEATURE_CTE);
+    }
+
+    /**
+     * Returns true if the connected server supports window functions.
+     *
+     * @return bool
+     * @deprecated 4.3.0 Use `supports(DriverInterface::FEATURE_WINDOW)` instead
+     */
+    public function supportsWindowFunctions(): bool
+    {
+        deprecationWarning('Feature support checks are now implemented by `supports()` with FEATURE_* constants.');
+
+        return $this->supports(static::FEATURE_WINDOW);
+    }
+}
diff --git a/vendor/cakephp/database/Driver/Sqlserver.php b/vendor/cakephp/database/Driver/Sqlserver.php
new file mode 100644
index 0000000..a0dc2ec
--- /dev/null
+++ b/vendor/cakephp/database/Driver/Sqlserver.php
@@ -0,0 +1,569 @@
+
+     */
+    protected $_baseConfig = [
+        'host' => 'localhost\SQLEXPRESS',
+        'username' => '',
+        'password' => '',
+        'database' => 'cake',
+        'port' => '',
+        // PDO::SQLSRV_ENCODING_UTF8
+        'encoding' => 65001,
+        'flags' => [],
+        'init' => [],
+        'settings' => [],
+        'attributes' => [],
+        'app' => null,
+        'connectionPooling' => null,
+        'failoverPartner' => null,
+        'loginTimeout' => null,
+        'multiSubnetFailover' => null,
+        'encrypt' => null,
+        'trustServerCertificate' => null,
+    ];
+
+    /**
+     * The schema dialect class for this driver
+     *
+     * @var \Cake\Database\Schema\SqlserverSchemaDialect|null
+     */
+    protected $_schemaDialect;
+
+    /**
+     * String used to start a database identifier quoting to make it safe
+     *
+     * @var string
+     */
+    protected $_startQuote = '[';
+
+    /**
+     * String used to end a database identifier quoting to make it safe
+     *
+     * @var string
+     */
+    protected $_endQuote = ']';
+
+    /**
+     * Establishes a connection to the database server.
+     *
+     * Please note that the PDO::ATTR_PERSISTENT attribute is not supported by
+     * the SQL Server PHP PDO drivers.  As a result you cannot use the
+     * persistent config option when connecting to a SQL Server  (for more
+     * information see: https://github.com/Microsoft/msphpsql/issues/65).
+     *
+     * @throws \InvalidArgumentException if an unsupported setting is in the driver config
+     * @return bool true on success
+     */
+    public function connect(): bool
+    {
+        if ($this->_connection) {
+            return true;
+        }
+        $config = $this->_config;
+
+        if (isset($config['persistent']) && $config['persistent']) {
+            throw new InvalidArgumentException(
+                'Config setting "persistent" cannot be set to true, '
+                . 'as the Sqlserver PDO driver does not support PDO::ATTR_PERSISTENT'
+            );
+        }
+
+        $config['flags'] += [
+            PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
+        ];
+
+        if (!empty($config['encoding'])) {
+            $config['flags'][PDO::SQLSRV_ATTR_ENCODING] = $config['encoding'];
+        }
+        $port = '';
+        if ($config['port']) {
+            $port = ',' . $config['port'];
+        }
+
+        $dsn = "sqlsrv:Server={$config['host']}{$port};Database={$config['database']};MultipleActiveResultSets=false";
+        if ($config['app'] !== null) {
+            $dsn .= ";APP={$config['app']}";
+        }
+        if ($config['connectionPooling'] !== null) {
+            $dsn .= ";ConnectionPooling={$config['connectionPooling']}";
+        }
+        if ($config['failoverPartner'] !== null) {
+            $dsn .= ";Failover_Partner={$config['failoverPartner']}";
+        }
+        if ($config['loginTimeout'] !== null) {
+            $dsn .= ";LoginTimeout={$config['loginTimeout']}";
+        }
+        if ($config['multiSubnetFailover'] !== null) {
+            $dsn .= ";MultiSubnetFailover={$config['multiSubnetFailover']}";
+        }
+        if ($config['encrypt'] !== null) {
+            $dsn .= ";Encrypt={$config['encrypt']}";
+        }
+        if ($config['trustServerCertificate'] !== null) {
+            $dsn .= ";TrustServerCertificate={$config['trustServerCertificate']}";
+        }
+        $this->_connect($dsn, $config);
+
+        $connection = $this->getConnection();
+        if (!empty($config['init'])) {
+            foreach ((array)$config['init'] as $command) {
+                $connection->exec($command);
+            }
+        }
+        if (!empty($config['settings']) && is_array($config['settings'])) {
+            foreach ($config['settings'] as $key => $value) {
+                $connection->exec("SET {$key} {$value}");
+            }
+        }
+        if (!empty($config['attributes']) && is_array($config['attributes'])) {
+            foreach ($config['attributes'] as $key => $value) {
+                $connection->setAttribute($key, $value);
+            }
+        }
+
+        return true;
+    }
+
+    /**
+     * Returns whether PHP is able to use this driver for connecting to database
+     *
+     * @return bool true if it is valid to use this driver
+     */
+    public function enabled(): bool
+    {
+        return in_array('sqlsrv', PDO::getAvailableDrivers(), true);
+    }
+
+    /**
+     * Prepares a sql statement to be executed
+     *
+     * @param \Cake\Database\Query|string $query The query to prepare.
+     * @return \Cake\Database\StatementInterface
+     */
+    public function prepare($query): StatementInterface
+    {
+        $this->connect();
+
+        $sql = $query;
+        $options = [
+            PDO::ATTR_CURSOR => PDO::CURSOR_SCROLL,
+            PDO::SQLSRV_ATTR_CURSOR_SCROLL_TYPE => PDO::SQLSRV_CURSOR_BUFFERED,
+        ];
+        if ($query instanceof Query) {
+            $sql = $query->sql();
+            if (count($query->getValueBinder()->bindings()) > 2100) {
+                throw new InvalidArgumentException(
+                    'Exceeded maximum number of parameters (2100) for prepared statements in Sql Server. ' .
+                    'This is probably due to a very large WHERE IN () clause which generates a parameter ' .
+                    'for each value in the array. ' .
+                    'If using an Association, try changing the `strategy` from select to subquery.'
+                );
+            }
+
+            if (!$query->isBufferedResultsEnabled()) {
+                $options = [];
+            }
+        }
+
+        /** @psalm-suppress PossiblyInvalidArgument */
+        $statement = $this->_connection->prepare($sql, $options);
+
+        return new SqlserverStatement($statement, $this);
+    }
+
+    /**
+     * @inheritDoc
+     */
+    public function savePointSQL($name): string
+    {
+        return 'SAVE TRANSACTION t' . $name;
+    }
+
+    /**
+     * @inheritDoc
+     */
+    public function releaseSavePointSQL($name): string
+    {
+        // SQLServer has no release save point operation.
+        return '';
+    }
+
+    /**
+     * @inheritDoc
+     */
+    public function rollbackSavePointSQL($name): string
+    {
+        return 'ROLLBACK TRANSACTION t' . $name;
+    }
+
+    /**
+     * @inheritDoc
+     */
+    public function disableForeignKeySQL(): string
+    {
+        return 'EXEC sp_MSforeachtable "ALTER TABLE ? NOCHECK CONSTRAINT all"';
+    }
+
+    /**
+     * @inheritDoc
+     */
+    public function enableForeignKeySQL(): string
+    {
+        return 'EXEC sp_MSforeachtable "ALTER TABLE ? WITH CHECK CHECK CONSTRAINT all"';
+    }
+
+    /**
+     * @inheritDoc
+     */
+    public function supports(string $feature): bool
+    {
+        switch ($feature) {
+            case static::FEATURE_CTE:
+            case static::FEATURE_TRUNCATE_WITH_CONSTRAINTS:
+            case static::FEATURE_WINDOW:
+                return true;
+
+            case static::FEATURE_QUOTE:
+                $this->connect();
+
+                return $this->_connection->getAttribute(PDO::ATTR_DRIVER_NAME) !== 'odbc';
+        }
+
+        return parent::supports($feature);
+    }
+
+    /**
+     * @inheritDoc
+     */
+    public function supportsDynamicConstraints(): bool
+    {
+        return true;
+    }
+
+    /**
+     * @inheritDoc
+     */
+    public function schemaDialect(): SchemaDialect
+    {
+        if ($this->_schemaDialect === null) {
+            $this->_schemaDialect = new SqlserverSchemaDialect($this);
+        }
+
+        return $this->_schemaDialect;
+    }
+
+    /**
+     * {@inheritDoc}
+     *
+     * @return \Cake\Database\SqlserverCompiler
+     */
+    public function newCompiler(): QueryCompiler
+    {
+        return new SqlserverCompiler();
+    }
+
+    /**
+     * @inheritDoc
+     */
+    protected function _selectQueryTranslator(Query $query): Query
+    {
+        $limit = $query->clause('limit');
+        $offset = $query->clause('offset');
+
+        if ($limit && $offset === null) {
+            $query->modifier(['_auto_top_' => sprintf('TOP %d', $limit)]);
+        }
+
+        if ($offset !== null && !$query->clause('order')) {
+            $query->order($query->newExpr()->add('(SELECT NULL)'));
+        }
+
+        if ($this->version() < 11 && $offset !== null) {
+            return $this->_pagingSubquery($query, $limit, $offset);
+        }
+
+        return $this->_transformDistinct($query);
+    }
+
+    /**
+     * Generate a paging subquery for older versions of SQLserver.
+     *
+     * Prior to SQLServer 2012 there was no equivalent to LIMIT OFFSET, so a subquery must
+     * be used.
+     *
+     * @param \Cake\Database\Query $original The query to wrap in a subquery.
+     * @param int|null $limit The number of rows to fetch.
+     * @param int|null $offset The number of rows to offset.
+     * @return \Cake\Database\Query Modified query object.
+     */
+    protected function _pagingSubquery(Query $original, ?int $limit, ?int $offset): Query
+    {
+        $field = '_cake_paging_._cake_page_rownum_';
+
+        if ($original->clause('order')) {
+            // SQL server does not support column aliases in OVER clauses.  But
+            // the only practical way to specify the use of calculated columns
+            // is with their alias.  So substitute the select SQL in place of
+            // any column aliases for those entries in the order clause.
+            $select = $original->clause('select');
+            $order = new OrderByExpression();
+            $original
+                ->clause('order')
+                ->iterateParts(function ($direction, $orderBy) use ($select, $order) {
+                    $key = $orderBy;
+                    if (
+                        isset($select[$orderBy]) &&
+                        $select[$orderBy] instanceof ExpressionInterface
+                    ) {
+                        $order->add(new OrderClauseExpression($select[$orderBy], $direction));
+                    } else {
+                        $order->add([$key => $direction]);
+                    }
+
+                    // Leave original order clause unchanged.
+                    return $orderBy;
+                });
+        } else {
+            $order = new OrderByExpression('(SELECT NULL)');
+        }
+
+        $query = clone $original;
+        $query->select([
+                '_cake_page_rownum_' => new UnaryExpression('ROW_NUMBER() OVER', $order),
+            ])->limit(null)
+            ->offset(null)
+            ->order([], true);
+
+        $outer = new Query($query->getConnection());
+        $outer->select('*')
+            ->from(['_cake_paging_' => $query]);
+
+        if ($offset) {
+            $outer->where(["$field > " . $offset]);
+        }
+        if ($limit) {
+            $value = (int)$offset + $limit;
+            $outer->where(["$field <= $value"]);
+        }
+
+        // Decorate the original query as that is what the
+        // end developer will be calling execute() on originally.
+        $original->decorateResults(function ($row) {
+            if (isset($row['_cake_page_rownum_'])) {
+                unset($row['_cake_page_rownum_']);
+            }
+
+            return $row;
+        });
+
+        return $outer;
+    }
+
+    /**
+     * @inheritDoc
+     */
+    protected function _transformDistinct(Query $query): Query
+    {
+        if (!is_array($query->clause('distinct'))) {
+            return $query;
+        }
+
+        $original = $query;
+        $query = clone $original;
+
+        $distinct = $query->clause('distinct');
+        $query->distinct(false);
+
+        $order = new OrderByExpression($distinct);
+        $query
+            ->select(function ($q) use ($distinct, $order) {
+                $over = $q->newExpr('ROW_NUMBER() OVER')
+                    ->add('(PARTITION BY')
+                    ->add($q->newExpr()->add($distinct)->setConjunction(','))
+                    ->add($order)
+                    ->add(')')
+                    ->setConjunction(' ');
+
+                return [
+                    '_cake_distinct_pivot_' => $over,
+                ];
+            })
+            ->limit(null)
+            ->offset(null)
+            ->order([], true);
+
+        $outer = new Query($query->getConnection());
+        $outer->select('*')
+            ->from(['_cake_distinct_' => $query])
+            ->where(['_cake_distinct_pivot_' => 1]);
+
+        // Decorate the original query as that is what the
+        // end developer will be calling execute() on originally.
+        $original->decorateResults(function ($row) {
+            if (isset($row['_cake_distinct_pivot_'])) {
+                unset($row['_cake_distinct_pivot_']);
+            }
+
+            return $row;
+        });
+
+        return $outer;
+    }
+
+    /**
+     * @inheritDoc
+     */
+    protected function _expressionTranslators(): array
+    {
+        return [
+            FunctionExpression::class => '_transformFunctionExpression',
+            TupleComparison::class => '_transformTupleComparison',
+        ];
+    }
+
+    /**
+     * Receives a FunctionExpression and changes it so that it conforms to this
+     * SQL dialect.
+     *
+     * @param \Cake\Database\Expression\FunctionExpression $expression The function expression to convert to TSQL.
+     * @return void
+     */
+    protected function _transformFunctionExpression(FunctionExpression $expression): void
+    {
+        switch ($expression->getName()) {
+            case 'CONCAT':
+                // CONCAT function is expressed as exp1 + exp2
+                $expression->setName('')->setConjunction(' +');
+                break;
+            case 'DATEDIFF':
+                /** @var bool $hasDay */
+                $hasDay = false;
+                $visitor = function ($value) use (&$hasDay) {
+                    if ($value === 'day') {
+                        $hasDay = true;
+                    }
+
+                    return $value;
+                };
+                $expression->iterateParts($visitor);
+
+                if (!$hasDay) {
+                    $expression->add(['day' => 'literal'], [], true);
+                }
+                break;
+            case 'CURRENT_DATE':
+                $time = new FunctionExpression('GETUTCDATE');
+                $expression->setName('CONVERT')->add(['date' => 'literal', $time]);
+                break;
+            case 'CURRENT_TIME':
+                $time = new FunctionExpression('GETUTCDATE');
+                $expression->setName('CONVERT')->add(['time' => 'literal', $time]);
+                break;
+            case 'NOW':
+                $expression->setName('GETUTCDATE');
+                break;
+            case 'EXTRACT':
+                $expression->setName('DATEPART')->setConjunction(' ,');
+                break;
+            case 'DATE_ADD':
+                $params = [];
+                $visitor = function ($p, $key) use (&$params) {
+                    if ($key === 0) {
+                        $params[2] = $p;
+                    } else {
+                        $valueUnit = explode(' ', $p);
+                        $params[0] = rtrim($valueUnit[1], 's');
+                        $params[1] = $valueUnit[0];
+                    }
+
+                    return $p;
+                };
+                $manipulator = function ($p, $key) use (&$params) {
+                    return $params[$key];
+                };
+
+                $expression
+                    ->setName('DATEADD')
+                    ->setConjunction(',')
+                    ->iterateParts($visitor)
+                    ->iterateParts($manipulator)
+                    ->add([$params[2] => 'literal']);
+                break;
+            case 'DAYOFWEEK':
+                $expression
+                    ->setName('DATEPART')
+                    ->setConjunction(' ')
+                    ->add(['weekday, ' => 'literal'], [], true);
+                break;
+            case 'SUBSTR':
+                $expression->setName('SUBSTRING');
+                if (count($expression) < 4) {
+                    $params = [];
+                    $expression
+                        ->iterateParts(function ($p) use (&$params) {
+                            return $params[] = $p;
+                        })
+                        ->add([new FunctionExpression('LEN', [$params[0]]), ['string']]);
+                }
+
+                break;
+        }
+    }
+}
diff --git a/vendor/cakephp/database/Driver/TupleComparisonTranslatorTrait.php b/vendor/cakephp/database/Driver/TupleComparisonTranslatorTrait.php
new file mode 100644
index 0000000..e21a79d
--- /dev/null
+++ b/vendor/cakephp/database/Driver/TupleComparisonTranslatorTrait.php
@@ -0,0 +1,113 @@
+getField();
+
+        if (!is_array($fields)) {
+            return;
+        }
+
+        $operator = strtoupper($expression->getOperator());
+        if (!in_array($operator, ['IN', '='])) {
+            throw new RuntimeException(
+                sprintf(
+                    'Tuple comparison transform only supports the `IN` and `=` operators, `%s` given.',
+                    $operator
+                )
+            );
+        }
+
+        $value = $expression->getValue();
+        $true = new QueryExpression('1');
+
+        if ($value instanceof Query) {
+            $selected = array_values($value->clause('select'));
+            foreach ($fields as $i => $field) {
+                $value->andWhere([$field => new IdentifierExpression($selected[$i])]);
+            }
+            $value->select($true, true);
+            $expression->setField($true);
+            $expression->setOperator('=');
+
+            return;
+        }
+
+        $type = $expression->getType();
+        if ($type) {
+            /** @var array $typeMap */
+            $typeMap = array_combine($fields, $type) ?: [];
+        } else {
+            $typeMap = [];
+        }
+
+        $surrogate = $query->getConnection()
+            ->selectQuery($true);
+
+        if (!is_array(current($value))) {
+            $value = [$value];
+        }
+
+        $conditions = ['OR' => []];
+        foreach ($value as $tuple) {
+            $item = [];
+            foreach (array_values($tuple) as $i => $value2) {
+                $item[] = [$fields[$i] => $value2];
+            }
+            $conditions['OR'][] = $item;
+        }
+        $surrogate->where($conditions, $typeMap);
+
+        $expression->setField($true);
+        $expression->setValue($surrogate);
+        $expression->setOperator('=');
+    }
+}
diff --git a/vendor/cakephp/database/DriverInterface.php b/vendor/cakephp/database/DriverInterface.php
new file mode 100644
index 0000000..914d6b7
--- /dev/null
+++ b/vendor/cakephp/database/DriverInterface.php
@@ -0,0 +1,336 @@
+ $types Associative array of type names used to bind values to query
+     * @return $this
+     * @see \Cake\Database\Query::where()
+     */
+    public function filter($conditions, array $types = [])
+    {
+        if ($this->filter === null) {
+            $this->filter = new QueryExpression();
+        }
+
+        if ($conditions instanceof Closure) {
+            $conditions = $conditions(new QueryExpression());
+        }
+
+        $this->filter->add($conditions, $types);
+
+        return $this;
+    }
+
+    /**
+     * Adds an empty `OVER()` window expression or a named window epression.
+     *
+     * @param string|null $name Window name
+     * @return $this
+     */
+    public function over(?string $name = null)
+    {
+        if ($this->window === null) {
+            $this->window = new WindowExpression();
+        }
+        if ($name) {
+            // Set name manually in case this was chained from FunctionsBuilder wrapper
+            $this->window->name($name);
+        }
+
+        return $this;
+    }
+
+    /**
+     * @inheritDoc
+     */
+    public function partition($partitions)
+    {
+        $this->over();
+        $this->window->partition($partitions);
+
+        return $this;
+    }
+
+    /**
+     * @inheritDoc
+     */
+    public function order($fields)
+    {
+        $this->over();
+        $this->window->order($fields);
+
+        return $this;
+    }
+
+    /**
+     * @inheritDoc
+     */
+    public function range($start, $end = 0)
+    {
+        $this->over();
+        $this->window->range($start, $end);
+
+        return $this;
+    }
+
+    /**
+     * @inheritDoc
+     */
+    public function rows(?int $start, ?int $end = 0)
+    {
+        $this->over();
+        $this->window->rows($start, $end);
+
+        return $this;
+    }
+
+    /**
+     * @inheritDoc
+     */
+    public function groups(?int $start, ?int $end = 0)
+    {
+        $this->over();
+        $this->window->groups($start, $end);
+
+        return $this;
+    }
+
+    /**
+     * @inheritDoc
+     */
+    public function frame(
+        string $type,
+        $startOffset,
+        string $startDirection,
+        $endOffset,
+        string $endDirection
+    ) {
+        $this->over();
+        $this->window->frame($type, $startOffset, $startDirection, $endOffset, $endDirection);
+
+        return $this;
+    }
+
+    /**
+     * @inheritDoc
+     */
+    public function excludeCurrent()
+    {
+        $this->over();
+        $this->window->excludeCurrent();
+
+        return $this;
+    }
+
+    /**
+     * @inheritDoc
+     */
+    public function excludeGroup()
+    {
+        $this->over();
+        $this->window->excludeGroup();
+
+        return $this;
+    }
+
+    /**
+     * @inheritDoc
+     */
+    public function excludeTies()
+    {
+        $this->over();
+        $this->window->excludeTies();
+
+        return $this;
+    }
+
+    /**
+     * @inheritDoc
+     */
+    public function sql(ValueBinder $binder): string
+    {
+        $sql = parent::sql($binder);
+        if ($this->filter !== null) {
+            $sql .= ' FILTER (WHERE ' . $this->filter->sql($binder) . ')';
+        }
+        if ($this->window !== null) {
+            if ($this->window->isNamedOnly()) {
+                $sql .= ' OVER ' . $this->window->sql($binder);
+            } else {
+                $sql .= ' OVER (' . $this->window->sql($binder) . ')';
+            }
+        }
+
+        return $sql;
+    }
+
+    /**
+     * @inheritDoc
+     */
+    public function traverse(Closure $callback)
+    {
+        parent::traverse($callback);
+        if ($this->filter !== null) {
+            $callback($this->filter);
+            $this->filter->traverse($callback);
+        }
+        if ($this->window !== null) {
+            $callback($this->window);
+            $this->window->traverse($callback);
+        }
+
+        return $this;
+    }
+
+    /**
+     * @inheritDoc
+     */
+    public function count(): int
+    {
+        $count = parent::count();
+        if ($this->window !== null) {
+            $count = $count + 1;
+        }
+
+        return $count;
+    }
+
+    /**
+     * Clone this object and its subtree of expressions.
+     *
+     * @return void
+     */
+    public function __clone()
+    {
+        parent::__clone();
+        if ($this->filter !== null) {
+            $this->filter = clone $this->filter;
+        }
+        if ($this->window !== null) {
+            $this->window = clone $this->window;
+        }
+    }
+}
diff --git a/vendor/cakephp/database/Expression/BetweenExpression.php b/vendor/cakephp/database/Expression/BetweenExpression.php
new file mode 100644
index 0000000..3466147
--- /dev/null
+++ b/vendor/cakephp/database/Expression/BetweenExpression.php
@@ -0,0 +1,144 @@
+_castToExpression($from, $type);
+            $to = $this->_castToExpression($to, $type);
+        }
+
+        $this->_field = $field;
+        $this->_from = $from;
+        $this->_to = $to;
+        $this->_type = $type;
+    }
+
+    /**
+     * @inheritDoc
+     */
+    public function sql(ValueBinder $binder): string
+    {
+        $parts = [
+            'from' => $this->_from,
+            'to' => $this->_to,
+        ];
+
+        /** @var \Cake\Database\ExpressionInterface|string $field */
+        $field = $this->_field;
+        if ($field instanceof ExpressionInterface) {
+            $field = $field->sql($binder);
+        }
+
+        foreach ($parts as $name => $part) {
+            if ($part instanceof ExpressionInterface) {
+                $parts[$name] = $part->sql($binder);
+                continue;
+            }
+            $parts[$name] = $this->_bindValue($part, $binder, $this->_type);
+        }
+
+        return sprintf('%s BETWEEN %s AND %s', $field, $parts['from'], $parts['to']);
+    }
+
+    /**
+     * @inheritDoc
+     */
+    public function traverse(Closure $callback)
+    {
+        foreach ([$this->_field, $this->_from, $this->_to] as $part) {
+            if ($part instanceof ExpressionInterface) {
+                $callback($part);
+            }
+        }
+
+        return $this;
+    }
+
+    /**
+     * Registers a value in the placeholder generator and returns the generated placeholder
+     *
+     * @param mixed $value The value to bind
+     * @param \Cake\Database\ValueBinder $binder The value binder to use
+     * @param string $type The type of $value
+     * @return string generated placeholder
+     */
+    protected function _bindValue($value, $binder, $type): string
+    {
+        $placeholder = $binder->placeholder('c');
+        $binder->bind($placeholder, $value, $type);
+
+        return $placeholder;
+    }
+
+    /**
+     * Do a deep clone of this expression.
+     *
+     * @return void
+     */
+    public function __clone()
+    {
+        foreach (['_field', '_from', '_to'] as $part) {
+            if ($this->{$part} instanceof ExpressionInterface) {
+                $this->{$part} = clone $this->{$part};
+            }
+        }
+    }
+}
diff --git a/vendor/cakephp/database/Expression/CaseExpression.php b/vendor/cakephp/database/Expression/CaseExpression.php
new file mode 100644
index 0000000..864a3bc
--- /dev/null
+++ b/vendor/cakephp/database/Expression/CaseExpression.php
@@ -0,0 +1,251 @@
+ :value"
+     *
+     * @var array
+     */
+    protected $_conditions = [];
+
+    /**
+     * Values that are associated with the conditions in the $_conditions array.
+     * Each value represents the 'true' value for the condition with the corresponding key.
+     *
+     * @var array
+     */
+    protected $_values = [];
+
+    /**
+     * The `ELSE` value for the case statement. If null then no `ELSE` will be included.
+     *
+     * @var \Cake\Database\ExpressionInterface|array|string|null
+     */
+    protected $_elseValue;
+
+    /**
+     * Constructs the case expression
+     *
+     * @param \Cake\Database\ExpressionInterface|array $conditions The conditions to test. Must be a ExpressionInterface
+     * instance, or an array of ExpressionInterface instances.
+     * @param \Cake\Database\ExpressionInterface|array $values Associative array of values to be associated with the
+     * conditions passed in $conditions. If there are more $values than $conditions,
+     * the last $value is used as the `ELSE` value.
+     * @param array $types Associative array of types to be associated with the values
+     * passed in $values
+     */
+    public function __construct($conditions = [], $values = [], $types = [])
+    {
+        $conditions = is_array($conditions) ? $conditions : [$conditions];
+        $values = is_array($values) ? $values : [$values];
+        $types = is_array($types) ? $types : [$types];
+
+        if (!empty($conditions)) {
+            $this->add($conditions, $values, $types);
+        }
+
+        if (count($values) > count($conditions)) {
+            end($values);
+            $key = key($values);
+            $this->elseValue($values[$key], $types[$key] ?? null);
+        }
+    }
+
+    /**
+     * Adds one or more conditions and their respective true values to the case object.
+     * Conditions must be a one dimensional array or a QueryExpression.
+     * The trueValues must be a similar structure, but may contain a string value.
+     *
+     * @param \Cake\Database\ExpressionInterface|array $conditions Must be a ExpressionInterface instance,
+     *   or an array of ExpressionInterface instances.
+     * @param \Cake\Database\ExpressionInterface|array $values Associative array of values of each condition
+     * @param array $types Associative array of types to be associated with the values
+     * @return $this
+     */
+    public function add($conditions = [], $values = [], $types = [])
+    {
+        $conditions = is_array($conditions) ? $conditions : [$conditions];
+        $values = is_array($values) ? $values : [$values];
+        $types = is_array($types) ? $types : [$types];
+
+        $this->_addExpressions($conditions, $values, $types);
+
+        return $this;
+    }
+
+    /**
+     * Iterates over the passed in conditions and ensures that there is a matching true value for each.
+     * If no matching true value, then it is defaulted to '1'.
+     *
+     * @param array $conditions Array of ExpressionInterface instances.
+     * @param array $values Associative array of values of each condition
+     * @param array $types Associative array of types to be associated with the values
+     * @return void
+     */
+    protected function _addExpressions(array $conditions, array $values, array $types): void
+    {
+        $rawValues = array_values($values);
+        $keyValues = array_keys($values);
+
+        foreach ($conditions as $k => $c) {
+            $numericKey = is_numeric($k);
+
+            if ($numericKey && empty($c)) {
+                continue;
+            }
+
+            if (!$c instanceof ExpressionInterface) {
+                continue;
+            }
+
+            $this->_conditions[] = $c;
+            $value = $rawValues[$k] ?? 1;
+
+            if ($value === 'literal') {
+                $value = $keyValues[$k];
+                $this->_values[] = $value;
+                continue;
+            }
+
+            if ($value === 'identifier') {
+                /** @var string $identifier */
+                $identifier = $keyValues[$k];
+                $value = new IdentifierExpression($identifier);
+                $this->_values[] = $value;
+                continue;
+            }
+
+            $type = $types[$k] ?? null;
+
+            if ($type !== null && !$value instanceof ExpressionInterface) {
+                $value = $this->_castToExpression($value, $type);
+            }
+
+            if ($value instanceof ExpressionInterface) {
+                $this->_values[] = $value;
+                continue;
+            }
+
+            $this->_values[] = ['value' => $value, 'type' => $type];
+        }
+    }
+
+    /**
+     * Sets the default value
+     *
+     * @param \Cake\Database\ExpressionInterface|array|string|null $value Value to set
+     * @param string|null $type Type of value
+     * @return void
+     */
+    public function elseValue($value = null, ?string $type = null): void
+    {
+        if (is_array($value)) {
+            end($value);
+            $value = key($value);
+        }
+
+        if ($value !== null && !$value instanceof ExpressionInterface) {
+            $value = $this->_castToExpression($value, $type);
+        }
+
+        if (!$value instanceof ExpressionInterface) {
+            $value = ['value' => $value, 'type' => $type];
+        }
+
+        $this->_elseValue = $value;
+    }
+
+    /**
+     * Compiles the relevant parts into sql
+     *
+     * @param \Cake\Database\ExpressionInterface|array|string $part The part to compile
+     * @param \Cake\Database\ValueBinder $binder Sql generator
+     * @return string
+     */
+    protected function _compile($part, ValueBinder $binder): string
+    {
+        if ($part instanceof ExpressionInterface) {
+            $part = $part->sql($binder);
+        } elseif (is_array($part)) {
+            $placeholder = $binder->placeholder('param');
+            $binder->bind($placeholder, $part['value'], $part['type']);
+            $part = $placeholder;
+        }
+
+        return $part;
+    }
+
+    /**
+     * Converts the Node into a SQL string fragment.
+     *
+     * @param \Cake\Database\ValueBinder $binder Placeholder generator object
+     * @return string
+     */
+    public function sql(ValueBinder $binder): string
+    {
+        $parts = [];
+        $parts[] = 'CASE';
+        foreach ($this->_conditions as $k => $part) {
+            $value = $this->_values[$k];
+            $parts[] = 'WHEN ' . $this->_compile($part, $binder) . ' THEN ' . $this->_compile($value, $binder);
+        }
+        if ($this->_elseValue !== null) {
+            $parts[] = 'ELSE';
+            $parts[] = $this->_compile($this->_elseValue, $binder);
+        }
+        $parts[] = 'END';
+
+        return implode(' ', $parts);
+    }
+
+    /**
+     * @inheritDoc
+     */
+    public function traverse(Closure $callback)
+    {
+        foreach (['_conditions', '_values'] as $part) {
+            foreach ($this->{$part} as $c) {
+                if ($c instanceof ExpressionInterface) {
+                    $callback($c);
+                    $c->traverse($callback);
+                }
+            }
+        }
+        if ($this->_elseValue instanceof ExpressionInterface) {
+            $callback($this->_elseValue);
+            $this->_elseValue->traverse($callback);
+        }
+
+        return $this;
+    }
+}
diff --git a/vendor/cakephp/database/Expression/CaseExpressionTrait.php b/vendor/cakephp/database/Expression/CaseExpressionTrait.php
new file mode 100644
index 0000000..1994ec9
--- /dev/null
+++ b/vendor/cakephp/database/Expression/CaseExpressionTrait.php
@@ -0,0 +1,109 @@
+_typeMap !== null &&
+            $value instanceof IdentifierExpression
+        ) {
+            $type = $this->_typeMap->type($value->getIdentifier());
+        } elseif ($value instanceof TypedResultInterface) {
+            $type = $value->getReturnType();
+        }
+
+        return $type;
+    }
+
+    /**
+     * Compiles a nullable value to SQL.
+     *
+     * @param \Cake\Database\ValueBinder $binder The value binder to use.
+     * @param \Cake\Database\ExpressionInterface|object|scalar|null $value The value to compile.
+     * @param string|null $type The value type.
+     * @return string
+     */
+    protected function compileNullableValue(ValueBinder $binder, $value, ?string $type = null): string
+    {
+        if (
+            $type !== null &&
+            !($value instanceof ExpressionInterface)
+        ) {
+            $value = $this->_castToExpression($value, $type);
+        }
+
+        if ($value === null) {
+            $value = 'NULL';
+        } elseif ($value instanceof Query) {
+            $value = sprintf('(%s)', $value->sql($binder));
+        } elseif ($value instanceof ExpressionInterface) {
+            $value = $value->sql($binder);
+        } else {
+            $placeholder = $binder->placeholder('c');
+            $binder->bind($placeholder, $value, $type);
+            $value = $placeholder;
+        }
+
+        return $value;
+    }
+}
diff --git a/vendor/cakephp/database/Expression/CaseStatementExpression.php b/vendor/cakephp/database/Expression/CaseStatementExpression.php
new file mode 100644
index 0000000..8e6ebd1
--- /dev/null
+++ b/vendor/cakephp/database/Expression/CaseStatementExpression.php
@@ -0,0 +1,597 @@
+
+     */
+    protected $validClauseNames = [
+        'value',
+        'when',
+        'else',
+    ];
+
+    /**
+     * Whether this is a simple case expression.
+     *
+     * @var bool
+     */
+    protected $isSimpleVariant = false;
+
+    /**
+     * The case value.
+     *
+     * @var \Cake\Database\ExpressionInterface|object|scalar|null
+     */
+    protected $value = null;
+
+    /**
+     * The case value type.
+     *
+     * @var string|null
+     */
+    protected $valueType = null;
+
+    /**
+     * The `WHEN ... THEN ...` expressions.
+     *
+     * @var array<\Cake\Database\Expression\WhenThenExpression>
+     */
+    protected $when = [];
+
+    /**
+     * Buffer that holds values and types for use with `then()`.
+     *
+     * @var array|null
+     */
+    protected $whenBuffer = null;
+
+    /**
+     * The else part result value.
+     *
+     * @var \Cake\Database\ExpressionInterface|object|scalar|null
+     */
+    protected $else = null;
+
+    /**
+     * The else part result type.
+     *
+     * @var string|null
+     */
+    protected $elseType = null;
+
+    /**
+     * The return type.
+     *
+     * @var string|null
+     */
+    protected $returnType = null;
+
+    /**
+     * Constructor.
+     *
+     * When a value is set, the syntax generated is
+     * `CASE case_value WHEN when_value ... END` (simple case),
+     * where the `when_value`'s are compared against the
+     * `case_value`.
+     *
+     * When no value is set, the syntax generated is
+     * `CASE WHEN when_conditions ... END` (searched case),
+     * where the conditions hold the comparisons.
+     *
+     * Note that `null` is a valid case value, and thus should
+     * only be passed if you actually want to create the simple
+     * case expression variant!
+     *
+     * @param \Cake\Database\ExpressionInterface|object|scalar|null $value The case value.
+     * @param string|null $type The case value type. If no type is provided, the type will be tried to be inferred
+     *  from the value.
+     */
+    public function __construct($value = null, ?string $type = null)
+    {
+        if (func_num_args() > 0) {
+            if (
+                $value !== null &&
+                !is_scalar($value) &&
+                !(is_object($value) && !($value instanceof Closure))
+            ) {
+                throw new InvalidArgumentException(sprintf(
+                    'The `$value` argument must be either `null`, a scalar value, an object, ' .
+                    'or an instance of `\%s`, `%s` given.',
+                    ExpressionInterface::class,
+                    getTypeName($value)
+                ));
+            }
+
+            $this->value = $value;
+
+            if (
+                $value !== null &&
+                $type === null &&
+                !($value instanceof ExpressionInterface)
+            ) {
+                $type = $this->inferType($value);
+            }
+            $this->valueType = $type;
+
+            $this->isSimpleVariant = true;
+        }
+    }
+
+    /**
+     * Sets the `WHEN` value for a `WHEN ... THEN ...` expression, or a
+     * self-contained expression that holds both the value for `WHEN`
+     * and the value for `THEN`.
+     *
+     * ### Order based syntax
+     *
+     * When passing a value other than a self-contained
+     * `\Cake\Database\Expression\WhenThenExpression`,
+     * instance, the `WHEN ... THEN ...` statement must be closed off with
+     * a call to `then()` before invoking `when()` again or `else()`:
+     *
+     * ```
+     * $queryExpression
+     *     ->case($query->identifier('Table.column'))
+     *     ->when(true)
+     *     ->then('Yes')
+     *     ->when(false)
+     *     ->then('No')
+     *     ->else('Maybe');
+     * ```
+     *
+     * ### Self-contained expressions
+     *
+     * When passing an instance of `\Cake\Database\Expression\WhenThenExpression`,
+     * being it directly, or via a callable, then there is no need to close
+     * using `then()` on this object, instead the statement will be closed
+     * on the `\Cake\Database\Expression\WhenThenExpression`
+     * object using
+     * `\Cake\Database\Expression\WhenThenExpression::then()`.
+     *
+     * Callables will receive an instance of `\Cake\Database\Expression\WhenThenExpression`,
+     * and must return one, being it the same object, or a custom one:
+     *
+     * ```
+     * $queryExpression
+     *     ->case()
+     *     ->when(function (\Cake\Database\Expression\WhenThenExpression $whenThen) {
+     *         return $whenThen
+     *             ->when(['Table.column' => true])
+     *             ->then('Yes');
+     *     })
+     *     ->when(function (\Cake\Database\Expression\WhenThenExpression $whenThen) {
+     *         return $whenThen
+     *             ->when(['Table.column' => false])
+     *             ->then('No');
+     *     })
+     *     ->else('Maybe');
+     * ```
+     *
+     * ### Type handling
+     *
+     * The types provided via the `$type` argument will be merged with the
+     * type map set for this expression. When using callables for `$when`,
+     * the `\Cake\Database\Expression\WhenThenExpression`
+     * instance received by the callables will inherit that type map, however
+     * the types passed here will _not_ be merged in case of using callables,
+     * instead the types must be passed in
+     * `\Cake\Database\Expression\WhenThenExpression::when()`:
+     *
+     * ```
+     * $queryExpression
+     *     ->case()
+     *     ->when(function (\Cake\Database\Expression\WhenThenExpression $whenThen) {
+     *         return $whenThen
+     *             ->when(['unmapped_column' => true], ['unmapped_column' => 'bool'])
+     *             ->then('Yes');
+     *     })
+     *     ->when(function (\Cake\Database\Expression\WhenThenExpression $whenThen) {
+     *         return $whenThen
+     *             ->when(['unmapped_column' => false], ['unmapped_column' => 'bool'])
+     *             ->then('No');
+     *     })
+     *     ->else('Maybe');
+     * ```
+     *
+     * ### User data safety
+     *
+     * When passing user data, be aware that allowing a user defined array
+     * to be passed, is a potential SQL injection vulnerability, as it
+     * allows for raw SQL to slip in!
+     *
+     * The following is _unsafe_ usage that must be avoided:
+     *
+     * ```
+     * $case
+     *      ->when($userData)
+     * ```
+     *
+     * A safe variant for the above would be to define a single type for
+     * the value:
+     *
+     * ```
+     * $case
+     *      ->when($userData, 'integer')
+     * ```
+     *
+     * This way an exception would be triggered when an array is passed for
+     * the value, thus preventing raw SQL from slipping in, and all other
+     * types of values would be forced to be bound as an integer.
+     *
+     * Another way to safely pass user data is when using a conditions
+     * array, and passing user data only on the value side of the array
+     * entries, which will cause them to be bound:
+     *
+     * ```
+     * $case
+     *      ->when([
+     *          'Table.column' => $userData,
+     *      ])
+     * ```
+     *
+     * Lastly, data can also be bound manually:
+     *
+     * ```
+     * $query
+     *      ->select([
+     *          'val' => $query->newExpr()
+     *              ->case()
+     *              ->when($query->newExpr(':userData'))
+     *              ->then(123)
+     *      ])
+     *      ->bind(':userData', $userData, 'integer')
+     * ```
+     *
+     * @param \Cake\Database\ExpressionInterface|\Closure|object|array|scalar $when The `WHEN` value. When using an
+     *  array of conditions, it must be compatible with `\Cake\Database\Query::where()`. Note that this argument is
+     *  _not_ completely safe for use with user data, as a user supplied array would allow for raw SQL to slip in! If
+     *  you plan to use user data, either pass a single type for the `$type` argument (which forces the `$when` value to
+     *  be a non-array, and then always binds the data), use a conditions array where the user data is only passed on
+     *  the value side of the array entries, or custom bindings!
+     * @param array|string|null $type The when value type. Either an associative array when using array style
+     *  conditions, or else a string. If no type is provided, the type will be tried to be inferred from the value.
+     * @return $this
+     * @throws \LogicException In case this a closing `then()` call is required before calling this method.
+     * @throws \LogicException In case the callable doesn't return an instance of
+     *  `\Cake\Database\Expression\WhenThenExpression`.
+     */
+    public function when($when, $type = null)
+    {
+        if ($this->whenBuffer !== null) {
+            throw new LogicException('Cannot call `when()` between `when()` and `then()`.');
+        }
+
+        if ($when instanceof Closure) {
+            $when = $when(new WhenThenExpression($this->getTypeMap()));
+            if (!($when instanceof WhenThenExpression)) {
+                throw new LogicException(sprintf(
+                    '`when()` callables must return an instance of `\%s`, `%s` given.',
+                    WhenThenExpression::class,
+                    getTypeName($when)
+                ));
+            }
+        }
+
+        if ($when instanceof WhenThenExpression) {
+            $this->when[] = $when;
+        } else {
+            $this->whenBuffer = ['when' => $when, 'type' => $type];
+        }
+
+        return $this;
+    }
+
+    /**
+     * Sets the `THEN` result value for the last `WHEN ... THEN ...`
+     * statement that was opened using `when()`.
+     *
+     * ### Order based syntax
+     *
+     * This method can only be invoked in case `when()` was previously
+     * used with a value other than a closure or an instance of
+     * `\Cake\Database\Expression\WhenThenExpression`:
+     *
+     * ```
+     * $case
+     *     ->when(['Table.column' => true])
+     *     ->then('Yes')
+     *     ->when(['Table.column' => false])
+     *     ->then('No')
+     *     ->else('Maybe');
+     * ```
+     *
+     * The following would all fail with an exception:
+     *
+     * ```
+     * $case
+     *     ->when(['Table.column' => true])
+     *     ->when(['Table.column' => false])
+     *     // ...
+     * ```
+     *
+     * ```
+     * $case
+     *     ->when(['Table.column' => true])
+     *     ->else('Maybe')
+     *     // ...
+     * ```
+     *
+     * ```
+     * $case
+     *     ->then('Yes')
+     *     // ...
+     * ```
+     *
+     * ```
+     * $case
+     *     ->when(['Table.column' => true])
+     *     ->then('Yes')
+     *     ->then('No')
+     *     // ...
+     * ```
+     *
+     * @param \Cake\Database\ExpressionInterface|object|scalar|null $result The result value.
+     * @param string|null $type The result type. If no type is provided, the type will be tried to be inferred from the
+     *  value.
+     * @return $this
+     * @throws \LogicException In case `when()` wasn't previously called with a value other than a closure or an
+     *  instance of `\Cake\Database\Expression\WhenThenExpression`.
+     */
+    public function then($result, ?string $type = null)
+    {
+        if ($this->whenBuffer === null) {
+            throw new LogicException('Cannot call `then()` before `when()`.');
+        }
+
+        $whenThen = (new WhenThenExpression($this->getTypeMap()))
+            ->when($this->whenBuffer['when'], $this->whenBuffer['type'])
+            ->then($result, $type);
+
+        $this->whenBuffer = null;
+
+        $this->when[] = $whenThen;
+
+        return $this;
+    }
+
+    /**
+     * Sets the `ELSE` result value.
+     *
+     * @param \Cake\Database\ExpressionInterface|object|scalar|null $result The result value.
+     * @param string|null $type The result type. If no type is provided, the type will be tried to be inferred from the
+     *  value.
+     * @return $this
+     * @throws \LogicException In case a closing `then()` call is required before calling this method.
+     * @throws \InvalidArgumentException In case the `$result` argument is neither a scalar value, nor an object, an
+     *  instance of `\Cake\Database\ExpressionInterface`, or `null`.
+     */
+    public function else($result, ?string $type = null)
+    {
+        if ($this->whenBuffer !== null) {
+            throw new LogicException('Cannot call `else()` between `when()` and `then()`.');
+        }
+
+        if (
+            $result !== null &&
+            !is_scalar($result) &&
+            !(is_object($result) && !($result instanceof Closure))
+        ) {
+            throw new InvalidArgumentException(sprintf(
+                'The `$result` argument must be either `null`, a scalar value, an object, ' .
+                'or an instance of `\%s`, `%s` given.',
+                ExpressionInterface::class,
+                getTypeName($result)
+            ));
+        }
+
+        if ($type === null) {
+            $type = $this->inferType($result);
+        }
+
+        $this->else = $result;
+        $this->elseType = $type;
+
+        return $this;
+    }
+
+    /**
+     * Returns the abstract type that this expression will return.
+     *
+     * If no type has been explicitly set via `setReturnType()`, this
+     * method will try to obtain the type from the result types of the
+     * `then()` and `else() `calls. All types must be identical in order
+     * for this to work, otherwise the type will default to `string`.
+     *
+     * @return string
+     * @see CaseStatementExpression::then()
+     */
+    public function getReturnType(): string
+    {
+        if ($this->returnType !== null) {
+            return $this->returnType;
+        }
+
+        $types = [];
+        foreach ($this->when as $when) {
+            $type = $when->getResultType();
+            if ($type !== null) {
+                $types[] = $type;
+            }
+        }
+
+        if ($this->elseType !== null) {
+            $types[] = $this->elseType;
+        }
+
+        $types = array_unique($types);
+        if (count($types) === 1) {
+            return $types[0];
+        }
+
+        return 'string';
+    }
+
+    /**
+     * Sets the abstract type that this expression will return.
+     *
+     * If no type is being explicitly set via this method, then the
+     * `getReturnType()` method will try to infer the type from the
+     * result types of the `then()` and `else() `calls.
+     *
+     * @param string $type The type name to use.
+     * @return $this
+     */
+    public function setReturnType(string $type)
+    {
+        $this->returnType = $type;
+
+        return $this;
+    }
+
+    /**
+     * Returns the available data for the given clause.
+     *
+     * ### Available clauses
+     *
+     * The following clause names are available:
+     *
+     * * `value`: The case value for a `CASE case_value WHEN ...` expression.
+     * * `when`: An array of `WHEN ... THEN ...` expressions.
+     * * `else`: The `ELSE` result value.
+     *
+     * @param string $clause The name of the clause to obtain.
+     * @return \Cake\Database\ExpressionInterface|object|array<\Cake\Database\Expression\WhenThenExpression>|scalar|null
+     * @throws \InvalidArgumentException In case the given clause name is invalid.
+     */
+    public function clause(string $clause)
+    {
+        if (!in_array($clause, $this->validClauseNames, true)) {
+            throw new InvalidArgumentException(
+                sprintf(
+                    'The `$clause` argument must be one of `%s`, the given value `%s` is invalid.',
+                    implode('`, `', $this->validClauseNames),
+                    $clause
+                )
+            );
+        }
+
+        return $this->{$clause};
+    }
+
+    /**
+     * @inheritDoc
+     */
+    public function sql(ValueBinder $binder): string
+    {
+        if ($this->whenBuffer !== null) {
+            throw new LogicException('Case expression has incomplete when clause. Missing `then()` after `when()`.');
+        }
+
+        if (empty($this->when)) {
+            throw new LogicException('Case expression must have at least one when statement.');
+        }
+
+        $value = '';
+        if ($this->isSimpleVariant) {
+            $value = $this->compileNullableValue($binder, $this->value, $this->valueType) . ' ';
+        }
+
+        $whenThenExpressions = [];
+        foreach ($this->when as $whenThen) {
+            $whenThenExpressions[] = $whenThen->sql($binder);
+        }
+        $whenThen = implode(' ', $whenThenExpressions);
+
+        $else = $this->compileNullableValue($binder, $this->else, $this->elseType);
+
+        return "CASE {$value}{$whenThen} ELSE $else END";
+    }
+
+    /**
+     * @inheritDoc
+     */
+    public function traverse(Closure $callback)
+    {
+        if ($this->whenBuffer !== null) {
+            throw new LogicException('Case expression has incomplete when clause. Missing `then()` after `when()`.');
+        }
+
+        if ($this->value instanceof ExpressionInterface) {
+            $callback($this->value);
+            $this->value->traverse($callback);
+        }
+
+        foreach ($this->when as $when) {
+            $callback($when);
+            $when->traverse($callback);
+        }
+
+        if ($this->else instanceof ExpressionInterface) {
+            $callback($this->else);
+            $this->else->traverse($callback);
+        }
+
+        return $this;
+    }
+
+    /**
+     * Clones the inner expression objects.
+     *
+     * @return void
+     */
+    public function __clone()
+    {
+        if ($this->whenBuffer !== null) {
+            throw new LogicException('Case expression has incomplete when clause. Missing `then()` after `when()`.');
+        }
+
+        if ($this->value instanceof ExpressionInterface) {
+            $this->value = clone $this->value;
+        }
+
+        foreach ($this->when as $key => $when) {
+            $this->when[$key] = clone $this->when[$key];
+        }
+
+        if ($this->else instanceof ExpressionInterface) {
+            $this->else = clone $this->else;
+        }
+    }
+}
diff --git a/vendor/cakephp/database/Expression/CommonTableExpression.php b/vendor/cakephp/database/Expression/CommonTableExpression.php
new file mode 100644
index 0000000..f3d359e
--- /dev/null
+++ b/vendor/cakephp/database/Expression/CommonTableExpression.php
@@ -0,0 +1,239 @@
+
+     */
+    protected $fields = [];
+
+    /**
+     * The CTE query definition.
+     *
+     * @var \Cake\Database\ExpressionInterface|null
+     */
+    protected $query;
+
+    /**
+     * Whether the CTE is materialized or not materialized.
+     *
+     * @var string|null
+     */
+    protected $materialized = null;
+
+    /**
+     * Whether the CTE is recursive.
+     *
+     * @var bool
+     */
+    protected $recursive = false;
+
+    /**
+     * Constructor.
+     *
+     * @param string $name The CTE name.
+     * @param \Cake\Database\ExpressionInterface|\Closure $query CTE query
+     */
+    public function __construct(string $name = '', $query = null)
+    {
+        $this->name = new IdentifierExpression($name);
+        if ($query) {
+            $this->query($query);
+        }
+    }
+
+    /**
+     * Sets the name of this CTE.
+     *
+     * This is the named you used to reference the expression
+     * in select, insert, etc queries.
+     *
+     * @param string $name The CTE name.
+     * @return $this
+     */
+    public function name(string $name)
+    {
+        $this->name = new IdentifierExpression($name);
+
+        return $this;
+    }
+
+    /**
+     * Sets the query for this CTE.
+     *
+     * @param \Cake\Database\ExpressionInterface|\Closure $query CTE query
+     * @return $this
+     */
+    public function query($query)
+    {
+        if ($query instanceof Closure) {
+            $query = $query();
+            if (!($query instanceof ExpressionInterface)) {
+                throw new RuntimeException(
+                    'You must return an `ExpressionInterface` from a Closure passed to `query()`.'
+                );
+            }
+        }
+        $this->query = $query;
+
+        return $this;
+    }
+
+    /**
+     * Adds one or more fields (arguments) to the CTE.
+     *
+     * @param \Cake\Database\Expression\IdentifierExpression|array<\Cake\Database\Expression\IdentifierExpression>|array|string $fields Field names
+     * @return $this
+     */
+    public function field($fields)
+    {
+        $fields = (array)$fields;
+        foreach ($fields as &$field) {
+            if (!($field instanceof IdentifierExpression)) {
+                $field = new IdentifierExpression($field);
+            }
+        }
+        $this->fields = array_merge($this->fields, $fields);
+
+        return $this;
+    }
+
+    /**
+     * Sets this CTE as materialized.
+     *
+     * @return $this
+     */
+    public function materialized()
+    {
+        $this->materialized = 'MATERIALIZED';
+
+        return $this;
+    }
+
+    /**
+     * Sets this CTE as not materialized.
+     *
+     * @return $this
+     */
+    public function notMaterialized()
+    {
+        $this->materialized = 'NOT MATERIALIZED';
+
+        return $this;
+    }
+
+    /**
+     * Gets whether this CTE is recursive.
+     *
+     * @return bool
+     */
+    public function isRecursive(): bool
+    {
+        return $this->recursive;
+    }
+
+    /**
+     * Sets this CTE as recursive.
+     *
+     * @return $this
+     */
+    public function recursive()
+    {
+        $this->recursive = true;
+
+        return $this;
+    }
+
+    /**
+     * @inheritDoc
+     */
+    public function sql(ValueBinder $binder): string
+    {
+        $fields = '';
+        if ($this->fields) {
+            $expressions = array_map(function (IdentifierExpression $e) use ($binder) {
+                return $e->sql($binder);
+            }, $this->fields);
+            $fields = sprintf('(%s)', implode(', ', $expressions));
+        }
+
+        $suffix = $this->materialized ? $this->materialized . ' ' : '';
+
+        return sprintf(
+            '%s%s AS %s(%s)',
+            $this->name->sql($binder),
+            $fields,
+            $suffix,
+            $this->query ? $this->query->sql($binder) : ''
+        );
+    }
+
+    /**
+     * @inheritDoc
+     */
+    public function traverse(Closure $callback)
+    {
+        $callback($this->name);
+        foreach ($this->fields as $field) {
+            $callback($field);
+            $field->traverse($callback);
+        }
+
+        if ($this->query) {
+            $callback($this->query);
+            $this->query->traverse($callback);
+        }
+
+        return $this;
+    }
+
+    /**
+     * Clones the inner expression objects.
+     *
+     * @return void
+     */
+    public function __clone()
+    {
+        $this->name = clone $this->name;
+        if ($this->query) {
+            $this->query = clone $this->query;
+        }
+
+        foreach ($this->fields as $key => $field) {
+            $this->fields[$key] = clone $field;
+        }
+    }
+}
diff --git a/vendor/cakephp/database/Expression/Comparison.php b/vendor/cakephp/database/Expression/Comparison.php
new file mode 100644
index 0000000..01bdbd5
--- /dev/null
+++ b/vendor/cakephp/database/Expression/Comparison.php
@@ -0,0 +1,7 @@
+
+     */
+    protected $_valueExpressions = [];
+
+    /**
+     * Constructor
+     *
+     * @param \Cake\Database\ExpressionInterface|string $field the field name to compare to a value
+     * @param mixed $value The value to be used in comparison
+     * @param string|null $type the type name used to cast the value
+     * @param string $operator the operator used for comparing field and value
+     */
+    public function __construct($field, $value, ?string $type = null, string $operator = '=')
+    {
+        $this->_type = $type;
+        $this->setField($field);
+        $this->setValue($value);
+        $this->_operator = $operator;
+    }
+
+    /**
+     * Sets the value
+     *
+     * @param mixed $value The value to compare
+     * @return void
+     */
+    public function setValue($value): void
+    {
+        $value = $this->_castToExpression($value, $this->_type);
+
+        $isMultiple = $this->_type && strpos($this->_type, '[]') !== false;
+        if ($isMultiple) {
+            [$value, $this->_valueExpressions] = $this->_collectExpressions($value);
+        }
+
+        $this->_isMultiple = $isMultiple;
+        $this->_value = $value;
+    }
+
+    /**
+     * Returns the value used for comparison
+     *
+     * @return mixed
+     */
+    public function getValue()
+    {
+        return $this->_value;
+    }
+
+    /**
+     * Sets the operator to use for the comparison
+     *
+     * @param string $operator The operator to be used for the comparison.
+     * @return void
+     */
+    public function setOperator(string $operator): void
+    {
+        $this->_operator = $operator;
+    }
+
+    /**
+     * Returns the operator used for comparison
+     *
+     * @return string
+     */
+    public function getOperator(): string
+    {
+        return $this->_operator;
+    }
+
+    /**
+     * @inheritDoc
+     */
+    public function sql(ValueBinder $binder): string
+    {
+        /** @var \Cake\Database\ExpressionInterface|string $field */
+        $field = $this->_field;
+
+        if ($field instanceof ExpressionInterface) {
+            $field = $field->sql($binder);
+        }
+
+        if ($this->_value instanceof IdentifierExpression) {
+            $template = '%s %s %s';
+            $value = $this->_value->sql($binder);
+        } elseif ($this->_value instanceof ExpressionInterface) {
+            $template = '%s %s (%s)';
+            $value = $this->_value->sql($binder);
+        } else {
+            [$template, $value] = $this->_stringExpression($binder);
+        }
+
+        return sprintf($template, $field, $this->_operator, $value);
+    }
+
+    /**
+     * @inheritDoc
+     */
+    public function traverse(Closure $callback)
+    {
+        if ($this->_field instanceof ExpressionInterface) {
+            $callback($this->_field);
+            $this->_field->traverse($callback);
+        }
+
+        if ($this->_value instanceof ExpressionInterface) {
+            $callback($this->_value);
+            $this->_value->traverse($callback);
+        }
+
+        foreach ($this->_valueExpressions as $v) {
+            $callback($v);
+            $v->traverse($callback);
+        }
+
+        return $this;
+    }
+
+    /**
+     * Create a deep clone.
+     *
+     * Clones the field and value if they are expression objects.
+     *
+     * @return void
+     */
+    public function __clone()
+    {
+        foreach (['_value', '_field'] as $prop) {
+            if ($this->{$prop} instanceof ExpressionInterface) {
+                $this->{$prop} = clone $this->{$prop};
+            }
+        }
+    }
+
+    /**
+     * Returns a template and a placeholder for the value after registering it
+     * with the placeholder $binder
+     *
+     * @param \Cake\Database\ValueBinder $binder The value binder to use.
+     * @return array First position containing the template and the second a placeholder
+     */
+    protected function _stringExpression(ValueBinder $binder): array
+    {
+        $template = '%s ';
+
+        if ($this->_field instanceof ExpressionInterface && !$this->_field instanceof IdentifierExpression) {
+            $template = '(%s) ';
+        }
+
+        if ($this->_isMultiple) {
+            $template .= '%s (%s)';
+            $type = $this->_type;
+            if ($type !== null) {
+                $type = str_replace('[]', '', $type);
+            }
+            $value = $this->_flattenValue($this->_value, $binder, $type);
+
+            // To avoid SQL errors when comparing a field to a list of empty values,
+            // better just throw an exception here
+            if ($value === '') {
+                $field = $this->_field instanceof ExpressionInterface ? $this->_field->sql($binder) : $this->_field;
+                /** @psalm-suppress PossiblyInvalidCast */
+                throw new DatabaseException(
+                    "Impossible to generate condition with empty list of values for field ($field)"
+                );
+            }
+        } else {
+            $template .= '%s %s';
+            $value = $this->_bindValue($this->_value, $binder, $this->_type);
+        }
+
+        return [$template, $value];
+    }
+
+    /**
+     * Registers a value in the placeholder generator and returns the generated placeholder
+     *
+     * @param mixed $value The value to bind
+     * @param \Cake\Database\ValueBinder $binder The value binder to use
+     * @param string|null $type The type of $value
+     * @return string generated placeholder
+     */
+    protected function _bindValue($value, ValueBinder $binder, ?string $type = null): string
+    {
+        $placeholder = $binder->placeholder('c');
+        $binder->bind($placeholder, $value, $type);
+
+        return $placeholder;
+    }
+
+    /**
+     * Converts a traversable value into a set of placeholders generated by
+     * $binder and separated by `,`
+     *
+     * @param iterable $value the value to flatten
+     * @param \Cake\Database\ValueBinder $binder The value binder to use
+     * @param string|null $type the type to cast values to
+     * @return string
+     */
+    protected function _flattenValue(iterable $value, ValueBinder $binder, ?string $type = null): string
+    {
+        $parts = [];
+        if (is_array($value)) {
+            foreach ($this->_valueExpressions as $k => $v) {
+                $parts[$k] = $v->sql($binder);
+                unset($value[$k]);
+            }
+        }
+
+        if (!empty($value)) {
+            $parts += $binder->generateManyNamed($value, $type);
+        }
+
+        return implode(',', $parts);
+    }
+
+    /**
+     * Returns an array with the original $values in the first position
+     * and all ExpressionInterface objects that could be found in the second
+     * position.
+     *
+     * @param \Cake\Database\ExpressionInterface|iterable $values The rows to insert
+     * @return array
+     */
+    protected function _collectExpressions($values): array
+    {
+        if ($values instanceof ExpressionInterface) {
+            return [$values, []];
+        }
+
+        $expressions = $result = [];
+        $isArray = is_array($values);
+
+        if ($isArray) {
+            /** @var array $result */
+            $result = $values;
+        }
+
+        foreach ($values as $k => $v) {
+            if ($v instanceof ExpressionInterface) {
+                $expressions[$k] = $v;
+            }
+
+            if ($isArray) {
+                $result[$k] = $v;
+            }
+        }
+
+        return [$result, $expressions];
+    }
+}
+
+// phpcs:disable
+class_alias(
+    'Cake\Database\Expression\ComparisonExpression',
+    'Cake\Database\Expression\Comparison'
+);
+// phpcs:enable
diff --git a/vendor/cakephp/database/Expression/FieldInterface.php b/vendor/cakephp/database/Expression/FieldInterface.php
new file mode 100644
index 0000000..f0554d9
--- /dev/null
+++ b/vendor/cakephp/database/Expression/FieldInterface.php
@@ -0,0 +1,39 @@
+_field = $field;
+    }
+
+    /**
+     * Returns the field name
+     *
+     * @return \Cake\Database\ExpressionInterface|array|string
+     */
+    public function getField()
+    {
+        return $this->_field;
+    }
+}
diff --git a/vendor/cakephp/database/Expression/FunctionExpression.php b/vendor/cakephp/database/Expression/FunctionExpression.php
new file mode 100644
index 0000000..105655b
--- /dev/null
+++ b/vendor/cakephp/database/Expression/FunctionExpression.php
@@ -0,0 +1,178 @@
+ 'literal', ' rules']);`
+     *
+     * Will produce `CONCAT(name, ' rules')`
+     *
+     * @param string $name the name of the function to be constructed
+     * @param array $params list of arguments to be passed to the function
+     * If associative the key would be used as argument when value is 'literal'
+     * @param array|array $types Associative array of types to be associated with the
+     * passed arguments
+     * @param string $returnType The return type of this expression
+     */
+    public function __construct(string $name, array $params = [], array $types = [], string $returnType = 'string')
+    {
+        $this->_name = $name;
+        $this->_returnType = $returnType;
+        parent::__construct($params, $types, ',');
+    }
+
+    /**
+     * Sets the name of the SQL function to be invoke in this expression.
+     *
+     * @param string $name The name of the function
+     * @return $this
+     */
+    public function setName(string $name)
+    {
+        $this->_name = $name;
+
+        return $this;
+    }
+
+    /**
+     * Gets the name of the SQL function to be invoke in this expression.
+     *
+     * @return string
+     */
+    public function getName(): string
+    {
+        return $this->_name;
+    }
+
+    /**
+     * Adds one or more arguments for the function call.
+     *
+     * @param array $conditions list of arguments to be passed to the function
+     * If associative the key would be used as argument when value is 'literal'
+     * @param array $types Associative array of types to be associated with the
+     * passed arguments
+     * @param bool $prepend Whether to prepend or append to the list of arguments
+     * @see \Cake\Database\Expression\FunctionExpression::__construct() for more details.
+     * @return $this
+     * @psalm-suppress MoreSpecificImplementedParamType
+     */
+    public function add($conditions, array $types = [], bool $prepend = false)
+    {
+        $put = $prepend ? 'array_unshift' : 'array_push';
+        $typeMap = $this->getTypeMap()->setTypes($types);
+        foreach ($conditions as $k => $p) {
+            if ($p === 'literal') {
+                $put($this->_conditions, $k);
+                continue;
+            }
+
+            if ($p === 'identifier') {
+                $put($this->_conditions, new IdentifierExpression($k));
+                continue;
+            }
+
+            $type = $typeMap->type($k);
+
+            if ($type !== null && !$p instanceof ExpressionInterface) {
+                $p = $this->_castToExpression($p, $type);
+            }
+
+            if ($p instanceof ExpressionInterface) {
+                $put($this->_conditions, $p);
+                continue;
+            }
+
+            $put($this->_conditions, ['value' => $p, 'type' => $type]);
+        }
+
+        return $this;
+    }
+
+    /**
+     * @inheritDoc
+     */
+    public function sql(ValueBinder $binder): string
+    {
+        $parts = [];
+        foreach ($this->_conditions as $condition) {
+            if ($condition instanceof Query) {
+                $condition = sprintf('(%s)', $condition->sql($binder));
+            } elseif ($condition instanceof ExpressionInterface) {
+                $condition = $condition->sql($binder);
+            } elseif (is_array($condition)) {
+                $p = $binder->placeholder('param');
+                $binder->bind($p, $condition['value'], $condition['type']);
+                $condition = $p;
+            }
+            $parts[] = $condition;
+        }
+
+        return $this->_name . sprintf('(%s)', implode(
+            $this->_conjunction . ' ',
+            $parts
+        ));
+    }
+
+    /**
+     * The name of the function is in itself an expression to generate, thus
+     * always adding 1 to the amount of expressions stored in this object.
+     *
+     * @return int
+     */
+    public function count(): int
+    {
+        return 1 + count($this->_conditions);
+    }
+}
diff --git a/vendor/cakephp/database/Expression/IdentifierExpression.php b/vendor/cakephp/database/Expression/IdentifierExpression.php
new file mode 100644
index 0000000..69486a4
--- /dev/null
+++ b/vendor/cakephp/database/Expression/IdentifierExpression.php
@@ -0,0 +1,119 @@
+_identifier = $identifier;
+        $this->collation = $collation;
+    }
+
+    /**
+     * Sets the identifier this expression represents
+     *
+     * @param string $identifier The identifier
+     * @return void
+     */
+    public function setIdentifier(string $identifier): void
+    {
+        $this->_identifier = $identifier;
+    }
+
+    /**
+     * Returns the identifier this expression represents
+     *
+     * @return string
+     */
+    public function getIdentifier(): string
+    {
+        return $this->_identifier;
+    }
+
+    /**
+     * Sets the collation.
+     *
+     * @param string $collation Identifier collation
+     * @return void
+     */
+    public function setCollation(string $collation): void
+    {
+        $this->collation = $collation;
+    }
+
+    /**
+     * Returns the collation.
+     *
+     * @return string|null
+     */
+    public function getCollation(): ?string
+    {
+        return $this->collation;
+    }
+
+    /**
+     * @inheritDoc
+     */
+    public function sql(ValueBinder $binder): string
+    {
+        $sql = $this->_identifier;
+        if ($this->collation) {
+            $sql .= ' COLLATE ' . $this->collation;
+        }
+
+        return $sql;
+    }
+
+    /**
+     * @inheritDoc
+     */
+    public function traverse(Closure $callback)
+    {
+        return $this;
+    }
+}
diff --git a/vendor/cakephp/database/Expression/OrderByExpression.php b/vendor/cakephp/database/Expression/OrderByExpression.php
new file mode 100644
index 0000000..74fbf21
--- /dev/null
+++ b/vendor/cakephp/database/Expression/OrderByExpression.php
@@ -0,0 +1,88 @@
+ $types The types for each column.
+     * @param string $conjunction The glue used to join conditions together.
+     */
+    public function __construct($conditions = [], $types = [], $conjunction = '')
+    {
+        parent::__construct($conditions, $types, $conjunction);
+    }
+
+    /**
+     * @inheritDoc
+     */
+    public function sql(ValueBinder $binder): string
+    {
+        $order = [];
+        foreach ($this->_conditions as $k => $direction) {
+            if ($direction instanceof ExpressionInterface) {
+                $direction = $direction->sql($binder);
+            }
+            $order[] = is_numeric($k) ? $direction : sprintf('%s %s', $k, $direction);
+        }
+
+        return sprintf('ORDER BY %s', implode(', ', $order));
+    }
+
+    /**
+     * Auxiliary function used for decomposing a nested array of conditions and
+     * building a tree structure inside this object to represent the full SQL expression.
+     *
+     * New order by expressions are merged to existing ones
+     *
+     * @param array $conditions list of order by expressions
+     * @param array $types list of types associated on fields referenced in $conditions
+     * @return void
+     */
+    protected function _addConditions(array $conditions, array $types): void
+    {
+        foreach ($conditions as $key => $val) {
+            if (
+                is_string($key) &&
+                is_string($val) &&
+                !in_array(strtoupper($val), ['ASC', 'DESC'], true)
+            ) {
+                throw new RuntimeException(
+                    sprintf(
+                        'Passing extra expressions by associative array (`\'%s\' => \'%s\'`) ' .
+                        'is not allowed to avoid potential SQL injection. ' .
+                        'Use QueryExpression or numeric array instead.',
+                        $key,
+                        $val
+                    )
+                );
+            }
+        }
+
+        $this->_conditions = array_merge($this->_conditions, $conditions);
+    }
+}
diff --git a/vendor/cakephp/database/Expression/OrderClauseExpression.php b/vendor/cakephp/database/Expression/OrderClauseExpression.php
new file mode 100644
index 0000000..dfab8b9
--- /dev/null
+++ b/vendor/cakephp/database/Expression/OrderClauseExpression.php
@@ -0,0 +1,90 @@
+_field = $field;
+        $this->_direction = strtolower($direction) === 'asc' ? 'ASC' : 'DESC';
+    }
+
+    /**
+     * @inheritDoc
+     */
+    public function sql(ValueBinder $binder): string
+    {
+        /** @var \Cake\Database\ExpressionInterface|string $field */
+        $field = $this->_field;
+        if ($field instanceof Query) {
+            $field = sprintf('(%s)', $field->sql($binder));
+        } elseif ($field instanceof ExpressionInterface) {
+            $field = $field->sql($binder);
+        }
+
+        return sprintf('%s %s', $field, $this->_direction);
+    }
+
+    /**
+     * @inheritDoc
+     */
+    public function traverse(Closure $callback)
+    {
+        if ($this->_field instanceof ExpressionInterface) {
+            $callback($this->_field);
+            $this->_field->traverse($callback);
+        }
+
+        return $this;
+    }
+
+    /**
+     * Create a deep clone of the order clause.
+     *
+     * @return void
+     */
+    public function __clone()
+    {
+        if ($this->_field instanceof ExpressionInterface) {
+            $this->_field = clone $this->_field;
+        }
+    }
+}
diff --git a/vendor/cakephp/database/Expression/QueryExpression.php b/vendor/cakephp/database/Expression/QueryExpression.php
new file mode 100644
index 0000000..0578c00
--- /dev/null
+++ b/vendor/cakephp/database/Expression/QueryExpression.php
@@ -0,0 +1,876 @@
+ :value"
+     *
+     * @var array
+     */
+    protected $_conditions = [];
+
+    /**
+     * Constructor. A new expression object can be created without any params and
+     * be built dynamically. Otherwise, it is possible to pass an array of conditions
+     * containing either a tree-like array structure to be parsed and/or other
+     * expression objects. Optionally, you can set the conjunction keyword to be used
+     * for joining each part of this level of the expression tree.
+     *
+     * @param \Cake\Database\ExpressionInterface|array|string $conditions Tree like array structure
+     * containing all the conditions to be added or nested inside this expression object.
+     * @param \Cake\Database\TypeMap|array $types Associative array of types to be associated with the values
+     * passed in $conditions.
+     * @param string $conjunction the glue that will join all the string conditions at this
+     * level of the expression tree. For example "AND", "OR", "XOR"...
+     * @see \Cake\Database\Expression\QueryExpression::add() for more details on $conditions and $types
+     */
+    public function __construct($conditions = [], $types = [], $conjunction = 'AND')
+    {
+        $this->setTypeMap($types);
+        $this->setConjunction(strtoupper($conjunction));
+        if (!empty($conditions)) {
+            $this->add($conditions, $this->getTypeMap()->getTypes());
+        }
+    }
+
+    /**
+     * Changes the conjunction for the conditions at this level of the expression tree.
+     *
+     * @param string $conjunction Value to be used for joining conditions
+     * @return $this
+     */
+    public function setConjunction(string $conjunction)
+    {
+        $this->_conjunction = strtoupper($conjunction);
+
+        return $this;
+    }
+
+    /**
+     * Gets the currently configured conjunction for the conditions at this level of the expression tree.
+     *
+     * @return string
+     */
+    public function getConjunction(): string
+    {
+        return $this->_conjunction;
+    }
+
+    /**
+     * Adds one or more conditions to this expression object. Conditions can be
+     * expressed in a one dimensional array, that will cause all conditions to
+     * be added directly at this level of the tree or they can be nested arbitrarily
+     * making it create more expression objects that will be nested inside and
+     * configured to use the specified conjunction.
+     *
+     * If the type passed for any of the fields is expressed "type[]" (note braces)
+     * then it will cause the placeholder to be re-written dynamically so if the
+     * value is an array, it will create as many placeholders as values are in it.
+     *
+     * @param \Cake\Database\ExpressionInterface|array|string $conditions single or multiple conditions to
+     * be added. When using an array and the key is 'OR' or 'AND' a new expression
+     * object will be created with that conjunction and internal array value passed
+     * as conditions.
+     * @param array $types Associative array of fields pointing to the type of the
+     * values that are being passed. Used for correctly binding values to statements.
+     * @see \Cake\Database\Query::where() for examples on conditions
+     * @return $this
+     */
+    public function add($conditions, array $types = [])
+    {
+        if (is_string($conditions) || $conditions instanceof ExpressionInterface) {
+            $this->_conditions[] = $conditions;
+
+            return $this;
+        }
+
+        $this->_addConditions($conditions, $types);
+
+        return $this;
+    }
+
+    /**
+     * Adds a new condition to the expression object in the form "field = value".
+     *
+     * @param \Cake\Database\ExpressionInterface|string $field Database field to be compared against value
+     * @param mixed $value The value to be bound to $field for comparison
+     * @param string|null $type the type name for $value as configured using the Type map.
+     * If it is suffixed with "[]" and the value is an array then multiple placeholders
+     * will be created, one per each value in the array.
+     * @return $this
+     */
+    public function eq($field, $value, ?string $type = null)
+    {
+        if ($type === null) {
+            $type = $this->_calculateType($field);
+        }
+
+        return $this->add(new ComparisonExpression($field, $value, $type, '='));
+    }
+
+    /**
+     * Adds a new condition to the expression object in the form "field != value".
+     *
+     * @param \Cake\Database\ExpressionInterface|string $field Database field to be compared against value
+     * @param mixed $value The value to be bound to $field for comparison
+     * @param string|null $type the type name for $value as configured using the Type map.
+     * If it is suffixed with "[]" and the value is an array then multiple placeholders
+     * will be created, one per each value in the array.
+     * @return $this
+     */
+    public function notEq($field, $value, $type = null)
+    {
+        if ($type === null) {
+            $type = $this->_calculateType($field);
+        }
+
+        return $this->add(new ComparisonExpression($field, $value, $type, '!='));
+    }
+
+    /**
+     * Adds a new condition to the expression object in the form "field > value".
+     *
+     * @param \Cake\Database\ExpressionInterface|string $field Database field to be compared against value
+     * @param mixed $value The value to be bound to $field for comparison
+     * @param string|null $type the type name for $value as configured using the Type map.
+     * @return $this
+     */
+    public function gt($field, $value, $type = null)
+    {
+        if ($type === null) {
+            $type = $this->_calculateType($field);
+        }
+
+        return $this->add(new ComparisonExpression($field, $value, $type, '>'));
+    }
+
+    /**
+     * Adds a new condition to the expression object in the form "field < value".
+     *
+     * @param \Cake\Database\ExpressionInterface|string $field Database field to be compared against value
+     * @param mixed $value The value to be bound to $field for comparison
+     * @param string|null $type the type name for $value as configured using the Type map.
+     * @return $this
+     */
+    public function lt($field, $value, $type = null)
+    {
+        if ($type === null) {
+            $type = $this->_calculateType($field);
+        }
+
+        return $this->add(new ComparisonExpression($field, $value, $type, '<'));
+    }
+
+    /**
+     * Adds a new condition to the expression object in the form "field >= value".
+     *
+     * @param \Cake\Database\ExpressionInterface|string $field Database field to be compared against value
+     * @param mixed $value The value to be bound to $field for comparison
+     * @param string|null $type the type name for $value as configured using the Type map.
+     * @return $this
+     */
+    public function gte($field, $value, $type = null)
+    {
+        if ($type === null) {
+            $type = $this->_calculateType($field);
+        }
+
+        return $this->add(new ComparisonExpression($field, $value, $type, '>='));
+    }
+
+    /**
+     * Adds a new condition to the expression object in the form "field <= value".
+     *
+     * @param \Cake\Database\ExpressionInterface|string $field Database field to be compared against value
+     * @param mixed $value The value to be bound to $field for comparison
+     * @param string|null $type the type name for $value as configured using the Type map.
+     * @return $this
+     */
+    public function lte($field, $value, $type = null)
+    {
+        if ($type === null) {
+            $type = $this->_calculateType($field);
+        }
+
+        return $this->add(new ComparisonExpression($field, $value, $type, '<='));
+    }
+
+    /**
+     * Adds a new condition to the expression object in the form "field IS NULL".
+     *
+     * @param \Cake\Database\ExpressionInterface|string $field database field to be
+     * tested for null
+     * @return $this
+     */
+    public function isNull($field)
+    {
+        if (!($field instanceof ExpressionInterface)) {
+            $field = new IdentifierExpression($field);
+        }
+
+        return $this->add(new UnaryExpression('IS NULL', $field, UnaryExpression::POSTFIX));
+    }
+
+    /**
+     * Adds a new condition to the expression object in the form "field IS NOT NULL".
+     *
+     * @param \Cake\Database\ExpressionInterface|string $field database field to be
+     * tested for not null
+     * @return $this
+     */
+    public function isNotNull($field)
+    {
+        if (!($field instanceof ExpressionInterface)) {
+            $field = new IdentifierExpression($field);
+        }
+
+        return $this->add(new UnaryExpression('IS NOT NULL', $field, UnaryExpression::POSTFIX));
+    }
+
+    /**
+     * Adds a new condition to the expression object in the form "field LIKE value".
+     *
+     * @param \Cake\Database\ExpressionInterface|string $field Database field to be compared against value
+     * @param mixed $value The value to be bound to $field for comparison
+     * @param string|null $type the type name for $value as configured using the Type map.
+     * @return $this
+     */
+    public function like($field, $value, $type = null)
+    {
+        if ($type === null) {
+            $type = $this->_calculateType($field);
+        }
+
+        return $this->add(new ComparisonExpression($field, $value, $type, 'LIKE'));
+    }
+
+    /**
+     * Adds a new condition to the expression object in the form "field NOT LIKE value".
+     *
+     * @param \Cake\Database\ExpressionInterface|string $field Database field to be compared against value
+     * @param mixed $value The value to be bound to $field for comparison
+     * @param string|null $type the type name for $value as configured using the Type map.
+     * @return $this
+     */
+    public function notLike($field, $value, $type = null)
+    {
+        if ($type === null) {
+            $type = $this->_calculateType($field);
+        }
+
+        return $this->add(new ComparisonExpression($field, $value, $type, 'NOT LIKE'));
+    }
+
+    /**
+     * Adds a new condition to the expression object in the form
+     * "field IN (value1, value2)".
+     *
+     * @param \Cake\Database\ExpressionInterface|string $field Database field to be compared against value
+     * @param \Cake\Database\ExpressionInterface|array|string $values the value to be bound to $field for comparison
+     * @param string|null $type the type name for $value as configured using the Type map.
+     * @return $this
+     */
+    public function in($field, $values, $type = null)
+    {
+        if ($type === null) {
+            $type = $this->_calculateType($field);
+        }
+        $type = $type ?: 'string';
+        $type .= '[]';
+        $values = $values instanceof ExpressionInterface ? $values : (array)$values;
+
+        return $this->add(new ComparisonExpression($field, $values, $type, 'IN'));
+    }
+
+    /**
+     * Adds a new case expression to the expression object
+     *
+     * @param \Cake\Database\ExpressionInterface|array $conditions The conditions to test. Must be a ExpressionInterface
+     * instance, or an array of ExpressionInterface instances.
+     * @param \Cake\Database\ExpressionInterface|array $values Associative array of values to be associated with the
+     * conditions passed in $conditions. If there are more $values than $conditions,
+     * the last $value is used as the `ELSE` value.
+     * @param array $types Associative array of types to be associated with the values
+     * passed in $values
+     * @return $this
+     * @deprecated 4.3.0 Use QueryExpression::case() or CaseStatementExpression instead
+     */
+    public function addCase($conditions, $values = [], $types = [])
+    {
+        deprecationWarning('QueryExpression::addCase() is deprecated, use case() instead.');
+
+        return $this->add(new CaseExpression($conditions, $values, $types));
+    }
+
+    /**
+     * Returns a new case expression object.
+     *
+     * When a value is set, the syntax generated is
+     * `CASE case_value WHEN when_value ... END` (simple case),
+     * where the `when_value`'s are compared against the
+     * `case_value`.
+     *
+     * When no value is set, the syntax generated is
+     * `CASE WHEN when_conditions ... END` (searched case),
+     * where the conditions hold the comparisons.
+     *
+     * Note that `null` is a valid case value, and thus should
+     * only be passed if you actually want to create the simple
+     * case expression variant!
+     *
+     * @param \Cake\Database\ExpressionInterface|object|scalar|null $value The case value.
+     * @param string|null $type The case value type. If no type is provided, the type will be tried to be inferred
+     *  from the value.
+     * @return \Cake\Database\Expression\CaseStatementExpression
+     */
+    public function case($value = null, ?string $type = null): CaseStatementExpression
+    {
+        if (func_num_args() > 0) {
+            $expression = new CaseStatementExpression($value, $type);
+        } else {
+            $expression = new CaseStatementExpression();
+        }
+
+        return $expression->setTypeMap($this->getTypeMap());
+    }
+
+    /**
+     * Adds a new condition to the expression object in the form
+     * "field NOT IN (value1, value2)".
+     *
+     * @param \Cake\Database\ExpressionInterface|string $field Database field to be compared against value
+     * @param \Cake\Database\ExpressionInterface|array|string $values the value to be bound to $field for comparison
+     * @param string|null $type the type name for $value as configured using the Type map.
+     * @return $this
+     */
+    public function notIn($field, $values, $type = null)
+    {
+        if ($type === null) {
+            $type = $this->_calculateType($field);
+        }
+        $type = $type ?: 'string';
+        $type .= '[]';
+        $values = $values instanceof ExpressionInterface ? $values : (array)$values;
+
+        return $this->add(new ComparisonExpression($field, $values, $type, 'NOT IN'));
+    }
+
+    /**
+     * Adds a new condition to the expression object in the form
+     * "(field NOT IN (value1, value2) OR field IS NULL".
+     *
+     * @param \Cake\Database\ExpressionInterface|string $field Database field to be compared against value
+     * @param \Cake\Database\ExpressionInterface|array|string $values the value to be bound to $field for comparison
+     * @param string|null $type the type name for $value as configured using the Type map.
+     * @return $this
+     */
+    public function notInOrNull($field, $values, ?string $type = null)
+    {
+        $or = new static([], [], 'OR');
+        $or
+            ->notIn($field, $values, $type)
+            ->isNull($field);
+
+        return $this->add($or);
+    }
+
+    /**
+     * Adds a new condition to the expression object in the form "EXISTS (...)".
+     *
+     * @param \Cake\Database\ExpressionInterface $expression the inner query
+     * @return $this
+     */
+    public function exists(ExpressionInterface $expression)
+    {
+        return $this->add(new UnaryExpression('EXISTS', $expression, UnaryExpression::PREFIX));
+    }
+
+    /**
+     * Adds a new condition to the expression object in the form "NOT EXISTS (...)".
+     *
+     * @param \Cake\Database\ExpressionInterface $expression the inner query
+     * @return $this
+     */
+    public function notExists(ExpressionInterface $expression)
+    {
+        return $this->add(new UnaryExpression('NOT EXISTS', $expression, UnaryExpression::PREFIX));
+    }
+
+    /**
+     * Adds a new condition to the expression object in the form
+     * "field BETWEEN from AND to".
+     *
+     * @param \Cake\Database\ExpressionInterface|string $field The field name to compare for values inbetween the range.
+     * @param mixed $from The initial value of the range.
+     * @param mixed $to The ending value in the comparison range.
+     * @param string|null $type the type name for $value as configured using the Type map.
+     * @return $this
+     */
+    public function between($field, $from, $to, $type = null)
+    {
+        if ($type === null) {
+            $type = $this->_calculateType($field);
+        }
+
+        return $this->add(new BetweenExpression($field, $from, $to, $type));
+    }
+
+    /**
+     * Returns a new QueryExpression object containing all the conditions passed
+     * and set up the conjunction to be "AND"
+     *
+     * @param \Cake\Database\ExpressionInterface|\Closure|array|string $conditions to be joined with AND
+     * @param array $types Associative array of fields pointing to the type of the
+     * values that are being passed. Used for correctly binding values to statements.
+     * @return \Cake\Database\Expression\QueryExpression
+     */
+    public function and($conditions, $types = [])
+    {
+        if ($conditions instanceof Closure) {
+            return $conditions(new static([], $this->getTypeMap()->setTypes($types)));
+        }
+
+        return new static($conditions, $this->getTypeMap()->setTypes($types));
+    }
+
+    /**
+     * Returns a new QueryExpression object containing all the conditions passed
+     * and set up the conjunction to be "OR"
+     *
+     * @param \Cake\Database\ExpressionInterface|\Closure|array|string $conditions to be joined with OR
+     * @param array $types Associative array of fields pointing to the type of the
+     * values that are being passed. Used for correctly binding values to statements.
+     * @return \Cake\Database\Expression\QueryExpression
+     */
+    public function or($conditions, $types = [])
+    {
+        if ($conditions instanceof Closure) {
+            return $conditions(new static([], $this->getTypeMap()->setTypes($types), 'OR'));
+        }
+
+        return new static($conditions, $this->getTypeMap()->setTypes($types), 'OR');
+    }
+
+    // phpcs:disable PSR1.Methods.CamelCapsMethodName.NotCamelCaps
+
+    /**
+     * Returns a new QueryExpression object containing all the conditions passed
+     * and set up the conjunction to be "AND"
+     *
+     * @param \Cake\Database\ExpressionInterface|\Closure|array|string $conditions to be joined with AND
+     * @param array $types Associative array of fields pointing to the type of the
+     * values that are being passed. Used for correctly binding values to statements.
+     * @return \Cake\Database\Expression\QueryExpression
+     * @deprecated 4.0.0 Use {@link and()} instead.
+     */
+    public function and_($conditions, $types = [])
+    {
+        deprecationWarning('QueryExpression::and_() is deprecated use and() instead.');
+
+        return $this->and($conditions, $types);
+    }
+
+    /**
+     * Returns a new QueryExpression object containing all the conditions passed
+     * and set up the conjunction to be "OR"
+     *
+     * @param \Cake\Database\ExpressionInterface|\Closure|array|string $conditions to be joined with OR
+     * @param array $types Associative array of fields pointing to the type of the
+     * values that are being passed. Used for correctly binding values to statements.
+     * @return \Cake\Database\Expression\QueryExpression
+     * @deprecated 4.0.0 Use {@link or()} instead.
+     */
+    public function or_($conditions, $types = [])
+    {
+        deprecationWarning('QueryExpression::or_() is deprecated use or() instead.');
+
+        return $this->or($conditions, $types);
+    }
+
+    // phpcs:enable
+
+    /**
+     * Adds a new set of conditions to this level of the tree and negates
+     * the final result by prepending a NOT, it will look like
+     * "NOT ( (condition1) AND (conditions2) )" conjunction depends on the one
+     * currently configured for this object.
+     *
+     * @param \Cake\Database\ExpressionInterface|\Closure|array|string $conditions to be added and negated
+     * @param array $types Associative array of fields pointing to the type of the
+     * values that are being passed. Used for correctly binding values to statements.
+     * @return $this
+     */
+    public function not($conditions, $types = [])
+    {
+        return $this->add(['NOT' => $conditions], $types);
+    }
+
+    /**
+     * Returns the number of internal conditions that are stored in this expression.
+     * Useful to determine if this expression object is void or it will generate
+     * a non-empty string when compiled
+     *
+     * @return int
+     */
+    public function count(): int
+    {
+        return count($this->_conditions);
+    }
+
+    /**
+     * Builds equal condition or assignment with identifier wrapping.
+     *
+     * @param string $leftField Left join condition field name.
+     * @param string $rightField Right join condition field name.
+     * @return $this
+     */
+    public function equalFields(string $leftField, string $rightField)
+    {
+        $wrapIdentifier = function ($field) {
+            if ($field instanceof ExpressionInterface) {
+                return $field;
+            }
+
+            return new IdentifierExpression($field);
+        };
+
+        return $this->eq($wrapIdentifier($leftField), $wrapIdentifier($rightField));
+    }
+
+    /**
+     * @inheritDoc
+     */
+    public function sql(ValueBinder $binder): string
+    {
+        $len = $this->count();
+        if ($len === 0) {
+            return '';
+        }
+        $conjunction = $this->_conjunction;
+        $template = $len === 1 ? '%s' : '(%s)';
+        $parts = [];
+        foreach ($this->_conditions as $part) {
+            if ($part instanceof Query) {
+                $part = '(' . $part->sql($binder) . ')';
+            } elseif ($part instanceof ExpressionInterface) {
+                $part = $part->sql($binder);
+            }
+            if ($part !== '') {
+                $parts[] = $part;
+            }
+        }
+
+        return sprintf($template, implode(" $conjunction ", $parts));
+    }
+
+    /**
+     * @inheritDoc
+     */
+    public function traverse(Closure $callback)
+    {
+        foreach ($this->_conditions as $c) {
+            if ($c instanceof ExpressionInterface) {
+                $callback($c);
+                $c->traverse($callback);
+            }
+        }
+
+        return $this;
+    }
+
+    /**
+     * Executes a callable function for each of the parts that form this expression.
+     *
+     * The callable function is required to return a value with which the currently
+     * visited part will be replaced. If the callable function returns null then
+     * the part will be discarded completely from this expression.
+     *
+     * The callback function will receive each of the conditions as first param and
+     * the key as second param. It is possible to declare the second parameter as
+     * passed by reference, this will enable you to change the key under which the
+     * modified part is stored.
+     *
+     * @param callable $callback The callable to apply to each part.
+     * @return $this
+     */
+    public function iterateParts(callable $callback)
+    {
+        $parts = [];
+        foreach ($this->_conditions as $k => $c) {
+            $key = &$k;
+            $part = $callback($c, $key);
+            if ($part !== null) {
+                $parts[$key] = $part;
+            }
+        }
+        $this->_conditions = $parts;
+
+        return $this;
+    }
+
+    /**
+     * Check whether a callable is acceptable.
+     *
+     * We don't accept ['class', 'method'] style callbacks,
+     * as they often contain user input and arrays of strings
+     * are easy to sneak in.
+     *
+     * @param \Cake\Database\ExpressionInterface|callable|array|string $callable The callable to check.
+     * @return bool Valid callable.
+     * @deprecated 4.2.0 This method is unused.
+     * @codeCoverageIgnore
+     */
+    public function isCallable($callable): bool
+    {
+        if (is_string($callable)) {
+            return false;
+        }
+        if (is_object($callable) && is_callable($callable)) {
+            return true;
+        }
+
+        return is_array($callable) && isset($callable[0]) && is_object($callable[0]) && is_callable($callable);
+    }
+
+    /**
+     * Returns true if this expression contains any other nested
+     * ExpressionInterface objects
+     *
+     * @return bool
+     */
+    public function hasNestedExpression(): bool
+    {
+        foreach ($this->_conditions as $c) {
+            if ($c instanceof ExpressionInterface) {
+                return true;
+            }
+        }
+
+        return false;
+    }
+
+    /**
+     * Auxiliary function used for decomposing a nested array of conditions and build
+     * a tree structure inside this object to represent the full SQL expression.
+     * String conditions are stored directly in the conditions, while any other
+     * representation is wrapped around an adequate instance or of this class.
+     *
+     * @param array $conditions list of conditions to be stored in this object
+     * @param array $types list of types associated on fields referenced in $conditions
+     * @return void
+     */
+    protected function _addConditions(array $conditions, array $types): void
+    {
+        $operators = ['and', 'or', 'xor'];
+
+        $typeMap = $this->getTypeMap()->setTypes($types);
+
+        foreach ($conditions as $k => $c) {
+            $numericKey = is_numeric($k);
+
+            if ($c instanceof Closure) {
+                $expr = new static([], $typeMap);
+                $c = $c($expr, $this);
+            }
+
+            if ($numericKey && empty($c)) {
+                continue;
+            }
+
+            $isArray = is_array($c);
+            $isOperator = $isNot = false;
+            if (!$numericKey) {
+                $normalizedKey = strtolower($k);
+                $isOperator = in_array($normalizedKey, $operators);
+                $isNot = $normalizedKey === 'not';
+            }
+
+            if (($isOperator || $isNot) && ($isArray || $c instanceof Countable) && count($c) === 0) {
+                continue;
+            }
+
+            if ($numericKey && $c instanceof ExpressionInterface) {
+                $this->_conditions[] = $c;
+                continue;
+            }
+
+            if ($numericKey && is_string($c)) {
+                $this->_conditions[] = $c;
+                continue;
+            }
+
+            if ($numericKey && $isArray || $isOperator) {
+                $this->_conditions[] = new static($c, $typeMap, $numericKey ? 'AND' : $k);
+                continue;
+            }
+
+            if ($isNot) {
+                $this->_conditions[] = new UnaryExpression('NOT', new static($c, $typeMap));
+                continue;
+            }
+
+            if (!$numericKey) {
+                $this->_conditions[] = $this->_parseCondition($k, $c);
+            }
+        }
+    }
+
+    /**
+     * Parses a string conditions by trying to extract the operator inside it if any
+     * and finally returning either an adequate QueryExpression object or a plain
+     * string representation of the condition. This function is responsible for
+     * generating the placeholders and replacing the values by them, while storing
+     * the value elsewhere for future binding.
+     *
+     * @param string $field The value from which the actual field and operator will
+     * be extracted.
+     * @param mixed $value The value to be bound to a placeholder for the field
+     * @return \Cake\Database\ExpressionInterface
+     * @throws \InvalidArgumentException If operator is invalid or missing on NULL usage.
+     */
+    protected function _parseCondition(string $field, $value)
+    {
+        $field = trim($field);
+        $operator = '=';
+        $expression = $field;
+
+        $spaces = substr_count($field, ' ');
+        // Handle field values that contain multiple spaces, such as
+        // operators with a space in them like `field IS NOT` and
+        // `field NOT LIKE`, or combinations with function expressions
+        // like `CONCAT(first_name, ' ', last_name) IN`.
+        if ($spaces > 1) {
+            $parts = explode(' ', $field);
+            if (preg_match('/(is not|not \w+)$/i', $field)) {
+                $last = array_pop($parts);
+                $second = array_pop($parts);
+                $parts[] = "{$second} {$last}";
+            }
+            $operator = array_pop($parts);
+            $expression = implode(' ', $parts);
+        } elseif ($spaces == 1) {
+            $parts = explode(' ', $field, 2);
+            [$expression, $operator] = $parts;
+        }
+        $operator = strtolower(trim($operator));
+        $type = $this->getTypeMap()->type($expression);
+
+        $typeMultiple = (is_string($type) && strpos($type, '[]') !== false);
+        if (in_array($operator, ['in', 'not in']) || $typeMultiple) {
+            $type = $type ?: 'string';
+            if (!$typeMultiple) {
+                $type .= '[]';
+            }
+            $operator = $operator === '=' ? 'IN' : $operator;
+            $operator = $operator === '!=' ? 'NOT IN' : $operator;
+            $typeMultiple = true;
+        }
+
+        if ($typeMultiple) {
+            $value = $value instanceof ExpressionInterface ? $value : (array)$value;
+        }
+
+        if ($operator === 'is' && $value === null) {
+            return new UnaryExpression(
+                'IS NULL',
+                new IdentifierExpression($expression),
+                UnaryExpression::POSTFIX
+            );
+        }
+
+        if ($operator === 'is not' && $value === null) {
+            return new UnaryExpression(
+                'IS NOT NULL',
+                new IdentifierExpression($expression),
+                UnaryExpression::POSTFIX
+            );
+        }
+
+        if ($operator === 'is' && $value !== null) {
+            $operator = '=';
+        }
+
+        if ($operator === 'is not' && $value !== null) {
+            $operator = '!=';
+        }
+
+        if ($value === null && $this->_conjunction !== ',') {
+            throw new InvalidArgumentException(
+                sprintf('Expression `%s` is missing operator (IS, IS NOT) with `null` value.', $expression)
+            );
+        }
+
+        return new ComparisonExpression($expression, $value, $type, $operator);
+    }
+
+    /**
+     * Returns the type name for the passed field if it was stored in the typeMap
+     *
+     * @param \Cake\Database\ExpressionInterface|string $field The field name to get a type for.
+     * @return string|null The computed type or null, if the type is unknown.
+     */
+    protected function _calculateType($field): ?string
+    {
+        $field = $field instanceof IdentifierExpression ? $field->getIdentifier() : $field;
+        if (is_string($field)) {
+            return $this->getTypeMap()->type($field);
+        }
+
+        return null;
+    }
+
+    /**
+     * Clone this object and its subtree of expressions.
+     *
+     * @return void
+     */
+    public function __clone()
+    {
+        foreach ($this->_conditions as $i => $condition) {
+            if ($condition instanceof ExpressionInterface) {
+                $this->_conditions[$i] = clone $condition;
+            }
+        }
+    }
+}
diff --git a/vendor/cakephp/database/Expression/StringExpression.php b/vendor/cakephp/database/Expression/StringExpression.php
new file mode 100644
index 0000000..e438074
--- /dev/null
+++ b/vendor/cakephp/database/Expression/StringExpression.php
@@ -0,0 +1,87 @@
+string = $string;
+        $this->collation = $collation;
+    }
+
+    /**
+     * Sets the string collation.
+     *
+     * @param string $collation String collation
+     * @return void
+     */
+    public function setCollation(string $collation): void
+    {
+        $this->collation = $collation;
+    }
+
+    /**
+     * Returns the string collation.
+     *
+     * @return string
+     */
+    public function getCollation(): string
+    {
+        return $this->collation;
+    }
+
+    /**
+     * @inheritDoc
+     */
+    public function sql(ValueBinder $binder): string
+    {
+        $placeholder = $binder->placeholder('c');
+        $binder->bind($placeholder, $this->string, 'string');
+
+        return $placeholder . ' COLLATE ' . $this->collation;
+    }
+
+    /**
+     * @inheritDoc
+     */
+    public function traverse(Closure $callback)
+    {
+        return $this;
+    }
+}
diff --git a/vendor/cakephp/database/Expression/TupleComparison.php b/vendor/cakephp/database/Expression/TupleComparison.php
new file mode 100644
index 0000000..b5c36f0
--- /dev/null
+++ b/vendor/cakephp/database/Expression/TupleComparison.php
@@ -0,0 +1,231 @@
+
+     * @psalm-suppress NonInvariantDocblockPropertyType
+     */
+    protected $_type;
+
+    /**
+     * Constructor
+     *
+     * @param \Cake\Database\ExpressionInterface|array|string $fields the fields to use to form a tuple
+     * @param \Cake\Database\ExpressionInterface|array $values the values to use to form a tuple
+     * @param array $types the types names to use for casting each of the values, only
+     * one type per position in the value array in needed
+     * @param string $conjunction the operator used for comparing field and value
+     */
+    public function __construct($fields, $values, array $types = [], string $conjunction = '=')
+    {
+        $this->_type = $types;
+        $this->setField($fields);
+        $this->_operator = $conjunction;
+        $this->setValue($values);
+    }
+
+    /**
+     * Returns the type to be used for casting the value to a database representation
+     *
+     * @return array
+     */
+    public function getType(): array
+    {
+        return $this->_type;
+    }
+
+    /**
+     * Sets the value
+     *
+     * @param mixed $value The value to compare
+     * @return void
+     */
+    public function setValue($value): void
+    {
+        if ($this->isMulti()) {
+            if (is_array($value) && !is_array(current($value))) {
+                throw new InvalidArgumentException(
+                    'Multi-tuple comparisons require a multi-tuple value, single-tuple given.'
+                );
+            }
+        } else {
+            if (is_array($value) && is_array(current($value))) {
+                throw new InvalidArgumentException(
+                    'Single-tuple comparisons require a single-tuple value, multi-tuple given.'
+                );
+            }
+        }
+
+        $this->_value = $value;
+    }
+
+    /**
+     * @inheritDoc
+     */
+    public function sql(ValueBinder $binder): string
+    {
+        $template = '(%s) %s (%s)';
+        $fields = [];
+        $originalFields = $this->getField();
+
+        if (!is_array($originalFields)) {
+            $originalFields = [$originalFields];
+        }
+
+        foreach ($originalFields as $field) {
+            $fields[] = $field instanceof ExpressionInterface ? $field->sql($binder) : $field;
+        }
+
+        $values = $this->_stringifyValues($binder);
+
+        $field = implode(', ', $fields);
+
+        return sprintf($template, $field, $this->_operator, $values);
+    }
+
+    /**
+     * Returns a string with the values as placeholders in a string to be used
+     * for the SQL version of this expression
+     *
+     * @param \Cake\Database\ValueBinder $binder The value binder to convert expressions with.
+     * @return string
+     */
+    protected function _stringifyValues(ValueBinder $binder): string
+    {
+        $values = [];
+        $parts = $this->getValue();
+
+        if ($parts instanceof ExpressionInterface) {
+            return $parts->sql($binder);
+        }
+
+        foreach ($parts as $i => $value) {
+            if ($value instanceof ExpressionInterface) {
+                $values[] = $value->sql($binder);
+                continue;
+            }
+
+            $type = $this->_type;
+            $isMultiOperation = $this->isMulti();
+            if (empty($type)) {
+                $type = null;
+            }
+
+            if ($isMultiOperation) {
+                $bound = [];
+                foreach ($value as $k => $val) {
+                    /** @var string $valType */
+                    $valType = $type && isset($type[$k]) ? $type[$k] : $type;
+                    $bound[] = $this->_bindValue($val, $binder, $valType);
+                }
+
+                $values[] = sprintf('(%s)', implode(',', $bound));
+                continue;
+            }
+
+            /** @var string $valType */
+            $valType = $type && isset($type[$i]) ? $type[$i] : $type;
+            $values[] = $this->_bindValue($value, $binder, $valType);
+        }
+
+        return implode(', ', $values);
+    }
+
+    /**
+     * @inheritDoc
+     */
+    protected function _bindValue($value, ValueBinder $binder, ?string $type = null): string
+    {
+        $placeholder = $binder->placeholder('tuple');
+        $binder->bind($placeholder, $value, $type);
+
+        return $placeholder;
+    }
+
+    /**
+     * @inheritDoc
+     */
+    public function traverse(Closure $callback)
+    {
+        /** @var array $fields */
+        $fields = $this->getField();
+        foreach ($fields as $field) {
+            $this->_traverseValue($field, $callback);
+        }
+
+        $value = $this->getValue();
+        if ($value instanceof ExpressionInterface) {
+            $callback($value);
+            $value->traverse($callback);
+
+            return $this;
+        }
+
+        foreach ($value as $val) {
+            if ($this->isMulti()) {
+                foreach ($val as $v) {
+                    $this->_traverseValue($v, $callback);
+                }
+            } else {
+                $this->_traverseValue($val, $callback);
+            }
+        }
+
+        return $this;
+    }
+
+    /**
+     * Conditionally executes the callback for the passed value if
+     * it is an ExpressionInterface
+     *
+     * @param mixed $value The value to traverse
+     * @param \Closure $callback The callable to use when traversing
+     * @return void
+     */
+    protected function _traverseValue($value, Closure $callback): void
+    {
+        if ($value instanceof ExpressionInterface) {
+            $callback($value);
+            $value->traverse($callback);
+        }
+    }
+
+    /**
+     * Determines if each of the values in this expressions is a tuple in
+     * itself
+     *
+     * @return bool
+     */
+    public function isMulti(): bool
+    {
+        return in_array(strtolower($this->_operator), ['in', 'not in']);
+    }
+}
diff --git a/vendor/cakephp/database/Expression/UnaryExpression.php b/vendor/cakephp/database/Expression/UnaryExpression.php
new file mode 100644
index 0000000..1c40f91
--- /dev/null
+++ b/vendor/cakephp/database/Expression/UnaryExpression.php
@@ -0,0 +1,118 @@
+_operator = $operator;
+        $this->_value = $value;
+        $this->position = $position;
+    }
+
+    /**
+     * @inheritDoc
+     */
+    public function sql(ValueBinder $binder): string
+    {
+        $operand = $this->_value;
+        if ($operand instanceof ExpressionInterface) {
+            $operand = $operand->sql($binder);
+        }
+
+        if ($this->position === self::POSTFIX) {
+            return '(' . $operand . ') ' . $this->_operator;
+        }
+
+        return $this->_operator . ' (' . $operand . ')';
+    }
+
+    /**
+     * @inheritDoc
+     */
+    public function traverse(Closure $callback)
+    {
+        if ($this->_value instanceof ExpressionInterface) {
+            $callback($this->_value);
+            $this->_value->traverse($callback);
+        }
+
+        return $this;
+    }
+
+    /**
+     * Perform a deep clone of the inner expression.
+     *
+     * @return void
+     */
+    public function __clone()
+    {
+        if ($this->_value instanceof ExpressionInterface) {
+            $this->_value = clone $this->_value;
+        }
+    }
+}
diff --git a/vendor/cakephp/database/Expression/ValuesExpression.php b/vendor/cakephp/database/Expression/ValuesExpression.php
new file mode 100644
index 0000000..68dbf25
--- /dev/null
+++ b/vendor/cakephp/database/Expression/ValuesExpression.php
@@ -0,0 +1,325 @@
+ type names
+     */
+    public function __construct(array $columns, TypeMap $typeMap)
+    {
+        $this->_columns = $columns;
+        $this->setTypeMap($typeMap);
+    }
+
+    /**
+     * Add a row of data to be inserted.
+     *
+     * @param \Cake\Database\Query|array $values Array of data to append into the insert, or
+     *   a query for doing INSERT INTO .. SELECT style commands
+     * @return void
+     * @throws \Cake\Database\Exception\DatabaseException When mixing array + Query data types.
+     */
+    public function add($values): void
+    {
+        if (
+            (
+                count($this->_values) &&
+                $values instanceof Query
+            ) ||
+            (
+                $this->_query &&
+                is_array($values)
+            )
+        ) {
+            throw new DatabaseException(
+                'You cannot mix subqueries and array values in inserts.'
+            );
+        }
+        if ($values instanceof Query) {
+            $this->setQuery($values);
+
+            return;
+        }
+        $this->_values[] = $values;
+        $this->_castedExpressions = false;
+    }
+
+    /**
+     * Sets the columns to be inserted.
+     *
+     * @param array $columns Array with columns to be inserted.
+     * @return $this
+     */
+    public function setColumns(array $columns)
+    {
+        $this->_columns = $columns;
+        $this->_castedExpressions = false;
+
+        return $this;
+    }
+
+    /**
+     * Gets the columns to be inserted.
+     *
+     * @return array
+     */
+    public function getColumns(): array
+    {
+        return $this->_columns;
+    }
+
+    /**
+     * Get the bare column names.
+     *
+     * Because column names could be identifier quoted, we
+     * need to strip the identifiers off of the columns.
+     *
+     * @return array
+     */
+    protected function _columnNames(): array
+    {
+        $columns = [];
+        foreach ($this->_columns as $col) {
+            if (is_string($col)) {
+                $col = trim($col, '`[]"');
+            }
+            $columns[] = $col;
+        }
+
+        return $columns;
+    }
+
+    /**
+     * Sets the values to be inserted.
+     *
+     * @param array $values Array with values to be inserted.
+     * @return $this
+     */
+    public function setValues(array $values)
+    {
+        $this->_values = $values;
+        $this->_castedExpressions = false;
+
+        return $this;
+    }
+
+    /**
+     * Gets the values to be inserted.
+     *
+     * @return array
+     */
+    public function getValues(): array
+    {
+        if (!$this->_castedExpressions) {
+            $this->_processExpressions();
+        }
+
+        return $this->_values;
+    }
+
+    /**
+     * Sets the query object to be used as the values expression to be evaluated
+     * to insert records in the table.
+     *
+     * @param \Cake\Database\Query $query The query to set
+     * @return $this
+     */
+    public function setQuery(Query $query)
+    {
+        $this->_query = $query;
+
+        return $this;
+    }
+
+    /**
+     * Gets the query object to be used as the values expression to be evaluated
+     * to insert records in the table.
+     *
+     * @return \Cake\Database\Query|null
+     */
+    public function getQuery(): ?Query
+    {
+        return $this->_query;
+    }
+
+    /**
+     * @inheritDoc
+     */
+    public function sql(ValueBinder $binder): string
+    {
+        if (empty($this->_values) && empty($this->_query)) {
+            return '';
+        }
+
+        if (!$this->_castedExpressions) {
+            $this->_processExpressions();
+        }
+
+        $columns = $this->_columnNames();
+        $defaults = array_fill_keys($columns, null);
+        $placeholders = [];
+
+        $types = [];
+        $typeMap = $this->getTypeMap();
+        foreach ($defaults as $col => $v) {
+            $types[$col] = $typeMap->type($col);
+        }
+
+        foreach ($this->_values as $row) {
+            $row += $defaults;
+            $rowPlaceholders = [];
+
+            foreach ($columns as $column) {
+                $value = $row[$column];
+
+                if ($value instanceof ExpressionInterface) {
+                    $rowPlaceholders[] = '(' . $value->sql($binder) . ')';
+                    continue;
+                }
+
+                $placeholder = $binder->placeholder('c');
+                $rowPlaceholders[] = $placeholder;
+                $binder->bind($placeholder, $value, $types[$column]);
+            }
+
+            $placeholders[] = implode(', ', $rowPlaceholders);
+        }
+
+        $query = $this->getQuery();
+        if ($query) {
+            return ' ' . $query->sql($binder);
+        }
+
+        return sprintf(' VALUES (%s)', implode('), (', $placeholders));
+    }
+
+    /**
+     * @inheritDoc
+     */
+    public function traverse(Closure $callback)
+    {
+        if ($this->_query) {
+            return $this;
+        }
+
+        if (!$this->_castedExpressions) {
+            $this->_processExpressions();
+        }
+
+        foreach ($this->_values as $v) {
+            if ($v instanceof ExpressionInterface) {
+                $v->traverse($callback);
+            }
+            if (!is_array($v)) {
+                continue;
+            }
+            foreach ($v as $field) {
+                if ($field instanceof ExpressionInterface) {
+                    $callback($field);
+                    $field->traverse($callback);
+                }
+            }
+        }
+
+        return $this;
+    }
+
+    /**
+     * Converts values that need to be casted to expressions
+     *
+     * @return void
+     */
+    protected function _processExpressions(): void
+    {
+        $types = [];
+        $typeMap = $this->getTypeMap();
+
+        $columns = $this->_columnNames();
+        foreach ($columns as $c) {
+            if (!is_string($c) && !is_int($c)) {
+                continue;
+            }
+            $types[$c] = $typeMap->type($c);
+        }
+
+        $types = $this->_requiresToExpressionCasting($types);
+
+        if (empty($types)) {
+            return;
+        }
+
+        foreach ($this->_values as $row => $values) {
+            foreach ($types as $col => $type) {
+                /** @var \Cake\Database\Type\ExpressionTypeInterface $type */
+                $this->_values[$row][$col] = $type->toExpression($values[$col]);
+            }
+        }
+        $this->_castedExpressions = true;
+    }
+}
diff --git a/vendor/cakephp/database/Expression/WhenThenExpression.php b/vendor/cakephp/database/Expression/WhenThenExpression.php
new file mode 100644
index 0000000..bbc4154
--- /dev/null
+++ b/vendor/cakephp/database/Expression/WhenThenExpression.php
@@ -0,0 +1,350 @@
+
+     */
+    protected $validClauseNames = [
+        'when',
+        'then',
+    ];
+
+    /**
+     * The type map to use when using an array of conditions for the
+     * `WHEN` value.
+     *
+     * @var \Cake\Database\TypeMap
+     */
+    protected $_typeMap;
+
+    /**
+     * Then `WHEN` value.
+     *
+     * @var \Cake\Database\ExpressionInterface|object|scalar|null
+     */
+    protected $when = null;
+
+    /**
+     * The `WHEN` value type.
+     *
+     * @var array|string|null
+     */
+    protected $whenType = null;
+
+    /**
+     * The `THEN` value.
+     *
+     * @var \Cake\Database\ExpressionInterface|object|scalar|null
+     */
+    protected $then = null;
+
+    /**
+     * Whether the `THEN` value has been defined, eg whether `then()`
+     * has been invoked.
+     *
+     * @var bool
+     */
+    protected $hasThenBeenDefined = false;
+
+    /**
+     * The `THEN` result type.
+     *
+     * @var string|null
+     */
+    protected $thenType = null;
+
+    /**
+     * Constructor.
+     *
+     * @param \Cake\Database\TypeMap|null $typeMap The type map to use when using an array of conditions for the `WHEN`
+     *  value.
+     */
+    public function __construct(?TypeMap $typeMap = null)
+    {
+        if ($typeMap === null) {
+            $typeMap = new TypeMap();
+        }
+        $this->_typeMap = $typeMap;
+    }
+
+    /**
+     * Sets the `WHEN` value.
+     *
+     * @param \Cake\Database\ExpressionInterface|object|array|scalar $when The `WHEN` value. When using an array of
+     *  conditions, it must be compatible with `\Cake\Database\Query::where()`. Note that this argument is _not_
+     *  completely safe for use with user data, as a user supplied array would allow for raw SQL to slip in! If you
+     *  plan to use user data, either pass a single type for the `$type` argument (which forces the `$when` value to be
+     *  a non-array, and then always binds the data), use a conditions array where the user data is only passed on the
+     *  value side of the array entries, or custom bindings!
+     * @param array|string|null $type The when value type. Either an associative array when using array style
+     *  conditions, or else a string. If no type is provided, the type will be tried to be inferred from the value.
+     * @return $this
+     * @throws \InvalidArgumentException In case the `$when` argument is neither a non-empty array, nor a scalar value,
+     *  an object, or an instance of `\Cake\Database\ExpressionInterface`.
+     * @throws \InvalidArgumentException In case the `$type` argument is neither an array, a string, nor null.
+     * @throws \InvalidArgumentException In case the `$when` argument is an array, and the `$type` argument is neither
+     * an array, nor null.
+     * @throws \InvalidArgumentException In case the `$when` argument is a non-array value, and the `$type` argument is
+     * neither a string, nor null.
+     * @see CaseStatementExpression::when() for a more detailed usage explanation.
+     */
+    public function when($when, $type = null)
+    {
+        if (
+            !(is_array($when) && !empty($when)) &&
+            !is_scalar($when) &&
+            !is_object($when)
+        ) {
+            throw new InvalidArgumentException(sprintf(
+                'The `$when` argument must be either a non-empty array, a scalar value, an object, ' .
+                'or an instance of `\%s`, `%s` given.',
+                ExpressionInterface::class,
+                is_array($when) ? '[]' : getTypeName($when)
+            ));
+        }
+
+        if (
+            $type !== null &&
+            !is_array($type) &&
+            !is_string($type)
+        ) {
+            throw new InvalidArgumentException(sprintf(
+                'The `$type` argument must be either an array, a string, or `null`, `%s` given.',
+                getTypeName($type)
+            ));
+        }
+
+        if (is_array($when)) {
+            if (
+                $type !== null &&
+                !is_array($type)
+            ) {
+                throw new InvalidArgumentException(sprintf(
+                    'When using an array for the `$when` argument, the `$type` argument must be an ' .
+                    'array too, `%s` given.',
+                    getTypeName($type)
+                ));
+            }
+
+            // avoid dirtying the type map for possible consecutive `when()` calls
+            $typeMap = clone $this->_typeMap;
+            if (
+                is_array($type) &&
+                count($type) > 0
+            ) {
+                $typeMap = $typeMap->setTypes($type);
+            }
+
+            $when = new QueryExpression($when, $typeMap);
+        } else {
+            if (
+                $type !== null &&
+                !is_string($type)
+            ) {
+                throw new InvalidArgumentException(sprintf(
+                    'When using a non-array value for the `$when` argument, the `$type` argument must ' .
+                    'be a string, `%s` given.',
+                    getTypeName($type)
+                ));
+            }
+
+            if (
+                $type === null &&
+                !($when instanceof ExpressionInterface)
+            ) {
+                $type = $this->inferType($when);
+            }
+        }
+
+        $this->when = $when;
+        $this->whenType = $type;
+
+        return $this;
+    }
+
+    /**
+     * Sets the `THEN` result value.
+     *
+     * @param \Cake\Database\ExpressionInterface|object|scalar|null $result The result value.
+     * @param string|null $type The result type. If no type is provided, the type will be inferred from the given
+     *  result value.
+     * @return $this
+     */
+    public function then($result, ?string $type = null)
+    {
+        if (
+            $result !== null &&
+            !is_scalar($result) &&
+            !(is_object($result) && !($result instanceof Closure))
+        ) {
+            throw new InvalidArgumentException(sprintf(
+                'The `$result` argument must be either `null`, a scalar value, an object, ' .
+                'or an instance of `\%s`, `%s` given.',
+                ExpressionInterface::class,
+                getTypeName($result)
+            ));
+        }
+
+        $this->then = $result;
+
+        if ($type === null) {
+            $type = $this->inferType($result);
+        }
+
+        $this->thenType = $type;
+
+        $this->hasThenBeenDefined = true;
+
+        return $this;
+    }
+
+    /**
+     * Returns the expression's result value type.
+     *
+     * @return string|null
+     * @see WhenThenExpression::then()
+     */
+    public function getResultType(): ?string
+    {
+        return $this->thenType;
+    }
+
+    /**
+     * Returns the available data for the given clause.
+     *
+     * ### Available clauses
+     *
+     * The following clause names are available:
+     *
+     * * `when`: The `WHEN` value.
+     * * `then`: The `THEN` result value.
+     *
+     * @param string $clause The name of the clause to obtain.
+     * @return \Cake\Database\ExpressionInterface|object|scalar|null
+     * @throws \InvalidArgumentException In case the given clause name is invalid.
+     */
+    public function clause(string $clause)
+    {
+        if (!in_array($clause, $this->validClauseNames, true)) {
+            throw new InvalidArgumentException(
+                sprintf(
+                    'The `$clause` argument must be one of `%s`, the given value `%s` is invalid.',
+                    implode('`, `', $this->validClauseNames),
+                    $clause
+                )
+            );
+        }
+
+        return $this->{$clause};
+    }
+
+    /**
+     * @inheritDoc
+     */
+    public function sql(ValueBinder $binder): string
+    {
+        if ($this->when === null) {
+            throw new LogicException('Case expression has incomplete when clause. Missing `when()`.');
+        }
+
+        if (!$this->hasThenBeenDefined) {
+            throw new LogicException('Case expression has incomplete when clause. Missing `then()` after `when()`.');
+        }
+
+        $when = $this->when;
+        if (
+            is_string($this->whenType) &&
+            !($when instanceof ExpressionInterface)
+        ) {
+            $when = $this->_castToExpression($when, $this->whenType);
+        }
+        if ($when instanceof Query) {
+            $when = sprintf('(%s)', $when->sql($binder));
+        } elseif ($when instanceof ExpressionInterface) {
+            $when = $when->sql($binder);
+        } else {
+            $placeholder = $binder->placeholder('c');
+            if (is_string($this->whenType)) {
+                $whenType = $this->whenType;
+            } else {
+                $whenType = null;
+            }
+            $binder->bind($placeholder, $when, $whenType);
+            $when = $placeholder;
+        }
+
+        $then = $this->compileNullableValue($binder, $this->then, $this->thenType);
+
+        return "WHEN $when THEN $then";
+    }
+
+    /**
+     * @inheritDoc
+     */
+    public function traverse(Closure $callback)
+    {
+        if ($this->when instanceof ExpressionInterface) {
+            $callback($this->when);
+            $this->when->traverse($callback);
+        }
+
+        if ($this->then instanceof ExpressionInterface) {
+            $callback($this->then);
+            $this->then->traverse($callback);
+        }
+
+        return $this;
+    }
+
+    /**
+     * Clones the inner expression objects.
+     *
+     * @return void
+     */
+    public function __clone()
+    {
+        if ($this->when instanceof ExpressionInterface) {
+            $this->when = clone $this->when;
+        }
+
+        if ($this->then instanceof ExpressionInterface) {
+            $this->then = clone $this->then;
+        }
+    }
+}
diff --git a/vendor/cakephp/database/Expression/WindowExpression.php b/vendor/cakephp/database/Expression/WindowExpression.php
new file mode 100644
index 0000000..383e652
--- /dev/null
+++ b/vendor/cakephp/database/Expression/WindowExpression.php
@@ -0,0 +1,335 @@
+
+     */
+    protected $partitions = [];
+
+    /**
+     * @var \Cake\Database\Expression\OrderByExpression|null
+     */
+    protected $order;
+
+    /**
+     * @var array|null
+     */
+    protected $frame;
+
+    /**
+     * @var string|null
+     */
+    protected $exclusion;
+
+    /**
+     * @param string $name Window name
+     */
+    public function __construct(string $name = '')
+    {
+        $this->name = new IdentifierExpression($name);
+    }
+
+    /**
+     * Return whether is only a named window expression.
+     *
+     * These window expressions only specify a named window and do not
+     * specify their own partitions, frame or order.
+     *
+     * @return bool
+     */
+    public function isNamedOnly(): bool
+    {
+        return $this->name->getIdentifier() && (!$this->partitions && !$this->frame && !$this->order);
+    }
+
+    /**
+     * Sets the window name.
+     *
+     * @param string $name Window name
+     * @return $this
+     */
+    public function name(string $name)
+    {
+        $this->name = new IdentifierExpression($name);
+
+        return $this;
+    }
+
+    /**
+     * @inheritDoc
+     */
+    public function partition($partitions)
+    {
+        if (!$partitions) {
+            return $this;
+        }
+
+        if ($partitions instanceof Closure) {
+            $partitions = $partitions(new QueryExpression([], [], ''));
+        }
+
+        if (!is_array($partitions)) {
+            $partitions = [$partitions];
+        }
+
+        foreach ($partitions as &$partition) {
+            if (is_string($partition)) {
+                $partition = new IdentifierExpression($partition);
+            }
+        }
+
+        $this->partitions = array_merge($this->partitions, $partitions);
+
+        return $this;
+    }
+
+    /**
+     * @inheritDoc
+     */
+    public function order($fields)
+    {
+        if (!$fields) {
+            return $this;
+        }
+
+        if ($this->order === null) {
+            $this->order = new OrderByExpression();
+        }
+
+        if ($fields instanceof Closure) {
+            $fields = $fields(new QueryExpression([], [], ''));
+        }
+
+        $this->order->add($fields);
+
+        return $this;
+    }
+
+    /**
+     * @inheritDoc
+     */
+    public function range($start, $end = 0)
+    {
+        return $this->frame(self::RANGE, $start, self::PRECEDING, $end, self::FOLLOWING);
+    }
+
+    /**
+     * @inheritDoc
+     */
+    public function rows(?int $start, ?int $end = 0)
+    {
+        return $this->frame(self::ROWS, $start, self::PRECEDING, $end, self::FOLLOWING);
+    }
+
+    /**
+     * @inheritDoc
+     */
+    public function groups(?int $start, ?int $end = 0)
+    {
+        return $this->frame(self::GROUPS, $start, self::PRECEDING, $end, self::FOLLOWING);
+    }
+
+    /**
+     * @inheritDoc
+     */
+    public function frame(
+        string $type,
+        $startOffset,
+        string $startDirection,
+        $endOffset,
+        string $endDirection
+    ) {
+        $this->frame = [
+            'type' => $type,
+            'start' => [
+                'offset' => $startOffset,
+                'direction' => $startDirection,
+            ],
+            'end' => [
+                'offset' => $endOffset,
+                'direction' => $endDirection,
+            ],
+        ];
+
+        return $this;
+    }
+
+    /**
+     * @inheritDoc
+     */
+    public function excludeCurrent()
+    {
+        $this->exclusion = 'CURRENT ROW';
+
+        return $this;
+    }
+
+    /**
+     * @inheritDoc
+     */
+    public function excludeGroup()
+    {
+        $this->exclusion = 'GROUP';
+
+        return $this;
+    }
+
+    /**
+     * @inheritDoc
+     */
+    public function excludeTies()
+    {
+        $this->exclusion = 'TIES';
+
+        return $this;
+    }
+
+    /**
+     * @inheritDoc
+     */
+    public function sql(ValueBinder $binder): string
+    {
+        $clauses = [];
+        if ($this->name->getIdentifier()) {
+            $clauses[] = $this->name->sql($binder);
+        }
+
+        if ($this->partitions) {
+            $expressions = [];
+            foreach ($this->partitions as $partition) {
+                $expressions[] = $partition->sql($binder);
+            }
+
+            $clauses[] = 'PARTITION BY ' . implode(', ', $expressions);
+        }
+
+        if ($this->order) {
+            $clauses[] = $this->order->sql($binder);
+        }
+
+        if ($this->frame) {
+            $start = $this->buildOffsetSql(
+                $binder,
+                $this->frame['start']['offset'],
+                $this->frame['start']['direction']
+            );
+            $end = $this->buildOffsetSql(
+                $binder,
+                $this->frame['end']['offset'],
+                $this->frame['end']['direction']
+            );
+
+            $frameSql = sprintf('%s BETWEEN %s AND %s', $this->frame['type'], $start, $end);
+
+            if ($this->exclusion !== null) {
+                $frameSql .= ' EXCLUDE ' . $this->exclusion;
+            }
+
+            $clauses[] = $frameSql;
+        }
+
+        return implode(' ', $clauses);
+    }
+
+    /**
+     * @inheritDoc
+     */
+    public function traverse(Closure $callback)
+    {
+        $callback($this->name);
+        foreach ($this->partitions as $partition) {
+            $callback($partition);
+            $partition->traverse($callback);
+        }
+
+        if ($this->order) {
+            $callback($this->order);
+            $this->order->traverse($callback);
+        }
+
+        if ($this->frame !== null) {
+            $offset = $this->frame['start']['offset'];
+            if ($offset instanceof ExpressionInterface) {
+                $callback($offset);
+                $offset->traverse($callback);
+            }
+            $offset = $this->frame['end']['offset'] ?? null;
+            if ($offset instanceof ExpressionInterface) {
+                $callback($offset);
+                $offset->traverse($callback);
+            }
+        }
+
+        return $this;
+    }
+
+    /**
+     * Builds frame offset sql.
+     *
+     * @param \Cake\Database\ValueBinder $binder Value binder
+     * @param \Cake\Database\ExpressionInterface|string|int|null $offset Frame offset
+     * @param string $direction Frame offset direction
+     * @return string
+     */
+    protected function buildOffsetSql(ValueBinder $binder, $offset, string $direction): string
+    {
+        if ($offset === 0) {
+            return 'CURRENT ROW';
+        }
+
+        if ($offset instanceof ExpressionInterface) {
+            $offset = $offset->sql($binder);
+        }
+
+        return sprintf(
+            '%s %s',
+            $offset ?? 'UNBOUNDED',
+            $direction
+        );
+    }
+
+    /**
+     * Clone this object and its subtree of expressions.
+     *
+     * @return void
+     */
+    public function __clone()
+    {
+        $this->name = clone $this->name;
+        foreach ($this->partitions as $i => $partition) {
+            $this->partitions[$i] = clone $partition;
+        }
+        if ($this->order !== null) {
+            $this->order = clone $this->order;
+        }
+    }
+}
diff --git a/vendor/cakephp/database/Expression/WindowInterface.php b/vendor/cakephp/database/Expression/WindowInterface.php
new file mode 100644
index 0000000..7a7bac5
--- /dev/null
+++ b/vendor/cakephp/database/Expression/WindowInterface.php
@@ -0,0 +1,163 @@
+|string $partitions Partition expressions
+     * @return $this
+     */
+    public function partition($partitions);
+
+    /**
+     * Adds one or more order clauses to the window.
+     *
+     * @param \Cake\Database\ExpressionInterface|\Closure|array<\Cake\Database\ExpressionInterface|string>|string $fields Order expressions
+     * @return $this
+     */
+    public function order($fields);
+
+    /**
+     * Adds a simple range frame to the window.
+     *
+     * `$start`:
+     *  - `0` - 'CURRENT ROW'
+     *  - `null` - 'UNBOUNDED PRECEDING'
+     *  - offset - 'offset PRECEDING'
+     *
+     * `$end`:
+     *  - `0` - 'CURRENT ROW'
+     *  - `null` - 'UNBOUNDED FOLLOWING'
+     *  - offset - 'offset FOLLOWING'
+     *
+     * If you need to use 'FOLLOWING' with frame start or
+     * 'PRECEDING' with frame end, use `frame()` instead.
+     *
+     * @param \Cake\Database\ExpressionInterface|string|int|null $start Frame start
+     * @param \Cake\Database\ExpressionInterface|string|int|null $end Frame end
+     *  If not passed in, only frame start SQL will be generated.
+     * @return $this
+     */
+    public function range($start, $end = 0);
+
+    /**
+     * Adds a simple rows frame to the window.
+     *
+     * See `range()` for details.
+     *
+     * @param int|null $start Frame start
+     * @param int|null $end Frame end
+     *  If not passed in, only frame start SQL will be generated.
+     * @return $this
+     */
+    public function rows(?int $start, ?int $end = 0);
+
+    /**
+     * Adds a simple groups frame to the window.
+     *
+     * See `range()` for details.
+     *
+     * @param int|null $start Frame start
+     * @param int|null $end Frame end
+     *  If not passed in, only frame start SQL will be generated.
+     * @return $this
+     */
+    public function groups(?int $start, ?int $end = 0);
+
+    /**
+     * Adds a frame to the window.
+     *
+     * Use the `range()`, `rows()` or `groups()` helpers if you need simple
+     * 'BETWEEN offset PRECEDING and offset FOLLOWING' frames.
+     *
+     * You can specify any direction for both frame start and frame end.
+     *
+     * With both `$startOffset` and `$endOffset`:
+     *  - `0` - 'CURRENT ROW'
+     *  - `null` - 'UNBOUNDED'
+     *
+     * @param string $type Frame type
+     * @param \Cake\Database\ExpressionInterface|string|int|null $startOffset Frame start offset
+     * @param string $startDirection Frame start direction
+     * @param \Cake\Database\ExpressionInterface|string|int|null $endOffset Frame end offset
+     * @param string $endDirection Frame end direction
+     * @return $this
+     * @throws \InvalidArgumentException WHen offsets are negative.
+     * @psalm-param self::RANGE|self::ROWS|self::GROUPS $type
+     * @psalm-param self::PRECEDING|self::FOLLOWING $startDirection
+     * @psalm-param self::PRECEDING|self::FOLLOWING $endDirection
+     */
+    public function frame(
+        string $type,
+        $startOffset,
+        string $startDirection,
+        $endOffset,
+        string $endDirection
+    );
+
+    /**
+     * Adds current row frame exclusion.
+     *
+     * @return $this
+     */
+    public function excludeCurrent();
+
+    /**
+     * Adds group frame exclusion.
+     *
+     * @return $this
+     */
+    public function excludeGroup();
+
+    /**
+     * Adds ties frame exclusion.
+     *
+     * @return $this
+     */
+    public function excludeTies();
+}
diff --git a/vendor/cakephp/database/ExpressionInterface.php b/vendor/cakephp/database/ExpressionInterface.php
new file mode 100644
index 0000000..3e3588c
--- /dev/null
+++ b/vendor/cakephp/database/ExpressionInterface.php
@@ -0,0 +1,44 @@
+
+     */
+    protected $_typeMap;
+
+    /**
+     * An array containing the name of the fields and the Type objects
+     * each should use when converting them using batching.
+     *
+     * @var array
+     */
+    protected $batchingTypeMap;
+
+    /**
+     * An array containing all the types registered in the Type system
+     * at the moment this object is created. Used so that the types list
+     * is not fetched on each single row of the results.
+     *
+     * @var array<\Cake\Database\TypeInterface|\Cake\Database\Type\BatchCastingInterface>
+     */
+    protected $types;
+
+    /**
+     * The driver object to be used in the type conversion
+     *
+     * @var \Cake\Database\DriverInterface
+     */
+    protected $_driver;
+
+    /**
+     * Builds the type map
+     *
+     * @param \Cake\Database\TypeMap $typeMap Contains the types to use for converting results
+     * @param \Cake\Database\DriverInterface $driver The driver to use for the type conversion
+     */
+    public function __construct(TypeMap $typeMap, DriverInterface $driver)
+    {
+        $this->_driver = $driver;
+        $map = $typeMap->toArray();
+        $types = TypeFactory::buildAll();
+
+        $simpleMap = $batchingMap = [];
+        $simpleResult = $batchingResult = [];
+
+        foreach ($types as $k => $type) {
+            if ($type instanceof OptionalConvertInterface && !$type->requiresToPhpCast()) {
+                continue;
+            }
+
+            if ($type instanceof BatchCastingInterface) {
+                $batchingMap[$k] = $type;
+                continue;
+            }
+
+            $simpleMap[$k] = $type;
+        }
+
+        foreach ($map as $field => $type) {
+            if (isset($simpleMap[$type])) {
+                $simpleResult[$field] = $simpleMap[$type];
+                continue;
+            }
+            if (isset($batchingMap[$type])) {
+                $batchingResult[$type][] = $field;
+            }
+        }
+
+        // Using batching when there is only a couple for the type is actually slower,
+        // so, let's check for that case here.
+        foreach ($batchingResult as $type => $fields) {
+            if (count($fields) > 2) {
+                continue;
+            }
+
+            foreach ($fields as $f) {
+                $simpleResult[$f] = $batchingMap[$type];
+            }
+            unset($batchingResult[$type]);
+        }
+
+        $this->types = $types;
+        $this->_typeMap = $simpleResult;
+        $this->batchingTypeMap = $batchingResult;
+    }
+
+    /**
+     * Converts each of the fields in the array that are present in the type map
+     * using the corresponding Type class.
+     *
+     * @param array $row The array with the fields to be casted
+     * @return array
+     */
+    public function __invoke(array $row): array
+    {
+        if (!empty($this->_typeMap)) {
+            foreach ($this->_typeMap as $field => $type) {
+                $row[$field] = $type->toPHP($row[$field], $this->_driver);
+            }
+        }
+
+        if (!empty($this->batchingTypeMap)) {
+            foreach ($this->batchingTypeMap as $t => $fields) {
+                /** @psalm-suppress PossiblyUndefinedMethod */
+                $row = $this->types[$t]->manyToPHP($row, $fields, $this->_driver);
+            }
+        }
+
+        return $row;
+    }
+}
diff --git a/vendor/cakephp/database/FunctionsBuilder.php b/vendor/cakephp/database/FunctionsBuilder.php
new file mode 100644
index 0000000..9e50ad6
--- /dev/null
+++ b/vendor/cakephp/database/FunctionsBuilder.php
@@ -0,0 +1,376 @@
+aggregate('SUM', $this->toLiteralParam($expression), $types, $returnType);
+    }
+
+    /**
+     * Returns a AggregateExpression representing a call to SQL AVG function.
+     *
+     * @param \Cake\Database\ExpressionInterface|string $expression the function argument
+     * @param array $types list of types to bind to the arguments
+     * @return \Cake\Database\Expression\AggregateExpression
+     */
+    public function avg($expression, $types = []): AggregateExpression
+    {
+        return $this->aggregate('AVG', $this->toLiteralParam($expression), $types, 'float');
+    }
+
+    /**
+     * Returns a AggregateExpression representing a call to SQL MAX function.
+     *
+     * @param \Cake\Database\ExpressionInterface|string $expression the function argument
+     * @param array $types list of types to bind to the arguments
+     * @return \Cake\Database\Expression\AggregateExpression
+     */
+    public function max($expression, $types = []): AggregateExpression
+    {
+        return $this->aggregate('MAX', $this->toLiteralParam($expression), $types, current($types) ?: 'float');
+    }
+
+    /**
+     * Returns a AggregateExpression representing a call to SQL MIN function.
+     *
+     * @param \Cake\Database\ExpressionInterface|string $expression the function argument
+     * @param array $types list of types to bind to the arguments
+     * @return \Cake\Database\Expression\AggregateExpression
+     */
+    public function min($expression, $types = []): AggregateExpression
+    {
+        return $this->aggregate('MIN', $this->toLiteralParam($expression), $types, current($types) ?: 'float');
+    }
+
+    /**
+     * Returns a AggregateExpression representing a call to SQL COUNT function.
+     *
+     * @param \Cake\Database\ExpressionInterface|string $expression the function argument
+     * @param array $types list of types to bind to the arguments
+     * @return \Cake\Database\Expression\AggregateExpression
+     */
+    public function count($expression, $types = []): AggregateExpression
+    {
+        return $this->aggregate('COUNT', $this->toLiteralParam($expression), $types, 'integer');
+    }
+
+    /**
+     * Returns a FunctionExpression representing a string concatenation
+     *
+     * @param array $args List of strings or expressions to concatenate
+     * @param array $types list of types to bind to the arguments
+     * @return \Cake\Database\Expression\FunctionExpression
+     */
+    public function concat(array $args, array $types = []): FunctionExpression
+    {
+        return new FunctionExpression('CONCAT', $args, $types, 'string');
+    }
+
+    /**
+     * Returns a FunctionExpression representing a call to SQL COALESCE function.
+     *
+     * @param array $args List of expressions to evaluate as function parameters
+     * @param array $types list of types to bind to the arguments
+     * @return \Cake\Database\Expression\FunctionExpression
+     */
+    public function coalesce(array $args, array $types = []): FunctionExpression
+    {
+        return new FunctionExpression('COALESCE', $args, $types, current($types) ?: 'string');
+    }
+
+    /**
+     * Returns a FunctionExpression representing a SQL CAST.
+     *
+     * The `$type` parameter is a SQL type. The return type for the returned expression
+     * is the default type name. Use `setReturnType()` to update it.
+     *
+     * @param \Cake\Database\ExpressionInterface|string $field Field or expression to cast.
+     * @param string $type The SQL data type
+     * @return \Cake\Database\Expression\FunctionExpression
+     */
+    public function cast($field, string $type = ''): FunctionExpression
+    {
+        if (is_array($field)) {
+            deprecationWarning(
+                'Build cast function by FunctionsBuilder::cast(array $args) is deprecated. ' .
+                'Use FunctionsBuilder::cast($field, string $type) instead.'
+            );
+
+            return new FunctionExpression('CAST', $field);
+        }
+
+        if (empty($type)) {
+            throw new InvalidArgumentException('The `$type` in a cast cannot be empty.');
+        }
+
+        $expression = new FunctionExpression('CAST', $this->toLiteralParam($field));
+        $expression->setConjunction(' AS')->add([$type => 'literal']);
+
+        return $expression;
+    }
+
+    /**
+     * Returns a FunctionExpression representing the difference in days between
+     * two dates.
+     *
+     * @param array $args List of expressions to obtain the difference in days.
+     * @param array $types list of types to bind to the arguments
+     * @return \Cake\Database\Expression\FunctionExpression
+     */
+    public function dateDiff(array $args, array $types = []): FunctionExpression
+    {
+        return new FunctionExpression('DATEDIFF', $args, $types, 'integer');
+    }
+
+    /**
+     * Returns the specified date part from the SQL expression.
+     *
+     * @param string $part Part of the date to return.
+     * @param \Cake\Database\ExpressionInterface|string $expression Expression to obtain the date part from.
+     * @param array $types list of types to bind to the arguments
+     * @return \Cake\Database\Expression\FunctionExpression
+     */
+    public function datePart(string $part, $expression, array $types = []): FunctionExpression
+    {
+        return $this->extract($part, $expression, $types);
+    }
+
+    /**
+     * Returns the specified date part from the SQL expression.
+     *
+     * @param string $part Part of the date to return.
+     * @param \Cake\Database\ExpressionInterface|string $expression Expression to obtain the date part from.
+     * @param array $types list of types to bind to the arguments
+     * @return \Cake\Database\Expression\FunctionExpression
+     */
+    public function extract(string $part, $expression, array $types = []): FunctionExpression
+    {
+        $expression = new FunctionExpression('EXTRACT', $this->toLiteralParam($expression), $types, 'integer');
+        $expression->setConjunction(' FROM')->add([$part => 'literal'], [], true);
+
+        return $expression;
+    }
+
+    /**
+     * Add the time unit to the date expression
+     *
+     * @param \Cake\Database\ExpressionInterface|string $expression Expression to obtain the date part from.
+     * @param string|int $value Value to be added. Use negative to subtract.
+     * @param string $unit Unit of the value e.g. hour or day.
+     * @param array $types list of types to bind to the arguments
+     * @return \Cake\Database\Expression\FunctionExpression
+     */
+    public function dateAdd($expression, $value, string $unit, array $types = []): FunctionExpression
+    {
+        if (!is_numeric($value)) {
+            $value = 0;
+        }
+        $interval = $value . ' ' . $unit;
+        $expression = new FunctionExpression('DATE_ADD', $this->toLiteralParam($expression), $types, 'datetime');
+        $expression->setConjunction(', INTERVAL')->add([$interval => 'literal']);
+
+        return $expression;
+    }
+
+    /**
+     * Returns a FunctionExpression representing a call to SQL WEEKDAY function.
+     * 1 - Sunday, 2 - Monday, 3 - Tuesday...
+     *
+     * @param \Cake\Database\ExpressionInterface|string $expression the function argument
+     * @param array $types list of types to bind to the arguments
+     * @return \Cake\Database\Expression\FunctionExpression
+     */
+    public function dayOfWeek($expression, $types = []): FunctionExpression
+    {
+        return new FunctionExpression('DAYOFWEEK', $this->toLiteralParam($expression), $types, 'integer');
+    }
+
+    /**
+     * Returns a FunctionExpression representing a call to SQL WEEKDAY function.
+     * 1 - Sunday, 2 - Monday, 3 - Tuesday...
+     *
+     * @param \Cake\Database\ExpressionInterface|string $expression the function argument
+     * @param array $types list of types to bind to the arguments
+     * @return \Cake\Database\Expression\FunctionExpression
+     */
+    public function weekday($expression, $types = []): FunctionExpression
+    {
+        return $this->dayOfWeek($expression, $types);
+    }
+
+    /**
+     * Returns a FunctionExpression representing a call that will return the current
+     * date and time. By default it returns both date and time, but you can also
+     * make it generate only the date or only the time.
+     *
+     * @param string $type (datetime|date|time)
+     * @return \Cake\Database\Expression\FunctionExpression
+     */
+    public function now(string $type = 'datetime'): FunctionExpression
+    {
+        if ($type === 'datetime') {
+            return new FunctionExpression('NOW', [], [], 'datetime');
+        }
+        if ($type === 'date') {
+            return new FunctionExpression('CURRENT_DATE', [], [], 'date');
+        }
+        if ($type === 'time') {
+            return new FunctionExpression('CURRENT_TIME', [], [], 'time');
+        }
+
+        throw new InvalidArgumentException('Invalid argument for FunctionsBuilder::now(): ' . $type);
+    }
+
+    /**
+     * Returns an AggregateExpression representing call to SQL ROW_NUMBER().
+     *
+     * @return \Cake\Database\Expression\AggregateExpression
+     */
+    public function rowNumber(): AggregateExpression
+    {
+        return (new AggregateExpression('ROW_NUMBER', [], [], 'integer'))->over();
+    }
+
+    /**
+     * Returns an AggregateExpression representing call to SQL LAG().
+     *
+     * @param \Cake\Database\ExpressionInterface|string $expression The value evaluated at offset
+     * @param int $offset The row offset
+     * @param mixed $default The default value if offset doesn't exist
+     * @param string $type The output type of the lag expression. Defaults to float.
+     * @return \Cake\Database\Expression\AggregateExpression
+     */
+    public function lag($expression, int $offset, $default = null, $type = null): AggregateExpression
+    {
+        $params = $this->toLiteralParam($expression) + [$offset => 'literal'];
+        if ($default !== null) {
+            $params[] = $default;
+        }
+
+        $types = [];
+        if ($type !== null) {
+            $types = [$type, 'integer', $type];
+        }
+
+        return (new AggregateExpression('LAG', $params, $types, $type ?? 'float'))->over();
+    }
+
+    /**
+     * Returns an AggregateExpression representing call to SQL LEAD().
+     *
+     * @param \Cake\Database\ExpressionInterface|string $expression The value evaluated at offset
+     * @param int $offset The row offset
+     * @param mixed $default The default value if offset doesn't exist
+     * @param string $type The output type of the lead expression. Defaults to float.
+     * @return \Cake\Database\Expression\AggregateExpression
+     */
+    public function lead($expression, int $offset, $default = null, $type = null): AggregateExpression
+    {
+        $params = $this->toLiteralParam($expression) + [$offset => 'literal'];
+        if ($default !== null) {
+            $params[] = $default;
+        }
+
+        $types = [];
+        if ($type !== null) {
+            $types = [$type, 'integer', $type];
+        }
+
+        return (new AggregateExpression('LEAD', $params, $types, $type ?? 'float'))->over();
+    }
+
+    /**
+     * Helper method to create arbitrary SQL aggregate function calls.
+     *
+     * @param string $name The SQL aggregate function name
+     * @param array $params Array of arguments to be passed to the function.
+     *     Can be an associative array with the literal value or identifier:
+     *     `['value' => 'literal']` or `['value' => 'identifier']
+     * @param array $types Array of types that match the names used in `$params`:
+     *     `['name' => 'type']`
+     * @param string $return Return type of the entire expression. Defaults to float.
+     * @return \Cake\Database\Expression\AggregateExpression
+     */
+    public function aggregate(string $name, array $params = [], array $types = [], string $return = 'float')
+    {
+        return new AggregateExpression($name, $params, $types, $return);
+    }
+
+    /**
+     * Magic method dispatcher to create custom SQL function calls
+     *
+     * @param string $name the SQL function name to construct
+     * @param array $args list with up to 3 arguments, first one being an array with
+     * parameters for the SQL function, the second one a list of types to bind to those
+     * params, and the third one the return type of the function
+     * @return \Cake\Database\Expression\FunctionExpression
+     */
+    public function __call(string $name, array $args): FunctionExpression
+    {
+        return new FunctionExpression($name, ...$args);
+    }
+
+    /**
+     * Creates function parameter array from expression or string literal.
+     *
+     * @param \Cake\Database\ExpressionInterface|string $expression function argument
+     * @return array<\Cake\Database\ExpressionInterface|string>
+     */
+    protected function toLiteralParam($expression)
+    {
+        if (is_string($expression)) {
+            return [$expression => 'literal'];
+        }
+
+        return [$expression];
+    }
+}
diff --git a/vendor/cakephp/database/IdentifierQuoter.php b/vendor/cakephp/database/IdentifierQuoter.php
new file mode 100644
index 0000000..b3a93e2
--- /dev/null
+++ b/vendor/cakephp/database/IdentifierQuoter.php
@@ -0,0 +1,269 @@
+_driver = $driver;
+    }
+
+    /**
+     * Iterates over each of the clauses in a query looking for identifiers and
+     * quotes them
+     *
+     * @param \Cake\Database\Query $query The query to have its identifiers quoted
+     * @return \Cake\Database\Query
+     */
+    public function quote(Query $query): Query
+    {
+        $binder = $query->getValueBinder();
+        $query->setValueBinder(null);
+
+        if ($query->type() === 'insert') {
+            $this->_quoteInsert($query);
+        } elseif ($query->type() === 'update') {
+            $this->_quoteUpdate($query);
+        } else {
+            $this->_quoteParts($query);
+        }
+
+        $query->traverseExpressions([$this, 'quoteExpression']);
+        $query->setValueBinder($binder);
+
+        return $query;
+    }
+
+    /**
+     * Quotes identifiers inside expression objects
+     *
+     * @param \Cake\Database\ExpressionInterface $expression The expression object to walk and quote.
+     * @return void
+     */
+    public function quoteExpression(ExpressionInterface $expression): void
+    {
+        if ($expression instanceof FieldInterface) {
+            $this->_quoteComparison($expression);
+
+            return;
+        }
+
+        if ($expression instanceof OrderByExpression) {
+            $this->_quoteOrderBy($expression);
+
+            return;
+        }
+
+        if ($expression instanceof IdentifierExpression) {
+            $this->_quoteIdentifierExpression($expression);
+
+            return;
+        }
+    }
+
+    /**
+     * Quotes all identifiers in each of the clauses of a query
+     *
+     * @param \Cake\Database\Query $query The query to quote.
+     * @return void
+     */
+    protected function _quoteParts(Query $query): void
+    {
+        foreach (['distinct', 'select', 'from', 'group'] as $part) {
+            $contents = $query->clause($part);
+
+            if (!is_array($contents)) {
+                continue;
+            }
+
+            $result = $this->_basicQuoter($contents);
+            if (!empty($result)) {
+                $query->{$part}($result, true);
+            }
+        }
+
+        $joins = $query->clause('join');
+        if ($joins) {
+            $joins = $this->_quoteJoins($joins);
+            $query->join($joins, [], true);
+        }
+    }
+
+    /**
+     * A generic identifier quoting function used for various parts of the query
+     *
+     * @param array $part the part of the query to quote
+     * @return array
+     */
+    protected function _basicQuoter(array $part): array
+    {
+        $result = [];
+        foreach ($part as $alias => $value) {
+            $value = !is_string($value) ? $value : $this->_driver->quoteIdentifier($value);
+            $alias = is_numeric($alias) ? $alias : $this->_driver->quoteIdentifier($alias);
+            $result[$alias] = $value;
+        }
+
+        return $result;
+    }
+
+    /**
+     * Quotes both the table and alias for an array of joins as stored in a Query
+     * object
+     *
+     * @param array $joins The joins to quote.
+     * @return array
+     */
+    protected function _quoteJoins(array $joins): array
+    {
+        $result = [];
+        foreach ($joins as $value) {
+            $alias = '';
+            if (!empty($value['alias'])) {
+                $alias = $this->_driver->quoteIdentifier($value['alias']);
+                $value['alias'] = $alias;
+            }
+
+            if (is_string($value['table'])) {
+                $value['table'] = $this->_driver->quoteIdentifier($value['table']);
+            }
+
+            $result[$alias] = $value;
+        }
+
+        return $result;
+    }
+
+    /**
+     * Quotes the table name and columns for an insert query
+     *
+     * @param \Cake\Database\Query $query The insert query to quote.
+     * @return void
+     */
+    protected function _quoteInsert(Query $query): void
+    {
+        $insert = $query->clause('insert');
+        if (!isset($insert[0]) || !isset($insert[1])) {
+            return;
+        }
+        [$table, $columns] = $insert;
+        $table = $this->_driver->quoteIdentifier($table);
+        foreach ($columns as &$column) {
+            if (is_scalar($column)) {
+                $column = $this->_driver->quoteIdentifier((string)$column);
+            }
+        }
+        $query->insert($columns)->into($table);
+    }
+
+    /**
+     * Quotes the table name for an update query
+     *
+     * @param \Cake\Database\Query $query The update query to quote.
+     * @return void
+     */
+    protected function _quoteUpdate(Query $query): void
+    {
+        $table = $query->clause('update')[0];
+
+        if (is_string($table)) {
+            $query->update($this->_driver->quoteIdentifier($table));
+        }
+    }
+
+    /**
+     * Quotes identifiers in expression objects implementing the field interface
+     *
+     * @param \Cake\Database\Expression\FieldInterface $expression The expression to quote.
+     * @return void
+     */
+    protected function _quoteComparison(FieldInterface $expression): void
+    {
+        $field = $expression->getField();
+        if (is_string($field)) {
+            $expression->setField($this->_driver->quoteIdentifier($field));
+        } elseif (is_array($field)) {
+            $quoted = [];
+            foreach ($field as $f) {
+                $quoted[] = $this->_driver->quoteIdentifier($f);
+            }
+            $expression->setField($quoted);
+        } elseif ($field instanceof ExpressionInterface) {
+            $this->quoteExpression($field);
+        }
+    }
+
+    /**
+     * Quotes identifiers in "order by" expression objects
+     *
+     * Strings with spaces are treated as literal expressions
+     * and will not have identifiers quoted.
+     *
+     * @param \Cake\Database\Expression\OrderByExpression $expression The expression to quote.
+     * @return void
+     */
+    protected function _quoteOrderBy(OrderByExpression $expression): void
+    {
+        $expression->iterateParts(function ($part, &$field) {
+            if (is_string($field)) {
+                $field = $this->_driver->quoteIdentifier($field);
+
+                return $part;
+            }
+            if (is_string($part) && strpos($part, ' ') === false) {
+                return $this->_driver->quoteIdentifier($part);
+            }
+
+            return $part;
+        });
+    }
+
+    /**
+     * Quotes identifiers in "order by" expression objects
+     *
+     * @param \Cake\Database\Expression\IdentifierExpression $expression The identifiers to quote.
+     * @return void
+     */
+    protected function _quoteIdentifierExpression(IdentifierExpression $expression): void
+    {
+        $expression->setIdentifier(
+            $this->_driver->quoteIdentifier($expression->getIdentifier())
+        );
+    }
+}
diff --git a/vendor/cakephp/database/LICENSE.txt b/vendor/cakephp/database/LICENSE.txt
new file mode 100644
index 0000000..b938c9e
--- /dev/null
+++ b/vendor/cakephp/database/LICENSE.txt
@@ -0,0 +1,22 @@
+The MIT License (MIT)
+
+CakePHP(tm) : The Rapid Development PHP Framework (https://cakephp.org)
+Copyright (c) 2005-2020, Cake Software Foundation, Inc. (https://cakefoundation.org)
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
diff --git a/vendor/cakephp/database/Log/LoggedQuery.php b/vendor/cakephp/database/Log/LoggedQuery.php
new file mode 100644
index 0000000..f029bc9
--- /dev/null
+++ b/vendor/cakephp/database/Log/LoggedQuery.php
@@ -0,0 +1,176 @@
+driver instanceof Sqlserver) {
+                    return $p ? '1' : '0';
+                }
+
+                return $p ? 'TRUE' : 'FALSE';
+            }
+
+            if (is_string($p)) {
+                // Likely binary data like a blob or binary uuid.
+                // pattern matches ascii control chars.
+                if (preg_replace('/[\x00-\x08\x0B\x0C\x0E-\x1F\x7F]/u', '', $p) !== $p) {
+                    $p = bin2hex($p);
+                }
+
+                $replacements = [
+                    '$' => '\\$',
+                    '\\' => '\\\\\\\\',
+                    "'" => "''",
+                ];
+
+                $p = strtr($p, $replacements);
+
+                return "'$p'";
+            }
+
+            return $p;
+        }, $this->params);
+
+        $keys = [];
+        $limit = is_int(key($params)) ? 1 : -1;
+        foreach ($params as $key => $param) {
+            $keys[] = is_string($key) ? "/:$key\b/" : '/[?]/';
+        }
+
+        return preg_replace($keys, $params, $this->query, $limit);
+    }
+
+    /**
+     * Get the logging context data for a query.
+     *
+     * @return array
+     */
+    public function getContext(): array
+    {
+        return [
+            'numRows' => $this->numRows,
+            'took' => $this->took,
+            'role' => $this->driver ? $this->driver->getRole() : '',
+        ];
+    }
+
+    /**
+     * Returns data that will be serialized as JSON
+     *
+     * @return array
+     */
+    public function jsonSerialize(): array
+    {
+        $error = $this->error;
+        if ($error !== null) {
+            $error = [
+                'class' => get_class($error),
+                'message' => $error->getMessage(),
+                'code' => $error->getCode(),
+            ];
+        }
+
+        return [
+            'query' => $this->query,
+            'numRows' => $this->numRows,
+            'params' => $this->params,
+            'took' => $this->took,
+            'error' => $error,
+        ];
+    }
+
+    /**
+     * Returns the string representation of this logged query
+     *
+     * @return string
+     */
+    public function __toString(): string
+    {
+        $sql = $this->query;
+        if (!empty($this->params)) {
+            $sql = $this->interpolate();
+        }
+
+        return $sql;
+    }
+}
diff --git a/vendor/cakephp/database/Log/LoggingStatement.php b/vendor/cakephp/database/Log/LoggingStatement.php
new file mode 100644
index 0000000..e83f6f6
--- /dev/null
+++ b/vendor/cakephp/database/Log/LoggingStatement.php
@@ -0,0 +1,219 @@
+
+     */
+    protected $_compiledParams = [];
+
+    /**
+     * Query execution start time.
+     *
+     * @var float
+     */
+    protected $startTime = 0.0;
+
+    /**
+     * Logged query
+     *
+     * @var \Cake\Database\Log\LoggedQuery|null
+     */
+    protected $loggedQuery;
+
+    /**
+     * Wrapper for the execute function to calculate time spent
+     * and log the query afterwards.
+     *
+     * @param array|null $params List of values to be bound to query
+     * @return bool True on success, false otherwise
+     * @throws \Exception Re-throws any exception raised during query execution.
+     */
+    public function execute(?array $params = null): bool
+    {
+        $this->startTime = microtime(true);
+
+        $this->loggedQuery = new LoggedQuery();
+        $this->loggedQuery->driver = $this->_driver;
+        $this->loggedQuery->params = $params ?: $this->_compiledParams;
+
+        try {
+            $result = parent::execute($params);
+            $this->loggedQuery->took = (int)round((microtime(true) - $this->startTime) * 1000, 0);
+        } catch (Exception $e) {
+            $this->loggedQuery->error = $e;
+            $this->_log();
+
+            if (Configure::read('Error.convertStatementToDatabaseException', false) === true) {
+                $code = $e->getCode();
+                if (!is_int($code)) {
+                    $code = null;
+                }
+
+                throw new DatabaseException([
+                    'message' => $e->getMessage(),
+                    'queryString' => $this->queryString,
+                ], $code, $e);
+            }
+
+            if (version_compare(PHP_VERSION, '8.2.0', '<')) {
+                deprecationWarning(
+                    '4.4.12 - Having queryString set on exceptions is deprecated.' .
+                    'If you are not using this attribute there is no action to take.' .
+                    'Otherwise, enable Error.convertStatementToDatabaseException.'
+                );
+                /** @psalm-suppress UndefinedPropertyAssignment */
+                $e->queryString = $this->queryString;
+            }
+
+            throw $e;
+        }
+
+        if (preg_match('/^(?!SELECT)/i', $this->queryString)) {
+            $this->rowCount();
+        }
+
+        return $result;
+    }
+
+    /**
+     * @inheritDoc
+     */
+    public function fetch($type = self::FETCH_TYPE_NUM)
+    {
+        $record = parent::fetch($type);
+
+        if ($this->loggedQuery) {
+            $this->rowCount();
+        }
+
+        return $record;
+    }
+
+    /**
+     * @inheritDoc
+     */
+    public function fetchAll($type = self::FETCH_TYPE_NUM)
+    {
+        $results = parent::fetchAll($type);
+
+        if ($this->loggedQuery) {
+            $this->rowCount();
+        }
+
+        return $results;
+    }
+
+    /**
+     * @inheritDoc
+     */
+    public function rowCount(): int
+    {
+        $result = parent::rowCount();
+
+        if ($this->loggedQuery) {
+            $this->loggedQuery->numRows = $result;
+            $this->_log();
+        }
+
+        return $result;
+    }
+
+    /**
+     * Copies the logging data to the passed LoggedQuery and sends it
+     * to the logging system.
+     *
+     * @return void
+     */
+    protected function _log(): void
+    {
+        if ($this->loggedQuery === null) {
+            return;
+        }
+
+        $this->loggedQuery->query = $this->queryString;
+        $this->getLogger()->debug((string)$this->loggedQuery, ['query' => $this->loggedQuery]);
+
+        $this->loggedQuery = null;
+    }
+
+    /**
+     * Wrapper for bindValue function to gather each parameter to be later used
+     * in the logger function.
+     *
+     * @param string|int $column Name or param position to be bound
+     * @param mixed $value The value to bind to variable in query
+     * @param string|int|null $type PDO type or name of configured Type class
+     * @return void
+     */
+    public function bindValue($column, $value, $type = 'string'): void
+    {
+        parent::bindValue($column, $value, $type);
+
+        if ($type === null) {
+            $type = 'string';
+        }
+        if (!ctype_digit($type)) {
+            $value = $this->cast($value, $type)[0];
+        }
+        $this->_compiledParams[$column] = $value;
+    }
+
+    /**
+     * Sets a logger
+     *
+     * @param \Psr\Log\LoggerInterface $logger Logger object
+     * @return void
+     */
+    public function setLogger(LoggerInterface $logger): void
+    {
+        $this->_logger = $logger;
+    }
+
+    /**
+     * Gets the logger object
+     *
+     * @return \Psr\Log\LoggerInterface logger instance
+     */
+    public function getLogger(): LoggerInterface
+    {
+        return $this->_logger;
+    }
+}
diff --git a/vendor/cakephp/database/Log/QueryLogger.php b/vendor/cakephp/database/Log/QueryLogger.php
new file mode 100644
index 0000000..e2faadc
--- /dev/null
+++ b/vendor/cakephp/database/Log/QueryLogger.php
@@ -0,0 +1,57 @@
+ $config Configuration array
+     */
+    public function __construct(array $config = [])
+    {
+        $this->_defaultConfig['scopes'] = ['queriesLog'];
+        $this->_defaultConfig['connection'] = '';
+
+        parent::__construct($config);
+    }
+
+    /**
+     * @inheritDoc
+     */
+    public function log($level, $message, array $context = [])
+    {
+        $context['scope'] = $this->scopes() ?: ['queriesLog'];
+        $context['connection'] = $this->getConfig('connection');
+
+        if ($context['query'] instanceof LoggedQuery) {
+            $context = $context['query']->getContext() + $context;
+            $message = 'connection={connection} role={role} duration={took} rows={numRows} ' . $message;
+        }
+        Log::write('debug', (string)$message, $context);
+    }
+}
diff --git a/vendor/cakephp/database/PostgresCompiler.php b/vendor/cakephp/database/PostgresCompiler.php
new file mode 100644
index 0000000..7beae8b
--- /dev/null
+++ b/vendor/cakephp/database/PostgresCompiler.php
@@ -0,0 +1,93 @@
+ 'DELETE',
+        'where' => ' WHERE %s',
+        'group' => ' GROUP BY %s',
+        'order' => ' %s',
+        'limit' => ' LIMIT %s',
+        'offset' => ' OFFSET %s',
+        'epilog' => ' %s',
+    ];
+
+    /**
+     * Helper function used to build the string representation of a HAVING clause,
+     * it constructs the field list taking care of aliasing and
+     * converting expression objects to string.
+     *
+     * @param array $parts list of fields to be transformed to string
+     * @param \Cake\Database\Query $query The query that is being compiled
+     * @param \Cake\Database\ValueBinder $binder Value binder used to generate parameter placeholder
+     * @return string
+     */
+    protected function _buildHavingPart($parts, $query, $binder)
+    {
+        $selectParts = $query->clause('select');
+
+        foreach ($selectParts as $selectKey => $selectPart) {
+            if (!$selectPart instanceof FunctionExpression) {
+                continue;
+            }
+            foreach ($parts as $k => $p) {
+                if (!is_string($p)) {
+                    continue;
+                }
+                preg_match_all(
+                    '/\b' . trim($selectKey, '"') . '\b/i',
+                    $p,
+                    $matches
+                );
+
+                if (empty($matches[0])) {
+                    continue;
+                }
+
+                $parts[$k] = preg_replace(
+                    ['/"/', '/\b' . trim($selectKey, '"') . '\b/i'],
+                    ['', $selectPart->sql($binder)],
+                    $p
+                );
+            }
+        }
+
+        return sprintf(' HAVING %s', implode(', ', $parts));
+    }
+}
diff --git a/vendor/cakephp/database/Query.php b/vendor/cakephp/database/Query.php
new file mode 100644
index 0000000..594b8a7
--- /dev/null
+++ b/vendor/cakephp/database/Query.php
@@ -0,0 +1,2516 @@
+
+     */
+    protected $_parts = [
+        'delete' => true,
+        'update' => [],
+        'set' => [],
+        'insert' => [],
+        'values' => [],
+        'with' => [],
+        'select' => [],
+        'distinct' => false,
+        'modifier' => [],
+        'from' => [],
+        'join' => [],
+        'where' => null,
+        'group' => [],
+        'having' => null,
+        'window' => [],
+        'order' => null,
+        'limit' => null,
+        'offset' => null,
+        'union' => [],
+        'epilog' => null,
+    ];
+
+    /**
+     * The list of query clauses to traverse for generating a SELECT statement
+     *
+     * @var array
+     * @deprecated 4.4.3 This property is unused.
+     */
+    protected $_selectParts = [
+        'with', 'select', 'from', 'join', 'where', 'group', 'having', 'order', 'limit',
+        'offset', 'union', 'epilog',
+    ];
+
+    /**
+     * The list of query clauses to traverse for generating an UPDATE statement
+     *
+     * @var array
+     * @deprecated 4.4.3 This property is unused.
+     */
+    protected $_updateParts = ['with', 'update', 'set', 'where', 'epilog'];
+
+    /**
+     * The list of query clauses to traverse for generating a DELETE statement
+     *
+     * @var array
+     * @deprecated 4.4.3 This property is unused.
+     */
+    protected $_deleteParts = ['with', 'delete', 'modifier', 'from', 'where', 'epilog'];
+
+    /**
+     * The list of query clauses to traverse for generating an INSERT statement
+     *
+     * @var array
+     * @deprecated 4.4.3 This property is unused.
+     */
+    protected $_insertParts = ['with', 'insert', 'values', 'epilog'];
+
+    /**
+     * Indicates whether internal state of this query was changed, this is used to
+     * discard internal cached objects such as the transformed query or the reference
+     * to the executed statement.
+     *
+     * @var bool
+     */
+    protected $_dirty = false;
+
+    /**
+     * A list of callback functions to be called to alter each row from resulting
+     * statement upon retrieval. Each one of the callback function will receive
+     * the row array as first argument.
+     *
+     * @var array
+     */
+    protected $_resultDecorators = [];
+
+    /**
+     * Statement object resulting from executing this query.
+     *
+     * @var \Cake\Database\StatementInterface|null
+     */
+    protected $_iterator;
+
+    /**
+     * The object responsible for generating query placeholders and temporarily store values
+     * associated to each of those.
+     *
+     * @var \Cake\Database\ValueBinder|null
+     */
+    protected $_valueBinder;
+
+    /**
+     * Instance of functions builder object used for generating arbitrary SQL functions.
+     *
+     * @var \Cake\Database\FunctionsBuilder|null
+     */
+    protected $_functionsBuilder;
+
+    /**
+     * Boolean for tracking whether buffered results
+     * are enabled.
+     *
+     * @var bool
+     * @deprecated 4.5.0 Results will always be buffered in 5.0.
+     */
+    protected $_useBufferedResults = true;
+
+    /**
+     * The Type map for fields in the select clause
+     *
+     * @var \Cake\Database\TypeMap|null
+     */
+    protected $_selectTypeMap;
+
+    /**
+     * Tracking flag to disable casting
+     *
+     * @var bool
+     */
+    protected $typeCastEnabled = true;
+
+    /**
+     * Constructor.
+     *
+     * @param \Cake\Database\Connection $connection The connection
+     * object to be used for transforming and executing this query
+     */
+    public function __construct(Connection $connection)
+    {
+        $this->setConnection($connection);
+    }
+
+    /**
+     * Sets the connection instance to be used for executing and transforming this query.
+     *
+     * @param \Cake\Database\Connection $connection Connection instance
+     * @return $this
+     */
+    public function setConnection(Connection $connection)
+    {
+        $this->_dirty();
+        $this->_connection = $connection;
+
+        return $this;
+    }
+
+    /**
+     * Gets the connection instance to be used for executing and transforming this query.
+     *
+     * @return \Cake\Database\Connection
+     */
+    public function getConnection(): Connection
+    {
+        return $this->_connection;
+    }
+
+    /**
+     * Returns the connection role ('read' or 'write')
+     *
+     * @return string
+     */
+    public function getConnectionRole(): string
+    {
+        return $this->connectionRole;
+    }
+
+    /**
+     * Compiles the SQL representation of this query and executes it using the
+     * configured connection object. Returns the resulting statement object.
+     *
+     * Executing a query internally executes several steps, the first one is
+     * letting the connection transform this object to fit its particular dialect,
+     * this might result in generating a different Query object that will be the one
+     * to actually be executed. Immediately after, literal values are passed to the
+     * connection so they are bound to the query in a safe way. Finally, the resulting
+     * statement is decorated with custom objects to execute callbacks for each row
+     * retrieved if necessary.
+     *
+     * Resulting statement is traversable, so it can be used in any loop as you would
+     * with an array.
+     *
+     * This method can be overridden in query subclasses to decorate behavior
+     * around query execution.
+     *
+     * @return \Cake\Database\StatementInterface
+     */
+    public function execute(): StatementInterface
+    {
+        $statement = $this->_connection->run($this);
+        $this->_iterator = $this->_decorateStatement($statement);
+        $this->_dirty = false;
+
+        return $this->_iterator;
+    }
+
+    /**
+     * Executes the SQL of this query and immediately closes the statement before returning the row count of records
+     * changed.
+     *
+     * This method can be used with UPDATE and DELETE queries, but is not recommended for SELECT queries and is not
+     * used to count records.
+     *
+     * ## Example
+     *
+     * ```
+     * $rowCount = $query->update('articles')
+     *                 ->set(['published'=>true])
+     *                 ->where(['published'=>false])
+     *                 ->rowCountAndClose();
+     * ```
+     *
+     * The above example will change the published column to true for all false records, and return the number of
+     * records that were updated.
+     *
+     * @return int
+     */
+    public function rowCountAndClose(): int
+    {
+        $statement = $this->execute();
+        try {
+            return $statement->rowCount();
+        } finally {
+            $statement->closeCursor();
+        }
+    }
+
+    /**
+     * Returns the SQL representation of this object.
+     *
+     * This function will compile this query to make it compatible
+     * with the SQL dialect that is used by the connection, This process might
+     * add, remove or alter any query part or internal expression to make it
+     * executable in the target platform.
+     *
+     * The resulting query may have placeholders that will be replaced with the actual
+     * values when the query is executed, hence it is most suitable to use with
+     * prepared statements.
+     *
+     * @param \Cake\Database\ValueBinder|null $binder Value binder that generates parameter placeholders
+     * @return string
+     */
+    public function sql(?ValueBinder $binder = null): string
+    {
+        if (!$binder) {
+            $binder = $this->getValueBinder();
+            $binder->resetCount();
+        }
+        $connection = $this->getConnection();
+
+        return $connection->getDriver($this->getConnectionRole())->compileQuery($this, $binder)[1];
+    }
+
+    /**
+     * Will iterate over every specified part. Traversing functions can aggregate
+     * results using variables in the closure or instance variables. This function
+     * is commonly used as a way for traversing all query parts that
+     * are going to be used for constructing a query.
+     *
+     * The callback will receive 2 parameters, the first one is the value of the query
+     * part that is being iterated and the second the name of such part.
+     *
+     * ### Example
+     * ```
+     * $query->select(['title'])->from('articles')->traverse(function ($value, $clause) {
+     *     if ($clause === 'select') {
+     *         var_dump($value);
+     *     }
+     * });
+     * ```
+     *
+     * @param callable $callback A function or callable to be executed for each part
+     * @return $this
+     */
+    public function traverse($callback)
+    {
+        foreach ($this->_parts as $name => $part) {
+            $callback($part, $name);
+        }
+
+        return $this;
+    }
+
+    /**
+     * Will iterate over the provided parts.
+     *
+     * Traversing functions can aggregate results using variables in the closure
+     * or instance variables. This method can be used to traverse a subset of
+     * query parts in order to render a SQL query.
+     *
+     * The callback will receive 2 parameters, the first one is the value of the query
+     * part that is being iterated and the second the name of such part.
+     *
+     * ### Example
+     *
+     * ```
+     * $query->select(['title'])->from('articles')->traverse(function ($value, $clause) {
+     *     if ($clause === 'select') {
+     *         var_dump($value);
+     *     }
+     * }, ['select', 'from']);
+     * ```
+     *
+     * @param callable $visitor A function or callable to be executed for each part
+     * @param array $parts The list of query parts to traverse
+     * @return $this
+     */
+    public function traverseParts(callable $visitor, array $parts)
+    {
+        foreach ($parts as $name) {
+            $visitor($this->_parts[$name], $name);
+        }
+
+        return $this;
+    }
+
+    /**
+     * Adds a new common table expression (CTE) to the query.
+     *
+     * ### Examples:
+     *
+     * Common table expressions can either be passed as preconstructed expression
+     * objects:
+     *
+     * ```
+     * $cte = new \Cake\Database\Expression\CommonTableExpression(
+     *     'cte',
+     *     $connection
+     *         ->newQuery()
+     *         ->select('*')
+     *         ->from('articles')
+     * );
+     *
+     * $query->with($cte);
+     * ```
+     *
+     * or returned from a closure, which will receive a new common table expression
+     * object as the first argument, and a new blank query object as
+     * the second argument:
+     *
+     * ```
+     * $query->with(function (
+     *     \Cake\Database\Expression\CommonTableExpression $cte,
+     *     \Cake\Database\Query $query
+     *  ) {
+     *     $cteQuery = $query
+     *         ->select('*')
+     *         ->from('articles');
+     *
+     *     return $cte
+     *         ->name('cte')
+     *         ->query($cteQuery);
+     * });
+     * ```
+     *
+     * @param \Cake\Database\Expression\CommonTableExpression|\Closure $cte The CTE to add.
+     * @param bool $overwrite Whether to reset the list of CTEs.
+     * @return $this
+     */
+    public function with($cte, bool $overwrite = false)
+    {
+        if ($overwrite) {
+            $this->_parts['with'] = [];
+        }
+
+        if ($cte instanceof Closure) {
+            $query = $this->getConnection()->selectQuery();
+            $cte = $cte(new CommonTableExpression(), $query);
+            if (!($cte instanceof CommonTableExpression)) {
+                throw new RuntimeException(
+                    'You must return a `CommonTableExpression` from a Closure passed to `with()`.'
+                );
+            }
+        }
+
+        $this->_parts['with'][] = $cte;
+        $this->_dirty();
+
+        return $this;
+    }
+
+    /**
+     * Adds new fields to be returned by a `SELECT` statement when this query is
+     * executed. Fields can be passed as an array of strings, array of expression
+     * objects, a single expression or a single string.
+     *
+     * If an array is passed, keys will be used to alias fields using the value as the
+     * real field to be aliased. It is possible to alias strings, Expression objects or
+     * even other Query objects.
+     *
+     * If a callable function is passed, the returning array of the function will
+     * be used as the list of fields.
+     *
+     * By default this function will append any passed argument to the list of fields
+     * to be selected, unless the second argument is set to true.
+     *
+     * ### Examples:
+     *
+     * ```
+     * $query->select(['id', 'title']); // Produces SELECT id, title
+     * $query->select(['author' => 'author_id']); // Appends author: SELECT id, title, author_id as author
+     * $query->select('id', true); // Resets the list: SELECT id
+     * $query->select(['total' => $countQuery]); // SELECT id, (SELECT ...) AS total
+     * $query->select(function ($query) {
+     *     return ['article_id', 'total' => $query->count('*')];
+     * })
+     * ```
+     *
+     * By default no fields are selected, if you have an instance of `Cake\ORM\Query` and try to append
+     * fields you should also call `Cake\ORM\Query::enableAutoFields()` to select the default fields
+     * from the table.
+     *
+     * @param \Cake\Database\ExpressionInterface|callable|array|string $fields fields to be added to the list.
+     * @param bool $overwrite whether to reset fields with passed list or not
+     * @return $this
+     */
+    public function select($fields = [], bool $overwrite = false)
+    {
+        if (!is_string($fields) && is_callable($fields)) {
+            $fields = $fields($this);
+        }
+
+        if (!is_array($fields)) {
+            $fields = [$fields];
+        }
+
+        if ($overwrite) {
+            $this->_parts['select'] = $fields;
+        } else {
+            $this->_parts['select'] = array_merge($this->_parts['select'], $fields);
+        }
+
+        $this->_dirty();
+        $this->_type = 'select';
+
+        return $this;
+    }
+
+    /**
+     * Adds a `DISTINCT` clause to the query to remove duplicates from the result set.
+     * This clause can only be used for select statements.
+     *
+     * If you wish to filter duplicates based of those rows sharing a particular field
+     * or set of fields, you may pass an array of fields to filter on. Beware that
+     * this option might not be fully supported in all database systems.
+     *
+     * ### Examples:
+     *
+     * ```
+     * // Filters products with the same name and city
+     * $query->select(['name', 'city'])->from('products')->distinct();
+     *
+     * // Filters products in the same city
+     * $query->distinct(['city']);
+     * $query->distinct('city');
+     *
+     * // Filter products with the same name
+     * $query->distinct(['name'], true);
+     * $query->distinct('name', true);
+     * ```
+     *
+     * @param \Cake\Database\ExpressionInterface|array|string|bool $on Enable/disable distinct class
+     * or list of fields to be filtered on
+     * @param bool $overwrite whether to reset fields with passed list or not
+     * @return $this
+     */
+    public function distinct($on = [], $overwrite = false)
+    {
+        if ($on === []) {
+            $on = true;
+        } elseif (is_string($on)) {
+            $on = [$on];
+        }
+
+        if (is_array($on)) {
+            $merge = [];
+            if (is_array($this->_parts['distinct'])) {
+                $merge = $this->_parts['distinct'];
+            }
+            $on = $overwrite ? array_values($on) : array_merge($merge, array_values($on));
+        }
+
+        $this->_parts['distinct'] = $on;
+        $this->_dirty();
+
+        return $this;
+    }
+
+    /**
+     * Adds a single or multiple `SELECT` modifiers to be used in the `SELECT`.
+     *
+     * By default this function will append any passed argument to the list of modifiers
+     * to be applied, unless the second argument is set to true.
+     *
+     * ### Example:
+     *
+     * ```
+     * // Ignore cache query in MySQL
+     * $query->select(['name', 'city'])->from('products')->modifier('SQL_NO_CACHE');
+     * // It will produce the SQL: SELECT SQL_NO_CACHE name, city FROM products
+     *
+     * // Or with multiple modifiers
+     * $query->select(['name', 'city'])->from('products')->modifier(['HIGH_PRIORITY', 'SQL_NO_CACHE']);
+     * // It will produce the SQL: SELECT HIGH_PRIORITY SQL_NO_CACHE name, city FROM products
+     * ```
+     *
+     * @param \Cake\Database\ExpressionInterface|array|string $modifiers modifiers to be applied to the query
+     * @param bool $overwrite whether to reset order with field list or not
+     * @return $this
+     */
+    public function modifier($modifiers, $overwrite = false)
+    {
+        $this->_dirty();
+        if ($overwrite) {
+            $this->_parts['modifier'] = [];
+        }
+        if (!is_array($modifiers)) {
+            $modifiers = [$modifiers];
+        }
+        $this->_parts['modifier'] = array_merge($this->_parts['modifier'], $modifiers);
+
+        return $this;
+    }
+
+    /**
+     * Adds a single or multiple tables to be used in the FROM clause for this query.
+     * Tables can be passed as an array of strings, array of expression
+     * objects, a single expression or a single string.
+     *
+     * If an array is passed, keys will be used to alias tables using the value as the
+     * real field to be aliased. It is possible to alias strings, ExpressionInterface objects or
+     * even other Query objects.
+     *
+     * By default this function will append any passed argument to the list of tables
+     * to be selected from, unless the second argument is set to true.
+     *
+     * This method can be used for select, update and delete statements.
+     *
+     * ### Examples:
+     *
+     * ```
+     * $query->from(['p' => 'posts']); // Produces FROM posts p
+     * $query->from('authors'); // Appends authors: FROM posts p, authors
+     * $query->from(['products'], true); // Resets the list: FROM products
+     * $query->from(['sub' => $countQuery]); // FROM (SELECT ...) sub
+     * ```
+     *
+     * @param array|string $tables tables to be added to the list. This argument, can be
+     *  passed as an array of strings, array of expression objects, or a single string. See
+     *  the examples above for the valid call types.
+     * @param bool $overwrite whether to reset tables with passed list or not
+     * @return $this
+     */
+    public function from($tables = [], $overwrite = false)
+    {
+        $tables = (array)$tables;
+
+        if ($overwrite) {
+            $this->_parts['from'] = $tables;
+        } else {
+            $this->_parts['from'] = array_merge($this->_parts['from'], $tables);
+        }
+
+        $this->_dirty();
+
+        return $this;
+    }
+
+    /**
+     * Adds a single or multiple tables to be used as JOIN clauses to this query.
+     * Tables can be passed as an array of strings, an array describing the
+     * join parts, an array with multiple join descriptions, or a single string.
+     *
+     * By default this function will append any passed argument to the list of tables
+     * to be joined, unless the third argument is set to true.
+     *
+     * When no join type is specified an `INNER JOIN` is used by default:
+     * `$query->join(['authors'])` will produce `INNER JOIN authors ON 1 = 1`
+     *
+     * It is also possible to alias joins using the array key:
+     * `$query->join(['a' => 'authors'])` will produce `INNER JOIN authors a ON 1 = 1`
+     *
+     * A join can be fully described and aliased using the array notation:
+     *
+     * ```
+     * $query->join([
+     *     'a' => [
+     *         'table' => 'authors',
+     *         'type' => 'LEFT',
+     *         'conditions' => 'a.id = b.author_id'
+     *     ]
+     * ]);
+     * // Produces LEFT JOIN authors a ON a.id = b.author_id
+     * ```
+     *
+     * You can even specify multiple joins in an array, including the full description:
+     *
+     * ```
+     * $query->join([
+     *     'a' => [
+     *         'table' => 'authors',
+     *         'type' => 'LEFT',
+     *         'conditions' => 'a.id = b.author_id'
+     *     ],
+     *     'p' => [
+     *         'table' => 'publishers',
+     *         'type' => 'INNER',
+     *         'conditions' => 'p.id = b.publisher_id AND p.name = "Cake Software Foundation"'
+     *     ]
+     * ]);
+     * // LEFT JOIN authors a ON a.id = b.author_id
+     * // INNER JOIN publishers p ON p.id = b.publisher_id AND p.name = "Cake Software Foundation"
+     * ```
+     *
+     * ### Using conditions and types
+     *
+     * Conditions can be expressed, as in the examples above, using a string for comparing
+     * columns, or string with already quoted literal values. Additionally it is
+     * possible to use conditions expressed in arrays or expression objects.
+     *
+     * When using arrays for expressing conditions, it is often desirable to convert
+     * the literal values to the correct database representation. This is achieved
+     * using the second parameter of this function.
+     *
+     * ```
+     * $query->join(['a' => [
+     *     'table' => 'articles',
+     *     'conditions' => [
+     *         'a.posted >=' => new DateTime('-3 days'),
+     *         'a.published' => true,
+     *         'a.author_id = authors.id'
+     *     ]
+     * ]], ['a.posted' => 'datetime', 'a.published' => 'boolean'])
+     * ```
+     *
+     * ### Overwriting joins
+     *
+     * When creating aliased joins using the array notation, you can override
+     * previous join definitions by using the same alias in consequent
+     * calls to this function or you can replace all previously defined joins
+     * with another list if the third parameter for this function is set to true.
+     *
+     * ```
+     * $query->join(['alias' => 'table']); // joins table with as alias
+     * $query->join(['alias' => 'another_table']); // joins another_table with as alias
+     * $query->join(['something' => 'different_table'], [], true); // resets joins list
+     * ```
+     *
+     * @param array|string $tables list of tables to be joined in the query
+     * @param array $types Associative array of type names used to bind values to query
+     * @param bool $overwrite whether to reset joins with passed list or not
+     * @see \Cake\Database\TypeFactory
+     * @return $this
+     */
+    public function join($tables, $types = [], $overwrite = false)
+    {
+        if (is_string($tables) || isset($tables['table'])) {
+            $tables = [$tables];
+        }
+
+        $joins = [];
+        $i = count($this->_parts['join']);
+        foreach ($tables as $alias => $t) {
+            if (!is_array($t)) {
+                $t = ['table' => $t, 'conditions' => $this->newExpr()];
+            }
+
+            if (!is_string($t['conditions']) && is_callable($t['conditions'])) {
+                $t['conditions'] = $t['conditions']($this->newExpr(), $this);
+            }
+
+            if (!($t['conditions'] instanceof ExpressionInterface)) {
+                $t['conditions'] = $this->newExpr()->add($t['conditions'], $types);
+            }
+            $alias = is_string($alias) ? $alias : null;
+            $joins[$alias ?: $i++] = $t + ['type' => static::JOIN_TYPE_INNER, 'alias' => $alias];
+        }
+
+        if ($overwrite) {
+            $this->_parts['join'] = $joins;
+        } else {
+            $this->_parts['join'] = array_merge($this->_parts['join'], $joins);
+        }
+
+        $this->_dirty();
+
+        return $this;
+    }
+
+    /**
+     * Remove a join if it has been defined.
+     *
+     * Useful when you are redefining joins or want to re-order
+     * the join clauses.
+     *
+     * @param string $name The alias/name of the join to remove.
+     * @return $this
+     */
+    public function removeJoin(string $name)
+    {
+        unset($this->_parts['join'][$name]);
+        $this->_dirty();
+
+        return $this;
+    }
+
+    /**
+     * Adds a single `LEFT JOIN` clause to the query.
+     *
+     * This is a shorthand method for building joins via `join()`.
+     *
+     * The table name can be passed as a string, or as an array in case it needs to
+     * be aliased:
+     *
+     * ```
+     * // LEFT JOIN authors ON authors.id = posts.author_id
+     * $query->leftJoin('authors', 'authors.id = posts.author_id');
+     *
+     * // LEFT JOIN authors a ON a.id = posts.author_id
+     * $query->leftJoin(['a' => 'authors'], 'a.id = posts.author_id');
+     * ```
+     *
+     * Conditions can be passed as strings, arrays, or expression objects. When
+     * using arrays it is possible to combine them with the `$types` parameter
+     * in order to define how to convert the values:
+     *
+     * ```
+     * $query->leftJoin(['a' => 'articles'], [
+     *      'a.posted >=' => new DateTime('-3 days'),
+     *      'a.published' => true,
+     *      'a.author_id = authors.id'
+     * ], ['a.posted' => 'datetime', 'a.published' => 'boolean']);
+     * ```
+     *
+     * See `join()` for further details on conditions and types.
+     *
+     * @param array|string $table The table to join with
+     * @param \Cake\Database\ExpressionInterface|array|string $conditions The conditions
+     * to use for joining.
+     * @param array $types a list of types associated to the conditions used for converting
+     * values to the corresponding database representation.
+     * @return $this
+     */
+    public function leftJoin($table, $conditions = [], $types = [])
+    {
+        $this->join($this->_makeJoin($table, $conditions, static::JOIN_TYPE_LEFT), $types);
+
+        return $this;
+    }
+
+    /**
+     * Adds a single `RIGHT JOIN` clause to the query.
+     *
+     * This is a shorthand method for building joins via `join()`.
+     *
+     * The arguments of this method are identical to the `leftJoin()` shorthand, please refer
+     * to that methods description for further details.
+     *
+     * @param array|string $table The table to join with
+     * @param \Cake\Database\ExpressionInterface|array|string $conditions The conditions
+     * to use for joining.
+     * @param array $types a list of types associated to the conditions used for converting
+     * values to the corresponding database representation.
+     * @return $this
+     */
+    public function rightJoin($table, $conditions = [], $types = [])
+    {
+        $this->join($this->_makeJoin($table, $conditions, static::JOIN_TYPE_RIGHT), $types);
+
+        return $this;
+    }
+
+    /**
+     * Adds a single `INNER JOIN` clause to the query.
+     *
+     * This is a shorthand method for building joins via `join()`.
+     *
+     * The arguments of this method are identical to the `leftJoin()` shorthand, please refer
+     * to that method's description for further details.
+     *
+     * @param array|string $table The table to join with
+     * @param \Cake\Database\ExpressionInterface|array|string $conditions The conditions
+     * to use for joining.
+     * @param array $types a list of types associated to the conditions used for converting
+     * values to the corresponding database representation.
+     * @return $this
+     */
+    public function innerJoin($table, $conditions = [], $types = [])
+    {
+        $this->join($this->_makeJoin($table, $conditions, static::JOIN_TYPE_INNER), $types);
+
+        return $this;
+    }
+
+    /**
+     * Returns an array that can be passed to the join method describing a single join clause
+     *
+     * @param array|string $table The table to join with
+     * @param \Cake\Database\ExpressionInterface|array|string $conditions The conditions
+     * to use for joining.
+     * @param string $type the join type to use
+     * @return array
+     */
+    protected function _makeJoin($table, $conditions, $type): array
+    {
+        $alias = $table;
+
+        if (is_array($table)) {
+            $alias = key($table);
+            $table = current($table);
+        }
+
+        /**
+         * @psalm-suppress InvalidArrayOffset
+         */
+        return [
+            $alias => [
+                'table' => $table,
+                'conditions' => $conditions,
+                'type' => $type,
+            ],
+        ];
+    }
+
+    /**
+     * Adds a condition or set of conditions to be used in the WHERE clause for this
+     * query. Conditions can be expressed as an array of fields as keys with
+     * comparison operators in it, the values for the array will be used for comparing
+     * the field to such literal. Finally, conditions can be expressed as a single
+     * string or an array of strings.
+     *
+     * When using arrays, each entry will be joined to the rest of the conditions using
+     * an `AND` operator. Consecutive calls to this function will also join the new
+     * conditions specified using the AND operator. Additionally, values can be
+     * expressed using expression objects which can include other query objects.
+     *
+     * Any conditions created with this methods can be used with any `SELECT`, `UPDATE`
+     * and `DELETE` type of queries.
+     *
+     * ### Conditions using operators:
+     *
+     * ```
+     * $query->where([
+     *     'posted >=' => new DateTime('3 days ago'),
+     *     'title LIKE' => 'Hello W%',
+     *     'author_id' => 1,
+     * ], ['posted' => 'datetime']);
+     * ```
+     *
+     * The previous example produces:
+     *
+     * `WHERE posted >= 2012-01-27 AND title LIKE 'Hello W%' AND author_id = 1`
+     *
+     * Second parameter is used to specify what type is expected for each passed
+     * key. Valid types can be used from the mapped with Database\Type class.
+     *
+     * ### Nesting conditions with conjunctions:
+     *
+     * ```
+     * $query->where([
+     *     'author_id !=' => 1,
+     *     'OR' => ['published' => true, 'posted <' => new DateTime('now')],
+     *     'NOT' => ['title' => 'Hello']
+     * ], ['published' => boolean, 'posted' => 'datetime']
+     * ```
+     *
+     * The previous example produces:
+     *
+     * `WHERE author_id = 1 AND (published = 1 OR posted < '2012-02-01') AND NOT (title = 'Hello')`
+     *
+     * You can nest conditions using conjunctions as much as you like. Sometimes, you
+     * may want to define 2 different options for the same key, in that case, you can
+     * wrap each condition inside a new array:
+     *
+     * `$query->where(['OR' => [['published' => false], ['published' => true]])`
+     *
+     * Would result in:
+     *
+     * `WHERE (published = false) OR (published = true)`
+     *
+     * Keep in mind that every time you call where() with the third param set to false
+     * (default), it will join the passed conditions to the previous stored list using
+     * the `AND` operator. Also, using the same array key twice in consecutive calls to
+     * this method will not override the previous value.
+     *
+     * ### Using expressions objects:
+     *
+     * ```
+     * $exp = $query->newExpr()->add(['id !=' => 100, 'author_id' != 1])->tieWith('OR');
+     * $query->where(['published' => true], ['published' => 'boolean'])->where($exp);
+     * ```
+     *
+     * The previous example produces:
+     *
+     * `WHERE (id != 100 OR author_id != 1) AND published = 1`
+     *
+     * Other Query objects that be used as conditions for any field.
+     *
+     * ### Adding conditions in multiple steps:
+     *
+     * You can use callable functions to construct complex expressions, functions
+     * receive as first argument a new QueryExpression object and this query instance
+     * as second argument. Functions must return an expression object, that will be
+     * added the list of conditions for the query using the `AND` operator.
+     *
+     * ```
+     * $query
+     *   ->where(['title !=' => 'Hello World'])
+     *   ->where(function ($exp, $query) {
+     *     $or = $exp->or(['id' => 1]);
+     *     $and = $exp->and(['id >' => 2, 'id <' => 10]);
+     *    return $or->add($and);
+     *   });
+     * ```
+     *
+     * * The previous example produces:
+     *
+     * `WHERE title != 'Hello World' AND (id = 1 OR (id > 2 AND id < 10))`
+     *
+     * ### Conditions as strings:
+     *
+     * ```
+     * $query->where(['articles.author_id = authors.id', 'modified IS NULL']);
+     * ```
+     *
+     * The previous example produces:
+     *
+     * `WHERE articles.author_id = authors.id AND modified IS NULL`
+     *
+     * Please note that when using the array notation or the expression objects, all
+     * *values* will be correctly quoted and transformed to the correspondent database
+     * data type automatically for you, thus securing your application from SQL injections.
+     * The keys however, are not treated as unsafe input, and should be validated/sanitized.
+     *
+     * If you use string conditions make sure that your values are correctly quoted.
+     * The safest thing you can do is to never use string conditions.
+     *
+     * ### Using null-able values
+     *
+     * When using values that can be null you can use the 'IS' keyword to let the ORM generate the correct SQL based on the value's type
+     *
+     * ```
+     * $query->where([
+     *     'posted >=' => new DateTime('3 days ago'),
+     *     'category_id IS' => $category,
+     * ]);
+     * ```
+     *
+     * If $category is `null` - it will actually convert that into `category_id IS NULL` - if it's `4` it will convert it into `category_id = 4`
+     *
+     * @param \Cake\Database\ExpressionInterface|\Closure|array|string|null $conditions The conditions to filter on.
+     * @param array $types Associative array of type names used to bind values to query
+     * @param bool $overwrite whether to reset conditions with passed list or not
+     * @see \Cake\Database\TypeFactory
+     * @see \Cake\Database\Expression\QueryExpression
+     * @return $this
+     */
+    public function where($conditions = null, array $types = [], bool $overwrite = false)
+    {
+        if ($overwrite) {
+            $this->_parts['where'] = $this->newExpr();
+        }
+        $this->_conjugate('where', $conditions, 'AND', $types);
+
+        return $this;
+    }
+
+    /**
+     * Convenience method that adds a NOT NULL condition to the query
+     *
+     * @param \Cake\Database\ExpressionInterface|array|string $fields A single field or expressions or a list of them
+     *  that should be not null.
+     * @return $this
+     */
+    public function whereNotNull($fields)
+    {
+        if (!is_array($fields)) {
+            $fields = [$fields];
+        }
+
+        $exp = $this->newExpr();
+
+        foreach ($fields as $field) {
+            $exp->isNotNull($field);
+        }
+
+        return $this->where($exp);
+    }
+
+    /**
+     * Convenience method that adds a IS NULL condition to the query
+     *
+     * @param \Cake\Database\ExpressionInterface|array|string $fields A single field or expressions or a list of them
+     *   that should be null.
+     * @return $this
+     */
+    public function whereNull($fields)
+    {
+        if (!is_array($fields)) {
+            $fields = [$fields];
+        }
+
+        $exp = $this->newExpr();
+
+        foreach ($fields as $field) {
+            $exp->isNull($field);
+        }
+
+        return $this->where($exp);
+    }
+
+    /**
+     * Adds an IN condition or set of conditions to be used in the WHERE clause for this
+     * query.
+     *
+     * This method does allow empty inputs in contrast to where() if you set
+     * 'allowEmpty' to true.
+     * Be careful about using it without proper sanity checks.
+     *
+     * Options:
+     *
+     * - `types` - Associative array of type names used to bind values to query
+     * - `allowEmpty` - Allow empty array.
+     *
+     * @param string $field Field
+     * @param array $values Array of values
+     * @param array $options Options
+     * @return $this
+     */
+    public function whereInList(string $field, array $values, array $options = [])
+    {
+        $options += [
+            'types' => [],
+            'allowEmpty' => false,
+        ];
+
+        if ($options['allowEmpty'] && !$values) {
+            return $this->where('1=0');
+        }
+
+        return $this->where([$field . ' IN' => $values], $options['types']);
+    }
+
+    /**
+     * Adds a NOT IN condition or set of conditions to be used in the WHERE clause for this
+     * query.
+     *
+     * This method does allow empty inputs in contrast to where() if you set
+     * 'allowEmpty' to true.
+     * Be careful about using it without proper sanity checks.
+     *
+     * @param string $field Field
+     * @param array $values Array of values
+     * @param array $options Options
+     * @return $this
+     */
+    public function whereNotInList(string $field, array $values, array $options = [])
+    {
+        $options += [
+            'types' => [],
+            'allowEmpty' => false,
+        ];
+
+        if ($options['allowEmpty'] && !$values) {
+            return $this->where([$field . ' IS NOT' => null]);
+        }
+
+        return $this->where([$field . ' NOT IN' => $values], $options['types']);
+    }
+
+    /**
+     * Adds a NOT IN condition or set of conditions to be used in the WHERE clause for this
+     * query. This also allows the field to be null with a IS NULL condition since the null
+     * value would cause the NOT IN condition to always fail.
+     *
+     * This method does allow empty inputs in contrast to where() if you set
+     * 'allowEmpty' to true.
+     * Be careful about using it without proper sanity checks.
+     *
+     * @param string $field Field
+     * @param array $values Array of values
+     * @param array $options Options
+     * @return $this
+     */
+    public function whereNotInListOrNull(string $field, array $values, array $options = [])
+    {
+        $options += [
+            'types' => [],
+            'allowEmpty' => false,
+        ];
+
+        if ($options['allowEmpty'] && !$values) {
+            return $this->where([$field . ' IS NOT' => null]);
+        }
+
+        return $this->where(
+            [
+                'OR' => [$field . ' NOT IN' => $values, $field . ' IS' => null],
+            ],
+            $options['types']
+        );
+    }
+
+    /**
+     * Connects any previously defined set of conditions to the provided list
+     * using the AND operator. This function accepts the conditions list in the same
+     * format as the method `where` does, hence you can use arrays, expression objects
+     * callback functions or strings.
+     *
+     * It is important to notice that when calling this function, any previous set
+     * of conditions defined for this query will be treated as a single argument for
+     * the AND operator. This function will not only operate the most recently defined
+     * condition, but all the conditions as a whole.
+     *
+     * When using an array for defining conditions, creating constraints form each
+     * array entry will use the same logic as with the `where()` function. This means
+     * that each array entry will be joined to the other using the AND operator, unless
+     * you nest the conditions in the array using other operator.
+     *
+     * ### Examples:
+     *
+     * ```
+     * $query->where(['title' => 'Hello World')->andWhere(['author_id' => 1]);
+     * ```
+     *
+     * Will produce:
+     *
+     * `WHERE title = 'Hello World' AND author_id = 1`
+     *
+     * ```
+     * $query
+     *   ->where(['OR' => ['published' => false, 'published is NULL']])
+     *   ->andWhere(['author_id' => 1, 'comments_count >' => 10])
+     * ```
+     *
+     * Produces:
+     *
+     * `WHERE (published = 0 OR published IS NULL) AND author_id = 1 AND comments_count > 10`
+     *
+     * ```
+     * $query
+     *   ->where(['title' => 'Foo'])
+     *   ->andWhere(function ($exp, $query) {
+     *     return $exp
+     *       ->or(['author_id' => 1])
+     *       ->add(['author_id' => 2]);
+     *   });
+     * ```
+     *
+     * Generates the following conditions:
+     *
+     * `WHERE (title = 'Foo') AND (author_id = 1 OR author_id = 2)`
+     *
+     * @param \Cake\Database\ExpressionInterface|\Closure|array|string $conditions The conditions to add with AND.
+     * @param array $types Associative array of type names used to bind values to query
+     * @see \Cake\Database\Query::where()
+     * @see \Cake\Database\TypeFactory
+     * @return $this
+     */
+    public function andWhere($conditions, array $types = [])
+    {
+        $this->_conjugate('where', $conditions, 'AND', $types);
+
+        return $this;
+    }
+
+    /**
+     * Adds a single or multiple fields to be used in the ORDER clause for this query.
+     * Fields can be passed as an array of strings, array of expression
+     * objects, a single expression or a single string.
+     *
+     * If an array is passed, keys will be used as the field itself and the value will
+     * represent the order in which such field should be ordered. When called multiple
+     * times with the same fields as key, the last order definition will prevail over
+     * the others.
+     *
+     * By default this function will append any passed argument to the list of fields
+     * to be selected, unless the second argument is set to true.
+     *
+     * ### Examples:
+     *
+     * ```
+     * $query->order(['title' => 'DESC', 'author_id' => 'ASC']);
+     * ```
+     *
+     * Produces:
+     *
+     * `ORDER BY title DESC, author_id ASC`
+     *
+     * ```
+     * $query
+     *     ->order(['title' => $query->newExpr('DESC NULLS FIRST')])
+     *     ->order('author_id');
+     * ```
+     *
+     * Will generate:
+     *
+     * `ORDER BY title DESC NULLS FIRST, author_id`
+     *
+     * ```
+     * $expression = $query->newExpr()->add(['id % 2 = 0']);
+     * $query->order($expression)->order(['title' => 'ASC']);
+     * ```
+     *
+     * and
+     *
+     * ```
+     * $query->order(function ($exp, $query) {
+     *     return [$exp->add(['id % 2 = 0']), 'title' => 'ASC'];
+     * });
+     * ```
+     *
+     * Will both become:
+     *
+     * `ORDER BY (id %2 = 0), title ASC`
+     *
+     * Order fields/directions are not sanitized by the query builder.
+     * You should use an allowed list of fields/directions when passing
+     * in user-supplied data to `order()`.
+     *
+     * If you need to set complex expressions as order conditions, you
+     * should use `orderAsc()` or `orderDesc()`.
+     *
+     * @param \Cake\Database\ExpressionInterface|\Closure|array|string $fields fields to be added to the list
+     * @param bool $overwrite whether to reset order with field list or not
+     * @return $this
+     */
+    public function order($fields, $overwrite = false)
+    {
+        if ($overwrite) {
+            $this->_parts['order'] = null;
+        }
+
+        if (!$fields) {
+            return $this;
+        }
+
+        if (!$this->_parts['order']) {
+            $this->_parts['order'] = new OrderByExpression();
+        }
+        $this->_conjugate('order', $fields, '', []);
+
+        return $this;
+    }
+
+    /**
+     * Add an ORDER BY clause with an ASC direction.
+     *
+     * This method allows you to set complex expressions
+     * as order conditions unlike order()
+     *
+     * Order fields are not suitable for use with user supplied data as they are
+     * not sanitized by the query builder.
+     *
+     * @param \Cake\Database\ExpressionInterface|\Closure|string $field The field to order on.
+     * @param bool $overwrite Whether to reset the order clauses.
+     * @return $this
+     */
+    public function orderAsc($field, $overwrite = false)
+    {
+        if ($overwrite) {
+            $this->_parts['order'] = null;
+        }
+        if (!$field) {
+            return $this;
+        }
+
+        if ($field instanceof Closure) {
+            $field = $field($this->newExpr(), $this);
+        }
+
+        if (!$this->_parts['order']) {
+            $this->_parts['order'] = new OrderByExpression();
+        }
+        $this->_parts['order']->add(new OrderClauseExpression($field, 'ASC'));
+
+        return $this;
+    }
+
+    /**
+     * Add an ORDER BY clause with a DESC direction.
+     *
+     * This method allows you to set complex expressions
+     * as order conditions unlike order()
+     *
+     * Order fields are not suitable for use with user supplied data as they are
+     * not sanitized by the query builder.
+     *
+     * @param \Cake\Database\ExpressionInterface|\Closure|string $field The field to order on.
+     * @param bool $overwrite Whether to reset the order clauses.
+     * @return $this
+     */
+    public function orderDesc($field, $overwrite = false)
+    {
+        if ($overwrite) {
+            $this->_parts['order'] = null;
+        }
+        if (!$field) {
+            return $this;
+        }
+
+        if ($field instanceof Closure) {
+            $field = $field($this->newExpr(), $this);
+        }
+
+        if (!$this->_parts['order']) {
+            $this->_parts['order'] = new OrderByExpression();
+        }
+        $this->_parts['order']->add(new OrderClauseExpression($field, 'DESC'));
+
+        return $this;
+    }
+
+    /**
+     * Adds a single or multiple fields to be used in the GROUP BY clause for this query.
+     * Fields can be passed as an array of strings, array of expression
+     * objects, a single expression or a single string.
+     *
+     * By default this function will append any passed argument to the list of fields
+     * to be grouped, unless the second argument is set to true.
+     *
+     * ### Examples:
+     *
+     * ```
+     * // Produces GROUP BY id, title
+     * $query->group(['id', 'title']);
+     *
+     * // Produces GROUP BY title
+     * $query->group('title');
+     * ```
+     *
+     * Group fields are not suitable for use with user supplied data as they are
+     * not sanitized by the query builder.
+     *
+     * @param \Cake\Database\ExpressionInterface|array|string $fields fields to be added to the list
+     * @param bool $overwrite whether to reset fields with passed list or not
+     * @return $this
+     */
+    public function group($fields, $overwrite = false)
+    {
+        if ($overwrite) {
+            $this->_parts['group'] = [];
+        }
+
+        if (!is_array($fields)) {
+            $fields = [$fields];
+        }
+
+        $this->_parts['group'] = array_merge($this->_parts['group'], array_values($fields));
+        $this->_dirty();
+
+        return $this;
+    }
+
+    /**
+     * Adds a condition or set of conditions to be used in the `HAVING` clause for this
+     * query. This method operates in exactly the same way as the method `where()`
+     * does. Please refer to its documentation for an insight on how to using each
+     * parameter.
+     *
+     * Having fields are not suitable for use with user supplied data as they are
+     * not sanitized by the query builder.
+     *
+     * @param \Cake\Database\ExpressionInterface|\Closure|array|string|null $conditions The having conditions.
+     * @param array $types Associative array of type names used to bind values to query
+     * @param bool $overwrite whether to reset conditions with passed list or not
+     * @see \Cake\Database\Query::where()
+     * @return $this
+     */
+    public function having($conditions = null, $types = [], $overwrite = false)
+    {
+        if ($overwrite) {
+            $this->_parts['having'] = $this->newExpr();
+        }
+        $this->_conjugate('having', $conditions, 'AND', $types);
+
+        return $this;
+    }
+
+    /**
+     * Connects any previously defined set of conditions to the provided list
+     * using the AND operator in the HAVING clause. This method operates in exactly
+     * the same way as the method `andWhere()` does. Please refer to its
+     * documentation for an insight on how to using each parameter.
+     *
+     * Having fields are not suitable for use with user supplied data as they are
+     * not sanitized by the query builder.
+     *
+     * @param \Cake\Database\ExpressionInterface|\Closure|array|string $conditions The AND conditions for HAVING.
+     * @param array $types Associative array of type names used to bind values to query
+     * @see \Cake\Database\Query::andWhere()
+     * @return $this
+     */
+    public function andHaving($conditions, $types = [])
+    {
+        $this->_conjugate('having', $conditions, 'AND', $types);
+
+        return $this;
+    }
+
+    /**
+     * Adds a named window expression.
+     *
+     * You are responsible for adding windows in the order your database requires.
+     *
+     * @param string $name Window name
+     * @param \Cake\Database\Expression\WindowExpression|\Closure $window Window expression
+     * @param bool $overwrite Clear all previous query window expressions
+     * @return $this
+     */
+    public function window(string $name, $window, bool $overwrite = false)
+    {
+        if ($overwrite) {
+            $this->_parts['window'] = [];
+        }
+
+        if ($window instanceof Closure) {
+            $window = $window(new WindowExpression(), $this);
+            if (!($window instanceof WindowExpression)) {
+                throw new RuntimeException('You must return a `WindowExpression` from a Closure passed to `window()`.');
+            }
+        }
+
+        $this->_parts['window'][] = ['name' => new IdentifierExpression($name), 'window' => $window];
+        $this->_dirty();
+
+        return $this;
+    }
+
+    /**
+     * Set the page of results you want.
+     *
+     * This method provides an easier to use interface to set the limit + offset
+     * in the record set you want as results. If empty the limit will default to
+     * the existing limit clause, and if that too is empty, then `25` will be used.
+     *
+     * Pages must start at 1.
+     *
+     * @param int $num The page number you want.
+     * @param int|null $limit The number of rows you want in the page. If null
+     *  the current limit clause will be used.
+     * @return $this
+     * @throws \InvalidArgumentException If page number < 1.
+     */
+    public function page(int $num, ?int $limit = null)
+    {
+        if ($num < 1) {
+            throw new InvalidArgumentException('Pages must start at 1.');
+        }
+        if ($limit !== null) {
+            $this->limit($limit);
+        }
+        $limit = $this->clause('limit');
+        if ($limit === null) {
+            $limit = 25;
+            $this->limit($limit);
+        }
+        $offset = ($num - 1) * $limit;
+        if (PHP_INT_MAX <= $offset) {
+            $offset = PHP_INT_MAX;
+        }
+        $this->offset((int)$offset);
+
+        return $this;
+    }
+
+    /**
+     * Sets the number of records that should be retrieved from database,
+     * accepts an integer or an expression object that evaluates to an integer.
+     * In some databases, this operation might not be supported or will require
+     * the query to be transformed in order to limit the result set size.
+     *
+     * ### Examples
+     *
+     * ```
+     * $query->limit(10) // generates LIMIT 10
+     * $query->limit($query->newExpr()->add(['1 + 1'])); // LIMIT (1 + 1)
+     * ```
+     *
+     * @param \Cake\Database\ExpressionInterface|int|null $limit number of records to be returned
+     * @return $this
+     */
+    public function limit($limit)
+    {
+        if (is_string($limit) && !is_numeric($limit)) {
+            throw new InvalidArgumentException('Invalid value for `limit()`');
+        }
+        $this->_dirty();
+        $this->_parts['limit'] = $limit;
+
+        return $this;
+    }
+
+    /**
+     * Sets the number of records that should be skipped from the original result set
+     * This is commonly used for paginating large results. Accepts an integer or an
+     * expression object that evaluates to an integer.
+     *
+     * In some databases, this operation might not be supported or will require
+     * the query to be transformed in order to limit the result set size.
+     *
+     * ### Examples
+     *
+     * ```
+     * $query->offset(10) // generates OFFSET 10
+     * $query->offset($query->newExpr()->add(['1 + 1'])); // OFFSET (1 + 1)
+     * ```
+     *
+     * @param \Cake\Database\ExpressionInterface|int|null $offset number of records to be skipped
+     * @return $this
+     */
+    public function offset($offset)
+    {
+        if (is_string($offset) && !is_numeric($offset)) {
+            throw new InvalidArgumentException('Invalid value for `offset()`');
+        }
+        $this->_dirty();
+        $this->_parts['offset'] = $offset;
+
+        return $this;
+    }
+
+    /**
+     * Adds a complete query to be used in conjunction with an UNION operator with
+     * this query. This is used to combine the result set of this query with the one
+     * that will be returned by the passed query. You can add as many queries as you
+     * required by calling multiple times this method with different queries.
+     *
+     * By default, the UNION operator will remove duplicate rows, if you wish to include
+     * every row for all queries, use unionAll().
+     *
+     * ### Examples
+     *
+     * ```
+     * $union = (new Query($conn))->select(['id', 'title'])->from(['a' => 'articles']);
+     * $query->select(['id', 'name'])->from(['d' => 'things'])->union($union);
+     * ```
+     *
+     * Will produce:
+     *
+     * `SELECT id, name FROM things d UNION SELECT id, title FROM articles a`
+     *
+     * @param \Cake\Database\Query|string $query full SQL query to be used in UNION operator
+     * @param bool $overwrite whether to reset the list of queries to be operated or not
+     * @return $this
+     */
+    public function union($query, $overwrite = false)
+    {
+        if ($overwrite) {
+            $this->_parts['union'] = [];
+        }
+        $this->_parts['union'][] = [
+            'all' => false,
+            'query' => $query,
+        ];
+        $this->_dirty();
+
+        return $this;
+    }
+
+    /**
+     * Adds a complete query to be used in conjunction with the UNION ALL operator with
+     * this query. This is used to combine the result set of this query with the one
+     * that will be returned by the passed query. You can add as many queries as you
+     * required by calling multiple times this method with different queries.
+     *
+     * Unlike UNION, UNION ALL will not remove duplicate rows.
+     *
+     * ```
+     * $union = (new Query($conn))->select(['id', 'title'])->from(['a' => 'articles']);
+     * $query->select(['id', 'name'])->from(['d' => 'things'])->unionAll($union);
+     * ```
+     *
+     * Will produce:
+     *
+     * `SELECT id, name FROM things d UNION ALL SELECT id, title FROM articles a`
+     *
+     * @param \Cake\Database\Query|string $query full SQL query to be used in UNION operator
+     * @param bool $overwrite whether to reset the list of queries to be operated or not
+     * @return $this
+     */
+    public function unionAll($query, $overwrite = false)
+    {
+        if ($overwrite) {
+            $this->_parts['union'] = [];
+        }
+        $this->_parts['union'][] = [
+            'all' => true,
+            'query' => $query,
+        ];
+        $this->_dirty();
+
+        return $this;
+    }
+
+    /**
+     * Create an insert query.
+     *
+     * Note calling this method will reset any data previously set
+     * with Query::values().
+     *
+     * @param array $columns The columns to insert into.
+     * @param array $types A map between columns & their datatypes.
+     * @return $this
+     * @throws \RuntimeException When there are 0 columns.
+     */
+    public function insert(array $columns, array $types = [])
+    {
+        if (empty($columns)) {
+            throw new RuntimeException('At least 1 column is required to perform an insert.');
+        }
+        $this->_dirty();
+        $this->_type = 'insert';
+        $this->_parts['insert'][1] = $columns;
+        if (!$this->_parts['values']) {
+            $this->_parts['values'] = new ValuesExpression($columns, $this->getTypeMap()->setTypes($types));
+        } else {
+            $this->_parts['values']->setColumns($columns);
+        }
+
+        return $this;
+    }
+
+    /**
+     * Set the table name for insert queries.
+     *
+     * @param string $table The table name to insert into.
+     * @return $this
+     */
+    public function into(string $table)
+    {
+        $this->_dirty();
+        $this->_type = 'insert';
+        $this->_parts['insert'][0] = $table;
+
+        return $this;
+    }
+
+    /**
+     * Creates an expression that refers to an identifier. Identifiers are used to refer to field names and allow
+     * the SQL compiler to apply quotes or escape the identifier.
+     *
+     * The value is used as is, and you might be required to use aliases or include the table reference in
+     * the identifier. Do not use this method to inject SQL methods or logical statements.
+     *
+     * ### Example
+     *
+     * ```
+     * $query->newExpr()->lte('count', $query->identifier('total'));
+     * ```
+     *
+     * @param string $identifier The identifier for an expression
+     * @return \Cake\Database\ExpressionInterface
+     */
+    public function identifier(string $identifier): ExpressionInterface
+    {
+        return new IdentifierExpression($identifier);
+    }
+
+    /**
+     * Set the values for an insert query.
+     *
+     * Multi inserts can be performed by calling values() more than one time,
+     * or by providing an array of value sets. Additionally $data can be a Query
+     * instance to insert data from another SELECT statement.
+     *
+     * @param \Cake\Database\Expression\ValuesExpression|\Cake\Database\Query|array $data The data to insert.
+     * @return $this
+     * @throws \Cake\Database\Exception\DatabaseException if you try to set values before declaring columns.
+     *   Or if you try to set values on non-insert queries.
+     */
+    public function values($data)
+    {
+        if ($this->_type !== 'insert') {
+            throw new DatabaseException(
+                'You cannot add values before defining columns to use.'
+            );
+        }
+        if (empty($this->_parts['insert'])) {
+            throw new DatabaseException(
+                'You cannot add values before defining columns to use.'
+            );
+        }
+
+        $this->_dirty();
+        if ($data instanceof ValuesExpression) {
+            $this->_parts['values'] = $data;
+
+            return $this;
+        }
+
+        $this->_parts['values']->add($data);
+
+        return $this;
+    }
+
+    /**
+     * Create an update query.
+     *
+     * Can be combined with set() and where() methods to create update queries.
+     *
+     * @param \Cake\Database\ExpressionInterface|string $table The table you want to update.
+     * @return $this
+     */
+    public function update($table)
+    {
+        if (!is_string($table) && !($table instanceof ExpressionInterface)) {
+            $text = 'Table must be of type string or "%s", got "%s"';
+            $message = sprintf($text, ExpressionInterface::class, gettype($table));
+            throw new InvalidArgumentException($message);
+        }
+
+        $this->_dirty();
+        $this->_type = 'update';
+        $this->_parts['update'][0] = $table;
+
+        return $this;
+    }
+
+    /**
+     * Set one or many fields to update.
+     *
+     * ### Examples
+     *
+     * Passing a string:
+     *
+     * ```
+     * $query->update('articles')->set('title', 'The Title');
+     * ```
+     *
+     * Passing an array:
+     *
+     * ```
+     * $query->update('articles')->set(['title' => 'The Title'], ['title' => 'string']);
+     * ```
+     *
+     * Passing a callable:
+     *
+     * ```
+     * $query->update('articles')->set(function ($exp) {
+     *   return $exp->eq('title', 'The title', 'string');
+     * });
+     * ```
+     *
+     * @param \Cake\Database\Expression\QueryExpression|\Closure|array|string $key The column name or array of keys
+     *    + values to set. This can also be a QueryExpression containing a SQL fragment.
+     *    It can also be a Closure, that is required to return an expression object.
+     * @param mixed $value The value to update $key to. Can be null if $key is an
+     *    array or QueryExpression. When $key is an array, this parameter will be
+     *    used as $types instead.
+     * @param array|string $types The column types to treat data as.
+     * @return $this
+     */
+    public function set($key, $value = null, $types = [])
+    {
+        if (empty($this->_parts['set'])) {
+            $this->_parts['set'] = $this->newExpr()->setConjunction(',');
+        }
+
+        if ($key instanceof Closure) {
+            $exp = $this->newExpr()->setConjunction(',');
+            $this->_parts['set']->add($key($exp));
+
+            return $this;
+        }
+
+        if (is_array($key) || $key instanceof ExpressionInterface) {
+            $types = (array)$value;
+            $this->_parts['set']->add($key, $types);
+
+            return $this;
+        }
+
+        if (!is_string($types)) {
+            $types = null;
+        }
+        $this->_parts['set']->eq($key, $value, $types);
+
+        return $this;
+    }
+
+    /**
+     * Create a delete query.
+     *
+     * Can be combined with from(), where() and other methods to
+     * create delete queries with specific conditions.
+     *
+     * @param string|null $table The table to use when deleting.
+     * @return $this
+     */
+    public function delete(?string $table = null)
+    {
+        $this->_dirty();
+        $this->_type = 'delete';
+        if ($table !== null) {
+            $this->from($table);
+        }
+
+        return $this;
+    }
+
+    /**
+     * A string or expression that will be appended to the generated query
+     *
+     * ### Examples:
+     * ```
+     * $query->select('id')->where(['author_id' => 1])->epilog('FOR UPDATE');
+     * $query
+     *  ->insert('articles', ['title'])
+     *  ->values(['author_id' => 1])
+     *  ->epilog('RETURNING id');
+     * ```
+     *
+     * Epliog content is raw SQL and not suitable for use with user supplied data.
+     *
+     * @param \Cake\Database\ExpressionInterface|string|null $expression The expression to be appended
+     * @return $this
+     */
+    public function epilog($expression = null)
+    {
+        $this->_dirty();
+        $this->_parts['epilog'] = $expression;
+
+        return $this;
+    }
+
+    /**
+     * Returns the type of this query (select, insert, update, delete)
+     *
+     * @return string
+     */
+    public function type(): string
+    {
+        return $this->_type;
+    }
+
+    /**
+     * Returns a new QueryExpression object. This is a handy function when
+     * building complex queries using a fluent interface. You can also override
+     * this function in subclasses to use a more specialized QueryExpression class
+     * if required.
+     *
+     * You can optionally pass a single raw SQL string or an array or expressions in
+     * any format accepted by \Cake\Database\Expression\QueryExpression:
+     *
+     * ```
+     * $expression = $query->expr(); // Returns an empty expression object
+     * $expression = $query->expr('Table.column = Table2.column'); // Return a raw SQL expression
+     * ```
+     *
+     * @param \Cake\Database\ExpressionInterface|array|string|null $rawExpression A string, array or anything you want wrapped in an expression object
+     * @return \Cake\Database\Expression\QueryExpression
+     */
+    public function newExpr($rawExpression = null): QueryExpression
+    {
+        return $this->expr($rawExpression);
+    }
+
+    /**
+     * Returns a new QueryExpression object. This is a handy function when
+     * building complex queries using a fluent interface. You can also override
+     * this function in subclasses to use a more specialized QueryExpression class
+     * if required.
+     *
+     * You can optionally pass a single raw SQL string or an array or expressions in
+     * any format accepted by \Cake\Database\Expression\QueryExpression:
+     *
+     * ```
+     * $expression = $query->expr(); // Returns an empty expression object
+     * $expression = $query->expr('Table.column = Table2.column'); // Return a raw SQL expression
+     * ```
+     *
+     * @param \Cake\Database\ExpressionInterface|array|string|null $rawExpression A string, array or anything you want wrapped in an expression object
+     * @return \Cake\Database\Expression\QueryExpression
+     */
+    public function expr($rawExpression = null): QueryExpression
+    {
+        $expression = new QueryExpression([], $this->getTypeMap());
+
+        if ($rawExpression !== null) {
+            $expression->add($rawExpression);
+        }
+
+        return $expression;
+    }
+
+    /**
+     * Returns an instance of a functions builder object that can be used for
+     * generating arbitrary SQL functions.
+     *
+     * ### Example:
+     *
+     * ```
+     * $query->func()->count('*');
+     * $query->func()->dateDiff(['2012-01-05', '2012-01-02'])
+     * ```
+     *
+     * @return \Cake\Database\FunctionsBuilder
+     */
+    public function func(): FunctionsBuilder
+    {
+        if ($this->_functionsBuilder === null) {
+            $this->_functionsBuilder = new FunctionsBuilder();
+        }
+
+        return $this->_functionsBuilder;
+    }
+
+    /**
+     * Executes this query and returns a results iterator. This function is required
+     * for implementing the IteratorAggregate interface and allows the query to be
+     * iterated without having to call execute() manually, thus making it look like
+     * a result set instead of the query itself.
+     *
+     * @return \Cake\Database\StatementInterface
+     * @psalm-suppress ImplementedReturnTypeMismatch
+     */
+    #[\ReturnTypeWillChange]
+    public function getIterator()
+    {
+        if ($this->_iterator === null || $this->_dirty) {
+            $this->_iterator = $this->execute();
+        }
+
+        return $this->_iterator;
+    }
+
+    /**
+     * Returns any data that was stored in the specified clause. This is useful for
+     * modifying any internal part of the query and it is used by the SQL dialects
+     * to transform the query accordingly before it is executed. The valid clauses that
+     * can be retrieved are: delete, update, set, insert, values, select, distinct,
+     * from, join, set, where, group, having, order, limit, offset and union.
+     *
+     * The return value for each of those parts may vary. Some clauses use QueryExpression
+     * to internally store their state, some use arrays and others may use booleans or
+     * integers. This is summary of the return types for each clause.
+     *
+     * - update: string The name of the table to update
+     * - set: QueryExpression
+     * - insert: array, will return an array containing the table + columns.
+     * - values: ValuesExpression
+     * - select: array, will return empty array when no fields are set
+     * - distinct: boolean
+     * - from: array of tables
+     * - join: array
+     * - set: array
+     * - where: QueryExpression, returns null when not set
+     * - group: array
+     * - having: QueryExpression, returns null when not set
+     * - order: OrderByExpression, returns null when not set
+     * - limit: integer or QueryExpression, null when not set
+     * - offset: integer or QueryExpression, null when not set
+     * - union: array
+     *
+     * @param string $name name of the clause to be returned
+     * @return mixed
+     * @throws \InvalidArgumentException When the named clause does not exist.
+     */
+    public function clause(string $name)
+    {
+        if (!array_key_exists($name, $this->_parts)) {
+            $clauses = implode(', ', array_keys($this->_parts));
+            throw new InvalidArgumentException("The '$name' clause is not defined. Valid clauses are: $clauses");
+        }
+
+        return $this->_parts[$name];
+    }
+
+    /**
+     * Registers a callback to be executed for each result that is fetched from the
+     * result set, the callback function will receive as first parameter an array with
+     * the raw data from the database for every row that is fetched and must return the
+     * row with any possible modifications.
+     *
+     * Callbacks will be executed lazily, if only 3 rows are fetched for database it will
+     * called 3 times, event though there might be more rows to be fetched in the cursor.
+     *
+     * Callbacks are stacked in the order they are registered, if you wish to reset the stack
+     * the call this function with the second parameter set to true.
+     *
+     * If you wish to remove all decorators from the stack, set the first parameter
+     * to null and the second to true.
+     *
+     * ### Example
+     *
+     * ```
+     * $query->decorateResults(function ($row) {
+     *   $row['order_total'] = $row['subtotal'] + ($row['subtotal'] * $row['tax']);
+     *    return $row;
+     * });
+     * ```
+     *
+     * @param callable|null $callback The callback to invoke when results are fetched.
+     * @param bool $overwrite Whether this should append or replace all existing decorators.
+     * @return $this
+     */
+    public function decorateResults(?callable $callback, bool $overwrite = false)
+    {
+        if ($overwrite) {
+            $this->_resultDecorators = [];
+        }
+
+        if ($callback !== null) {
+            $this->_resultDecorators[] = $callback;
+        }
+
+        return $this;
+    }
+
+    /**
+     * This function works similar to the traverse() function, with the difference
+     * that it does a full depth traversal of the entire expression tree. This will execute
+     * the provided callback function for each ExpressionInterface object that is
+     * stored inside this query at any nesting depth in any part of the query.
+     *
+     * Callback will receive as first parameter the currently visited expression.
+     *
+     * @param callable $callback the function to be executed for each ExpressionInterface
+     *   found inside this query.
+     * @return $this
+     */
+    public function traverseExpressions(callable $callback)
+    {
+        if (!$callback instanceof Closure) {
+            $callback = Closure::fromCallable($callback);
+        }
+
+        foreach ($this->_parts as $part) {
+            $this->_expressionsVisitor($part, $callback);
+        }
+
+        return $this;
+    }
+
+    /**
+     * Query parts traversal method used by traverseExpressions()
+     *
+     * @param \Cake\Database\ExpressionInterface|array<\Cake\Database\ExpressionInterface> $expression Query expression or
+     *   array of expressions.
+     * @param \Closure $callback The callback to be executed for each ExpressionInterface
+     *   found inside this query.
+     * @return void
+     */
+    protected function _expressionsVisitor($expression, Closure $callback): void
+    {
+        if (is_array($expression)) {
+            foreach ($expression as $e) {
+                $this->_expressionsVisitor($e, $callback);
+            }
+
+            return;
+        }
+
+        if ($expression instanceof ExpressionInterface) {
+            $expression->traverse(function ($exp) use ($callback) {
+                $this->_expressionsVisitor($exp, $callback);
+            });
+
+            if (!$expression instanceof self) {
+                $callback($expression);
+            }
+        }
+    }
+
+    /**
+     * Associates a query placeholder to a value and a type.
+     *
+     * ```
+     * $query->bind(':id', 1, 'integer');
+     * ```
+     *
+     * @param string|int $param placeholder to be replaced with quoted version
+     *   of $value
+     * @param mixed $value The value to be bound
+     * @param string|int|null $type the mapped type name, used for casting when sending
+     *   to database
+     * @return $this
+     */
+    public function bind($param, $value, $type = null)
+    {
+        $this->getValueBinder()->bind($param, $value, $type);
+
+        return $this;
+    }
+
+    /**
+     * Returns the currently used ValueBinder instance.
+     *
+     * A ValueBinder is responsible for generating query placeholders and temporarily
+     * associate values to those placeholders so that they can be passed correctly
+     * to the statement object.
+     *
+     * @return \Cake\Database\ValueBinder
+     */
+    public function getValueBinder(): ValueBinder
+    {
+        if ($this->_valueBinder === null) {
+            $this->_valueBinder = new ValueBinder();
+        }
+
+        return $this->_valueBinder;
+    }
+
+    /**
+     * Overwrite the current value binder
+     *
+     * A ValueBinder is responsible for generating query placeholders and temporarily
+     * associate values to those placeholders so that they can be passed correctly
+     * to the statement object.
+     *
+     * @param \Cake\Database\ValueBinder|null $binder The binder or null to disable binding.
+     * @return $this
+     */
+    public function setValueBinder(?ValueBinder $binder)
+    {
+        $this->_valueBinder = $binder;
+
+        return $this;
+    }
+
+    /**
+     * Enables/Disables buffered results.
+     *
+     * When enabled the results returned by this Query will be
+     * buffered. This enables you to iterate a result set multiple times, or
+     * both cache and iterate it.
+     *
+     * When disabled it will consume less memory as fetched results are not
+     * remembered for future iterations.
+     *
+     * @param bool $enable Whether to enable buffering
+     * @return $this
+     * @deprecated 4.5.0 Results will always be buffered in 5.0.
+     */
+    public function enableBufferedResults(bool $enable = true)
+    {
+        if (!$enable) {
+            deprecationWarning(
+                '4.5.0 enableBufferedResults() is deprecated. Results will always be buffered in 5.0.'
+            );
+        }
+        $this->_dirty();
+        $this->_useBufferedResults = $enable;
+
+        return $this;
+    }
+
+    /**
+     * Disables buffered results.
+     *
+     * Disabling buffering will consume less memory as fetched results are not
+     * remembered for future iterations.
+     *
+     * @return $this
+     * @deprecated 4.5.0 Results will always be buffered in 5.0.
+     */
+    public function disableBufferedResults()
+    {
+        $this->_dirty();
+        $this->_useBufferedResults = false;
+
+        return $this;
+    }
+
+    /**
+     * Returns whether buffered results are enabled/disabled.
+     *
+     * When enabled the results returned by this Query will be
+     * buffered. This enables you to iterate a result set multiple times, or
+     * both cache and iterate it.
+     *
+     * When disabled it will consume less memory as fetched results are not
+     * remembered for future iterations.
+     *
+     * @return bool
+     * @deprecated 4.5.0 Results will always be buffered in 5.0.
+     */
+    public function isBufferedResultsEnabled(): bool
+    {
+        return $this->_useBufferedResults;
+    }
+
+    /**
+     * Sets the TypeMap class where the types for each of the fields in the
+     * select clause are stored.
+     *
+     * @param \Cake\Database\TypeMap $typeMap The map object to use
+     * @return $this
+     */
+    public function setSelectTypeMap(TypeMap $typeMap)
+    {
+        $this->_selectTypeMap = $typeMap;
+        $this->_dirty();
+
+        return $this;
+    }
+
+    /**
+     * Gets the TypeMap class where the types for each of the fields in the
+     * select clause are stored.
+     *
+     * @return \Cake\Database\TypeMap
+     */
+    public function getSelectTypeMap(): TypeMap
+    {
+        if ($this->_selectTypeMap === null) {
+            $this->_selectTypeMap = new TypeMap();
+        }
+
+        return $this->_selectTypeMap;
+    }
+
+    /**
+     * Disables result casting.
+     *
+     * When disabled, the fields will be returned as received from the database
+     * driver (which in most environments means they are being returned as
+     * strings), which can improve performance with larger datasets.
+     *
+     * @return $this
+     */
+    public function disableResultsCasting()
+    {
+        $this->typeCastEnabled = false;
+
+        return $this;
+    }
+
+    /**
+     * Enables result casting.
+     *
+     * When enabled, the fields in the results returned by this Query will be
+     * cast to their corresponding PHP data type.
+     *
+     * @return $this
+     */
+    public function enableResultsCasting()
+    {
+        $this->typeCastEnabled = true;
+
+        return $this;
+    }
+
+    /**
+     * Returns whether result casting is enabled/disabled.
+     *
+     * When enabled, the fields in the results returned by this Query will be
+     * casted to their corresponding PHP data type.
+     *
+     * When disabled, the fields will be returned as received from the database
+     * driver (which in most environments means they are being returned as
+     * strings), which can improve performance with larger datasets.
+     *
+     * @return bool
+     */
+    public function isResultsCastingEnabled(): bool
+    {
+        return $this->typeCastEnabled;
+    }
+
+    /**
+     * Auxiliary function used to wrap the original statement from the driver with
+     * any registered callbacks.
+     *
+     * @param \Cake\Database\StatementInterface $statement to be decorated
+     * @return \Cake\Database\Statement\CallbackStatement|\Cake\Database\StatementInterface
+     */
+    protected function _decorateStatement(StatementInterface $statement)
+    {
+        $typeMap = $this->getSelectTypeMap();
+        $driver = $this->getConnection()->getDriver($this->connectionRole);
+
+        if ($this->typeCastEnabled && $typeMap->toArray()) {
+            $statement = new CallbackStatement($statement, $driver, new FieldTypeConverter($typeMap, $driver));
+        }
+
+        foreach ($this->_resultDecorators as $f) {
+            $statement = new CallbackStatement($statement, $driver, $f);
+        }
+
+        return $statement;
+    }
+
+    /**
+     * Helper function used to build conditions by composing QueryExpression objects.
+     *
+     * @param string $part Name of the query part to append the new part to
+     * @param \Cake\Database\ExpressionInterface|\Closure|array|string|null $append Expression or builder function to append.
+     *   to append.
+     * @param string $conjunction type of conjunction to be used to operate part
+     * @param array $types Associative array of type names used to bind values to query
+     * @return void
+     */
+    protected function _conjugate(string $part, $append, $conjunction, array $types): void
+    {
+        $expression = $this->_parts[$part] ?: $this->newExpr();
+        if (empty($append)) {
+            $this->_parts[$part] = $expression;
+
+            return;
+        }
+
+        if ($append instanceof Closure) {
+            $append = $append($this->newExpr(), $this);
+        }
+
+        if ($expression->getConjunction() === $conjunction) {
+            $expression->add($append, $types);
+        } else {
+            $expression = $this->newExpr()
+                ->setConjunction($conjunction)
+                ->add([$expression, $append], $types);
+        }
+
+        $this->_parts[$part] = $expression;
+        $this->_dirty();
+    }
+
+    /**
+     * Marks a query as dirty, removing any preprocessed information
+     * from in memory caching.
+     *
+     * @return void
+     */
+    protected function _dirty(): void
+    {
+        $this->_dirty = true;
+
+        if ($this->_iterator && $this->_valueBinder) {
+            $this->getValueBinder()->reset();
+        }
+    }
+
+    /**
+     * Handles clearing iterator and cloning all expressions and value binders.
+     *
+     * @return void
+     */
+    public function __clone()
+    {
+        $this->_iterator = null;
+        if ($this->_valueBinder !== null) {
+            $this->_valueBinder = clone $this->_valueBinder;
+        }
+        if ($this->_selectTypeMap !== null) {
+            $this->_selectTypeMap = clone $this->_selectTypeMap;
+        }
+        foreach ($this->_parts as $name => $part) {
+            if (empty($part)) {
+                continue;
+            }
+            if (is_array($part)) {
+                foreach ($part as $i => $piece) {
+                    if (is_array($piece)) {
+                        foreach ($piece as $j => $value) {
+                            if ($value instanceof ExpressionInterface) {
+                                /** @psalm-suppress PossiblyUndefinedMethod */
+                                $this->_parts[$name][$i][$j] = clone $value;
+                            }
+                        }
+                    } elseif ($piece instanceof ExpressionInterface) {
+                        $this->_parts[$name][$i] = clone $piece;
+                    }
+                }
+            }
+            if ($part instanceof ExpressionInterface) {
+                $this->_parts[$name] = clone $part;
+            }
+        }
+    }
+
+    /**
+     * Returns string representation of this query (complete SQL statement).
+     *
+     * @return string
+     */
+    public function __toString(): string
+    {
+        return $this->sql();
+    }
+
+    /**
+     * Returns an array that can be used to describe the internal state of this
+     * object.
+     *
+     * @return array
+     */
+    public function __debugInfo(): array
+    {
+        try {
+            set_error_handler(
+                /** @return no-return */
+                function ($errno, $errstr) {
+                    throw new RuntimeException($errstr, $errno);
+                },
+                E_ALL
+            );
+            $sql = $this->sql();
+            $params = $this->getValueBinder()->bindings();
+        } catch (Throwable $e) {
+            $sql = 'SQL could not be generated for this query as it is incomplete.';
+            $params = [];
+        } finally {
+            restore_error_handler();
+        }
+
+        return [
+            '(help)' => 'This is a Query object, to get the results execute or iterate it.',
+            'sql' => $sql,
+            'params' => $params,
+            'defaultTypes' => $this->getDefaultTypes(),
+            'decorators' => count($this->_resultDecorators),
+            'executed' => $this->_iterator ? true : false,
+        ];
+    }
+
+    /**
+     * Helper for Query deprecation methods.
+     *
+     * @param string $method The method that is invalid.
+     * @param string $message An additional message.
+     * @return void
+     * @internal
+     */
+    protected function _deprecatedMethod($method, $message = '')
+    {
+        $class = static::class;
+        $text = "As of 4.5.0 calling {$method}() on {$class} is deprecated. " . $message;
+        deprecationWarning($text);
+    }
+}
diff --git a/vendor/cakephp/database/Query/DeleteQuery.php b/vendor/cakephp/database/Query/DeleteQuery.php
new file mode 100644
index 0000000..5c11ae9
--- /dev/null
+++ b/vendor/cakephp/database/Query/DeleteQuery.php
@@ -0,0 +1,222 @@
+_deprecatedMethod('select()', 'Create your query with selectQuery() instead.');
+
+        return parent::select($fields, $overwrite);
+    }
+
+    /**
+     * @inheritDoc
+     */
+    public function distinct($on = [], $overwrite = false)
+    {
+        $this->_deprecatedMethod('distint()');
+
+        return parent::distinct($on, $overwrite);
+    }
+
+    /**
+     * @inheritDoc
+     */
+    public function modifier($modifiers, $overwrite = false)
+    {
+        $this->_deprecatedMethod('modifier()');
+
+        return parent::modifier($modifiers, $overwrite);
+    }
+
+    /**
+     * @inheritDoc
+     */
+    public function order($fields, $overwrite = false)
+    {
+        $this->_deprecatedMethod('order()');
+
+        return parent::order($fields, $overwrite);
+    }
+
+    /**
+     * @inheritDoc
+     */
+    public function orderAsc($field, $overwrite = false)
+    {
+        $this->_deprecatedMethod('orderAsc()');
+
+        return parent::orderAsc($field, $overwrite);
+    }
+
+    /**
+     * @inheritDoc
+     */
+    public function orderDesc($field, $overwrite = false)
+    {
+        $this->_deprecatedMethod('orderDesc()');
+
+        return parent::orderDesc($field, $overwrite);
+    }
+
+    /**
+     * @inheritDoc
+     */
+    public function group($fields, $overwrite = false)
+    {
+        $this->_deprecatedMethod('group()');
+
+        return parent::group($fields, $overwrite);
+    }
+
+    /**
+     * @inheritDoc
+     */
+    public function having($conditions = null, $types = [], $overwrite = false)
+    {
+        $this->_deprecatedMethod('having()');
+
+        return parent::having($conditions, $types, $overwrite);
+    }
+
+    /**
+     * @inheritDoc
+     */
+    public function andHaving($conditions, $types = [])
+    {
+        $this->_deprecatedMethod('andHaving()');
+
+        return parent::andHaving($conditions, $types);
+    }
+
+    /**
+     * @inheritDoc
+     */
+    public function page(int $num, ?int $limit = null)
+    {
+        $this->_deprecatedMethod('page()');
+
+        return parent::page($num, $limit);
+    }
+
+    /**
+     * @inheritDoc
+     */
+    public function limit($limit)
+    {
+        $this->_deprecatedMethod('limit()');
+
+        return parent::limit($limit);
+    }
+
+    /**
+     * @inheritDoc
+     */
+    public function offset($offset)
+    {
+        $this->_deprecatedMethod('offset()');
+
+        return parent::offset($offset);
+    }
+
+    /**
+     * @inheritDoc
+     */
+    public function union($query, $overwrite = false)
+    {
+        $this->_deprecatedMethod('union()');
+
+        return parent::union($query, $overwrite);
+    }
+
+    /**
+     * @inheritDoc
+     */
+    public function unionAll($query, $overwrite = false)
+    {
+        $this->_deprecatedMethod('unionAll()');
+
+        return parent::unionAll($query, $overwrite);
+    }
+
+    /**
+     * @inheritDoc
+     */
+    public function insert(array $columns, array $types = [])
+    {
+        $this->_deprecatedMethod('insert()', 'Create your query with insertQuery() instead.');
+
+        return parent::insert($columns, $types);
+    }
+
+    /**
+     * @inheritDoc
+     */
+    public function into(string $table)
+    {
+        $this->_deprecatedMethod('into()');
+
+        return parent::into($table);
+    }
+
+    /**
+     * @inheritDoc
+     */
+    public function values($data)
+    {
+        $this->_deprecatedMethod('values()');
+
+        return parent::values($data);
+    }
+
+    /**
+     * @inheritDoc
+     */
+    public function update($table)
+    {
+        $this->_deprecatedMethod('update()', 'Create your query with updateQuery() instead.');
+
+        return parent::update($table);
+    }
+
+    /**
+     * @inheritDoc
+     */
+    public function set($key, $value = null, $types = [])
+    {
+        $this->_deprecatedMethod('set()');
+
+        return parent::set($key, $value, $types);
+    }
+}
diff --git a/vendor/cakephp/database/Query/InsertQuery.php b/vendor/cakephp/database/Query/InsertQuery.php
new file mode 100644
index 0000000..7d32623
--- /dev/null
+++ b/vendor/cakephp/database/Query/InsertQuery.php
@@ -0,0 +1,322 @@
+_deprecatedMethod('delete()', 'Create your query with deleteQuery() instead.');
+
+        return parent::delete($table);
+    }
+
+    /**
+     * @inheritDoc
+     */
+    public function select($fields = [], bool $overwrite = false)
+    {
+        $this->_deprecatedMethod('select()', 'Create your query with selectQuery() instead.');
+
+        return parent::select($fields, $overwrite);
+    }
+
+    /**
+     * @inheritDoc
+     */
+    public function distinct($on = [], $overwrite = false)
+    {
+        $this->_deprecatedMethod('distinct()');
+
+        return parent::distinct($on, $overwrite);
+    }
+
+    /**
+     * @inheritDoc
+     */
+    public function modifier($modifiers, $overwrite = false)
+    {
+        $this->_deprecatedMethod('modifier()');
+
+        return parent::modifier($modifiers, $overwrite);
+    }
+
+    /**
+     * @inheritDoc
+     */
+    public function join($tables, $types = [], $overwrite = false)
+    {
+        $this->_deprecatedMethod('join()');
+
+        return parent::join($tables, $types, $overwrite);
+    }
+
+    /**
+     * @inheritDoc
+     */
+    public function removeJoin(string $name)
+    {
+        $this->_deprecatedMethod('removeJoin()');
+
+        return parent::removeJoin($name);
+    }
+
+    /**
+     * @inheritDoc
+     */
+    public function leftJoin($table, $conditions = [], $types = [])
+    {
+        $this->_deprecatedMethod('leftJoin()');
+
+        return parent::leftJoin($table, $conditions, $types);
+    }
+
+    /**
+     * @inheritDoc
+     */
+    public function rightJoin($table, $conditions = [], $types = [])
+    {
+        $this->_deprecatedMethod('rightJoin()');
+
+        return parent::rightJoin($table, $conditions, $types);
+    }
+
+    /**
+     * @inheritDoc
+     */
+    public function innerJoin($table, $conditions = [], $types = [])
+    {
+        $this->_deprecatedMethod('innerJoin()');
+
+        return parent::innerJoin($table, $conditions, $types);
+    }
+
+    /**
+     * @inheritDoc
+     */
+    public function group($fields, $overwrite = false)
+    {
+        $this->_deprecatedMethod('group()');
+
+        return parent::group($fields, $overwrite);
+    }
+
+    /**
+     * @inheritDoc
+     */
+    public function having($conditions = null, $types = [], $overwrite = false)
+    {
+        $this->_deprecatedMethod('having()');
+
+        return parent::having($conditions, $types, $overwrite);
+    }
+
+    /**
+     * @inheritDoc
+     */
+    public function andHaving($conditions, $types = [])
+    {
+        $this->_deprecatedMethod('andHaving()');
+
+        return parent::andHaving($conditions, $types);
+    }
+
+    /**
+     * @inheritDoc
+     */
+    public function page(int $num, ?int $limit = null)
+    {
+        $this->_deprecatedMethod('page()');
+
+        return parent::page($num, $limit);
+    }
+
+    /**
+     * @inheritDoc
+     */
+    public function offset($offset)
+    {
+        $this->_deprecatedMethod('offset()');
+
+        return parent::offset($offset);
+    }
+
+    /**
+     * @inheritDoc
+     */
+    public function union($query, $overwrite = false)
+    {
+        $this->_deprecatedMethod('union()');
+
+        return parent::union($query, $overwrite);
+    }
+
+    /**
+     * @inheritDoc
+     */
+    public function unionAll($query, $overwrite = false)
+    {
+        $this->_deprecatedMethod('union()');
+
+        return parent::unionAll($query, $overwrite);
+    }
+
+    /**
+     * @inheritDoc
+     */
+    public function from($tables = [], $overwrite = false)
+    {
+        $this->_deprecatedMethod('from()', 'Use into() instead.');
+
+        return parent::from($tables, $overwrite);
+    }
+
+    /**
+     * @inheritDoc
+     */
+    public function update($table)
+    {
+        $this->_deprecatedMethod('update()', 'Create your query with updateQuery() instead.');
+
+        return parent::update($table);
+    }
+
+    /**
+     * @inheritDoc
+     */
+    public function set($key, $value = null, $types = [])
+    {
+        $this->_deprecatedMethod('set()');
+
+        return parent::set($key, $value, $types);
+    }
+
+    /**
+     * @inheritDoc
+     */
+    public function where($conditions = null, array $types = [], bool $overwrite = false)
+    {
+        $this->_deprecatedMethod('where()');
+
+        return parent::where($conditions, $types, $overwrite);
+    }
+
+    /**
+     * @inheritDoc
+     */
+    public function whereNotNull($fields)
+    {
+        $this->_deprecatedMethod('whereNotNull()');
+
+        return parent::whereNotNull($fields);
+    }
+
+    /**
+     * @inheritDoc
+     */
+    public function whereNull($fields)
+    {
+        $this->_deprecatedMethod('whereNull()');
+
+        return parent::whereNull($fields);
+    }
+
+    /**
+     * @inheritDoc
+     */
+    public function whereInList(string $field, array $values, array $options = [])
+    {
+        $this->_deprecatedMethod('whereInList()');
+
+        return parent::whereInList($field, $values, $options);
+    }
+
+    /**
+     * @inheritDoc
+     */
+    public function whereNotInList(string $field, array $values, array $options = [])
+    {
+        $this->_deprecatedMethod('whereNotInList()');
+
+        return parent::whereNotInList($field, $values, $options);
+    }
+
+    /**
+     * @inheritDoc
+     */
+    public function whereNotInListOrNull(string $field, array $values, array $options = [])
+    {
+        $this->_deprecatedMethod('whereNotInListOrNull()');
+
+        return parent::whereNotInListOrNull($field, $values, $options);
+    }
+
+    /**
+     * @inheritDoc
+     */
+    public function andWhere($conditions, array $types = [])
+    {
+        $this->_deprecatedMethod('andWhere()');
+
+        return parent::andWhere($conditions, $types);
+    }
+
+    /**
+     * @inheritDoc
+     */
+    public function order($fields, $overwrite = false)
+    {
+        $this->_deprecatedMethod('order()');
+
+        return parent::order($fields, $overwrite);
+    }
+
+    /**
+     * @inheritDoc
+     */
+    public function orderAsc($field, $overwrite = false)
+    {
+        $this->_deprecatedMethod('orderAsc()');
+
+        return parent::orderAsc($field, $overwrite);
+    }
+
+    /**
+     * @inheritDoc
+     */
+    public function orderDesc($field, $overwrite = false)
+    {
+        $this->_deprecatedMethod('orderDesc()');
+
+        return parent::orderDesc($field, $overwrite);
+    }
+}
diff --git a/vendor/cakephp/database/Query/SelectQuery.php b/vendor/cakephp/database/Query/SelectQuery.php
new file mode 100644
index 0000000..7d2986a
--- /dev/null
+++ b/vendor/cakephp/database/Query/SelectQuery.php
@@ -0,0 +1,127 @@
+_deprecatedMethod('delete()', 'Create your query with deleteQuery() instead.');
+
+        return parent::delete($table);
+    }
+
+    /**
+     * @inheritDoc
+     */
+    public function insert(array $columns, array $types = [])
+    {
+        $this->_deprecatedMethod('insert()', 'Create your query with insertQuery() instead.');
+
+        return parent::insert($columns, $types);
+    }
+
+    /**
+     * @inheritDoc
+     */
+    public function into(string $table)
+    {
+        $this->_deprecatedMethod('into()', 'Use from() instead.');
+
+        return parent::into($table);
+    }
+
+    /**
+     * @inheritDoc
+     */
+    public function values($data)
+    {
+        $this->_deprecatedMethod('values()');
+
+        return parent::values($data);
+    }
+
+    /**
+     * @inheritDoc
+     */
+    public function update($table)
+    {
+        $this->_deprecatedMethod('update()', 'Create your query with updateQuery() instead.');
+
+        return parent::update($table);
+    }
+
+    /**
+     * @inheritDoc
+     */
+    public function set($key, $value = null, $types = [])
+    {
+        $this->_deprecatedMethod('set()');
+
+        return parent::set($key, $value, $types);
+    }
+
+    /**
+     * Sets the connection role.
+     *
+     * @param string $role Connection role ('read' or 'write')
+     * @return $this
+     */
+    public function setConnectionRole(string $role)
+    {
+        assert($role === Connection::ROLE_READ || $role === Connection::ROLE_WRITE);
+        $this->connectionRole = $role;
+
+        return $this;
+    }
+
+    /**
+     * Sets the connection role to read.
+     *
+     * @return $this
+     */
+    public function useReadRole()
+    {
+        return $this->setConnectionRole(Connection::ROLE_READ);
+    }
+
+    /**
+     * Sets the connection role to write.
+     *
+     * @return $this
+     */
+    public function useWriteRole()
+    {
+        return $this->setConnectionRole(Connection::ROLE_WRITE);
+    }
+}
diff --git a/vendor/cakephp/database/Query/UpdateQuery.php b/vendor/cakephp/database/Query/UpdateQuery.php
new file mode 100644
index 0000000..0f84cce
--- /dev/null
+++ b/vendor/cakephp/database/Query/UpdateQuery.php
@@ -0,0 +1,182 @@
+_deprecatedMethod('delete()', 'Create your query with deleteQuery() instead.');
+
+        return parent::delete($table);
+    }
+
+    /**
+     * @inheritDoc
+     */
+    public function select($fields = [], bool $overwrite = false)
+    {
+        $this->_deprecatedMethod('select()', 'Create your query with selectQuery() instead.');
+
+        return parent::select($fields, $overwrite);
+    }
+
+    /**
+     * @inheritDoc
+     */
+    public function distinct($on = [], $overwrite = false)
+    {
+        $this->_deprecatedMethod('distinct()');
+
+        return parent::distinct($on, $overwrite);
+    }
+
+    /**
+     * @inheritDoc
+     */
+    public function modifier($modifiers, $overwrite = false)
+    {
+        $this->_deprecatedMethod('modifier()');
+
+        return parent::modifier($modifiers, $overwrite);
+    }
+
+    /**
+     * @inheritDoc
+     */
+    public function group($fields, $overwrite = false)
+    {
+        $this->_deprecatedMethod('group()');
+
+        return parent::group($fields, $overwrite);
+    }
+
+    /**
+     * @inheritDoc
+     */
+    public function having($conditions = null, $types = [], $overwrite = false)
+    {
+        $this->_deprecatedMethod('having()');
+
+        return parent::having($conditions, $types, $overwrite);
+    }
+
+    /**
+     * @inheritDoc
+     */
+    public function andHaving($conditions, $types = [])
+    {
+        $this->_deprecatedMethod('andHaving()');
+
+        return parent::andHaving($conditions, $types);
+    }
+
+    /**
+     * @inheritDoc
+     */
+    public function page(int $num, ?int $limit = null)
+    {
+        $this->_deprecatedMethod('page()');
+
+        return parent::page($num, $limit);
+    }
+
+    /**
+     * @inheritDoc
+     */
+    public function offset($offset)
+    {
+        $this->_deprecatedMethod('offset()');
+
+        return parent::offset($offset);
+    }
+
+    /**
+     * @inheritDoc
+     */
+    public function union($query, $overwrite = false)
+    {
+        $this->_deprecatedMethod('union()');
+
+        return parent::union($query, $overwrite);
+    }
+
+    /**
+     * @inheritDoc
+     */
+    public function unionAll($query, $overwrite = false)
+    {
+        $this->_deprecatedMethod('union()');
+
+        return parent::unionAll($query, $overwrite);
+    }
+
+    /**
+     * @inheritDoc
+     */
+    public function insert(array $columns, array $types = [])
+    {
+        $this->_deprecatedMethod('insert()', 'Create your query with insertQuery() instead.');
+
+        return parent::insert($columns, $types);
+    }
+
+    /**
+     * @inheritDoc
+     */
+    public function into(string $table)
+    {
+        $this->_deprecatedMethod('into()', 'Use update() instead.');
+
+        return parent::into($table);
+    }
+
+    /**
+     * @inheritDoc
+     */
+    public function values($data)
+    {
+        $this->_deprecatedMethod('values()');
+
+        return parent::values($data);
+    }
+
+    /**
+     * @inheritDoc
+     */
+    public function from($tables = [], $overwrite = false)
+    {
+        $this->_deprecatedMethod('from()', 'Use update() instead.');
+
+        return parent::from($tables, $overwrite);
+    }
+}
diff --git a/vendor/cakephp/database/QueryCompiler.php b/vendor/cakephp/database/QueryCompiler.php
new file mode 100644
index 0000000..9ed4422
--- /dev/null
+++ b/vendor/cakephp/database/QueryCompiler.php
@@ -0,0 +1,462 @@
+
+     */
+    protected $_templates = [
+        'delete' => 'DELETE',
+        'where' => ' WHERE %s',
+        'group' => ' GROUP BY %s ',
+        'having' => ' HAVING %s ',
+        'order' => ' %s',
+        'limit' => ' LIMIT %s',
+        'offset' => ' OFFSET %s',
+        'epilog' => ' %s',
+    ];
+
+    /**
+     * The list of query clauses to traverse for generating a SELECT statement
+     *
+     * @var array
+     */
+    protected $_selectParts = [
+        'with', 'select', 'from', 'join', 'where', 'group', 'having', 'window', 'order',
+        'limit', 'offset', 'union', 'epilog',
+    ];
+
+    /**
+     * The list of query clauses to traverse for generating an UPDATE statement
+     *
+     * @var array
+     */
+    protected $_updateParts = ['with', 'update', 'set', 'where', 'epilog'];
+
+    /**
+     * The list of query clauses to traverse for generating a DELETE statement
+     *
+     * @var array
+     */
+    protected $_deleteParts = ['with', 'delete', 'modifier', 'from', 'where', 'epilog'];
+
+    /**
+     * The list of query clauses to traverse for generating an INSERT statement
+     *
+     * @var array
+     */
+    protected $_insertParts = ['with', 'insert', 'values', 'epilog'];
+
+    /**
+     * Indicate whether this query dialect supports ordered unions.
+     *
+     * Overridden in subclasses.
+     *
+     * @var bool
+     */
+    protected $_orderedUnion = true;
+
+    /**
+     * Indicate whether aliases in SELECT clause need to be always quoted.
+     *
+     * @var bool
+     */
+    protected $_quotedSelectAliases = false;
+
+    /**
+     * Returns the SQL representation of the provided query after generating
+     * the placeholders for the bound values using the provided generator
+     *
+     * @param \Cake\Database\Query $query The query that is being compiled
+     * @param \Cake\Database\ValueBinder $binder Value binder used to generate parameter placeholders
+     * @return string
+     */
+    public function compile(Query $query, ValueBinder $binder): string
+    {
+        $sql = '';
+        $type = $query->type();
+        $query->traverseParts(
+            $this->_sqlCompiler($sql, $query, $binder),
+            $this->{"_{$type}Parts"}
+        );
+
+        // Propagate bound parameters from sub-queries if the
+        // placeholders can be found in the SQL statement.
+        if ($query->getValueBinder() !== $binder) {
+            foreach ($query->getValueBinder()->bindings() as $binding) {
+                $placeholder = ':' . $binding['placeholder'];
+                if (preg_match('/' . $placeholder . '(?:\W|$)/', $sql) > 0) {
+                    $binder->bind($placeholder, $binding['value'], $binding['type']);
+                }
+            }
+        }
+
+        return $sql;
+    }
+
+    /**
+     * Returns a callable object that can be used to compile a SQL string representation
+     * of this query.
+     *
+     * @param string $sql initial sql string to append to
+     * @param \Cake\Database\Query $query The query that is being compiled
+     * @param \Cake\Database\ValueBinder $binder Value binder used to generate parameter placeholder
+     * @return \Closure
+     */
+    protected function _sqlCompiler(string &$sql, Query $query, ValueBinder $binder): Closure
+    {
+        return function ($part, $partName) use (&$sql, $query, $binder) {
+            if (
+                $part === null ||
+                (is_array($part) && empty($part)) ||
+                ($part instanceof Countable && count($part) === 0)
+            ) {
+                return;
+            }
+
+            if ($part instanceof ExpressionInterface) {
+                $part = [$part->sql($binder)];
+            }
+            if (isset($this->_templates[$partName])) {
+                $part = $this->_stringifyExpressions((array)$part, $binder);
+                $sql .= sprintf($this->_templates[$partName], implode(', ', $part));
+
+                return;
+            }
+
+            $sql .= $this->{'_build' . $partName . 'Part'}($part, $query, $binder);
+        };
+    }
+
+    /**
+     * Helper function used to build the string representation of a `WITH` clause,
+     * it constructs the CTE definitions list and generates the `RECURSIVE`
+     * keyword when required.
+     *
+     * @param array $parts List of CTEs to be transformed to string
+     * @param \Cake\Database\Query $query The query that is being compiled
+     * @param \Cake\Database\ValueBinder $binder Value binder used to generate parameter placeholder
+     * @return string
+     */
+    protected function _buildWithPart(array $parts, Query $query, ValueBinder $binder): string
+    {
+        $recursive = false;
+        $expressions = [];
+        foreach ($parts as $cte) {
+            $recursive = $recursive || $cte->isRecursive();
+            $expressions[] = $cte->sql($binder);
+        }
+
+        $recursive = $recursive ? 'RECURSIVE ' : '';
+
+        return sprintf('WITH %s%s ', $recursive, implode(', ', $expressions));
+    }
+
+    /**
+     * Helper function used to build the string representation of a SELECT clause,
+     * it constructs the field list taking care of aliasing and
+     * converting expression objects to string. This function also constructs the
+     * DISTINCT clause for the query.
+     *
+     * @param array $parts list of fields to be transformed to string
+     * @param \Cake\Database\Query $query The query that is being compiled
+     * @param \Cake\Database\ValueBinder $binder Value binder used to generate parameter placeholder
+     * @return string
+     */
+    protected function _buildSelectPart(array $parts, Query $query, ValueBinder $binder): string
+    {
+        $select = 'SELECT%s %s%s';
+        if ($this->_orderedUnion && $query->clause('union')) {
+            $select = '(SELECT%s %s%s';
+        }
+        $distinct = $query->clause('distinct');
+        $modifiers = $this->_buildModifierPart($query->clause('modifier'), $query, $binder);
+
+        $driver = $query->getConnection()->getDriver($query->getConnectionRole());
+        $quoteIdentifiers = $driver->isAutoQuotingEnabled() || $this->_quotedSelectAliases;
+        $normalized = [];
+        $parts = $this->_stringifyExpressions($parts, $binder);
+        foreach ($parts as $k => $p) {
+            if (!is_numeric($k)) {
+                $p = $p . ' AS ';
+                if ($quoteIdentifiers) {
+                    $p .= $driver->quoteIdentifier($k);
+                } else {
+                    $p .= $k;
+                }
+            }
+            $normalized[] = $p;
+        }
+
+        if ($distinct === true) {
+            $distinct = 'DISTINCT ';
+        }
+
+        if (is_array($distinct)) {
+            $distinct = $this->_stringifyExpressions($distinct, $binder);
+            $distinct = sprintf('DISTINCT ON (%s) ', implode(', ', $distinct));
+        }
+
+        return sprintf($select, $modifiers, $distinct, implode(', ', $normalized));
+    }
+
+    /**
+     * Helper function used to build the string representation of a FROM clause,
+     * it constructs the tables list taking care of aliasing and
+     * converting expression objects to string.
+     *
+     * @param array $parts list of tables to be transformed to string
+     * @param \Cake\Database\Query $query The query that is being compiled
+     * @param \Cake\Database\ValueBinder $binder Value binder used to generate parameter placeholder
+     * @return string
+     */
+    protected function _buildFromPart(array $parts, Query $query, ValueBinder $binder): string
+    {
+        $select = ' FROM %s';
+        $normalized = [];
+        $parts = $this->_stringifyExpressions($parts, $binder);
+        foreach ($parts as $k => $p) {
+            if (!is_numeric($k)) {
+                $p = $p . ' ' . $k;
+            }
+            $normalized[] = $p;
+        }
+
+        return sprintf($select, implode(', ', $normalized));
+    }
+
+    /**
+     * Helper function used to build the string representation of multiple JOIN clauses,
+     * it constructs the joins list taking care of aliasing and converting
+     * expression objects to string in both the table to be joined and the conditions
+     * to be used.
+     *
+     * @param array $parts list of joins to be transformed to string
+     * @param \Cake\Database\Query $query The query that is being compiled
+     * @param \Cake\Database\ValueBinder $binder Value binder used to generate parameter placeholder
+     * @return string
+     */
+    protected function _buildJoinPart(array $parts, Query $query, ValueBinder $binder): string
+    {
+        $joins = '';
+        foreach ($parts as $join) {
+            if (!isset($join['table'])) {
+                throw new DatabaseException(sprintf(
+                    'Could not compile join clause for alias `%s`. No table was specified. ' .
+                    'Use the `table` key to define a table.',
+                    $join['alias']
+                ));
+            }
+            if ($join['table'] instanceof ExpressionInterface) {
+                $join['table'] = '(' . $join['table']->sql($binder) . ')';
+            }
+
+            $joins .= sprintf(' %s JOIN %s %s', $join['type'], $join['table'], $join['alias']);
+
+            $condition = '';
+            if (isset($join['conditions']) && $join['conditions'] instanceof ExpressionInterface) {
+                $condition = $join['conditions']->sql($binder);
+            }
+            if ($condition === '') {
+                $joins .= ' ON 1 = 1';
+            } else {
+                $joins .= " ON {$condition}";
+            }
+        }
+
+        return $joins;
+    }
+
+    /**
+     * Helper function to build the string representation of a window clause.
+     *
+     * @param array $parts List of windows to be transformed to string
+     * @param \Cake\Database\Query $query The query that is being compiled
+     * @param \Cake\Database\ValueBinder $binder Value binder used to generate parameter placeholder
+     * @return string
+     */
+    protected function _buildWindowPart(array $parts, Query $query, ValueBinder $binder): string
+    {
+        $windows = [];
+        foreach ($parts as $window) {
+            $windows[] = $window['name']->sql($binder) . ' AS (' . $window['window']->sql($binder) . ')';
+        }
+
+        return ' WINDOW ' . implode(', ', $windows);
+    }
+
+    /**
+     * Helper function to generate SQL for SET expressions.
+     *
+     * @param array $parts List of keys & values to set.
+     * @param \Cake\Database\Query $query The query that is being compiled
+     * @param \Cake\Database\ValueBinder $binder Value binder used to generate parameter placeholder
+     * @return string
+     */
+    protected function _buildSetPart(array $parts, Query $query, ValueBinder $binder): string
+    {
+        $set = [];
+        foreach ($parts as $part) {
+            if ($part instanceof ExpressionInterface) {
+                $part = $part->sql($binder);
+            }
+            if ($part[0] === '(') {
+                $part = substr($part, 1, -1);
+            }
+            $set[] = $part;
+        }
+
+        return ' SET ' . implode('', $set);
+    }
+
+    /**
+     * Builds the SQL string for all the UNION clauses in this query, when dealing
+     * with query objects it will also transform them using their configured SQL
+     * dialect.
+     *
+     * @param array $parts list of queries to be operated with UNION
+     * @param \Cake\Database\Query $query The query that is being compiled
+     * @param \Cake\Database\ValueBinder $binder Value binder used to generate parameter placeholder
+     * @return string
+     */
+    protected function _buildUnionPart(array $parts, Query $query, ValueBinder $binder): string
+    {
+        $parts = array_map(function ($p) use ($binder) {
+            $p['query'] = $p['query']->sql($binder);
+            $p['query'] = $p['query'][0] === '(' ? trim($p['query'], '()') : $p['query'];
+            $prefix = $p['all'] ? 'ALL ' : '';
+            if ($this->_orderedUnion) {
+                return "{$prefix}({$p['query']})";
+            }
+
+            return $prefix . $p['query'];
+        }, $parts);
+
+        if ($this->_orderedUnion) {
+            return sprintf(")\nUNION %s", implode("\nUNION ", $parts));
+        }
+
+        return sprintf("\nUNION %s", implode("\nUNION ", $parts));
+    }
+
+    /**
+     * Builds the SQL fragment for INSERT INTO.
+     *
+     * @param array $parts The insert parts.
+     * @param \Cake\Database\Query $query The query that is being compiled
+     * @param \Cake\Database\ValueBinder $binder Value binder used to generate parameter placeholder
+     * @return string SQL fragment.
+     */
+    protected function _buildInsertPart(array $parts, Query $query, ValueBinder $binder): string
+    {
+        if (!isset($parts[0])) {
+            throw new DatabaseException(
+                'Could not compile insert query. No table was specified. ' .
+                'Use `into()` to define a table.'
+            );
+        }
+        $table = $parts[0];
+        $columns = $this->_stringifyExpressions($parts[1], $binder);
+        $modifiers = $this->_buildModifierPart($query->clause('modifier'), $query, $binder);
+
+        return sprintf('INSERT%s INTO %s (%s)', $modifiers, $table, implode(', ', $columns));
+    }
+
+    /**
+     * Builds the SQL fragment for INSERT INTO.
+     *
+     * @param array $parts The values parts.
+     * @param \Cake\Database\Query $query The query that is being compiled
+     * @param \Cake\Database\ValueBinder $binder Value binder used to generate parameter placeholder
+     * @return string SQL fragment.
+     */
+    protected function _buildValuesPart(array $parts, Query $query, ValueBinder $binder): string
+    {
+        return implode('', $this->_stringifyExpressions($parts, $binder));
+    }
+
+    /**
+     * Builds the SQL fragment for UPDATE.
+     *
+     * @param array $parts The update parts.
+     * @param \Cake\Database\Query $query The query that is being compiled
+     * @param \Cake\Database\ValueBinder $binder Value binder used to generate parameter placeholder
+     * @return string SQL fragment.
+     */
+    protected function _buildUpdatePart(array $parts, Query $query, ValueBinder $binder): string
+    {
+        $table = $this->_stringifyExpressions($parts, $binder);
+        $modifiers = $this->_buildModifierPart($query->clause('modifier'), $query, $binder);
+
+        return sprintf('UPDATE%s %s', $modifiers, implode(',', $table));
+    }
+
+    /**
+     * Builds the SQL modifier fragment
+     *
+     * @param array $parts The query modifier parts
+     * @param \Cake\Database\Query $query The query that is being compiled
+     * @param \Cake\Database\ValueBinder $binder Value binder used to generate parameter placeholder
+     * @return string SQL fragment.
+     */
+    protected function _buildModifierPart(array $parts, Query $query, ValueBinder $binder): string
+    {
+        if ($parts === []) {
+            return '';
+        }
+
+        return ' ' . implode(' ', $this->_stringifyExpressions($parts, $binder, false));
+    }
+
+    /**
+     * Helper function used to covert ExpressionInterface objects inside an array
+     * into their string representation.
+     *
+     * @param array $expressions list of strings and ExpressionInterface objects
+     * @param \Cake\Database\ValueBinder $binder Value binder used to generate parameter placeholder
+     * @param bool $wrap Whether to wrap each expression object with parenthesis
+     * @return array
+     */
+    protected function _stringifyExpressions(array $expressions, ValueBinder $binder, bool $wrap = true): array
+    {
+        $result = [];
+        foreach ($expressions as $k => $expression) {
+            if ($expression instanceof ExpressionInterface) {
+                $value = $expression->sql($binder);
+                $expression = $wrap ? '(' . $value . ')' : $value;
+            }
+            $result[$k] = $expression;
+        }
+
+        return $result;
+    }
+}
diff --git a/vendor/cakephp/database/README.md b/vendor/cakephp/database/README.md
new file mode 100644
index 0000000..d7bbe8e
--- /dev/null
+++ b/vendor/cakephp/database/README.md
@@ -0,0 +1,358 @@
+[![Total Downloads](https://img.shields.io/packagist/dt/cakephp/database.svg?style=flat-square)](https://packagist.org/packages/cakephp/database)
+[![License](https://img.shields.io/badge/license-MIT-blue.svg?style=flat-square)](LICENSE.txt)
+
+# A flexible and lightweight Database Library for PHP
+
+This library abstracts and provides help with most aspects of dealing with relational
+databases such as keeping connections to the server, building queries,
+preventing SQL injections, inspecting and altering schemas, and with debugging and
+profiling queries sent to the database.
+
+It adopts the API from the native PDO extension in PHP for familiarity, but solves many of the
+inconsistencies PDO has, while also providing several features that extend PDO's capabilities.
+
+A distinguishing factor of this library when compared to similar database connection packages,
+is that it takes the concept of "data types" to its core. It lets you work with complex PHP objects
+or structures that can be passed as query conditions or to be inserted in the database.
+
+The typing system will intelligently convert the PHP structures when passing them to the database, and
+convert them back when retrieving.
+
+
+## Connecting to the database
+
+This library is able to work with the following databases:
+
+* MySQL
+* Postgres
+* SQLite
+* Microsoft SQL Server (2008 and above)
+
+The first thing you need to do when using this library is create a connection object.
+Before performing any operations with the connection, you need to specify a driver
+to use:
+
+```php
+use Cake\Database\Connection;
+use Cake\Database\Driver\Mysql;
+use Cake\Database\Driver\Sqlite;
+
+$connection = new Connection([
+	'driver' => Mysql::class,
+	'database' => 'test',
+	'username' => 'root',
+	'password' => 'secret',
+]);
+
+$connection2 = new Connection([
+	'driver' => Sqlite::class,
+	'database' => '/path/to/file.db'
+]);
+```
+
+Drivers are classes responsible for actually executing the commands to the database and
+correctly building the SQL according to the database specific dialect.
+
+### Connection options
+
+This is a list of possible options that can be passed when creating a connection:
+
+* `driver`: Driver class name
+* `persistent`: Creates a persistent connection
+* `host`: The server host
+* `database`: The database name
+* `username`: Login credential
+* `password`: Connection secret
+* `encoding`: The connection encoding (or charset)
+* `timezone`: The connection timezone or time offset
+
+## Using connections
+
+After creating a connection, you can immediately interact with the database. You can choose
+either to use the shorthand methods `execute()`, `insert()`, `update()`, `delete()` or use the
+`newQuery()` for using a query builder.
+
+The easiest way of executing queries is by using the `execute()` method, it will return a
+`Cake\Database\StatementInterface` that you can use to get the data back:
+
+```php
+$statement = $connection->execute('SELECT * FROM articles');
+
+while($row = $statement->fetch('assoc')) {
+	echo $row['title'] . PHP_EOL;
+}
+```
+Binding values to parametrized arguments is also possible with the execute function:
+
+```php
+$statement = $connection->execute('SELECT * FROM articles WHERE id = :id', ['id' => 1], ['id' => 'integer']);
+$results = $statement->fetch('assoc');
+```
+
+The third parameter is the types the passed values should be converted to when passed to the database. If
+no types are passed, all arguments will be interpreted as a string.
+
+Alternatively you can construct a statement manually and then fetch rows from it:
+
+```php
+$statement = $connection->prepare('SELECT * from articles WHERE id != :id');
+$statement->bind(['id' => 1], ['id' => 'integer']);
+$results = $statement->fetchAll('assoc');
+```
+
+The default types that are understood by this library and can be passed to the `bind()` function or to `execute()`
+are:
+
+* biginteger
+* binary
+* date
+* float
+* decimal
+* integer
+* time
+* datetime
+* timestamp
+* uuid
+
+More types can be added dynamically in a bit.
+
+Statements can be reused by binding new values to the parameters in the query:
+
+```php
+$statement = $connection->prepare('SELECT * from articles WHERE id = :id');
+$statement->bind(['id' => 1], ['id' => 'integer']);
+$results = $statement->fetchAll('assoc');
+
+$statement->bind(['id' => 1], ['id' => 'integer']);
+$results = $statement->fetchAll('assoc');
+```
+
+### Updating Rows
+
+Updating can be done using the `update()` function in the connection object. In the following
+example we will update the title of the article with id = 1:
+
+```php
+$connection->update('articles', ['title' => 'New title'], ['id' => 1]);
+```
+
+The concept of data types is central to this library, so you can use the last parameter of the function
+to specify what types should be used:
+
+```php
+$connection->update(
+	'articles',
+	['title' => 'New title'],
+	['created >=' => new DateTime('-3 day'), 'created <' => new DateTime('now')],
+	['created' => 'datetime']
+);
+```
+
+The example above will execute the following SQL:
+
+```sql
+UPDATE articles SET title = 'New Title' WHERE created >= '2014-10-10 00:00:00' AND created < '2014-10-13 00:00:00';
+```
+
+More on creating complex where conditions or more complex update queries later.
+
+### Deleting Rows
+
+Similarly, the `delete()` method is used to delete rows from the database:
+
+```php
+$connection->delete('articles', ['created <' => DateTime('now')], ['created' => 'date']);
+```
+
+Will generate the following SQL
+
+```sql
+DELETE FROM articles where created < '2014-10-10'
+```
+
+### Inserting Rows
+
+Rows can be inserted using the `insert()` method:
+
+```php
+$connection->insert(
+	'articles',
+	['title' => 'My Title', 'body' => 'Some paragraph', 'created' => new DateTime()],
+	['created' => 'datetime']
+);
+```
+
+More complex updates, deletes and insert queries can be generated using the `Query` class.
+
+## Query Builder
+
+One of the goals of this library is to allow the generation of both simple and complex queries with
+ease. The query builder can be accessed by getting a new instance of a query:
+
+```php
+$query = $connection->newQuery();
+```
+
+### Selecting Fields
+
+Adding fields to the `SELECT` clause:
+
+```php
+$query->select(['id', 'title', 'body']);
+
+// Results in SELECT id AS pk, title AS aliased_title, body ...
+$query->select(['pk' => 'id', 'aliased_title' => 'title', 'body']);
+
+// Use a closure
+$query->select(function ($query) {
+	return ['id', 'title', 'body'];
+});
+```
+
+### Where Conditions
+
+Generating conditions:
+
+```php
+// WHERE id = 1
+$query->where(['id' => 1]);
+
+// WHERE id > 2
+$query->where(['id >' => 1]);
+```
+
+As you can see you can use any operator by placing it with a space after the field name.
+Adding multiple conditions is easy as well:
+
+```php
+$query->where(['id >' => 1])->andWhere(['title' => 'My Title']);
+
+// Equivalent to
+$query->where(['id >' => 1, 'title' => 'My title']);
+```
+
+It is possible to generate `OR` conditions as well
+
+```php
+$query->where(['OR' => ['id >' => 1, 'title' => 'My title']]);
+```
+
+For even more complex conditions you can use closures and expression objects:
+
+```php
+$query->where(function ($exp) {
+        return $exp
+            ->eq('author_id', 2)
+            ->eq('published', true)
+            ->notEq('spam', true)
+            ->gt('view_count', 10);
+    });
+```
+
+Which results in:
+
+```sql
+SELECT * FROM articles
+WHERE
+	author_id = 2
+	AND published = 1
+	AND spam != 1
+	AND view_count > 10
+```
+
+Combining expressions is also possible:
+
+```php
+$query->where(function ($exp) {
+        $orConditions = $exp->or(['author_id' => 2])
+            ->eq('author_id', 5);
+        return $exp
+            ->not($orConditions)
+            ->lte('view_count', 10);
+    });
+```
+
+That generates:
+
+```sql
+SELECT *
+FROM articles
+WHERE
+	NOT (author_id = 2 OR author_id = 5)
+	AND view_count <= 10
+```
+
+When using the expression objects you can use the following methods to create conditions:
+
+* `eq()` Creates an equality condition.
+* `notEq()` Create an inequality condition
+* `like()` Create a condition using the LIKE operator.
+* `notLike()` Create a negated LIKE condition.
+* `in()` Create a condition using IN.
+* `notIn()` Create a negated condition using IN.
+* `gt()` Create a > condition.
+* `gte()` Create a >= condition.
+* `lt()` Create a < condition.
+* `lte()` Create a <= condition.
+* `isNull()` Create an IS NULL condition.
+* `isNotNull()` Create a negated IS NULL condition.
+
+### Aggregates and SQL Functions
+
+```php
+// Results in SELECT COUNT(*) count FROM ...
+$query->select(['count' => $query->func()->count('*')]);
+```
+
+A number of commonly used functions can be created with the func() method:
+
+* `sum()` Calculate a sum. The arguments will be treated as literal values.
+* `avg()` Calculate an average. The arguments will be treated as literal values.
+* `min()` Calculate the min of a column. The arguments will be treated as literal values.
+* `max()` Calculate the max of a column. The arguments will be treated as literal values.
+* `count()` Calculate the count. The arguments will be treated as literal values.
+* `concat()` Concatenate two values together. The arguments are treated as bound parameters unless marked as literal.
+* `coalesce()` Coalesce values. The arguments are treated as bound parameters unless marked as literal.
+* `dateDiff()` Get the difference between two dates/times. The arguments are treated as bound parameters unless marked as literal.
+* `now()` Take either 'time' or 'date' as an argument allowing you to get either the current time, or current date.
+
+When providing arguments for SQL functions, there are two kinds of parameters you can use, literal arguments and bound parameters. Literal
+parameters allow you to reference columns or other SQL literals. Bound parameters can be used to safely add user data to SQL functions.
+For example:
+
+```php
+$concat = $query->func()->concat([
+    'title' => 'literal',
+    ' NEW'
+]);
+$query->select(['title' => $concat]);
+```
+
+The above generates:
+
+```sql
+SELECT CONCAT(title, :c0) ...;
+```
+
+### Other SQL Clauses
+
+Read of all other SQL clauses that the builder is capable of generating in the [official API docs](https://api.cakephp.org/4.x/class-Cake.Database.Query.html)
+
+### Getting Results out of a Query
+
+Once you’ve made your query, you’ll want to retrieve rows from it. There are a few ways of doing this:
+
+```php
+// Iterate the query
+foreach ($query as $row) {
+    // Do stuff.
+}
+
+// Get the statement and fetch all results
+$results = $query->execute()->fetchAll('assoc');
+```
+
+## Official API
+
+You can read the official [official API docs](https://api.cakephp.org/4.x/namespace-Cake.Database.html) to learn more of what this library
+has to offer.
diff --git a/vendor/cakephp/database/Retry/ErrorCodeWaitStrategy.php b/vendor/cakephp/database/Retry/ErrorCodeWaitStrategy.php
new file mode 100644
index 0000000..010a531
--- /dev/null
+++ b/vendor/cakephp/database/Retry/ErrorCodeWaitStrategy.php
@@ -0,0 +1,69 @@
+
+     */
+    protected $errorCodes;
+
+    /**
+     * @var int
+     */
+    protected $retryInterval;
+
+    /**
+     * @param array $errorCodes DB-specific error codes that allow retrying
+     * @param int $retryInterval Seconds to wait before allowing next retry, 0 for no wait.
+     */
+    public function __construct(array $errorCodes, int $retryInterval)
+    {
+        $this->errorCodes = $errorCodes;
+        $this->retryInterval = $retryInterval;
+    }
+
+    /**
+     * @inheritDoc
+     */
+    public function shouldRetry(Exception $exception, int $retryCount): bool
+    {
+        if (
+            $exception instanceof PDOException &&
+            $exception->errorInfo &&
+            in_array($exception->errorInfo[1], $this->errorCodes)
+        ) {
+            if ($this->retryInterval > 0) {
+                sleep($this->retryInterval);
+            }
+
+            return true;
+        }
+
+        return false;
+    }
+}
diff --git a/vendor/cakephp/database/Retry/ReconnectStrategy.php b/vendor/cakephp/database/Retry/ReconnectStrategy.php
new file mode 100644
index 0000000..ac84781
--- /dev/null
+++ b/vendor/cakephp/database/Retry/ReconnectStrategy.php
@@ -0,0 +1,124 @@
+
+     */
+    protected static $causes = [
+        'gone away',
+        'Lost connection',
+        'Transaction() on null',
+        'closed the connection unexpectedly',
+        'closed unexpectedly',
+        'deadlock avoided',
+        'decryption failed or bad record mac',
+        'is dead or not enabled',
+        'no connection to the server',
+        'query_wait_timeout',
+        'reset by peer',
+        'terminate due to client_idle_limit',
+        'while sending',
+        'writing data to the connection',
+    ];
+
+    /**
+     * The connection to check for validity
+     *
+     * @var \Cake\Database\Connection
+     */
+    protected $connection;
+
+    /**
+     * Creates the ReconnectStrategy object by storing a reference to the
+     * passed connection. This reference will be used to automatically
+     * reconnect to the server in case of failure.
+     *
+     * @param \Cake\Database\Connection $connection The connection to check
+     */
+    public function __construct(Connection $connection)
+    {
+        $this->connection = $connection;
+    }
+
+    /**
+     * {@inheritDoc}
+     *
+     * Checks whether the exception was caused by a lost connection,
+     * and returns true if it was able to successfully reconnect.
+     */
+    public function shouldRetry(Exception $exception, int $retryCount): bool
+    {
+        $message = $exception->getMessage();
+
+        foreach (static::$causes as $cause) {
+            if (strstr($message, $cause) !== false) {
+                return $this->reconnect();
+            }
+        }
+
+        return false;
+    }
+
+    /**
+     * Tries to re-establish the connection to the server, if it is safe to do so
+     *
+     * @return bool Whether the connection was re-established
+     */
+    protected function reconnect(): bool
+    {
+        if ($this->connection->inTransaction()) {
+            // It is not safe to blindly reconnect in the middle of a transaction
+            return false;
+        }
+
+        try {
+            // Make sure we free any resources associated with the old connection
+            $this->connection->getDriver()->disconnect();
+        } catch (Exception $e) {
+        }
+
+        try {
+            $this->connection->connect();
+            if ($this->connection->isQueryLoggingEnabled()) {
+                $this->connection->log('[RECONNECT]');
+            }
+
+            return true;
+        } catch (Exception $e) {
+            // If there was an error connecting again, don't report it back,
+            // let the retry handler do it.
+            return false;
+        }
+    }
+}
diff --git a/vendor/cakephp/database/Schema/BaseSchema.php b/vendor/cakephp/database/Schema/BaseSchema.php
new file mode 100644
index 0000000..8d32d34
--- /dev/null
+++ b/vendor/cakephp/database/Schema/BaseSchema.php
@@ -0,0 +1,10 @@
+collection = $collection;
+        $this->prefix = $prefix;
+        $this->cacher = $cacher;
+    }
+
+    /**
+     * @inheritDoc
+     */
+    public function listTablesWithoutViews(): array
+    {
+        return $this->collection->listTablesWithoutViews();
+    }
+
+    /**
+     * @inheritDoc
+     */
+    public function listTables(): array
+    {
+        return $this->collection->listTables();
+    }
+
+    /**
+     * @inheritDoc
+     */
+    public function describe(string $name, array $options = []): TableSchemaInterface
+    {
+        $options += ['forceRefresh' => false];
+        $cacheKey = $this->cacheKey($name);
+
+        if (!$options['forceRefresh']) {
+            $cached = $this->cacher->get($cacheKey);
+            if ($cached !== null) {
+                return $cached;
+            }
+        }
+
+        $table = $this->collection->describe($name, $options);
+        $this->cacher->set($cacheKey, $table);
+
+        return $table;
+    }
+
+    /**
+     * Get the cache key for a given name.
+     *
+     * @param string $name The name to get a cache key for.
+     * @return string The cache key.
+     */
+    public function cacheKey(string $name): string
+    {
+        return $this->prefix . '_' . $name;
+    }
+
+    /**
+     * Set a cacher.
+     *
+     * @param \Psr\SimpleCache\CacheInterface $cacher Cacher object
+     * @return $this
+     */
+    public function setCacher(CacheInterface $cacher)
+    {
+        $this->cacher = $cacher;
+
+        return $this;
+    }
+
+    /**
+     * Get a cacher.
+     *
+     * @return \Psr\SimpleCache\CacheInterface $cacher Cacher object
+     */
+    public function getCacher(): CacheInterface
+    {
+        return $this->cacher;
+    }
+}
diff --git a/vendor/cakephp/database/Schema/Collection.php b/vendor/cakephp/database/Schema/Collection.php
new file mode 100644
index 0000000..181ef24
--- /dev/null
+++ b/vendor/cakephp/database/Schema/Collection.php
@@ -0,0 +1,168 @@
+_connection = $connection;
+        $this->_dialect = $connection->getDriver()->schemaDialect();
+    }
+
+    /**
+     * Get the list of tables, excluding any views, available in the current connection.
+     *
+     * @return array The list of tables in the connected database/schema.
+     */
+    public function listTablesWithoutViews(): array
+    {
+        [$sql, $params] = $this->_dialect->listTablesWithoutViewsSql($this->_connection->getDriver()->config());
+        $result = [];
+        $statement = $this->_connection->execute($sql, $params);
+        while ($row = $statement->fetch()) {
+            $result[] = $row[0];
+        }
+        $statement->closeCursor();
+
+        return $result;
+    }
+
+    /**
+     * Get the list of tables and views available in the current connection.
+     *
+     * @return array The list of tables and views in the connected database/schema.
+     */
+    public function listTables(): array
+    {
+        [$sql, $params] = $this->_dialect->listTablesSql($this->_connection->getDriver()->config());
+        $result = [];
+        $statement = $this->_connection->execute($sql, $params);
+        while ($row = $statement->fetch()) {
+            $result[] = $row[0];
+        }
+        $statement->closeCursor();
+
+        return $result;
+    }
+
+    /**
+     * Get the column metadata for a table.
+     *
+     * The name can include a database schema name in the form 'schema.table'.
+     *
+     * Caching will be applied if `cacheMetadata` key is present in the Connection
+     * configuration options. Defaults to _cake_model_ when true.
+     *
+     * ### Options
+     *
+     * - `forceRefresh` - Set to true to force rebuilding the cached metadata.
+     *   Defaults to false.
+     *
+     * @param string $name The name of the table to describe.
+     * @param array $options The options to use, see above.
+     * @return \Cake\Database\Schema\TableSchema Object with column metadata.
+     * @throws \Cake\Database\Exception\DatabaseException when table cannot be described.
+     */
+    public function describe(string $name, array $options = []): TableSchemaInterface
+    {
+        $config = $this->_connection->getDriver()->config();
+        if (strpos($name, '.')) {
+            [$config['schema'], $name] = explode('.', $name);
+        }
+        $table = $this->_connection->getDriver()->newTableSchema($name);
+
+        $this->_reflect('Column', $name, $config, $table);
+        if (count($table->columns()) === 0) {
+            throw new DatabaseException(sprintf('Cannot describe %s. It has 0 columns.', $name));
+        }
+
+        $this->_reflect('Index', $name, $config, $table);
+        $this->_reflect('ForeignKey', $name, $config, $table);
+        $this->_reflect('Options', $name, $config, $table);
+
+        return $table;
+    }
+
+    /**
+     * Helper method for running each step of the reflection process.
+     *
+     * @param string $stage The stage name.
+     * @param string $name The table name.
+     * @param array $config The config data.
+     * @param \Cake\Database\Schema\TableSchema $schema The table schema instance.
+     * @return void
+     * @throws \Cake\Database\Exception\DatabaseException on query failure.
+     * @uses \Cake\Database\Schema\SchemaDialect::describeColumnSql
+     * @uses \Cake\Database\Schema\SchemaDialect::describeIndexSql
+     * @uses \Cake\Database\Schema\SchemaDialect::describeForeignKeySql
+     * @uses \Cake\Database\Schema\SchemaDialect::describeOptionsSql
+     * @uses \Cake\Database\Schema\SchemaDialect::convertColumnDescription
+     * @uses \Cake\Database\Schema\SchemaDialect::convertIndexDescription
+     * @uses \Cake\Database\Schema\SchemaDialect::convertForeignKeyDescription
+     * @uses \Cake\Database\Schema\SchemaDialect::convertOptionsDescription
+     */
+    protected function _reflect(string $stage, string $name, array $config, TableSchema $schema): void
+    {
+        $describeMethod = "describe{$stage}Sql";
+        $convertMethod = "convert{$stage}Description";
+
+        [$sql, $params] = $this->_dialect->{$describeMethod}($name, $config);
+        if (empty($sql)) {
+            return;
+        }
+        try {
+            $statement = $this->_connection->execute($sql, $params);
+        } catch (PDOException $e) {
+            throw new DatabaseException($e->getMessage(), 500, $e);
+        }
+        /** @psalm-suppress PossiblyFalseIterator */
+        foreach ($statement->fetchAll('assoc') as $row) {
+            $this->_dialect->{$convertMethod}($schema, $row);
+        }
+        $statement->closeCursor();
+    }
+}
diff --git a/vendor/cakephp/database/Schema/CollectionInterface.php b/vendor/cakephp/database/Schema/CollectionInterface.php
new file mode 100644
index 0000000..1861e36
--- /dev/null
+++ b/vendor/cakephp/database/Schema/CollectionInterface.php
@@ -0,0 +1,54 @@
+ listTablesWithoutViews() Get the list of tables available in the current connection.
+ * This will exclude any views in the schema.
+ */
+interface CollectionInterface
+{
+    /**
+     * Get the list of tables available in the current connection.
+     *
+     * @return array The list of tables in the connected database/schema.
+     */
+    public function listTables(): array;
+
+    /**
+     * Get the column metadata for a table.
+     *
+     * Caching will be applied if `cacheMetadata` key is present in the Connection
+     * configuration options. Defaults to _cake_model_ when true.
+     *
+     * ### Options
+     *
+     * - `forceRefresh` - Set to true to force rebuilding the cached metadata.
+     *   Defaults to false.
+     *
+     * @param string $name The name of the table to describe.
+     * @param array $options The options to use, see above.
+     * @return \Cake\Database\Schema\TableSchemaInterface Object with column metadata.
+     * @throws \Cake\Database\Exception\DatabaseException when table cannot be described.
+     */
+    public function describe(string $name, array $options = []): TableSchemaInterface;
+}
diff --git a/vendor/cakephp/database/Schema/MysqlSchema.php b/vendor/cakephp/database/Schema/MysqlSchema.php
new file mode 100644
index 0000000..30b20db
--- /dev/null
+++ b/vendor/cakephp/database/Schema/MysqlSchema.php
@@ -0,0 +1,10 @@
+ $config The connection configuration to use for
+     *    getting tables from.
+     * @return array An array of (sql, params) to execute.
+     */
+    public function listTablesSql(array $config): array
+    {
+        return ['SHOW FULL TABLES FROM ' . $this->_driver->quoteIdentifier($config['database']), []];
+    }
+
+    /**
+     * Generate the SQL to list the tables, excluding all views.
+     *
+     * @param array $config The connection configuration to use for
+     *    getting tables from.
+     * @return array An array of (sql, params) to execute.
+     */
+    public function listTablesWithoutViewsSql(array $config): array
+    {
+        return [
+            'SHOW FULL TABLES FROM ' . $this->_driver->quoteIdentifier($config['database'])
+            . ' WHERE TABLE_TYPE = "BASE TABLE"'
+        , []];
+    }
+
+    /**
+     * @inheritDoc
+     */
+    public function describeColumnSql(string $tableName, array $config): array
+    {
+        return ['SHOW FULL COLUMNS FROM ' . $this->_driver->quoteIdentifier($tableName), []];
+    }
+
+    /**
+     * @inheritDoc
+     */
+    public function describeIndexSql(string $tableName, array $config): array
+    {
+        return ['SHOW INDEXES FROM ' . $this->_driver->quoteIdentifier($tableName), []];
+    }
+
+    /**
+     * @inheritDoc
+     */
+    public function describeOptionsSql(string $tableName, array $config): array
+    {
+        return ['SHOW TABLE STATUS WHERE Name = ?', [$tableName]];
+    }
+
+    /**
+     * @inheritDoc
+     */
+    public function convertOptionsDescription(TableSchema $schema, array $row): void
+    {
+        $schema->setOptions([
+            'engine' => $row['Engine'],
+            'collation' => $row['Collation'],
+        ]);
+    }
+
+    /**
+     * Convert a MySQL column type into an abstract type.
+     *
+     * The returned type will be a type that Cake\Database\TypeFactory can handle.
+     *
+     * @param string $column The column type + length
+     * @return array Array of column information.
+     * @throws \Cake\Database\Exception\DatabaseException When column type cannot be parsed.
+     */
+    protected function _convertColumn(string $column): array
+    {
+        preg_match('/([a-z]+)(?:\(([0-9,]+)\))?\s*([a-z]+)?/i', $column, $matches);
+        if (empty($matches)) {
+            throw new DatabaseException(sprintf('Unable to parse column type from "%s"', $column));
+        }
+
+        $col = strtolower($matches[1]);
+        $length = $precision = $scale = null;
+        if (isset($matches[2]) && strlen($matches[2])) {
+            $length = $matches[2];
+            if (strpos($matches[2], ',') !== false) {
+                [$length, $precision] = explode(',', $length);
+            }
+            $length = (int)$length;
+            $precision = (int)$precision;
+        }
+
+        $type = $this->_applyTypeSpecificColumnConversion(
+            $col,
+            compact('length', 'precision', 'scale')
+        );
+        if ($type !== null) {
+            return $type;
+        }
+
+        if (in_array($col, ['date', 'time'])) {
+            return ['type' => $col, 'length' => null];
+        }
+        if (in_array($col, ['datetime', 'timestamp'])) {
+            $typeName = $col;
+            if ($length > 0) {
+                $typeName = $col . 'fractional';
+            }
+
+            return ['type' => $typeName, 'length' => null, 'precision' => $length];
+        }
+
+        if (($col === 'tinyint' && $length === 1) || $col === 'boolean') {
+            return ['type' => TableSchema::TYPE_BOOLEAN, 'length' => null];
+        }
+
+        $unsigned = (isset($matches[3]) && strtolower($matches[3]) === 'unsigned');
+        if (strpos($col, 'bigint') !== false || $col === 'bigint') {
+            return ['type' => TableSchema::TYPE_BIGINTEGER, 'length' => null, 'unsigned' => $unsigned];
+        }
+        if ($col === 'tinyint') {
+            return ['type' => TableSchema::TYPE_TINYINTEGER, 'length' => null, 'unsigned' => $unsigned];
+        }
+        if ($col === 'smallint') {
+            return ['type' => TableSchema::TYPE_SMALLINTEGER, 'length' => null, 'unsigned' => $unsigned];
+        }
+        if (in_array($col, ['int', 'integer', 'mediumint'])) {
+            return ['type' => TableSchema::TYPE_INTEGER, 'length' => null, 'unsigned' => $unsigned];
+        }
+        if ($col === 'char' && $length === 36) {
+            return ['type' => TableSchema::TYPE_UUID, 'length' => null];
+        }
+        if ($col === 'char') {
+            return ['type' => TableSchema::TYPE_CHAR, 'length' => $length];
+        }
+        if (strpos($col, 'char') !== false) {
+            return ['type' => TableSchema::TYPE_STRING, 'length' => $length];
+        }
+        if (strpos($col, 'text') !== false) {
+            $lengthName = substr($col, 0, -4);
+            $length = TableSchema::$columnLengths[$lengthName] ?? null;
+
+            return ['type' => TableSchema::TYPE_TEXT, 'length' => $length];
+        }
+        if ($col === 'binary' && $length === 16) {
+            return ['type' => TableSchema::TYPE_BINARY_UUID, 'length' => null];
+        }
+        if (strpos($col, 'blob') !== false || in_array($col, ['binary', 'varbinary'])) {
+            $lengthName = substr($col, 0, -4);
+            $length = TableSchema::$columnLengths[$lengthName] ?? $length;
+
+            return ['type' => TableSchema::TYPE_BINARY, 'length' => $length];
+        }
+        if (strpos($col, 'float') !== false || strpos($col, 'double') !== false) {
+            return [
+                'type' => TableSchema::TYPE_FLOAT,
+                'length' => $length,
+                'precision' => $precision,
+                'unsigned' => $unsigned,
+            ];
+        }
+        if (strpos($col, 'decimal') !== false) {
+            return [
+                'type' => TableSchema::TYPE_DECIMAL,
+                'length' => $length,
+                'precision' => $precision,
+                'unsigned' => $unsigned,
+            ];
+        }
+
+        if (strpos($col, 'json') !== false) {
+            return ['type' => TableSchema::TYPE_JSON, 'length' => null];
+        }
+
+        return ['type' => TableSchema::TYPE_STRING, 'length' => null];
+    }
+
+    /**
+     * @inheritDoc
+     */
+    public function convertColumnDescription(TableSchema $schema, array $row): void
+    {
+        $field = $this->_convertColumn($row['Type']);
+        $field += [
+            'null' => $row['Null'] === 'YES',
+            'default' => $row['Default'],
+            'collate' => $row['Collation'],
+            'comment' => $row['Comment'],
+        ];
+        if (isset($row['Extra']) && $row['Extra'] === 'auto_increment') {
+            $field['autoIncrement'] = true;
+        }
+        $schema->addColumn($row['Field'], $field);
+    }
+
+    /**
+     * @inheritDoc
+     */
+    public function convertIndexDescription(TableSchema $schema, array $row): void
+    {
+        $type = null;
+        $columns = $length = [];
+
+        $name = $row['Key_name'];
+        if ($name === 'PRIMARY') {
+            $name = $type = TableSchema::CONSTRAINT_PRIMARY;
+        }
+
+        if (!empty($row['Column_name'])) {
+            $columns[] = $row['Column_name'];
+        }
+
+        if ($row['Index_type'] === 'FULLTEXT') {
+            $type = TableSchema::INDEX_FULLTEXT;
+        } elseif ((int)$row['Non_unique'] === 0 && $type !== 'primary') {
+            $type = TableSchema::CONSTRAINT_UNIQUE;
+        } elseif ($type !== 'primary') {
+            $type = TableSchema::INDEX_INDEX;
+        }
+
+        if (!empty($row['Sub_part'])) {
+            $length[$row['Column_name']] = $row['Sub_part'];
+        }
+        $isIndex = (
+            $type === TableSchema::INDEX_INDEX ||
+            $type === TableSchema::INDEX_FULLTEXT
+        );
+        if ($isIndex) {
+            $existing = $schema->getIndex($name);
+        } else {
+            $existing = $schema->getConstraint($name);
+        }
+
+        // MySQL multi column indexes come back as multiple rows.
+        if (!empty($existing)) {
+            $columns = array_merge($existing['columns'], $columns);
+            $length = array_merge($existing['length'], $length);
+        }
+        if ($isIndex) {
+            $schema->addIndex($name, [
+                'type' => $type,
+                'columns' => $columns,
+                'length' => $length,
+            ]);
+        } else {
+            $schema->addConstraint($name, [
+                'type' => $type,
+                'columns' => $columns,
+                'length' => $length,
+            ]);
+        }
+    }
+
+    /**
+     * @inheritDoc
+     */
+    public function describeForeignKeySql(string $tableName, array $config): array
+    {
+        $sql = 'SELECT * FROM information_schema.key_column_usage AS kcu
+            INNER JOIN information_schema.referential_constraints AS rc
+            ON (
+                kcu.CONSTRAINT_NAME = rc.CONSTRAINT_NAME
+                AND kcu.CONSTRAINT_SCHEMA = rc.CONSTRAINT_SCHEMA
+            )
+            WHERE kcu.TABLE_SCHEMA = ? AND kcu.TABLE_NAME = ? AND rc.TABLE_NAME = ?
+            ORDER BY kcu.ORDINAL_POSITION ASC';
+
+        return [$sql, [$config['database'], $tableName, $tableName]];
+    }
+
+    /**
+     * @inheritDoc
+     */
+    public function convertForeignKeyDescription(TableSchema $schema, array $row): void
+    {
+        $data = [
+            'type' => TableSchema::CONSTRAINT_FOREIGN,
+            'columns' => [$row['COLUMN_NAME']],
+            'references' => [$row['REFERENCED_TABLE_NAME'], $row['REFERENCED_COLUMN_NAME']],
+            'update' => $this->_convertOnClause($row['UPDATE_RULE']),
+            'delete' => $this->_convertOnClause($row['DELETE_RULE']),
+        ];
+        $name = $row['CONSTRAINT_NAME'];
+        $schema->addConstraint($name, $data);
+    }
+
+    /**
+     * @inheritDoc
+     */
+    public function truncateTableSql(TableSchema $schema): array
+    {
+        return [sprintf('TRUNCATE TABLE `%s`', $schema->name())];
+    }
+
+    /**
+     * @inheritDoc
+     */
+    public function createTableSql(TableSchema $schema, array $columns, array $constraints, array $indexes): array
+    {
+        $content = implode(",\n", array_merge($columns, $constraints, $indexes));
+        $temporary = $schema->isTemporary() ? ' TEMPORARY ' : ' ';
+        $content = sprintf("CREATE%sTABLE `%s` (\n%s\n)", $temporary, $schema->name(), $content);
+        $options = $schema->getOptions();
+        if (isset($options['engine'])) {
+            $content .= sprintf(' ENGINE=%s', $options['engine']);
+        }
+        if (isset($options['charset'])) {
+            $content .= sprintf(' DEFAULT CHARSET=%s', $options['charset']);
+        }
+        if (isset($options['collate'])) {
+            $content .= sprintf(' COLLATE=%s', $options['collate']);
+        }
+
+        return [$content];
+    }
+
+    /**
+     * @inheritDoc
+     */
+    public function columnSql(TableSchema $schema, string $name): string
+    {
+        /** @var array $data */
+        $data = $schema->getColumn($name);
+
+        $sql = $this->_getTypeSpecificColumnSql($data['type'], $schema, $name);
+        if ($sql !== null) {
+            return $sql;
+        }
+
+        $out = $this->_driver->quoteIdentifier($name);
+        $nativeJson = $this->_driver->supports(DriverInterface::FEATURE_JSON);
+
+        $typeMap = [
+            TableSchema::TYPE_TINYINTEGER => ' TINYINT',
+            TableSchema::TYPE_SMALLINTEGER => ' SMALLINT',
+            TableSchema::TYPE_INTEGER => ' INTEGER',
+            TableSchema::TYPE_BIGINTEGER => ' BIGINT',
+            TableSchema::TYPE_BINARY_UUID => ' BINARY(16)',
+            TableSchema::TYPE_BOOLEAN => ' BOOLEAN',
+            TableSchema::TYPE_FLOAT => ' FLOAT',
+            TableSchema::TYPE_DECIMAL => ' DECIMAL',
+            TableSchema::TYPE_DATE => ' DATE',
+            TableSchema::TYPE_TIME => ' TIME',
+            TableSchema::TYPE_DATETIME => ' DATETIME',
+            TableSchema::TYPE_DATETIME_FRACTIONAL => ' DATETIME',
+            TableSchema::TYPE_TIMESTAMP => ' TIMESTAMP',
+            TableSchema::TYPE_TIMESTAMP_FRACTIONAL => ' TIMESTAMP',
+            TableSchema::TYPE_TIMESTAMP_TIMEZONE => ' TIMESTAMP',
+            TableSchema::TYPE_CHAR => ' CHAR',
+            TableSchema::TYPE_UUID => ' CHAR(36)',
+            TableSchema::TYPE_JSON => $nativeJson ? ' JSON' : ' LONGTEXT',
+        ];
+        $specialMap = [
+            'string' => true,
+            'text' => true,
+            'char' => true,
+            'binary' => true,
+        ];
+        if (isset($typeMap[$data['type']])) {
+            $out .= $typeMap[$data['type']];
+        }
+        if (isset($specialMap[$data['type']])) {
+            switch ($data['type']) {
+                case TableSchema::TYPE_STRING:
+                    $out .= ' VARCHAR';
+                    if (!isset($data['length'])) {
+                        $data['length'] = 255;
+                    }
+                    break;
+                case TableSchema::TYPE_TEXT:
+                    $isKnownLength = in_array($data['length'], TableSchema::$columnLengths);
+                    if (empty($data['length']) || !$isKnownLength) {
+                        $out .= ' TEXT';
+                        break;
+                    }
+
+                    /** @var string $length */
+                    $length = array_search($data['length'], TableSchema::$columnLengths);
+                    $out .= ' ' . strtoupper($length) . 'TEXT';
+
+                    break;
+                case TableSchema::TYPE_BINARY:
+                    $isKnownLength = in_array($data['length'], TableSchema::$columnLengths);
+                    if ($isKnownLength) {
+                        /** @var string $length */
+                        $length = array_search($data['length'], TableSchema::$columnLengths);
+                        $out .= ' ' . strtoupper($length) . 'BLOB';
+                        break;
+                    }
+
+                    if (empty($data['length'])) {
+                        $out .= ' BLOB';
+                        break;
+                    }
+
+                    if ($data['length'] > 2) {
+                        $out .= ' VARBINARY(' . $data['length'] . ')';
+                    } else {
+                        $out .= ' BINARY(' . $data['length'] . ')';
+                    }
+                    break;
+            }
+        }
+        $hasLength = [
+            TableSchema::TYPE_INTEGER,
+            TableSchema::TYPE_CHAR,
+            TableSchema::TYPE_SMALLINTEGER,
+            TableSchema::TYPE_TINYINTEGER,
+            TableSchema::TYPE_STRING,
+        ];
+        if (in_array($data['type'], $hasLength, true) && isset($data['length'])) {
+            $out .= '(' . $data['length'] . ')';
+        }
+
+        $lengthAndPrecisionTypes = [TableSchema::TYPE_FLOAT, TableSchema::TYPE_DECIMAL];
+        if (in_array($data['type'], $lengthAndPrecisionTypes, true) && isset($data['length'])) {
+            if (isset($data['precision'])) {
+                $out .= '(' . (int)$data['length'] . ',' . (int)$data['precision'] . ')';
+            } else {
+                $out .= '(' . (int)$data['length'] . ')';
+            }
+        }
+
+        $precisionTypes = [TableSchema::TYPE_DATETIME_FRACTIONAL, TableSchema::TYPE_TIMESTAMP_FRACTIONAL];
+        if (in_array($data['type'], $precisionTypes, true) && isset($data['precision'])) {
+            $out .= '(' . (int)$data['precision'] . ')';
+        }
+
+        $hasUnsigned = [
+            TableSchema::TYPE_TINYINTEGER,
+            TableSchema::TYPE_SMALLINTEGER,
+            TableSchema::TYPE_INTEGER,
+            TableSchema::TYPE_BIGINTEGER,
+            TableSchema::TYPE_FLOAT,
+            TableSchema::TYPE_DECIMAL,
+        ];
+        if (
+            in_array($data['type'], $hasUnsigned, true) &&
+            isset($data['unsigned']) &&
+            $data['unsigned'] === true
+        ) {
+            $out .= ' UNSIGNED';
+        }
+
+        $hasCollate = [
+            TableSchema::TYPE_TEXT,
+            TableSchema::TYPE_CHAR,
+            TableSchema::TYPE_STRING,
+        ];
+        if (in_array($data['type'], $hasCollate, true) && isset($data['collate']) && $data['collate'] !== '') {
+            $out .= ' COLLATE ' . $data['collate'];
+        }
+
+        if (isset($data['null']) && $data['null'] === false) {
+            $out .= ' NOT NULL';
+        }
+        $addAutoIncrement = (
+            $schema->getPrimaryKey() === [$name] &&
+            !$schema->hasAutoincrement() &&
+            !isset($data['autoIncrement'])
+        );
+        if (
+            in_array($data['type'], [TableSchema::TYPE_INTEGER, TableSchema::TYPE_BIGINTEGER]) &&
+            (
+                $data['autoIncrement'] === true ||
+                $addAutoIncrement
+            )
+        ) {
+            $out .= ' AUTO_INCREMENT';
+        }
+
+        $timestampTypes = [
+            TableSchema::TYPE_TIMESTAMP,
+            TableSchema::TYPE_TIMESTAMP_FRACTIONAL,
+            TableSchema::TYPE_TIMESTAMP_TIMEZONE,
+        ];
+        if (isset($data['null']) && $data['null'] === true && in_array($data['type'], $timestampTypes, true)) {
+            $out .= ' NULL';
+            unset($data['default']);
+        }
+
+        $dateTimeTypes = [
+            TableSchema::TYPE_DATETIME,
+            TableSchema::TYPE_DATETIME_FRACTIONAL,
+            TableSchema::TYPE_TIMESTAMP,
+            TableSchema::TYPE_TIMESTAMP_FRACTIONAL,
+            TableSchema::TYPE_TIMESTAMP_TIMEZONE,
+        ];
+        if (
+            isset($data['default']) &&
+            in_array($data['type'], $dateTimeTypes) &&
+            strpos(strtolower($data['default']), 'current_timestamp') !== false
+        ) {
+            $out .= ' DEFAULT CURRENT_TIMESTAMP';
+            if (isset($data['precision'])) {
+                $out .= '(' . $data['precision'] . ')';
+            }
+            unset($data['default']);
+        }
+        if (isset($data['default'])) {
+            $out .= ' DEFAULT ' . $this->_driver->schemaValue($data['default']);
+            unset($data['default']);
+        }
+        if (isset($data['comment']) && $data['comment'] !== '') {
+            $out .= ' COMMENT ' . $this->_driver->schemaValue($data['comment']);
+        }
+
+        return $out;
+    }
+
+    /**
+     * @inheritDoc
+     */
+    public function constraintSql(TableSchema $schema, string $name): string
+    {
+        /** @var array $data */
+        $data = $schema->getConstraint($name);
+        if ($data['type'] === TableSchema::CONSTRAINT_PRIMARY) {
+            $columns = array_map(
+                [$this->_driver, 'quoteIdentifier'],
+                $data['columns']
+            );
+
+            return sprintf('PRIMARY KEY (%s)', implode(', ', $columns));
+        }
+
+        $out = '';
+        if ($data['type'] === TableSchema::CONSTRAINT_UNIQUE) {
+            $out = 'UNIQUE KEY ';
+        }
+        if ($data['type'] === TableSchema::CONSTRAINT_FOREIGN) {
+            $out = 'CONSTRAINT ';
+        }
+        $out .= $this->_driver->quoteIdentifier($name);
+
+        return $this->_keySql($out, $data);
+    }
+
+    /**
+     * @inheritDoc
+     */
+    public function addConstraintSql(TableSchema $schema): array
+    {
+        $sqlPattern = 'ALTER TABLE %s ADD %s;';
+        $sql = [];
+
+        foreach ($schema->constraints() as $name) {
+            /** @var array $constraint */
+            $constraint = $schema->getConstraint($name);
+            if ($constraint['type'] === TableSchema::CONSTRAINT_FOREIGN) {
+                $tableName = $this->_driver->quoteIdentifier($schema->name());
+                $sql[] = sprintf($sqlPattern, $tableName, $this->constraintSql($schema, $name));
+            }
+        }
+
+        return $sql;
+    }
+
+    /**
+     * @inheritDoc
+     */
+    public function dropConstraintSql(TableSchema $schema): array
+    {
+        $sqlPattern = 'ALTER TABLE %s DROP FOREIGN KEY %s;';
+        $sql = [];
+
+        foreach ($schema->constraints() as $name) {
+            /** @var array $constraint */
+            $constraint = $schema->getConstraint($name);
+            if ($constraint['type'] === TableSchema::CONSTRAINT_FOREIGN) {
+                $tableName = $this->_driver->quoteIdentifier($schema->name());
+                $constraintName = $this->_driver->quoteIdentifier($name);
+                $sql[] = sprintf($sqlPattern, $tableName, $constraintName);
+            }
+        }
+
+        return $sql;
+    }
+
+    /**
+     * @inheritDoc
+     */
+    public function indexSql(TableSchema $schema, string $name): string
+    {
+        /** @var array $data */
+        $data = $schema->getIndex($name);
+        $out = '';
+        if ($data['type'] === TableSchema::INDEX_INDEX) {
+            $out = 'KEY ';
+        }
+        if ($data['type'] === TableSchema::INDEX_FULLTEXT) {
+            $out = 'FULLTEXT KEY ';
+        }
+        $out .= $this->_driver->quoteIdentifier($name);
+
+        return $this->_keySql($out, $data);
+    }
+
+    /**
+     * Helper method for generating key SQL snippets.
+     *
+     * @param string $prefix The key prefix
+     * @param array $data Key data.
+     * @return string
+     */
+    protected function _keySql(string $prefix, array $data): string
+    {
+        $columns = array_map(
+            [$this->_driver, 'quoteIdentifier'],
+            $data['columns']
+        );
+        foreach ($data['columns'] as $i => $column) {
+            if (isset($data['length'][$column])) {
+                $columns[$i] .= sprintf('(%d)', $data['length'][$column]);
+            }
+        }
+        if ($data['type'] === TableSchema::CONSTRAINT_FOREIGN) {
+            return $prefix . sprintf(
+                ' FOREIGN KEY (%s) REFERENCES %s (%s) ON UPDATE %s ON DELETE %s',
+                implode(', ', $columns),
+                $this->_driver->quoteIdentifier($data['references'][0]),
+                $this->_convertConstraintColumns($data['references'][1]),
+                $this->_foreignOnClause($data['update']),
+                $this->_foreignOnClause($data['delete'])
+            );
+        }
+
+        return $prefix . ' (' . implode(', ', $columns) . ')';
+    }
+}
+
+// phpcs:disable
+class_alias(
+    'Cake\Database\Schema\MysqlSchemaDialect',
+    'Cake\Database\Schema\MysqlSchema'
+);
+// phpcs:enable
diff --git a/vendor/cakephp/database/Schema/PostgresSchema.php b/vendor/cakephp/database/Schema/PostgresSchema.php
new file mode 100644
index 0000000..bd45991
--- /dev/null
+++ b/vendor/cakephp/database/Schema/PostgresSchema.php
@@ -0,0 +1,10 @@
+ $config The connection configuration to use for
+     *    getting tables from.
+     * @return array An array of (sql, params) to execute.
+     */
+    public function listTablesSql(array $config): array
+    {
+        $sql = 'SELECT table_name as name FROM information_schema.tables
+                WHERE table_schema = ? ORDER BY name';
+        $schema = empty($config['schema']) ? 'public' : $config['schema'];
+
+        return [$sql, [$schema]];
+    }
+
+    /**
+     * Generate the SQL to list the tables, excluding all views.
+     *
+     * @param array $config The connection configuration to use for
+     *    getting tables from.
+     * @return array An array of (sql, params) to execute.
+     */
+    public function listTablesWithoutViewsSql(array $config): array
+    {
+        $sql = 'SELECT table_name as name FROM information_schema.tables
+                WHERE table_schema = ? AND table_type = \'BASE TABLE\' ORDER BY name';
+        $schema = empty($config['schema']) ? 'public' : $config['schema'];
+
+        return [$sql, [$schema]];
+    }
+
+    /**
+     * @inheritDoc
+     */
+    public function describeColumnSql(string $tableName, array $config): array
+    {
+        $sql = 'SELECT DISTINCT table_schema AS schema,
+            column_name AS name,
+            data_type AS type,
+            is_nullable AS null, column_default AS default,
+            character_maximum_length AS char_length,
+            c.collation_name,
+            d.description as comment,
+            ordinal_position,
+            c.datetime_precision,
+            c.numeric_precision as column_precision,
+            c.numeric_scale as column_scale,
+            pg_get_serial_sequence(attr.attrelid::regclass::text, attr.attname) IS NOT NULL AS has_serial
+        FROM information_schema.columns c
+        INNER JOIN pg_catalog.pg_namespace ns ON (ns.nspname = table_schema)
+        INNER JOIN pg_catalog.pg_class cl ON (cl.relnamespace = ns.oid AND cl.relname = table_name)
+        LEFT JOIN pg_catalog.pg_index i ON (i.indrelid = cl.oid AND i.indkey[0] = c.ordinal_position)
+        LEFT JOIN pg_catalog.pg_description d on (cl.oid = d.objoid AND d.objsubid = c.ordinal_position)
+        LEFT JOIN pg_catalog.pg_attribute attr ON (cl.oid = attr.attrelid AND column_name = attr.attname)
+        WHERE table_name = ? AND table_schema = ? AND table_catalog = ?
+        ORDER BY ordinal_position';
+
+        $schema = empty($config['schema']) ? 'public' : $config['schema'];
+
+        return [$sql, [$tableName, $schema, $config['database']]];
+    }
+
+    /**
+     * Convert a column definition to the abstract types.
+     *
+     * The returned type will be a type that
+     * Cake\Database\TypeFactory can handle.
+     *
+     * @param string $column The column type + length
+     * @throws \Cake\Database\Exception\DatabaseException when column cannot be parsed.
+     * @return array Array of column information.
+     */
+    protected function _convertColumn(string $column): array
+    {
+        preg_match('/([a-z\s]+)(?:\(([0-9,]+)\))?/i', $column, $matches);
+        if (empty($matches)) {
+            throw new DatabaseException(sprintf('Unable to parse column type from "%s"', $column));
+        }
+
+        $col = strtolower($matches[1]);
+        $length = $precision = $scale = null;
+        if (isset($matches[2])) {
+            $length = (int)$matches[2];
+        }
+
+        $type = $this->_applyTypeSpecificColumnConversion(
+            $col,
+            compact('length', 'precision', 'scale')
+        );
+        if ($type !== null) {
+            return $type;
+        }
+
+        if (in_array($col, ['date', 'time', 'boolean'], true)) {
+            return ['type' => $col, 'length' => null];
+        }
+        if (in_array($col, ['timestamptz', 'timestamp with time zone'], true)) {
+            return ['type' => TableSchema::TYPE_TIMESTAMP_TIMEZONE, 'length' => null];
+        }
+        if (strpos($col, 'timestamp') !== false) {
+            return ['type' => TableSchema::TYPE_TIMESTAMP_FRACTIONAL, 'length' => null];
+        }
+        if (strpos($col, 'time') !== false) {
+            return ['type' => TableSchema::TYPE_TIME, 'length' => null];
+        }
+        if ($col === 'serial' || $col === 'integer') {
+            return ['type' => TableSchema::TYPE_INTEGER, 'length' => 10];
+        }
+        if ($col === 'bigserial' || $col === 'bigint') {
+            return ['type' => TableSchema::TYPE_BIGINTEGER, 'length' => 20];
+        }
+        if ($col === 'smallint') {
+            return ['type' => TableSchema::TYPE_SMALLINTEGER, 'length' => 5];
+        }
+        if ($col === 'inet') {
+            return ['type' => TableSchema::TYPE_STRING, 'length' => 39];
+        }
+        if ($col === 'uuid') {
+            return ['type' => TableSchema::TYPE_UUID, 'length' => null];
+        }
+        if ($col === 'char') {
+            return ['type' => TableSchema::TYPE_CHAR, 'length' => $length];
+        }
+        if (strpos($col, 'character') !== false) {
+            return ['type' => TableSchema::TYPE_STRING, 'length' => $length];
+        }
+        // money is 'string' as it includes arbitrary text content
+        // before the number value.
+        if (strpos($col, 'money') !== false || $col === 'string') {
+            return ['type' => TableSchema::TYPE_STRING, 'length' => $length];
+        }
+        if (strpos($col, 'text') !== false) {
+            return ['type' => TableSchema::TYPE_TEXT, 'length' => null];
+        }
+        if ($col === 'bytea') {
+            return ['type' => TableSchema::TYPE_BINARY, 'length' => null];
+        }
+        if ($col === 'real' || strpos($col, 'double') !== false) {
+            return ['type' => TableSchema::TYPE_FLOAT, 'length' => null];
+        }
+        if (
+            strpos($col, 'numeric') !== false ||
+            strpos($col, 'decimal') !== false
+        ) {
+            return ['type' => TableSchema::TYPE_DECIMAL, 'length' => null];
+        }
+
+        if (strpos($col, 'json') !== false) {
+            return ['type' => TableSchema::TYPE_JSON, 'length' => null];
+        }
+
+        $length = is_numeric($length) ? $length : null;
+
+        return ['type' => TableSchema::TYPE_STRING, 'length' => $length];
+    }
+
+    /**
+     * @inheritDoc
+     */
+    public function convertColumnDescription(TableSchema $schema, array $row): void
+    {
+        $field = $this->_convertColumn($row['type']);
+
+        if ($field['type'] === TableSchema::TYPE_BOOLEAN) {
+            if ($row['default'] === 'true') {
+                $row['default'] = 1;
+            }
+            if ($row['default'] === 'false') {
+                $row['default'] = 0;
+            }
+        }
+        if (!empty($row['has_serial'])) {
+            $field['autoIncrement'] = true;
+        }
+
+        $field += [
+            'default' => $this->_defaultValue($row['default']),
+            'null' => $row['null'] === 'YES',
+            'collate' => $row['collation_name'],
+            'comment' => $row['comment'],
+        ];
+        $field['length'] = $row['char_length'] ?: $field['length'];
+
+        if ($field['type'] === 'numeric' || $field['type'] === 'decimal') {
+            $field['length'] = $row['column_precision'];
+            $field['precision'] = $row['column_scale'] ?: null;
+        }
+
+        if ($field['type'] === TableSchema::TYPE_TIMESTAMP_FRACTIONAL) {
+            $field['precision'] = $row['datetime_precision'];
+            if ($field['precision'] === 0) {
+                $field['type'] = TableSchema::TYPE_TIMESTAMP;
+            }
+        }
+
+        if ($field['type'] === TableSchema::TYPE_TIMESTAMP_TIMEZONE) {
+            $field['precision'] = $row['datetime_precision'];
+        }
+
+        $schema->addColumn($row['name'], $field);
+    }
+
+    /**
+     * Manipulate the default value.
+     *
+     * Postgres includes sequence data and casting information in default values.
+     * We need to remove those.
+     *
+     * @param string|int|null $default The default value.
+     * @return string|int|null
+     */
+    protected function _defaultValue($default)
+    {
+        if (is_numeric($default) || $default === null) {
+            return $default;
+        }
+        // Sequences
+        if (strpos($default, 'nextval') === 0) {
+            return null;
+        }
+
+        if (strpos($default, 'NULL::') === 0) {
+            return null;
+        }
+
+        // Remove quotes and postgres casts
+        return preg_replace(
+            "/^'(.*)'(?:::.*)$/",
+            '$1',
+            $default
+        );
+    }
+
+    /**
+     * @inheritDoc
+     */
+    public function describeIndexSql(string $tableName, array $config): array
+    {
+        $sql = 'SELECT
+        c2.relname,
+        a.attname,
+        i.indisprimary,
+        i.indisunique
+        FROM pg_catalog.pg_namespace n
+        INNER JOIN pg_catalog.pg_class c ON (n.oid = c.relnamespace)
+        INNER JOIN pg_catalog.pg_index i ON (c.oid = i.indrelid)
+        INNER JOIN pg_catalog.pg_class c2 ON (c2.oid = i.indexrelid)
+        INNER JOIN pg_catalog.pg_attribute a ON (a.attrelid = c.oid AND i.indrelid::regclass = a.attrelid::regclass)
+        WHERE n.nspname = ?
+        AND a.attnum = ANY(i.indkey)
+        AND c.relname = ?
+        ORDER BY i.indisprimary DESC, i.indisunique DESC, c.relname, a.attnum';
+
+        $schema = 'public';
+        if (!empty($config['schema'])) {
+            $schema = $config['schema'];
+        }
+
+        return [$sql, [$schema, $tableName]];
+    }
+
+    /**
+     * @inheritDoc
+     */
+    public function convertIndexDescription(TableSchema $schema, array $row): void
+    {
+        $type = TableSchema::INDEX_INDEX;
+        $name = $row['relname'];
+        if ($row['indisprimary']) {
+            $name = $type = TableSchema::CONSTRAINT_PRIMARY;
+        }
+        if ($row['indisunique'] && $type === TableSchema::INDEX_INDEX) {
+            $type = TableSchema::CONSTRAINT_UNIQUE;
+        }
+        if ($type === TableSchema::CONSTRAINT_PRIMARY || $type === TableSchema::CONSTRAINT_UNIQUE) {
+            $this->_convertConstraint($schema, $name, $type, $row);
+
+            return;
+        }
+        $index = $schema->getIndex($name);
+        if (!$index) {
+            $index = [
+                'type' => $type,
+                'columns' => [],
+            ];
+        }
+        $index['columns'][] = $row['attname'];
+        $schema->addIndex($name, $index);
+    }
+
+    /**
+     * Add/update a constraint into the schema object.
+     *
+     * @param \Cake\Database\Schema\TableSchema $schema The table to update.
+     * @param string $name The index name.
+     * @param string $type The index type.
+     * @param array $row The metadata record to update with.
+     * @return void
+     */
+    protected function _convertConstraint(TableSchema $schema, string $name, string $type, array $row): void
+    {
+        $constraint = $schema->getConstraint($name);
+        if (!$constraint) {
+            $constraint = [
+                'type' => $type,
+                'columns' => [],
+            ];
+        }
+        $constraint['columns'][] = $row['attname'];
+        $schema->addConstraint($name, $constraint);
+    }
+
+    /**
+     * @inheritDoc
+     */
+    public function describeForeignKeySql(string $tableName, array $config): array
+    {
+        // phpcs:disable Generic.Files.LineLength
+        $sql = 'SELECT
+        c.conname AS name,
+        c.contype AS type,
+        a.attname AS column_name,
+        c.confmatchtype AS match_type,
+        c.confupdtype AS on_update,
+        c.confdeltype AS on_delete,
+        c.confrelid::regclass AS references_table,
+        ab.attname AS references_field
+        FROM pg_catalog.pg_namespace n
+        INNER JOIN pg_catalog.pg_class cl ON (n.oid = cl.relnamespace)
+        INNER JOIN pg_catalog.pg_constraint c ON (n.oid = c.connamespace)
+        INNER JOIN pg_catalog.pg_attribute a ON (a.attrelid = cl.oid AND c.conrelid = a.attrelid AND a.attnum = ANY(c.conkey))
+        INNER JOIN pg_catalog.pg_attribute ab ON (a.attrelid = cl.oid AND c.confrelid = ab.attrelid AND ab.attnum = ANY(c.confkey))
+        WHERE n.nspname = ?
+        AND cl.relname = ?
+        ORDER BY name, a.attnum, ab.attnum DESC';
+        // phpcs:enable Generic.Files.LineLength
+
+        $schema = empty($config['schema']) ? 'public' : $config['schema'];
+
+        return [$sql, [$schema, $tableName]];
+    }
+
+    /**
+     * @inheritDoc
+     */
+    public function convertForeignKeyDescription(TableSchema $schema, array $row): void
+    {
+        $data = [
+            'type' => TableSchema::CONSTRAINT_FOREIGN,
+            'columns' => $row['column_name'],
+            'references' => [$row['references_table'], $row['references_field']],
+            'update' => $this->_convertOnClause($row['on_update']),
+            'delete' => $this->_convertOnClause($row['on_delete']),
+        ];
+        $schema->addConstraint($row['name'], $data);
+    }
+
+    /**
+     * @inheritDoc
+     */
+    protected function _convertOnClause(string $clause): string
+    {
+        if ($clause === 'r') {
+            return TableSchema::ACTION_RESTRICT;
+        }
+        if ($clause === 'a') {
+            return TableSchema::ACTION_NO_ACTION;
+        }
+        if ($clause === 'c') {
+            return TableSchema::ACTION_CASCADE;
+        }
+
+        return TableSchema::ACTION_SET_NULL;
+    }
+
+    /**
+     * @inheritDoc
+     */
+    public function columnSql(TableSchema $schema, string $name): string
+    {
+        /** @var array $data */
+        $data = $schema->getColumn($name);
+
+        $sql = $this->_getTypeSpecificColumnSql($data['type'], $schema, $name);
+        if ($sql !== null) {
+            return $sql;
+        }
+
+        $out = $this->_driver->quoteIdentifier($name);
+        $typeMap = [
+            TableSchema::TYPE_TINYINTEGER => ' SMALLINT',
+            TableSchema::TYPE_SMALLINTEGER => ' SMALLINT',
+            TableSchema::TYPE_BINARY_UUID => ' UUID',
+            TableSchema::TYPE_BOOLEAN => ' BOOLEAN',
+            TableSchema::TYPE_FLOAT => ' FLOAT',
+            TableSchema::TYPE_DECIMAL => ' DECIMAL',
+            TableSchema::TYPE_DATE => ' DATE',
+            TableSchema::TYPE_TIME => ' TIME',
+            TableSchema::TYPE_DATETIME => ' TIMESTAMP',
+            TableSchema::TYPE_DATETIME_FRACTIONAL => ' TIMESTAMP',
+            TableSchema::TYPE_TIMESTAMP => ' TIMESTAMP',
+            TableSchema::TYPE_TIMESTAMP_FRACTIONAL => ' TIMESTAMP',
+            TableSchema::TYPE_TIMESTAMP_TIMEZONE => ' TIMESTAMPTZ',
+            TableSchema::TYPE_UUID => ' UUID',
+            TableSchema::TYPE_CHAR => ' CHAR',
+            TableSchema::TYPE_JSON => ' JSONB',
+        ];
+
+        if (isset($typeMap[$data['type']])) {
+            $out .= $typeMap[$data['type']];
+        }
+
+        if ($data['type'] === TableSchema::TYPE_INTEGER || $data['type'] === TableSchema::TYPE_BIGINTEGER) {
+            $type = $data['type'] === TableSchema::TYPE_INTEGER ? ' INTEGER' : ' BIGINT';
+            if ($schema->getPrimaryKey() === [$name] || $data['autoIncrement'] === true) {
+                $type = $data['type'] === TableSchema::TYPE_INTEGER ? ' SERIAL' : ' BIGSERIAL';
+                unset($data['null'], $data['default']);
+            }
+            $out .= $type;
+        }
+
+        if ($data['type'] === TableSchema::TYPE_TEXT && $data['length'] !== TableSchema::LENGTH_TINY) {
+            $out .= ' TEXT';
+        }
+        if ($data['type'] === TableSchema::TYPE_BINARY) {
+            $out .= ' BYTEA';
+        }
+
+        if ($data['type'] === TableSchema::TYPE_CHAR) {
+            $out .= '(' . $data['length'] . ')';
+        }
+
+        if (
+            $data['type'] === TableSchema::TYPE_STRING ||
+            (
+                $data['type'] === TableSchema::TYPE_TEXT &&
+                $data['length'] === TableSchema::LENGTH_TINY
+            )
+        ) {
+            $out .= ' VARCHAR';
+            if (isset($data['length']) && $data['length'] !== '') {
+                $out .= '(' . $data['length'] . ')';
+            }
+        }
+
+        $hasCollate = [TableSchema::TYPE_TEXT, TableSchema::TYPE_STRING, TableSchema::TYPE_CHAR];
+        if (in_array($data['type'], $hasCollate, true) && isset($data['collate']) && $data['collate'] !== '') {
+            $out .= ' COLLATE "' . $data['collate'] . '"';
+        }
+
+        $hasPrecision = [
+            TableSchema::TYPE_FLOAT,
+            TableSchema::TYPE_DATETIME,
+            TableSchema::TYPE_DATETIME_FRACTIONAL,
+            TableSchema::TYPE_TIMESTAMP,
+            TableSchema::TYPE_TIMESTAMP_FRACTIONAL,
+            TableSchema::TYPE_TIMESTAMP_TIMEZONE,
+        ];
+        if (in_array($data['type'], $hasPrecision) && isset($data['precision'])) {
+            $out .= '(' . $data['precision'] . ')';
+        }
+
+        if (
+            $data['type'] === TableSchema::TYPE_DECIMAL &&
+            (
+                isset($data['length']) ||
+                isset($data['precision'])
+            )
+        ) {
+            $out .= '(' . $data['length'] . ',' . (int)$data['precision'] . ')';
+        }
+
+        if (isset($data['null']) && $data['null'] === false) {
+            $out .= ' NOT NULL';
+        }
+
+        $datetimeTypes = [
+            TableSchema::TYPE_DATETIME,
+            TableSchema::TYPE_DATETIME_FRACTIONAL,
+            TableSchema::TYPE_TIMESTAMP,
+            TableSchema::TYPE_TIMESTAMP_FRACTIONAL,
+            TableSchema::TYPE_TIMESTAMP_TIMEZONE,
+        ];
+        if (
+            isset($data['default']) &&
+            in_array($data['type'], $datetimeTypes) &&
+            strtolower($data['default']) === 'current_timestamp'
+        ) {
+            $out .= ' DEFAULT CURRENT_TIMESTAMP';
+        } elseif (isset($data['default'])) {
+            $defaultValue = $data['default'];
+            if ($data['type'] === 'boolean') {
+                $defaultValue = (bool)$defaultValue;
+            }
+            $out .= ' DEFAULT ' . $this->_driver->schemaValue($defaultValue);
+        } elseif (isset($data['null']) && $data['null'] !== false) {
+            $out .= ' DEFAULT NULL';
+        }
+
+        return $out;
+    }
+
+    /**
+     * @inheritDoc
+     */
+    public function addConstraintSql(TableSchema $schema): array
+    {
+        $sqlPattern = 'ALTER TABLE %s ADD %s;';
+        $sql = [];
+
+        foreach ($schema->constraints() as $name) {
+            /** @var array $constraint */
+            $constraint = $schema->getConstraint($name);
+            if ($constraint['type'] === TableSchema::CONSTRAINT_FOREIGN) {
+                $tableName = $this->_driver->quoteIdentifier($schema->name());
+                $sql[] = sprintf($sqlPattern, $tableName, $this->constraintSql($schema, $name));
+            }
+        }
+
+        return $sql;
+    }
+
+    /**
+     * @inheritDoc
+     */
+    public function dropConstraintSql(TableSchema $schema): array
+    {
+        $sqlPattern = 'ALTER TABLE %s DROP CONSTRAINT %s;';
+        $sql = [];
+
+        foreach ($schema->constraints() as $name) {
+            /** @var array $constraint */
+            $constraint = $schema->getConstraint($name);
+            if ($constraint['type'] === TableSchema::CONSTRAINT_FOREIGN) {
+                $tableName = $this->_driver->quoteIdentifier($schema->name());
+                $constraintName = $this->_driver->quoteIdentifier($name);
+                $sql[] = sprintf($sqlPattern, $tableName, $constraintName);
+            }
+        }
+
+        return $sql;
+    }
+
+    /**
+     * @inheritDoc
+     */
+    public function indexSql(TableSchema $schema, string $name): string
+    {
+        /** @var array $data */
+        $data = $schema->getIndex($name);
+        $columns = array_map(
+            [$this->_driver, 'quoteIdentifier'],
+            $data['columns']
+        );
+
+        return sprintf(
+            'CREATE INDEX %s ON %s (%s)',
+            $this->_driver->quoteIdentifier($name),
+            $this->_driver->quoteIdentifier($schema->name()),
+            implode(', ', $columns)
+        );
+    }
+
+    /**
+     * @inheritDoc
+     */
+    public function constraintSql(TableSchema $schema, string $name): string
+    {
+        /** @var array $data */
+        $data = $schema->getConstraint($name);
+        $out = 'CONSTRAINT ' . $this->_driver->quoteIdentifier($name);
+        if ($data['type'] === TableSchema::CONSTRAINT_PRIMARY) {
+            $out = 'PRIMARY KEY';
+        }
+        if ($data['type'] === TableSchema::CONSTRAINT_UNIQUE) {
+            $out .= ' UNIQUE';
+        }
+
+        return $this->_keySql($out, $data);
+    }
+
+    /**
+     * Helper method for generating key SQL snippets.
+     *
+     * @param string $prefix The key prefix
+     * @param array $data Key data.
+     * @return string
+     */
+    protected function _keySql(string $prefix, array $data): string
+    {
+        $columns = array_map(
+            [$this->_driver, 'quoteIdentifier'],
+            $data['columns']
+        );
+        if ($data['type'] === TableSchema::CONSTRAINT_FOREIGN) {
+            return $prefix . sprintf(
+                ' FOREIGN KEY (%s) REFERENCES %s (%s) ON UPDATE %s ON DELETE %s DEFERRABLE INITIALLY IMMEDIATE',
+                implode(', ', $columns),
+                $this->_driver->quoteIdentifier($data['references'][0]),
+                $this->_convertConstraintColumns($data['references'][1]),
+                $this->_foreignOnClause($data['update']),
+                $this->_foreignOnClause($data['delete'])
+            );
+        }
+
+        return $prefix . ' (' . implode(', ', $columns) . ')';
+    }
+
+    /**
+     * @inheritDoc
+     */
+    public function createTableSql(TableSchema $schema, array $columns, array $constraints, array $indexes): array
+    {
+        $content = array_merge($columns, $constraints);
+        $content = implode(",\n", array_filter($content));
+        $tableName = $this->_driver->quoteIdentifier($schema->name());
+        $dbSchema = $this->_driver->schema();
+        if ($dbSchema != 'public') {
+            $tableName = $this->_driver->quoteIdentifier($dbSchema) . '.' . $tableName;
+        }
+        $temporary = $schema->isTemporary() ? ' TEMPORARY ' : ' ';
+        $out = [];
+        $out[] = sprintf("CREATE%sTABLE %s (\n%s\n)", $temporary, $tableName, $content);
+        foreach ($indexes as $index) {
+            $out[] = $index;
+        }
+        foreach ($schema->columns() as $column) {
+            $columnData = $schema->getColumn($column);
+            if (isset($columnData['comment'])) {
+                $out[] = sprintf(
+                    'COMMENT ON COLUMN %s.%s IS %s',
+                    $tableName,
+                    $this->_driver->quoteIdentifier($column),
+                    $this->_driver->schemaValue($columnData['comment'])
+                );
+            }
+        }
+
+        return $out;
+    }
+
+    /**
+     * @inheritDoc
+     */
+    public function truncateTableSql(TableSchema $schema): array
+    {
+        $name = $this->_driver->quoteIdentifier($schema->name());
+
+        return [
+            sprintf('TRUNCATE %s RESTART IDENTITY CASCADE', $name),
+        ];
+    }
+
+    /**
+     * Generate the SQL to drop a table.
+     *
+     * @param \Cake\Database\Schema\TableSchema $schema Table instance
+     * @return array SQL statements to drop a table.
+     */
+    public function dropTableSql(TableSchema $schema): array
+    {
+        $sql = sprintf(
+            'DROP TABLE %s CASCADE',
+            $this->_driver->quoteIdentifier($schema->name())
+        );
+
+        return [$sql];
+    }
+}
+
+// phpcs:disable
+class_alias(
+    'Cake\Database\Schema\PostgresSchemaDialect',
+    'Cake\Database\Schema\PostgresSchema'
+);
+// phpcs:enable
diff --git a/vendor/cakephp/database/Schema/SchemaDialect.php b/vendor/cakephp/database/Schema/SchemaDialect.php
new file mode 100644
index 0000000..a9a1f91
--- /dev/null
+++ b/vendor/cakephp/database/Schema/SchemaDialect.php
@@ -0,0 +1,346 @@
+ listTablesWithoutViewsSql(array $config) Generate the SQL to list the tables, excluding all views.
+ */
+abstract class SchemaDialect
+{
+    /**
+     * The driver instance being used.
+     *
+     * @var \Cake\Database\DriverInterface
+     */
+    protected $_driver;
+
+    /**
+     * Constructor
+     *
+     * This constructor will connect the driver so that methods like columnSql() and others
+     * will fail when the driver has not been connected.
+     *
+     * @param \Cake\Database\DriverInterface $driver The driver to use.
+     */
+    public function __construct(DriverInterface $driver)
+    {
+        $driver->connect();
+        $this->_driver = $driver;
+    }
+
+    /**
+     * Generate an ON clause for a foreign key.
+     *
+     * @param string $on The on clause
+     * @return string
+     */
+    protected function _foreignOnClause(string $on): string
+    {
+        if ($on === TableSchema::ACTION_SET_NULL) {
+            return 'SET NULL';
+        }
+        if ($on === TableSchema::ACTION_SET_DEFAULT) {
+            return 'SET DEFAULT';
+        }
+        if ($on === TableSchema::ACTION_CASCADE) {
+            return 'CASCADE';
+        }
+        if ($on === TableSchema::ACTION_RESTRICT) {
+            return 'RESTRICT';
+        }
+        if ($on === TableSchema::ACTION_NO_ACTION) {
+            return 'NO ACTION';
+        }
+
+        throw new InvalidArgumentException('Invalid value for "on": ' . $on);
+    }
+
+    /**
+     * Convert string on clauses to the abstract ones.
+     *
+     * @param string $clause The on clause to convert.
+     * @return string
+     */
+    protected function _convertOnClause(string $clause): string
+    {
+        if ($clause === 'CASCADE' || $clause === 'RESTRICT') {
+            return strtolower($clause);
+        }
+        if ($clause === 'NO ACTION') {
+            return TableSchema::ACTION_NO_ACTION;
+        }
+
+        return TableSchema::ACTION_SET_NULL;
+    }
+
+    /**
+     * Convert foreign key constraints references to a valid
+     * stringified list
+     *
+     * @param array|string $references The referenced columns of a foreign key constraint statement
+     * @return string
+     */
+    protected function _convertConstraintColumns($references): string
+    {
+        if (is_string($references)) {
+            return $this->_driver->quoteIdentifier($references);
+        }
+
+        return implode(', ', array_map(
+            [$this->_driver, 'quoteIdentifier'],
+            $references
+        ));
+    }
+
+    /**
+     * Tries to use a matching database type to generate the SQL
+     * fragment for a single column in a table.
+     *
+     * @param string $columnType The column type.
+     * @param \Cake\Database\Schema\TableSchemaInterface $schema The table schema instance the column is in.
+     * @param string $column The name of the column.
+     * @return string|null An SQL fragment, or `null` in case no corresponding type was found or the type didn't provide
+     *  custom column SQL.
+     */
+    protected function _getTypeSpecificColumnSql(
+        string $columnType,
+        TableSchemaInterface $schema,
+        string $column
+    ): ?string {
+        if (!TypeFactory::getMap($columnType)) {
+            return null;
+        }
+
+        $type = TypeFactory::build($columnType);
+        if (!($type instanceof ColumnSchemaAwareInterface)) {
+            return null;
+        }
+
+        return $type->getColumnSql($schema, $column, $this->_driver);
+    }
+
+    /**
+     * Tries to use a matching database type to convert a SQL column
+     * definition to an abstract type definition.
+     *
+     * @param string $columnType The column type.
+     * @param array $definition The column definition.
+     * @return array|null Array of column information, or `null` in case no corresponding type was found or the type
+     *  didn't provide custom column information.
+     */
+    protected function _applyTypeSpecificColumnConversion(string $columnType, array $definition): ?array
+    {
+        if (!TypeFactory::getMap($columnType)) {
+            return null;
+        }
+
+        $type = TypeFactory::build($columnType);
+        if (!($type instanceof ColumnSchemaAwareInterface)) {
+            return null;
+        }
+
+        return $type->convertColumnDefinition($definition, $this->_driver);
+    }
+
+    /**
+     * Generate the SQL to drop a table.
+     *
+     * @param \Cake\Database\Schema\TableSchema $schema Schema instance
+     * @return array SQL statements to drop a table.
+     */
+    public function dropTableSql(TableSchema $schema): array
+    {
+        $sql = sprintf(
+            'DROP TABLE %s',
+            $this->_driver->quoteIdentifier($schema->name())
+        );
+
+        return [$sql];
+    }
+
+    /**
+     * Generate the SQL to list the tables.
+     *
+     * @param array $config The connection configuration to use for
+     *    getting tables from.
+     * @return array An array of (sql, params) to execute.
+     */
+    abstract public function listTablesSql(array $config): array;
+
+    /**
+     * Generate the SQL to describe a table.
+     *
+     * @param string $tableName The table name to get information on.
+     * @param array $config The connection configuration.
+     * @return array An array of (sql, params) to execute.
+     */
+    abstract public function describeColumnSql(string $tableName, array $config): array;
+
+    /**
+     * Generate the SQL to describe the indexes in a table.
+     *
+     * @param string $tableName The table name to get information on.
+     * @param array $config The connection configuration.
+     * @return array An array of (sql, params) to execute.
+     */
+    abstract public function describeIndexSql(string $tableName, array $config): array;
+
+    /**
+     * Generate the SQL to describe the foreign keys in a table.
+     *
+     * @param string $tableName The table name to get information on.
+     * @param array $config The connection configuration.
+     * @return array An array of (sql, params) to execute.
+     */
+    abstract public function describeForeignKeySql(string $tableName, array $config): array;
+
+    /**
+     * Generate the SQL to describe table options
+     *
+     * @param string $tableName Table name.
+     * @param array $config The connection configuration.
+     * @return array SQL statements to get options for a table.
+     */
+    public function describeOptionsSql(string $tableName, array $config): array
+    {
+        return ['', ''];
+    }
+
+    /**
+     * Convert field description results into abstract schema fields.
+     *
+     * @param \Cake\Database\Schema\TableSchema $schema The table object to append fields to.
+     * @param array $row The row data from `describeColumnSql`.
+     * @return void
+     */
+    abstract public function convertColumnDescription(TableSchema $schema, array $row): void;
+
+    /**
+     * Convert an index description results into abstract schema indexes or constraints.
+     *
+     * @param \Cake\Database\Schema\TableSchema $schema The table object to append
+     *    an index or constraint to.
+     * @param array $row The row data from `describeIndexSql`.
+     * @return void
+     */
+    abstract public function convertIndexDescription(TableSchema $schema, array $row): void;
+
+    /**
+     * Convert a foreign key description into constraints on the Table object.
+     *
+     * @param \Cake\Database\Schema\TableSchema $schema The table object to append
+     *    a constraint to.
+     * @param array $row The row data from `describeForeignKeySql`.
+     * @return void
+     */
+    abstract public function convertForeignKeyDescription(TableSchema $schema, array $row): void;
+
+    /**
+     * Convert options data into table options.
+     *
+     * @param \Cake\Database\Schema\TableSchema $schema Table instance.
+     * @param array $row The row of data.
+     * @return void
+     */
+    public function convertOptionsDescription(TableSchema $schema, array $row): void
+    {
+    }
+
+    /**
+     * Generate the SQL to create a table.
+     *
+     * @param \Cake\Database\Schema\TableSchema $schema Table instance.
+     * @param array $columns The columns to go inside the table.
+     * @param array $constraints The constraints for the table.
+     * @param array $indexes The indexes for the table.
+     * @return array SQL statements to create a table.
+     */
+    abstract public function createTableSql(
+        TableSchema $schema,
+        array $columns,
+        array $constraints,
+        array $indexes
+    ): array;
+
+    /**
+     * Generate the SQL fragment for a single column in a table.
+     *
+     * @param \Cake\Database\Schema\TableSchema $schema The table instance the column is in.
+     * @param string $name The name of the column.
+     * @return string SQL fragment.
+     */
+    abstract public function columnSql(TableSchema $schema, string $name): string;
+
+    /**
+     * Generate the SQL queries needed to add foreign key constraints to the table
+     *
+     * @param \Cake\Database\Schema\TableSchema $schema The table instance the foreign key constraints are.
+     * @return array SQL fragment.
+     */
+    abstract public function addConstraintSql(TableSchema $schema): array;
+
+    /**
+     * Generate the SQL queries needed to drop foreign key constraints from the table
+     *
+     * @param \Cake\Database\Schema\TableSchema $schema The table instance the foreign key constraints are.
+     * @return array SQL fragment.
+     */
+    abstract public function dropConstraintSql(TableSchema $schema): array;
+
+    /**
+     * Generate the SQL fragments for defining table constraints.
+     *
+     * @param \Cake\Database\Schema\TableSchema $schema The table instance the column is in.
+     * @param string $name The name of the column.
+     * @return string SQL fragment.
+     */
+    abstract public function constraintSql(TableSchema $schema, string $name): string;
+
+    /**
+     * Generate the SQL fragment for a single index in a table.
+     *
+     * @param \Cake\Database\Schema\TableSchema $schema The table object the column is in.
+     * @param string $name The name of the column.
+     * @return string SQL fragment.
+     */
+    abstract public function indexSql(TableSchema $schema, string $name): string;
+
+    /**
+     * Generate the SQL to truncate a table.
+     *
+     * @param \Cake\Database\Schema\TableSchema $schema Table instance.
+     * @return array SQL statements to truncate a table.
+     */
+    abstract public function truncateTableSql(TableSchema $schema): array;
+}
+
+// phpcs:disable
+class_alias(
+    'Cake\Database\Schema\SchemaDialect',
+    'Cake\Database\Schema\BaseSchema'
+);
+// phpcs:enable
diff --git a/vendor/cakephp/database/Schema/SqlGeneratorInterface.php b/vendor/cakephp/database/Schema/SqlGeneratorInterface.php
new file mode 100644
index 0000000..9fbd591
--- /dev/null
+++ b/vendor/cakephp/database/Schema/SqlGeneratorInterface.php
@@ -0,0 +1,72 @@
+
+     */
+    protected $_constraintsIdMap = [];
+
+    /**
+     * Whether there is any table in this connection to SQLite containing sequences.
+     *
+     * @var bool
+     */
+    protected $_hasSequences;
+
+    /**
+     * Convert a column definition to the abstract types.
+     *
+     * The returned type will be a type that
+     * Cake\Database\TypeFactory can handle.
+     *
+     * @param string $column The column type + length
+     * @throws \Cake\Database\Exception\DatabaseException when unable to parse column type
+     * @return array Array of column information.
+     */
+    protected function _convertColumn(string $column): array
+    {
+        if ($column === '') {
+            return ['type' => TableSchema::TYPE_TEXT, 'length' => null];
+        }
+
+        preg_match('/(unsigned)?\s*([a-z]+)(?:\(([0-9,]+)\))?/i', $column, $matches);
+        if (empty($matches)) {
+            throw new DatabaseException(sprintf('Unable to parse column type from "%s"', $column));
+        }
+
+        $unsigned = false;
+        if (strtolower($matches[1]) === 'unsigned') {
+            $unsigned = true;
+        }
+
+        $col = strtolower($matches[2]);
+        $length = $precision = $scale = null;
+        if (isset($matches[3])) {
+            $length = $matches[3];
+            if (strpos($length, ',') !== false) {
+                [$length, $precision] = explode(',', $length);
+            }
+            $length = (int)$length;
+            $precision = (int)$precision;
+        }
+
+        $type = $this->_applyTypeSpecificColumnConversion(
+            $col,
+            compact('length', 'precision', 'scale')
+        );
+        if ($type !== null) {
+            return $type;
+        }
+
+        if ($col === 'bigint') {
+            return ['type' => TableSchema::TYPE_BIGINTEGER, 'length' => $length, 'unsigned' => $unsigned];
+        }
+        if ($col === 'smallint') {
+            return ['type' => TableSchema::TYPE_SMALLINTEGER, 'length' => $length, 'unsigned' => $unsigned];
+        }
+        if ($col === 'tinyint') {
+            return ['type' => TableSchema::TYPE_TINYINTEGER, 'length' => $length, 'unsigned' => $unsigned];
+        }
+        if (strpos($col, 'int') !== false) {
+            return ['type' => TableSchema::TYPE_INTEGER, 'length' => $length, 'unsigned' => $unsigned];
+        }
+        if (strpos($col, 'decimal') !== false) {
+            return [
+                'type' => TableSchema::TYPE_DECIMAL,
+                'length' => $length,
+                'precision' => $precision,
+                'unsigned' => $unsigned,
+            ];
+        }
+        if (in_array($col, ['float', 'real', 'double'])) {
+            return [
+                'type' => TableSchema::TYPE_FLOAT,
+                'length' => $length,
+                'precision' => $precision,
+                'unsigned' => $unsigned,
+            ];
+        }
+
+        if (strpos($col, 'boolean') !== false) {
+            return ['type' => TableSchema::TYPE_BOOLEAN, 'length' => null];
+        }
+
+        if (($col === 'char' && $length === 36) || $col === 'uuid') {
+            return ['type' => TableSchema::TYPE_UUID, 'length' => null];
+        }
+        if ($col === 'char') {
+            return ['type' => TableSchema::TYPE_CHAR, 'length' => $length];
+        }
+        if (strpos($col, 'char') !== false) {
+            return ['type' => TableSchema::TYPE_STRING, 'length' => $length];
+        }
+
+        if ($col === 'binary' && $length === 16) {
+            return ['type' => TableSchema::TYPE_BINARY_UUID, 'length' => null];
+        }
+        if (in_array($col, ['blob', 'clob', 'binary', 'varbinary'])) {
+            return ['type' => TableSchema::TYPE_BINARY, 'length' => $length];
+        }
+
+        $datetimeTypes = [
+            'date',
+            'time',
+            'timestamp',
+            'timestampfractional',
+            'timestamptimezone',
+            'datetime',
+            'datetimefractional',
+        ];
+        if (in_array($col, $datetimeTypes)) {
+            return ['type' => $col, 'length' => null];
+        }
+
+        return ['type' => TableSchema::TYPE_TEXT, 'length' => null];
+    }
+
+    /**
+     * Generate the SQL to list the tables and views.
+     *
+     * @param array $config The connection configuration to use for
+     *    getting tables from.
+     * @return array An array of (sql, params) to execute.
+     */
+    public function listTablesSql(array $config): array
+    {
+        return [
+            'SELECT name FROM sqlite_master ' .
+            'WHERE (type="table" OR type="view") ' .
+            'AND name != "sqlite_sequence" ORDER BY name',
+            [],
+        ];
+    }
+
+    /**
+     * Generate the SQL to list the tables, excluding all views.
+     *
+     * @param array $config The connection configuration to use for
+     *    getting tables from.
+     * @return array An array of (sql, params) to execute.
+     */
+    public function listTablesWithoutViewsSql(array $config): array
+    {
+        return [
+            'SELECT name FROM sqlite_master WHERE type="table" ' .
+            'AND name != "sqlite_sequence" ORDER BY name',
+            [],
+        ];
+    }
+
+    /**
+     * @inheritDoc
+     */
+    public function describeColumnSql(string $tableName, array $config): array
+    {
+        $sql = sprintf(
+            'PRAGMA table_info(%s)',
+            $this->_driver->quoteIdentifier($tableName)
+        );
+
+        return [$sql, []];
+    }
+
+    /**
+     * @inheritDoc
+     */
+    public function convertColumnDescription(TableSchema $schema, array $row): void
+    {
+        $field = $this->_convertColumn($row['type']);
+        $field += [
+            'null' => !$row['notnull'],
+            'default' => $this->_defaultValue($row['dflt_value']),
+        ];
+        $primary = $schema->getConstraint('primary');
+
+        if ($row['pk'] && empty($primary)) {
+            $field['null'] = false;
+            $field['autoIncrement'] = true;
+        }
+
+        // SQLite does not support autoincrement on composite keys.
+        if ($row['pk'] && !empty($primary)) {
+            $existingColumn = $primary['columns'][0];
+            /** @psalm-suppress PossiblyNullOperand */
+            $schema->addColumn($existingColumn, ['autoIncrement' => null] + $schema->getColumn($existingColumn));
+        }
+
+        $schema->addColumn($row['name'], $field);
+        if ($row['pk']) {
+            $constraint = (array)$schema->getConstraint('primary') + [
+                'type' => TableSchema::CONSTRAINT_PRIMARY,
+                'columns' => [],
+            ];
+            $constraint['columns'] = array_merge($constraint['columns'], [$row['name']]);
+            $schema->addConstraint('primary', $constraint);
+        }
+    }
+
+    /**
+     * Manipulate the default value.
+     *
+     * Sqlite includes quotes and bared NULLs in default values.
+     * We need to remove those.
+     *
+     * @param string|int|null $default The default value.
+     * @return string|int|null
+     */
+    protected function _defaultValue($default)
+    {
+        if ($default === 'NULL' || $default === null) {
+            return null;
+        }
+
+        // Remove quotes
+        if (is_string($default) && preg_match("/^'(.*)'$/", $default, $matches)) {
+            return str_replace("''", "'", $matches[1]);
+        }
+
+        return $default;
+    }
+
+    /**
+     * @inheritDoc
+     */
+    public function describeIndexSql(string $tableName, array $config): array
+    {
+        $sql = sprintf(
+            'PRAGMA index_list(%s)',
+            $this->_driver->quoteIdentifier($tableName)
+        );
+
+        return [$sql, []];
+    }
+
+    /**
+     * {@inheritDoc}
+     *
+     * Since SQLite does not have a way to get metadata about all indexes at once,
+     * additional queries are done here. Sqlite constraint names are not
+     * stable, and the names for constraints will not match those used to create
+     * the table. This is a limitation in Sqlite's metadata features.
+     *
+     * @param \Cake\Database\Schema\TableSchema $schema The table object to append
+     *    an index or constraint to.
+     * @param array $row The row data from `describeIndexSql`.
+     * @return void
+     */
+    public function convertIndexDescription(TableSchema $schema, array $row): void
+    {
+        $sql = sprintf(
+            'PRAGMA index_info(%s)',
+            $this->_driver->quoteIdentifier($row['name'])
+        );
+        $statement = $this->_driver->prepare($sql);
+        $statement->execute();
+        $columns = [];
+        /** @psalm-suppress PossiblyFalseIterator */
+        foreach ($statement->fetchAll('assoc') as $column) {
+            $columns[] = $column['name'];
+        }
+        $statement->closeCursor();
+        if ($row['unique']) {
+            $schema->addConstraint($row['name'], [
+                'type' => TableSchema::CONSTRAINT_UNIQUE,
+                'columns' => $columns,
+            ]);
+        } else {
+            $schema->addIndex($row['name'], [
+                'type' => TableSchema::INDEX_INDEX,
+                'columns' => $columns,
+            ]);
+        }
+    }
+
+    /**
+     * @inheritDoc
+     */
+    public function describeForeignKeySql(string $tableName, array $config): array
+    {
+        $sql = sprintf('PRAGMA foreign_key_list(%s)', $this->_driver->quoteIdentifier($tableName));
+
+        return [$sql, []];
+    }
+
+    /**
+     * @inheritDoc
+     */
+    public function convertForeignKeyDescription(TableSchema $schema, array $row): void
+    {
+        $name = $row['from'] . '_fk';
+
+        $update = $row['on_update'] ?? '';
+        $delete = $row['on_delete'] ?? '';
+        $data = [
+            'type' => TableSchema::CONSTRAINT_FOREIGN,
+            'columns' => [$row['from']],
+            'references' => [$row['table'], $row['to']],
+            'update' => $this->_convertOnClause($update),
+            'delete' => $this->_convertOnClause($delete),
+        ];
+
+        if (isset($this->_constraintsIdMap[$schema->name()][$row['id']])) {
+            $name = $this->_constraintsIdMap[$schema->name()][$row['id']];
+        } else {
+            $this->_constraintsIdMap[$schema->name()][$row['id']] = $name;
+        }
+
+        $schema->addConstraint($name, $data);
+    }
+
+    /**
+     * {@inheritDoc}
+     *
+     * @param \Cake\Database\Schema\TableSchema $schema The table instance the column is in.
+     * @param string $name The name of the column.
+     * @return string SQL fragment.
+     * @throws \Cake\Database\Exception\DatabaseException when the column type is unknown
+     */
+    public function columnSql(TableSchema $schema, string $name): string
+    {
+        /** @var array $data */
+        $data = $schema->getColumn($name);
+
+        $sql = $this->_getTypeSpecificColumnSql($data['type'], $schema, $name);
+        if ($sql !== null) {
+            return $sql;
+        }
+
+        $typeMap = [
+            TableSchema::TYPE_BINARY_UUID => ' BINARY(16)',
+            TableSchema::TYPE_UUID => ' CHAR(36)',
+            TableSchema::TYPE_CHAR => ' CHAR',
+            TableSchema::TYPE_TINYINTEGER => ' TINYINT',
+            TableSchema::TYPE_SMALLINTEGER => ' SMALLINT',
+            TableSchema::TYPE_INTEGER => ' INTEGER',
+            TableSchema::TYPE_BIGINTEGER => ' BIGINT',
+            TableSchema::TYPE_BOOLEAN => ' BOOLEAN',
+            TableSchema::TYPE_FLOAT => ' FLOAT',
+            TableSchema::TYPE_DECIMAL => ' DECIMAL',
+            TableSchema::TYPE_DATE => ' DATE',
+            TableSchema::TYPE_TIME => ' TIME',
+            TableSchema::TYPE_DATETIME => ' DATETIME',
+            TableSchema::TYPE_DATETIME_FRACTIONAL => ' DATETIMEFRACTIONAL',
+            TableSchema::TYPE_TIMESTAMP => ' TIMESTAMP',
+            TableSchema::TYPE_TIMESTAMP_FRACTIONAL => ' TIMESTAMPFRACTIONAL',
+            TableSchema::TYPE_TIMESTAMP_TIMEZONE => ' TIMESTAMPTIMEZONE',
+            TableSchema::TYPE_JSON => ' TEXT',
+        ];
+
+        $out = $this->_driver->quoteIdentifier($name);
+        $hasUnsigned = [
+            TableSchema::TYPE_TINYINTEGER,
+            TableSchema::TYPE_SMALLINTEGER,
+            TableSchema::TYPE_INTEGER,
+            TableSchema::TYPE_BIGINTEGER,
+            TableSchema::TYPE_FLOAT,
+            TableSchema::TYPE_DECIMAL,
+        ];
+
+        if (
+            in_array($data['type'], $hasUnsigned, true) &&
+            isset($data['unsigned']) &&
+            $data['unsigned'] === true
+        ) {
+            if ($data['type'] !== TableSchema::TYPE_INTEGER || $schema->getPrimaryKey() !== [$name]) {
+                $out .= ' UNSIGNED';
+            }
+        }
+
+        if (isset($typeMap[$data['type']])) {
+            $out .= $typeMap[$data['type']];
+        }
+
+        if ($data['type'] === TableSchema::TYPE_TEXT && $data['length'] !== TableSchema::LENGTH_TINY) {
+            $out .= ' TEXT';
+        }
+
+        if ($data['type'] === TableSchema::TYPE_CHAR) {
+            $out .= '(' . $data['length'] . ')';
+        }
+
+        if (
+            $data['type'] === TableSchema::TYPE_STRING ||
+            (
+                $data['type'] === TableSchema::TYPE_TEXT &&
+                $data['length'] === TableSchema::LENGTH_TINY
+            )
+        ) {
+            $out .= ' VARCHAR';
+
+            if (isset($data['length'])) {
+                $out .= '(' . $data['length'] . ')';
+            }
+        }
+
+        if ($data['type'] === TableSchema::TYPE_BINARY) {
+            if (isset($data['length'])) {
+                $out .= ' BLOB(' . $data['length'] . ')';
+            } else {
+                $out .= ' BLOB';
+            }
+        }
+
+        $integerTypes = [
+            TableSchema::TYPE_TINYINTEGER,
+            TableSchema::TYPE_SMALLINTEGER,
+            TableSchema::TYPE_INTEGER,
+        ];
+        if (
+            in_array($data['type'], $integerTypes, true) &&
+            isset($data['length']) &&
+            $schema->getPrimaryKey() !== [$name]
+        ) {
+            $out .= '(' . (int)$data['length'] . ')';
+        }
+
+        $hasPrecision = [TableSchema::TYPE_FLOAT, TableSchema::TYPE_DECIMAL];
+        if (
+            in_array($data['type'], $hasPrecision, true) &&
+            (
+                isset($data['length']) ||
+                isset($data['precision'])
+            )
+        ) {
+            $out .= '(' . (int)$data['length'] . ',' . (int)$data['precision'] . ')';
+        }
+
+        if (isset($data['null']) && $data['null'] === false) {
+            $out .= ' NOT NULL';
+        }
+
+        if ($data['type'] === TableSchema::TYPE_INTEGER && $schema->getPrimaryKey() === [$name]) {
+            $out .= ' PRIMARY KEY AUTOINCREMENT';
+        }
+
+        $timestampTypes = [
+            TableSchema::TYPE_DATETIME,
+            TableSchema::TYPE_DATETIME_FRACTIONAL,
+            TableSchema::TYPE_TIMESTAMP,
+            TableSchema::TYPE_TIMESTAMP_FRACTIONAL,
+            TableSchema::TYPE_TIMESTAMP_TIMEZONE,
+        ];
+        if (isset($data['null']) && $data['null'] === true && in_array($data['type'], $timestampTypes, true)) {
+            $out .= ' DEFAULT NULL';
+        }
+        if (isset($data['default'])) {
+            $out .= ' DEFAULT ' . $this->_driver->schemaValue($data['default']);
+        }
+
+        return $out;
+    }
+
+    /**
+     * {@inheritDoc}
+     *
+     * Note integer primary keys will return ''. This is intentional as Sqlite requires
+     * that integer primary keys be defined in the column definition.
+     *
+     * @param \Cake\Database\Schema\TableSchema $schema The table instance the column is in.
+     * @param string $name The name of the column.
+     * @return string SQL fragment.
+     */
+    public function constraintSql(TableSchema $schema, string $name): string
+    {
+        /** @var array $data */
+        $data = $schema->getConstraint($name);
+        /** @psalm-suppress PossiblyNullArrayAccess */
+        if (
+            $data['type'] === TableSchema::CONSTRAINT_PRIMARY &&
+            count($data['columns']) === 1 &&
+            $schema->getColumn($data['columns'][0])['type'] === TableSchema::TYPE_INTEGER
+        ) {
+            return '';
+        }
+        $clause = '';
+        $type = '';
+        if ($data['type'] === TableSchema::CONSTRAINT_PRIMARY) {
+            $type = 'PRIMARY KEY';
+        }
+        if ($data['type'] === TableSchema::CONSTRAINT_UNIQUE) {
+            $type = 'UNIQUE';
+        }
+        if ($data['type'] === TableSchema::CONSTRAINT_FOREIGN) {
+            $type = 'FOREIGN KEY';
+
+            $clause = sprintf(
+                ' REFERENCES %s (%s) ON UPDATE %s ON DELETE %s',
+                $this->_driver->quoteIdentifier($data['references'][0]),
+                $this->_convertConstraintColumns($data['references'][1]),
+                $this->_foreignOnClause($data['update']),
+                $this->_foreignOnClause($data['delete'])
+            );
+        }
+        $columns = array_map(
+            [$this->_driver, 'quoteIdentifier'],
+            $data['columns']
+        );
+
+        return sprintf(
+            'CONSTRAINT %s %s (%s)%s',
+            $this->_driver->quoteIdentifier($name),
+            $type,
+            implode(', ', $columns),
+            $clause
+        );
+    }
+
+    /**
+     * {@inheritDoc}
+     *
+     * SQLite can not properly handle adding a constraint to an existing table.
+     * This method is no-op
+     *
+     * @param \Cake\Database\Schema\TableSchema $schema The table instance the foreign key constraints are.
+     * @return array SQL fragment.
+     */
+    public function addConstraintSql(TableSchema $schema): array
+    {
+        return [];
+    }
+
+    /**
+     * {@inheritDoc}
+     *
+     * SQLite can not properly handle dropping a constraint to an existing table.
+     * This method is no-op
+     *
+     * @param \Cake\Database\Schema\TableSchema $schema The table instance the foreign key constraints are.
+     * @return array SQL fragment.
+     */
+    public function dropConstraintSql(TableSchema $schema): array
+    {
+        return [];
+    }
+
+    /**
+     * @inheritDoc
+     */
+    public function indexSql(TableSchema $schema, string $name): string
+    {
+        /** @var array $data */
+        $data = $schema->getIndex($name);
+        $columns = array_map(
+            [$this->_driver, 'quoteIdentifier'],
+            $data['columns']
+        );
+
+        return sprintf(
+            'CREATE INDEX %s ON %s (%s)',
+            $this->_driver->quoteIdentifier($name),
+            $this->_driver->quoteIdentifier($schema->name()),
+            implode(', ', $columns)
+        );
+    }
+
+    /**
+     * @inheritDoc
+     */
+    public function createTableSql(TableSchema $schema, array $columns, array $constraints, array $indexes): array
+    {
+        $lines = array_merge($columns, $constraints);
+        $content = implode(",\n", array_filter($lines));
+        $temporary = $schema->isTemporary() ? ' TEMPORARY ' : ' ';
+        $table = sprintf("CREATE%sTABLE \"%s\" (\n%s\n)", $temporary, $schema->name(), $content);
+        $out = [$table];
+        foreach ($indexes as $index) {
+            $out[] = $index;
+        }
+
+        return $out;
+    }
+
+    /**
+     * @inheritDoc
+     */
+    public function truncateTableSql(TableSchema $schema): array
+    {
+        $name = $schema->name();
+        $sql = [];
+        if ($this->hasSequences()) {
+            $sql[] = sprintf('DELETE FROM sqlite_sequence WHERE name="%s"', $name);
+        }
+
+        $sql[] = sprintf('DELETE FROM "%s"', $name);
+
+        return $sql;
+    }
+
+    /**
+     * Returns whether there is any table in this connection to SQLite containing
+     * sequences
+     *
+     * @return bool
+     */
+    public function hasSequences(): bool
+    {
+        $result = $this->_driver->prepare(
+            'SELECT 1 FROM sqlite_master WHERE name = "sqlite_sequence"'
+        );
+        $result->execute();
+        $this->_hasSequences = (bool)$result->rowCount();
+        $result->closeCursor();
+
+        return $this->_hasSequences;
+    }
+}
+
+// phpcs:disable
+class_alias(
+    'Cake\Database\Schema\SqliteSchemaDialect',
+    'Cake\Database\Schema\SqliteSchema'
+);
+// phpcs:enable
diff --git a/vendor/cakephp/database/Schema/SqlserverSchema.php b/vendor/cakephp/database/Schema/SqlserverSchema.php
new file mode 100644
index 0000000..62e3f69
--- /dev/null
+++ b/vendor/cakephp/database/Schema/SqlserverSchema.php
@@ -0,0 +1,10 @@
+ $config The connection configuration to use for
+     *    getting tables from.
+     * @return array An array of (sql, params) to execute.
+     */
+    public function listTablesSql(array $config): array
+    {
+        $sql = "SELECT TABLE_NAME
+            FROM INFORMATION_SCHEMA.TABLES
+            WHERE TABLE_SCHEMA = ?
+            AND (TABLE_TYPE = 'BASE TABLE' OR TABLE_TYPE = 'VIEW')
+            ORDER BY TABLE_NAME";
+        $schema = empty($config['schema']) ? static::DEFAULT_SCHEMA_NAME : $config['schema'];
+
+        return [$sql, [$schema]];
+    }
+
+    /**
+     * Generate the SQL to list the tables, excluding all views.
+     *
+     * @param array $config The connection configuration to use for
+     *    getting tables from.
+     * @return array An array of (sql, params) to execute.
+     */
+    public function listTablesWithoutViewsSql(array $config): array
+    {
+        $sql = "SELECT TABLE_NAME
+            FROM INFORMATION_SCHEMA.TABLES
+            WHERE TABLE_SCHEMA = ?
+            AND (TABLE_TYPE = 'BASE TABLE')
+            ORDER BY TABLE_NAME";
+        $schema = empty($config['schema']) ? static::DEFAULT_SCHEMA_NAME : $config['schema'];
+
+        return [$sql, [$schema]];
+    }
+
+    /**
+     * @inheritDoc
+     */
+    public function describeColumnSql(string $tableName, array $config): array
+    {
+        $sql = 'SELECT DISTINCT
+            AC.column_id AS [column_id],
+            AC.name AS [name],
+            TY.name AS [type],
+            AC.max_length AS [char_length],
+            AC.precision AS [precision],
+            AC.scale AS [scale],
+            AC.is_identity AS [autoincrement],
+            AC.is_nullable AS [null],
+            OBJECT_DEFINITION(AC.default_object_id) AS [default],
+            AC.collation_name AS [collation_name]
+            FROM sys.[objects] T
+            INNER JOIN sys.[schemas] S ON S.[schema_id] = T.[schema_id]
+            INNER JOIN sys.[all_columns] AC ON T.[object_id] = AC.[object_id]
+            INNER JOIN sys.[types] TY ON TY.[user_type_id] = AC.[user_type_id]
+            WHERE T.[name] = ? AND S.[name] = ?
+            ORDER BY column_id';
+
+        $schema = empty($config['schema']) ? static::DEFAULT_SCHEMA_NAME : $config['schema'];
+
+        return [$sql, [$tableName, $schema]];
+    }
+
+    /**
+     * Convert a column definition to the abstract types.
+     *
+     * The returned type will be a type that
+     * Cake\Database\TypeFactory  can handle.
+     *
+     * @param string $col The column type
+     * @param int|null $length the column length
+     * @param int|null $precision The column precision
+     * @param int|null $scale The column scale
+     * @return array Array of column information.
+     * @link https://technet.microsoft.com/en-us/library/ms187752.aspx
+     */
+    protected function _convertColumn(
+        string $col,
+        ?int $length = null,
+        ?int $precision = null,
+        ?int $scale = null
+    ): array {
+        $col = strtolower($col);
+
+        $type = $this->_applyTypeSpecificColumnConversion(
+            $col,
+            compact('length', 'precision', 'scale')
+        );
+        if ($type !== null) {
+            return $type;
+        }
+
+        if (in_array($col, ['date', 'time'])) {
+            return ['type' => $col, 'length' => null];
+        }
+
+        if ($col === 'datetime') {
+            // datetime cannot parse more than 3 digits of precision and isn't accurate
+            return ['type' => TableSchema::TYPE_DATETIME, 'length' => null];
+        }
+        if (strpos($col, 'datetime') !== false) {
+            $typeName = TableSchema::TYPE_DATETIME;
+            if ($scale > 0) {
+                $typeName = TableSchema::TYPE_DATETIME_FRACTIONAL;
+            }
+
+            return ['type' => $typeName, 'length' => null, 'precision' => $scale];
+        }
+
+        if ($col === 'char') {
+            return ['type' => TableSchema::TYPE_CHAR, 'length' => $length];
+        }
+
+        if ($col === 'tinyint') {
+            return ['type' => TableSchema::TYPE_TINYINTEGER, 'length' => $precision ?: 3];
+        }
+        if ($col === 'smallint') {
+            return ['type' => TableSchema::TYPE_SMALLINTEGER, 'length' => $precision ?: 5];
+        }
+        if ($col === 'int' || $col === 'integer') {
+            return ['type' => TableSchema::TYPE_INTEGER, 'length' => $precision ?: 10];
+        }
+        if ($col === 'bigint') {
+            return ['type' => TableSchema::TYPE_BIGINTEGER, 'length' => $precision ?: 20];
+        }
+        if ($col === 'bit') {
+            return ['type' => TableSchema::TYPE_BOOLEAN, 'length' => null];
+        }
+        if (
+            strpos($col, 'numeric') !== false ||
+            strpos($col, 'money') !== false ||
+            strpos($col, 'decimal') !== false
+        ) {
+            return ['type' => TableSchema::TYPE_DECIMAL, 'length' => $precision, 'precision' => $scale];
+        }
+
+        if ($col === 'real' || $col === 'float') {
+            return ['type' => TableSchema::TYPE_FLOAT, 'length' => null];
+        }
+        // SqlServer schema reflection returns double length for unicode
+        // columns because internally it uses UTF16/UCS2
+        if ($col === 'nvarchar' || $col === 'nchar' || $col === 'ntext') {
+            $length /= 2;
+        }
+        if (strpos($col, 'varchar') !== false && $length < 0) {
+            return ['type' => TableSchema::TYPE_TEXT, 'length' => null];
+        }
+
+        if (strpos($col, 'varchar') !== false) {
+            return ['type' => TableSchema::TYPE_STRING, 'length' => $length ?: 255];
+        }
+
+        if (strpos($col, 'char') !== false) {
+            return ['type' => TableSchema::TYPE_CHAR, 'length' => $length];
+        }
+
+        if (strpos($col, 'text') !== false) {
+            return ['type' => TableSchema::TYPE_TEXT, 'length' => null];
+        }
+
+        if ($col === 'image' || strpos($col, 'binary') !== false) {
+            // -1 is the value for MAX which we treat as a 'long' binary
+            if ($length == -1) {
+                $length = TableSchema::LENGTH_LONG;
+            }
+
+            return ['type' => TableSchema::TYPE_BINARY, 'length' => $length];
+        }
+
+        if ($col === 'uniqueidentifier') {
+            return ['type' => TableSchema::TYPE_UUID];
+        }
+
+        return ['type' => TableSchema::TYPE_STRING, 'length' => null];
+    }
+
+    /**
+     * @inheritDoc
+     */
+    public function convertColumnDescription(TableSchema $schema, array $row): void
+    {
+        $field = $this->_convertColumn(
+            $row['type'],
+            $row['char_length'] !== null ? (int)$row['char_length'] : null,
+            $row['precision'] !== null ? (int)$row['precision'] : null,
+            $row['scale'] !== null ? (int)$row['scale'] : null
+        );
+
+        if (!empty($row['autoincrement'])) {
+            $field['autoIncrement'] = true;
+        }
+
+        $field += [
+            'null' => $row['null'] === '1',
+            'default' => $this->_defaultValue($field['type'], $row['default']),
+            'collate' => $row['collation_name'],
+        ];
+        $schema->addColumn($row['name'], $field);
+    }
+
+    /**
+     * Manipulate the default value.
+     *
+     * Removes () wrapping default values, extracts strings from
+     * N'' wrappers and collation text and converts NULL strings.
+     *
+     * @param string $type The schema type
+     * @param string|null $default The default value.
+     * @return string|int|null
+     */
+    protected function _defaultValue($type, $default)
+    {
+        if ($default === null) {
+            return null;
+        }
+
+        // remove () surrounding value (NULL) but leave () at the end of functions
+        // integers might have two ((0)) wrapping value
+        if (preg_match('/^\(+(.*?(\(\))?)\)+$/', $default, $matches)) {
+            $default = $matches[1];
+        }
+
+        if ($default === 'NULL') {
+            return null;
+        }
+
+        if ($type === TableSchema::TYPE_BOOLEAN) {
+            return (int)$default;
+        }
+
+        // Remove quotes
+        if (preg_match("/^\(?N?'(.*)'\)?/", $default, $matches)) {
+            return str_replace("''", "'", $matches[1]);
+        }
+
+        return $default;
+    }
+
+    /**
+     * @inheritDoc
+     */
+    public function describeIndexSql(string $tableName, array $config): array
+    {
+        $sql = "SELECT
+                I.[name] AS [index_name],
+                IC.[index_column_id] AS [index_order],
+                AC.[name] AS [column_name],
+                I.[is_unique], I.[is_primary_key],
+                I.[is_unique_constraint]
+            FROM sys.[tables] AS T
+            INNER JOIN sys.[schemas] S ON S.[schema_id] = T.[schema_id]
+            INNER JOIN sys.[indexes] I ON T.[object_id] = I.[object_id]
+            INNER JOIN sys.[index_columns] IC ON I.[object_id] = IC.[object_id] AND I.[index_id] = IC.[index_id]
+            INNER JOIN sys.[all_columns] AC ON T.[object_id] = AC.[object_id] AND IC.[column_id] = AC.[column_id]
+            WHERE T.[is_ms_shipped] = 0 AND I.[type_desc] <> 'HEAP' AND T.[name] = ? AND S.[name] = ?
+            ORDER BY I.[index_id], IC.[index_column_id]";
+
+        $schema = empty($config['schema']) ? static::DEFAULT_SCHEMA_NAME : $config['schema'];
+
+        return [$sql, [$tableName, $schema]];
+    }
+
+    /**
+     * @inheritDoc
+     */
+    public function convertIndexDescription(TableSchema $schema, array $row): void
+    {
+        $type = TableSchema::INDEX_INDEX;
+        $name = $row['index_name'];
+        if ($row['is_primary_key']) {
+            $name = $type = TableSchema::CONSTRAINT_PRIMARY;
+        }
+        if ($row['is_unique_constraint'] && $type === TableSchema::INDEX_INDEX) {
+            $type = TableSchema::CONSTRAINT_UNIQUE;
+        }
+
+        if ($type === TableSchema::INDEX_INDEX) {
+            $existing = $schema->getIndex($name);
+        } else {
+            $existing = $schema->getConstraint($name);
+        }
+
+        $columns = [$row['column_name']];
+        if (!empty($existing)) {
+            $columns = array_merge($existing['columns'], $columns);
+        }
+
+        if ($type === TableSchema::CONSTRAINT_PRIMARY || $type === TableSchema::CONSTRAINT_UNIQUE) {
+            $schema->addConstraint($name, [
+                'type' => $type,
+                'columns' => $columns,
+            ]);
+
+            return;
+        }
+        $schema->addIndex($name, [
+            'type' => $type,
+            'columns' => $columns,
+        ]);
+    }
+
+    /**
+     * @inheritDoc
+     */
+    public function describeForeignKeySql(string $tableName, array $config): array
+    {
+        // phpcs:disable Generic.Files.LineLength
+        $sql = 'SELECT FK.[name] AS [foreign_key_name], FK.[delete_referential_action_desc] AS [delete_type],
+                FK.[update_referential_action_desc] AS [update_type], C.name AS [column], RT.name AS [reference_table],
+                RC.name AS [reference_column]
+            FROM sys.foreign_keys FK
+            INNER JOIN sys.foreign_key_columns FKC ON FKC.constraint_object_id = FK.object_id
+            INNER JOIN sys.tables T ON T.object_id = FKC.parent_object_id
+            INNER JOIN sys.tables RT ON RT.object_id = FKC.referenced_object_id
+            INNER JOIN sys.schemas S ON S.schema_id = T.schema_id AND S.schema_id = RT.schema_id
+            INNER JOIN sys.columns C ON C.column_id = FKC.parent_column_id AND C.object_id = FKC.parent_object_id
+            INNER JOIN sys.columns RC ON RC.column_id = FKC.referenced_column_id AND RC.object_id = FKC.referenced_object_id
+            WHERE FK.is_ms_shipped = 0 AND T.name = ? AND S.name = ?
+            ORDER BY FKC.constraint_column_id';
+        // phpcs:enable Generic.Files.LineLength
+
+        $schema = empty($config['schema']) ? static::DEFAULT_SCHEMA_NAME : $config['schema'];
+
+        return [$sql, [$tableName, $schema]];
+    }
+
+    /**
+     * @inheritDoc
+     */
+    public function convertForeignKeyDescription(TableSchema $schema, array $row): void
+    {
+        $data = [
+            'type' => TableSchema::CONSTRAINT_FOREIGN,
+            'columns' => [$row['column']],
+            'references' => [$row['reference_table'], $row['reference_column']],
+            'update' => $this->_convertOnClause($row['update_type']),
+            'delete' => $this->_convertOnClause($row['delete_type']),
+        ];
+        $name = $row['foreign_key_name'];
+        $schema->addConstraint($name, $data);
+    }
+
+    /**
+     * @inheritDoc
+     */
+    protected function _foreignOnClause(string $on): string
+    {
+        $parent = parent::_foreignOnClause($on);
+
+        return $parent === 'RESTRICT' ? parent::_foreignOnClause(TableSchema::ACTION_NO_ACTION) : $parent;
+    }
+
+    /**
+     * @inheritDoc
+     */
+    protected function _convertOnClause(string $clause): string
+    {
+        switch ($clause) {
+            case 'NO_ACTION':
+                return TableSchema::ACTION_NO_ACTION;
+            case 'CASCADE':
+                return TableSchema::ACTION_CASCADE;
+            case 'SET_NULL':
+                return TableSchema::ACTION_SET_NULL;
+            case 'SET_DEFAULT':
+                return TableSchema::ACTION_SET_DEFAULT;
+        }
+
+        return TableSchema::ACTION_SET_NULL;
+    }
+
+    /**
+     * @inheritDoc
+     */
+    public function columnSql(TableSchema $schema, string $name): string
+    {
+        /** @var array $data */
+        $data = $schema->getColumn($name);
+
+        $sql = $this->_getTypeSpecificColumnSql($data['type'], $schema, $name);
+        if ($sql !== null) {
+            return $sql;
+        }
+
+        $out = $this->_driver->quoteIdentifier($name);
+        $typeMap = [
+            TableSchema::TYPE_TINYINTEGER => ' TINYINT',
+            TableSchema::TYPE_SMALLINTEGER => ' SMALLINT',
+            TableSchema::TYPE_INTEGER => ' INTEGER',
+            TableSchema::TYPE_BIGINTEGER => ' BIGINT',
+            TableSchema::TYPE_BINARY_UUID => ' UNIQUEIDENTIFIER',
+            TableSchema::TYPE_BOOLEAN => ' BIT',
+            TableSchema::TYPE_CHAR => ' NCHAR',
+            TableSchema::TYPE_FLOAT => ' FLOAT',
+            TableSchema::TYPE_DECIMAL => ' DECIMAL',
+            TableSchema::TYPE_DATE => ' DATE',
+            TableSchema::TYPE_TIME => ' TIME',
+            TableSchema::TYPE_DATETIME => ' DATETIME2',
+            TableSchema::TYPE_DATETIME_FRACTIONAL => ' DATETIME2',
+            TableSchema::TYPE_TIMESTAMP => ' DATETIME2',
+            TableSchema::TYPE_TIMESTAMP_FRACTIONAL => ' DATETIME2',
+            TableSchema::TYPE_TIMESTAMP_TIMEZONE => ' DATETIME2',
+            TableSchema::TYPE_UUID => ' UNIQUEIDENTIFIER',
+            TableSchema::TYPE_JSON => ' NVARCHAR(MAX)',
+        ];
+
+        if (isset($typeMap[$data['type']])) {
+            $out .= $typeMap[$data['type']];
+        }
+
+        if ($data['type'] === TableSchema::TYPE_INTEGER || $data['type'] === TableSchema::TYPE_BIGINTEGER) {
+            if ($schema->getPrimaryKey() === [$name] || $data['autoIncrement'] === true) {
+                unset($data['null'], $data['default']);
+                $out .= ' IDENTITY(1, 1)';
+            }
+        }
+
+        if ($data['type'] === TableSchema::TYPE_TEXT && $data['length'] !== TableSchema::LENGTH_TINY) {
+            $out .= ' NVARCHAR(MAX)';
+        }
+
+        if ($data['type'] === TableSchema::TYPE_CHAR) {
+            $out .= '(' . $data['length'] . ')';
+        }
+
+        if ($data['type'] === TableSchema::TYPE_BINARY) {
+            if (
+                !isset($data['length'])
+                || in_array($data['length'], [TableSchema::LENGTH_MEDIUM, TableSchema::LENGTH_LONG], true)
+            ) {
+                $data['length'] = 'MAX';
+            }
+
+            if ($data['length'] === 1) {
+                $out .= ' BINARY(1)';
+            } else {
+                $out .= ' VARBINARY';
+
+                $out .= sprintf('(%s)', $data['length']);
+            }
+        }
+
+        if (
+            $data['type'] === TableSchema::TYPE_STRING ||
+            (
+                $data['type'] === TableSchema::TYPE_TEXT &&
+                $data['length'] === TableSchema::LENGTH_TINY
+            )
+        ) {
+            $type = ' NVARCHAR';
+            $length = $data['length'] ?? TableSchema::LENGTH_TINY;
+            $out .= sprintf('%s(%d)', $type, $length);
+        }
+
+        $hasCollate = [TableSchema::TYPE_TEXT, TableSchema::TYPE_STRING, TableSchema::TYPE_CHAR];
+        if (in_array($data['type'], $hasCollate, true) && isset($data['collate']) && $data['collate'] !== '') {
+            $out .= ' COLLATE ' . $data['collate'];
+        }
+
+        $precisionTypes = [
+            TableSchema::TYPE_FLOAT,
+            TableSchema::TYPE_DATETIME,
+            TableSchema::TYPE_DATETIME_FRACTIONAL,
+            TableSchema::TYPE_TIMESTAMP,
+            TableSchema::TYPE_TIMESTAMP_FRACTIONAL,
+        ];
+        if (in_array($data['type'], $precisionTypes, true) && isset($data['precision'])) {
+            $out .= '(' . (int)$data['precision'] . ')';
+        }
+
+        if (
+            $data['type'] === TableSchema::TYPE_DECIMAL &&
+            (
+                isset($data['length']) ||
+                isset($data['precision'])
+            )
+        ) {
+            $out .= '(' . (int)$data['length'] . ',' . (int)$data['precision'] . ')';
+        }
+
+        if (isset($data['null']) && $data['null'] === false) {
+            $out .= ' NOT NULL';
+        }
+
+        $dateTimeTypes = [
+            TableSchema::TYPE_DATETIME,
+            TableSchema::TYPE_DATETIME_FRACTIONAL,
+            TableSchema::TYPE_TIMESTAMP,
+            TableSchema::TYPE_TIMESTAMP_FRACTIONAL,
+        ];
+        $dateTimeDefaults = [
+            'current_timestamp',
+            'getdate()',
+            'getutcdate()',
+            'sysdatetime()',
+            'sysutcdatetime()',
+            'sysdatetimeoffset()',
+        ];
+        if (
+            isset($data['default']) &&
+            in_array($data['type'], $dateTimeTypes, true) &&
+            in_array(strtolower($data['default']), $dateTimeDefaults, true)
+        ) {
+            $out .= ' DEFAULT ' . strtoupper($data['default']);
+        } elseif (isset($data['default'])) {
+            $default = is_bool($data['default'])
+                ? (int)$data['default']
+                : $this->_driver->schemaValue($data['default']);
+            $out .= ' DEFAULT ' . $default;
+        } elseif (isset($data['null']) && $data['null'] !== false) {
+            $out .= ' DEFAULT NULL';
+        }
+
+        return $out;
+    }
+
+    /**
+     * @inheritDoc
+     */
+    public function addConstraintSql(TableSchema $schema): array
+    {
+        $sqlPattern = 'ALTER TABLE %s ADD %s;';
+        $sql = [];
+
+        foreach ($schema->constraints() as $name) {
+            /** @var array $constraint */
+            $constraint = $schema->getConstraint($name);
+            if ($constraint['type'] === TableSchema::CONSTRAINT_FOREIGN) {
+                $tableName = $this->_driver->quoteIdentifier($schema->name());
+                $sql[] = sprintf($sqlPattern, $tableName, $this->constraintSql($schema, $name));
+            }
+        }
+
+        return $sql;
+    }
+
+    /**
+     * @inheritDoc
+     */
+    public function dropConstraintSql(TableSchema $schema): array
+    {
+        $sqlPattern = 'ALTER TABLE %s DROP CONSTRAINT %s;';
+        $sql = [];
+
+        foreach ($schema->constraints() as $name) {
+            /** @var array $constraint */
+            $constraint = $schema->getConstraint($name);
+            if ($constraint['type'] === TableSchema::CONSTRAINT_FOREIGN) {
+                $tableName = $this->_driver->quoteIdentifier($schema->name());
+                $constraintName = $this->_driver->quoteIdentifier($name);
+                $sql[] = sprintf($sqlPattern, $tableName, $constraintName);
+            }
+        }
+
+        return $sql;
+    }
+
+    /**
+     * @inheritDoc
+     */
+    public function indexSql(TableSchema $schema, string $name): string
+    {
+        /** @var array $data */
+        $data = $schema->getIndex($name);
+        $columns = array_map(
+            [$this->_driver, 'quoteIdentifier'],
+            $data['columns']
+        );
+
+        return sprintf(
+            'CREATE INDEX %s ON %s (%s)',
+            $this->_driver->quoteIdentifier($name),
+            $this->_driver->quoteIdentifier($schema->name()),
+            implode(', ', $columns)
+        );
+    }
+
+    /**
+     * @inheritDoc
+     */
+    public function constraintSql(TableSchema $schema, string $name): string
+    {
+        /** @var array $data */
+        $data = $schema->getConstraint($name);
+        $out = 'CONSTRAINT ' . $this->_driver->quoteIdentifier($name);
+        if ($data['type'] === TableSchema::CONSTRAINT_PRIMARY) {
+            $out = 'PRIMARY KEY';
+        }
+        if ($data['type'] === TableSchema::CONSTRAINT_UNIQUE) {
+            $out .= ' UNIQUE';
+        }
+
+        return $this->_keySql($out, $data);
+    }
+
+    /**
+     * Helper method for generating key SQL snippets.
+     *
+     * @param string $prefix The key prefix
+     * @param array $data Key data.
+     * @return string
+     */
+    protected function _keySql(string $prefix, array $data): string
+    {
+        $columns = array_map(
+            [$this->_driver, 'quoteIdentifier'],
+            $data['columns']
+        );
+        if ($data['type'] === TableSchema::CONSTRAINT_FOREIGN) {
+            return $prefix . sprintf(
+                ' FOREIGN KEY (%s) REFERENCES %s (%s) ON UPDATE %s ON DELETE %s',
+                implode(', ', $columns),
+                $this->_driver->quoteIdentifier($data['references'][0]),
+                $this->_convertConstraintColumns($data['references'][1]),
+                $this->_foreignOnClause($data['update']),
+                $this->_foreignOnClause($data['delete'])
+            );
+        }
+
+        return $prefix . ' (' . implode(', ', $columns) . ')';
+    }
+
+    /**
+     * @inheritDoc
+     */
+    public function createTableSql(TableSchema $schema, array $columns, array $constraints, array $indexes): array
+    {
+        $content = array_merge($columns, $constraints);
+        $content = implode(",\n", array_filter($content));
+        $tableName = $this->_driver->quoteIdentifier($schema->name());
+        $out = [];
+        $out[] = sprintf("CREATE TABLE %s (\n%s\n)", $tableName, $content);
+        foreach ($indexes as $index) {
+            $out[] = $index;
+        }
+
+        return $out;
+    }
+
+    /**
+     * @inheritDoc
+     */
+    public function truncateTableSql(TableSchema $schema): array
+    {
+        $name = $this->_driver->quoteIdentifier($schema->name());
+        $queries = [
+            sprintf('DELETE FROM %s', $name),
+        ];
+
+        // Restart identity sequences
+        $pk = $schema->getPrimaryKey();
+        if (count($pk) === 1) {
+            /** @var array $column */
+            $column = $schema->getColumn($pk[0]);
+            if (in_array($column['type'], ['integer', 'biginteger'])) {
+                $queries[] = sprintf(
+                    "IF EXISTS (SELECT * FROM sys.identity_columns WHERE OBJECT_NAME(OBJECT_ID) = '%s' AND " .
+                    "last_value IS NOT NULL) DBCC CHECKIDENT('%s', RESEED, 0)",
+                    $schema->name(),
+                    $schema->name()
+                );
+            }
+        }
+
+        return $queries;
+    }
+}
+
+// phpcs:disable
+class_alias(
+    'Cake\Database\Schema\SqlserverSchemaDialect', 
+    'Cake\Database\Schema\SqlserverSchema'
+);
+// phpcs:enable
diff --git a/vendor/cakephp/database/Schema/TableSchema.php b/vendor/cakephp/database/Schema/TableSchema.php
new file mode 100644
index 0000000..a58779a
--- /dev/null
+++ b/vendor/cakephp/database/Schema/TableSchema.php
@@ -0,0 +1,793 @@
+
+     */
+    protected $_columns = [];
+
+    /**
+     * A map with columns to types
+     *
+     * @var array
+     */
+    protected $_typeMap = [];
+
+    /**
+     * Indexes in the table.
+     *
+     * @var array
+     */
+    protected $_indexes = [];
+
+    /**
+     * Constraints in the table.
+     *
+     * @var array>
+     */
+    protected $_constraints = [];
+
+    /**
+     * Options for the table.
+     *
+     * @var array
+     */
+    protected $_options = [];
+
+    /**
+     * Whether the table is temporary
+     *
+     * @var bool
+     */
+    protected $_temporary = false;
+
+    /**
+     * Column length when using a `tiny` column type
+     *
+     * @var int
+     */
+    public const LENGTH_TINY = 255;
+
+    /**
+     * Column length when using a `medium` column type
+     *
+     * @var int
+     */
+    public const LENGTH_MEDIUM = 16777215;
+
+    /**
+     * Column length when using a `long` column type
+     *
+     * @var int
+     */
+    public const LENGTH_LONG = 4294967295;
+
+    /**
+     * Valid column length that can be used with text type columns
+     *
+     * @var array
+     */
+    public static $columnLengths = [
+        'tiny' => self::LENGTH_TINY,
+        'medium' => self::LENGTH_MEDIUM,
+        'long' => self::LENGTH_LONG,
+    ];
+
+    /**
+     * The valid keys that can be used in a column
+     * definition.
+     *
+     * @var array
+     */
+    protected static $_columnKeys = [
+        'type' => null,
+        'baseType' => null,
+        'length' => null,
+        'precision' => null,
+        'null' => null,
+        'default' => null,
+        'comment' => null,
+    ];
+
+    /**
+     * Additional type specific properties.
+     *
+     * @var array>
+     */
+    protected static $_columnExtras = [
+        'string' => [
+            'collate' => null,
+        ],
+        'char' => [
+            'collate' => null,
+        ],
+        'text' => [
+            'collate' => null,
+        ],
+        'tinyinteger' => [
+            'unsigned' => null,
+        ],
+        'smallinteger' => [
+            'unsigned' => null,
+        ],
+        'integer' => [
+            'unsigned' => null,
+            'autoIncrement' => null,
+        ],
+        'biginteger' => [
+            'unsigned' => null,
+            'autoIncrement' => null,
+        ],
+        'decimal' => [
+            'unsigned' => null,
+        ],
+        'float' => [
+            'unsigned' => null,
+        ],
+    ];
+
+    /**
+     * The valid keys that can be used in an index
+     * definition.
+     *
+     * @var array
+     */
+    protected static $_indexKeys = [
+        'type' => null,
+        'columns' => [],
+        'length' => [],
+        'references' => [],
+        'update' => 'restrict',
+        'delete' => 'restrict',
+    ];
+
+    /**
+     * Names of the valid index types.
+     *
+     * @var array
+     */
+    protected static $_validIndexTypes = [
+        self::INDEX_INDEX,
+        self::INDEX_FULLTEXT,
+    ];
+
+    /**
+     * Names of the valid constraint types.
+     *
+     * @var array
+     */
+    protected static $_validConstraintTypes = [
+        self::CONSTRAINT_PRIMARY,
+        self::CONSTRAINT_UNIQUE,
+        self::CONSTRAINT_FOREIGN,
+    ];
+
+    /**
+     * Names of the valid foreign key actions.
+     *
+     * @var array
+     */
+    protected static $_validForeignKeyActions = [
+        self::ACTION_CASCADE,
+        self::ACTION_SET_NULL,
+        self::ACTION_SET_DEFAULT,
+        self::ACTION_NO_ACTION,
+        self::ACTION_RESTRICT,
+    ];
+
+    /**
+     * Primary constraint type
+     *
+     * @var string
+     */
+    public const CONSTRAINT_PRIMARY = 'primary';
+
+    /**
+     * Unique constraint type
+     *
+     * @var string
+     */
+    public const CONSTRAINT_UNIQUE = 'unique';
+
+    /**
+     * Foreign constraint type
+     *
+     * @var string
+     */
+    public const CONSTRAINT_FOREIGN = 'foreign';
+
+    /**
+     * Index - index type
+     *
+     * @var string
+     */
+    public const INDEX_INDEX = 'index';
+
+    /**
+     * Fulltext index type
+     *
+     * @var string
+     */
+    public const INDEX_FULLTEXT = 'fulltext';
+
+    /**
+     * Foreign key cascade action
+     *
+     * @var string
+     */
+    public const ACTION_CASCADE = 'cascade';
+
+    /**
+     * Foreign key set null action
+     *
+     * @var string
+     */
+    public const ACTION_SET_NULL = 'setNull';
+
+    /**
+     * Foreign key no action
+     *
+     * @var string
+     */
+    public const ACTION_NO_ACTION = 'noAction';
+
+    /**
+     * Foreign key restrict action
+     *
+     * @var string
+     */
+    public const ACTION_RESTRICT = 'restrict';
+
+    /**
+     * Foreign key restrict default
+     *
+     * @var string
+     */
+    public const ACTION_SET_DEFAULT = 'setDefault';
+
+    /**
+     * Constructor.
+     *
+     * @param string $table The table name.
+     * @param array $columns The list of columns for the schema.
+     */
+    public function __construct(string $table, array $columns = [])
+    {
+        $this->_table = $table;
+        foreach ($columns as $field => $definition) {
+            $this->addColumn($field, $definition);
+        }
+    }
+
+    /**
+     * @inheritDoc
+     */
+    public function name(): string
+    {
+        return $this->_table;
+    }
+
+    /**
+     * @inheritDoc
+     */
+    public function addColumn(string $name, $attrs)
+    {
+        if (is_string($attrs)) {
+            $attrs = ['type' => $attrs];
+        }
+        $valid = static::$_columnKeys;
+        if (isset(static::$_columnExtras[$attrs['type']])) {
+            $valid += static::$_columnExtras[$attrs['type']];
+        }
+        $attrs = array_intersect_key($attrs, $valid);
+        $this->_columns[$name] = $attrs + $valid;
+        $this->_typeMap[$name] = $this->_columns[$name]['type'];
+
+        return $this;
+    }
+
+    /**
+     * @inheritDoc
+     */
+    public function removeColumn(string $name)
+    {
+        unset($this->_columns[$name], $this->_typeMap[$name]);
+
+        return $this;
+    }
+
+    /**
+     * @inheritDoc
+     */
+    public function columns(): array
+    {
+        return array_keys($this->_columns);
+    }
+
+    /**
+     * @inheritDoc
+     */
+    public function getColumn(string $name): ?array
+    {
+        if (!isset($this->_columns[$name])) {
+            return null;
+        }
+        $column = $this->_columns[$name];
+        unset($column['baseType']);
+
+        return $column;
+    }
+
+    /**
+     * @inheritDoc
+     */
+    public function getColumnType(string $name): ?string
+    {
+        if (!isset($this->_columns[$name])) {
+            return null;
+        }
+
+        return $this->_columns[$name]['type'];
+    }
+
+    /**
+     * @inheritDoc
+     */
+    public function setColumnType(string $name, string $type)
+    {
+        if (!isset($this->_columns[$name])) {
+            return $this;
+        }
+
+        $this->_columns[$name]['type'] = $type;
+        $this->_typeMap[$name] = $type;
+
+        return $this;
+    }
+
+    /**
+     * @inheritDoc
+     */
+    public function hasColumn(string $name): bool
+    {
+        return isset($this->_columns[$name]);
+    }
+
+    /**
+     * @inheritDoc
+     */
+    public function baseColumnType(string $column): ?string
+    {
+        if (isset($this->_columns[$column]['baseType'])) {
+            return $this->_columns[$column]['baseType'];
+        }
+
+        $type = $this->getColumnType($column);
+
+        if ($type === null) {
+            return null;
+        }
+
+        if (TypeFactory::getMap($type)) {
+            $type = TypeFactory::build($type)->getBaseType();
+        }
+
+        return $this->_columns[$column]['baseType'] = $type;
+    }
+
+    /**
+     * @inheritDoc
+     */
+    public function typeMap(): array
+    {
+        return $this->_typeMap;
+    }
+
+    /**
+     * @inheritDoc
+     */
+    public function isNullable(string $name): bool
+    {
+        if (!isset($this->_columns[$name])) {
+            return true;
+        }
+
+        return $this->_columns[$name]['null'] === true;
+    }
+
+    /**
+     * @inheritDoc
+     */
+    public function defaultValues(): array
+    {
+        $defaults = [];
+        foreach ($this->_columns as $name => $data) {
+            if (!array_key_exists('default', $data)) {
+                continue;
+            }
+            if ($data['default'] === null && $data['null'] !== true) {
+                continue;
+            }
+            $defaults[$name] = $data['default'];
+        }
+
+        return $defaults;
+    }
+
+    /**
+     * @inheritDoc
+     */
+    public function addIndex(string $name, $attrs)
+    {
+        if (is_string($attrs)) {
+            $attrs = ['type' => $attrs];
+        }
+        $attrs = array_intersect_key($attrs, static::$_indexKeys);
+        $attrs += static::$_indexKeys;
+        unset($attrs['references'], $attrs['update'], $attrs['delete']);
+
+        if (!in_array($attrs['type'], static::$_validIndexTypes, true)) {
+            throw new DatabaseException(sprintf(
+                'Invalid index type "%s" in index "%s" in table "%s".',
+                $attrs['type'],
+                $name,
+                $this->_table
+            ));
+        }
+        $attrs['columns'] = (array)$attrs['columns'];
+        foreach ($attrs['columns'] as $field) {
+            if (empty($this->_columns[$field])) {
+                $msg = sprintf(
+                    'Columns used in index "%s" in table "%s" must be added to the Table schema first. ' .
+                    'The column "%s" was not found.',
+                    $name,
+                    $this->_table,
+                    $field
+                );
+                throw new DatabaseException($msg);
+            }
+        }
+        $this->_indexes[$name] = $attrs;
+
+        return $this;
+    }
+
+    /**
+     * @inheritDoc
+     */
+    public function indexes(): array
+    {
+        return array_keys($this->_indexes);
+    }
+
+    /**
+     * @inheritDoc
+     */
+    public function getIndex(string $name): ?array
+    {
+        if (!isset($this->_indexes[$name])) {
+            return null;
+        }
+
+        return $this->_indexes[$name];
+    }
+
+    /**
+     * Get the column(s) used for the primary key.
+     *
+     * @return array Column name(s) for the primary key. An
+     *   empty list will be returned when the table has no primary key.
+     * @deprecated 4.0.0 Renamed to {@link getPrimaryKey()}.
+     */
+    public function primaryKey(): array
+    {
+        deprecationWarning('`TableSchema::primaryKey()` is deprecated. Use `TableSchema::getPrimaryKey()`.');
+
+        return $this->getPrimarykey();
+    }
+
+    /**
+     * @inheritDoc
+     */
+    public function getPrimaryKey(): array
+    {
+        foreach ($this->_constraints as $data) {
+            if ($data['type'] === static::CONSTRAINT_PRIMARY) {
+                return $data['columns'];
+            }
+        }
+
+        return [];
+    }
+
+    /**
+     * @inheritDoc
+     */
+    public function addConstraint(string $name, $attrs)
+    {
+        if (is_string($attrs)) {
+            $attrs = ['type' => $attrs];
+        }
+        $attrs = array_intersect_key($attrs, static::$_indexKeys);
+        $attrs += static::$_indexKeys;
+        if (!in_array($attrs['type'], static::$_validConstraintTypes, true)) {
+            throw new DatabaseException(sprintf(
+                'Invalid constraint type "%s" in table "%s".',
+                $attrs['type'],
+                $this->_table
+            ));
+        }
+        if (empty($attrs['columns'])) {
+            throw new DatabaseException(sprintf(
+                'Constraints in table "%s" must have at least one column.',
+                $this->_table
+            ));
+        }
+        $attrs['columns'] = (array)$attrs['columns'];
+        foreach ($attrs['columns'] as $field) {
+            if (empty($this->_columns[$field])) {
+                $msg = sprintf(
+                    'Columns used in constraints must be added to the Table schema first. ' .
+                    'The column "%s" was not found in table "%s".',
+                    $field,
+                    $this->_table
+                );
+                throw new DatabaseException($msg);
+            }
+        }
+
+        if ($attrs['type'] === static::CONSTRAINT_FOREIGN) {
+            $attrs = $this->_checkForeignKey($attrs);
+
+            if (isset($this->_constraints[$name])) {
+                $this->_constraints[$name]['columns'] = array_unique(array_merge(
+                    $this->_constraints[$name]['columns'],
+                    $attrs['columns']
+                ));
+
+                if (isset($this->_constraints[$name]['references'])) {
+                    $this->_constraints[$name]['references'][1] = array_unique(array_merge(
+                        (array)$this->_constraints[$name]['references'][1],
+                        [$attrs['references'][1]]
+                    ));
+                }
+
+                return $this;
+            }
+        } else {
+            unset($attrs['references'], $attrs['update'], $attrs['delete']);
+        }
+
+        $this->_constraints[$name] = $attrs;
+
+        return $this;
+    }
+
+    /**
+     * @inheritDoc
+     */
+    public function dropConstraint(string $name)
+    {
+        if (isset($this->_constraints[$name])) {
+            unset($this->_constraints[$name]);
+        }
+
+        return $this;
+    }
+
+    /**
+     * Check whether a table has an autoIncrement column defined.
+     *
+     * @return bool
+     */
+    public function hasAutoincrement(): bool
+    {
+        foreach ($this->_columns as $column) {
+            if (isset($column['autoIncrement']) && $column['autoIncrement']) {
+                return true;
+            }
+        }
+
+        return false;
+    }
+
+    /**
+     * Helper method to check/validate foreign keys.
+     *
+     * @param array $attrs Attributes to set.
+     * @return array
+     * @throws \Cake\Database\Exception\DatabaseException When foreign key definition is not valid.
+     */
+    protected function _checkForeignKey(array $attrs): array
+    {
+        if (count($attrs['references']) < 2) {
+            throw new DatabaseException('References must contain a table and column.');
+        }
+        if (!in_array($attrs['update'], static::$_validForeignKeyActions)) {
+            throw new DatabaseException(sprintf(
+                'Update action is invalid. Must be one of %s',
+                implode(',', static::$_validForeignKeyActions)
+            ));
+        }
+        if (!in_array($attrs['delete'], static::$_validForeignKeyActions)) {
+            throw new DatabaseException(sprintf(
+                'Delete action is invalid. Must be one of %s',
+                implode(',', static::$_validForeignKeyActions)
+            ));
+        }
+
+        return $attrs;
+    }
+
+    /**
+     * @inheritDoc
+     */
+    public function constraints(): array
+    {
+        return array_keys($this->_constraints);
+    }
+
+    /**
+     * @inheritDoc
+     */
+    public function getConstraint(string $name): ?array
+    {
+        return $this->_constraints[$name] ?? null;
+    }
+
+    /**
+     * @inheritDoc
+     */
+    public function setOptions(array $options)
+    {
+        $this->_options = $options + $this->_options;
+
+        return $this;
+    }
+
+    /**
+     * @inheritDoc
+     */
+    public function getOptions(): array
+    {
+        return $this->_options;
+    }
+
+    /**
+     * @inheritDoc
+     */
+    public function setTemporary(bool $temporary)
+    {
+        $this->_temporary = $temporary;
+
+        return $this;
+    }
+
+    /**
+     * @inheritDoc
+     */
+    public function isTemporary(): bool
+    {
+        return $this->_temporary;
+    }
+
+    /**
+     * @inheritDoc
+     */
+    public function createSql(Connection $connection): array
+    {
+        $dialect = $connection->getDriver()->schemaDialect();
+        $columns = $constraints = $indexes = [];
+        foreach (array_keys($this->_columns) as $name) {
+            $columns[] = $dialect->columnSql($this, $name);
+        }
+        foreach (array_keys($this->_constraints) as $name) {
+            $constraints[] = $dialect->constraintSql($this, $name);
+        }
+        foreach (array_keys($this->_indexes) as $name) {
+            $indexes[] = $dialect->indexSql($this, $name);
+        }
+
+        return $dialect->createTableSql($this, $columns, $constraints, $indexes);
+    }
+
+    /**
+     * @inheritDoc
+     */
+    public function dropSql(Connection $connection): array
+    {
+        $dialect = $connection->getDriver()->schemaDialect();
+
+        return $dialect->dropTableSql($this);
+    }
+
+    /**
+     * @inheritDoc
+     */
+    public function truncateSql(Connection $connection): array
+    {
+        $dialect = $connection->getDriver()->schemaDialect();
+
+        return $dialect->truncateTableSql($this);
+    }
+
+    /**
+     * @inheritDoc
+     */
+    public function addConstraintSql(Connection $connection): array
+    {
+        $dialect = $connection->getDriver()->schemaDialect();
+
+        return $dialect->addConstraintSql($this);
+    }
+
+    /**
+     * @inheritDoc
+     */
+    public function dropConstraintSql(Connection $connection): array
+    {
+        $dialect = $connection->getDriver()->schemaDialect();
+
+        return $dialect->dropConstraintSql($this);
+    }
+
+    /**
+     * Returns an array of the table schema.
+     *
+     * @return array
+     */
+    public function __debugInfo(): array
+    {
+        return [
+            'table' => $this->_table,
+            'columns' => $this->_columns,
+            'indexes' => $this->_indexes,
+            'constraints' => $this->_constraints,
+            'options' => $this->_options,
+            'typeMap' => $this->_typeMap,
+            'temporary' => $this->_temporary,
+        ];
+    }
+}
diff --git a/vendor/cakephp/database/Schema/TableSchemaAwareInterface.php b/vendor/cakephp/database/Schema/TableSchemaAwareInterface.php
new file mode 100644
index 0000000..d4045f9
--- /dev/null
+++ b/vendor/cakephp/database/Schema/TableSchemaAwareInterface.php
@@ -0,0 +1,38 @@
+ Column name(s) for the primary key. An
+     *   empty list will be returned when the table has no primary key.
+     */
+    public function getPrimaryKey(): array;
+
+    /**
+     * Add an index.
+     *
+     * Used to add indexes, and full text indexes in platforms that support
+     * them.
+     *
+     * ### Attributes
+     *
+     * - `type` The type of index being added.
+     * - `columns` The columns in the index.
+     *
+     * @param string $name The name of the index.
+     * @param array|string $attrs The attributes for the index.
+     *   If string it will be used as `type`.
+     * @return $this
+     * @throws \Cake\Database\Exception\DatabaseException
+     */
+    public function addIndex(string $name, $attrs);
+
+    /**
+     * Read information about an index based on name.
+     *
+     * @param string $name The name of the index.
+     * @return array|null Array of index data, or null
+     */
+    public function getIndex(string $name): ?array;
+
+    /**
+     * Get the names of all the indexes in the table.
+     *
+     * @return array
+     */
+    public function indexes(): array;
+
+    /**
+     * Add a constraint.
+     *
+     * Used to add constraints to a table. For example primary keys, unique
+     * keys and foreign keys.
+     *
+     * ### Attributes
+     *
+     * - `type` The type of constraint being added.
+     * - `columns` The columns in the index.
+     * - `references` The table, column a foreign key references.
+     * - `update` The behavior on update. Options are 'restrict', 'setNull', 'cascade', 'noAction'.
+     * - `delete` The behavior on delete. Options are 'restrict', 'setNull', 'cascade', 'noAction'.
+     *
+     * The default for 'update' & 'delete' is 'cascade'.
+     *
+     * @param string $name The name of the constraint.
+     * @param array|string $attrs The attributes for the constraint.
+     *   If string it will be used as `type`.
+     * @return $this
+     * @throws \Cake\Database\Exception\DatabaseException
+     */
+    public function addConstraint(string $name, $attrs);
+
+    /**
+     * Read information about a constraint based on name.
+     *
+     * @param string $name The name of the constraint.
+     * @return array|null Array of constraint data, or null
+     */
+    public function getConstraint(string $name): ?array;
+
+    /**
+     * Remove a constraint.
+     *
+     * @param string $name Name of the constraint to remove
+     * @return $this
+     */
+    public function dropConstraint(string $name);
+
+    /**
+     * Get the names of all the constraints in the table.
+     *
+     * @return array
+     */
+    public function constraints(): array;
+}
diff --git a/vendor/cakephp/database/SchemaCache.php b/vendor/cakephp/database/SchemaCache.php
new file mode 100644
index 0000000..953ff1e
--- /dev/null
+++ b/vendor/cakephp/database/SchemaCache.php
@@ -0,0 +1,114 @@
+_schema = $this->getSchema($connection);
+    }
+
+    /**
+     * Build metadata.
+     *
+     * @param string|null $name The name of the table to build cache data for.
+     * @return array Returns a list build table caches
+     */
+    public function build(?string $name = null): array
+    {
+        if ($name) {
+            $tables = [$name];
+        } else {
+            $tables = $this->_schema->listTables();
+        }
+
+        foreach ($tables as $table) {
+            $this->_schema->describe($table, ['forceRefresh' => true]);
+        }
+
+        return $tables;
+    }
+
+    /**
+     * Clear metadata.
+     *
+     * @param string|null $name The name of the table to clear cache data for.
+     * @return array Returns a list of cleared table caches
+     */
+    public function clear(?string $name = null): array
+    {
+        if ($name) {
+            $tables = [$name];
+        } else {
+            $tables = $this->_schema->listTables();
+        }
+
+        $cacher = $this->_schema->getCacher();
+
+        foreach ($tables as $table) {
+            $key = $this->_schema->cacheKey($table);
+            $cacher->delete($key);
+        }
+
+        return $tables;
+    }
+
+    /**
+     * Helper method to get the schema collection.
+     *
+     * @param \Cake\Database\Connection $connection Connection object
+     * @return \Cake\Database\Schema\CachedCollection
+     * @throws \RuntimeException If given connection object is not compatible with schema caching
+     */
+    public function getSchema(Connection $connection): CachedCollection
+    {
+        $config = $connection->config();
+        if (empty($config['cacheMetadata'])) {
+            $connection->cacheMetadata(true);
+        }
+
+        /** @var \Cake\Database\Schema\CachedCollection $schemaCollection */
+        $schemaCollection = $connection->getSchemaCollection();
+
+        return $schemaCollection;
+    }
+}
diff --git a/vendor/cakephp/database/SqlDialectTrait.php b/vendor/cakephp/database/SqlDialectTrait.php
new file mode 100644
index 0000000..763f8fd
--- /dev/null
+++ b/vendor/cakephp/database/SqlDialectTrait.php
@@ -0,0 +1,10 @@
+ 'DELETE',
+        'where' => ' WHERE %s',
+        'group' => ' GROUP BY %s',
+        'order' => ' %s',
+        'offset' => ' OFFSET %s ROWS',
+        'epilog' => ' %s',
+    ];
+
+    /**
+     * @inheritDoc
+     */
+    protected $_selectParts = [
+        'with', 'select', 'from', 'join', 'where', 'group', 'having', 'window', 'order',
+        'offset', 'limit', 'union', 'epilog',
+    ];
+
+    /**
+     * Helper function used to build the string representation of a `WITH` clause,
+     * it constructs the CTE definitions list without generating the `RECURSIVE`
+     * keyword that is neither required nor valid.
+     *
+     * @param array $parts List of CTEs to be transformed to string
+     * @param \Cake\Database\Query $query The query that is being compiled
+     * @param \Cake\Database\ValueBinder $binder Value binder used to generate parameter placeholder
+     * @return string
+     */
+    protected function _buildWithPart(array $parts, Query $query, ValueBinder $binder): string
+    {
+        $expressions = [];
+        foreach ($parts as $cte) {
+            $expressions[] = $cte->sql($binder);
+        }
+
+        return sprintf('WITH %s ', implode(', ', $expressions));
+    }
+
+    /**
+     * Generates the INSERT part of a SQL query
+     *
+     * To better handle concurrency and low transaction isolation levels,
+     * we also include an OUTPUT clause so we can ensure we get the inserted
+     * row's data back.
+     *
+     * @param array $parts The parts to build
+     * @param \Cake\Database\Query $query The query that is being compiled
+     * @param \Cake\Database\ValueBinder $binder Value binder used to generate parameter placeholder
+     * @return string
+     */
+    protected function _buildInsertPart(array $parts, Query $query, ValueBinder $binder): string
+    {
+        if (!isset($parts[0])) {
+            throw new DatabaseException(
+                'Could not compile insert query. No table was specified. ' .
+                'Use `into()` to define a table.'
+            );
+        }
+        $table = $parts[0];
+        $columns = $this->_stringifyExpressions($parts[1], $binder);
+        $modifiers = $this->_buildModifierPart($query->clause('modifier'), $query, $binder);
+
+        return sprintf(
+            'INSERT%s INTO %s (%s) OUTPUT INSERTED.*',
+            $modifiers,
+            $table,
+            implode(', ', $columns)
+        );
+    }
+
+    /**
+     * Generates the LIMIT part of a SQL query
+     *
+     * @param int $limit the limit clause
+     * @param \Cake\Database\Query $query The query that is being compiled
+     * @return string
+     */
+    protected function _buildLimitPart(int $limit, Query $query): string
+    {
+        if ($query->clause('offset') === null) {
+            return '';
+        }
+
+        return sprintf(' FETCH FIRST %d ROWS ONLY', $limit);
+    }
+
+    /**
+     * Helper function used to build the string representation of a HAVING clause,
+     * it constructs the field list taking care of aliasing and
+     * converting expression objects to string.
+     *
+     * @param array $parts list of fields to be transformed to string
+     * @param \Cake\Database\Query $query The query that is being compiled
+     * @param \Cake\Database\ValueBinder $binder Value binder used to generate parameter placeholder
+     * @return string
+     */
+    protected function _buildHavingPart($parts, $query, $binder)
+    {
+        $selectParts = $query->clause('select');
+
+        foreach ($selectParts as $selectKey => $selectPart) {
+            if (!$selectPart instanceof FunctionExpression) {
+                continue;
+            }
+            foreach ($parts as $k => $p) {
+                if (!is_string($p)) {
+                    continue;
+                }
+                preg_match_all(
+                    '/\b' . trim($selectKey, '[]') . '\b/i',
+                    $p,
+                    $matches
+                );
+
+                if (empty($matches[0])) {
+                    continue;
+                }
+
+                $parts[$k] = preg_replace(
+                    ['/\[|\]/', '/\b' . trim($selectKey, '[]') . '\b/i'],
+                    ['', $selectPart->sql($binder)],
+                    $p
+                );
+            }
+        }
+
+        return sprintf(' HAVING %s', implode(', ', $parts));
+    }
+}
diff --git a/vendor/cakephp/database/Statement/BufferResultsTrait.php b/vendor/cakephp/database/Statement/BufferResultsTrait.php
new file mode 100644
index 0000000..b6a5e57
--- /dev/null
+++ b/vendor/cakephp/database/Statement/BufferResultsTrait.php
@@ -0,0 +1,45 @@
+_bufferResults = $buffer;
+
+        return $this;
+    }
+}
diff --git a/vendor/cakephp/database/Statement/BufferedStatement.php b/vendor/cakephp/database/Statement/BufferedStatement.php
new file mode 100644
index 0000000..59aea0d
--- /dev/null
+++ b/vendor/cakephp/database/Statement/BufferedStatement.php
@@ -0,0 +1,361 @@
+
+ */
+class BufferedStatement implements Iterator, StatementInterface
+{
+    use TypeConverterTrait;
+
+    /**
+     * If true, all rows were fetched
+     *
+     * @var bool
+     */
+    protected $_allFetched = false;
+
+    /**
+     * The decorated statement
+     *
+     * @var \Cake\Database\StatementInterface
+     */
+    protected $statement;
+
+    /**
+     * The driver for the statement
+     *
+     * @var \Cake\Database\DriverInterface
+     */
+    protected $_driver;
+
+    /**
+     * The in-memory cache containing results from previous iterators
+     *
+     * @var array
+     */
+    protected $buffer = [];
+
+    /**
+     * Whether this statement has already been executed
+     *
+     * @var bool
+     */
+    protected $_hasExecuted = false;
+
+    /**
+     * The current iterator index.
+     *
+     * @var int
+     */
+    protected $index = 0;
+
+    /**
+     * Constructor
+     *
+     * @param \Cake\Database\StatementInterface $statement Statement implementation such as PDOStatement
+     * @param \Cake\Database\DriverInterface $driver Driver instance
+     */
+    public function __construct(StatementInterface $statement, DriverInterface $driver)
+    {
+        $this->statement = $statement;
+        $this->_driver = $driver;
+    }
+
+    /**
+     * Returns the connection driver.
+     *
+     * @return \Cake\Database\DriverInterface
+     */
+    protected function getDriver(): DriverInterface
+    {
+        return $this->_driver;
+    }
+
+    /**
+     * Magic getter to return $queryString as read-only.
+     *
+     * @param string $property internal property to get
+     * @return string|null
+     */
+    public function __get(string $property)
+    {
+        if ($property === 'queryString') {
+            /** @psalm-suppress NoInterfaceProperties */
+            return $this->statement->queryString;
+        }
+
+        return null;
+    }
+
+    /**
+     * @inheritDoc
+     */
+    public function bindValue($column, $value, $type = 'string'): void
+    {
+        $this->statement->bindValue($column, $value, $type);
+    }
+
+    /**
+     * @inheritDoc
+     */
+    public function closeCursor(): void
+    {
+        $this->statement->closeCursor();
+    }
+
+    /**
+     * @inheritDoc
+     */
+    public function columnCount(): int
+    {
+        return $this->statement->columnCount();
+    }
+
+    /**
+     * @inheritDoc
+     */
+    public function errorCode()
+    {
+        return $this->statement->errorCode();
+    }
+
+    /**
+     * @inheritDoc
+     */
+    public function errorInfo(): array
+    {
+        return $this->statement->errorInfo();
+    }
+
+    /**
+     * @inheritDoc
+     */
+    public function execute(?array $params = null): bool
+    {
+        $this->_reset();
+        $this->_hasExecuted = true;
+
+        return $this->statement->execute($params);
+    }
+
+    /**
+     * @inheritDoc
+     */
+    public function fetchColumn(int $position)
+    {
+        $result = $this->fetch(static::FETCH_TYPE_NUM);
+        if ($result !== false && isset($result[$position])) {
+            return $result[$position];
+        }
+
+        return false;
+    }
+
+    /**
+     * Statements can be passed as argument for count() to return the number
+     * for affected rows from last execution.
+     *
+     * @return int
+     */
+    public function count(): int
+    {
+        return $this->rowCount();
+    }
+
+    /**
+     * @inheritDoc
+     */
+    public function bind(array $params, array $types): void
+    {
+        $this->statement->bind($params, $types);
+    }
+
+    /**
+     * @inheritDoc
+     */
+    public function lastInsertId(?string $table = null, ?string $column = null)
+    {
+        return $this->statement->lastInsertId($table, $column);
+    }
+
+    /**
+     * {@inheritDoc}
+     *
+     * @param string|int $type The type to fetch.
+     * @return array|false
+     */
+    public function fetch($type = self::FETCH_TYPE_NUM)
+    {
+        if ($this->_allFetched) {
+            $row = false;
+            if (isset($this->buffer[$this->index])) {
+                $row = $this->buffer[$this->index];
+            }
+            $this->index += 1;
+
+            if ($row && $type === static::FETCH_TYPE_NUM) {
+                return array_values($row);
+            }
+
+            return $row;
+        }
+
+        $record = $this->statement->fetch($type);
+        if ($record === false) {
+            $this->_allFetched = true;
+            $this->statement->closeCursor();
+
+            return false;
+        }
+        $this->buffer[] = $record;
+
+        return $record;
+    }
+
+    /**
+     * @return array
+     */
+    public function fetchAssoc(): array
+    {
+        $result = $this->fetch(static::FETCH_TYPE_ASSOC);
+
+        return $result ?: [];
+    }
+
+    /**
+     * @inheritDoc
+     */
+    public function fetchAll($type = self::FETCH_TYPE_NUM)
+    {
+        if ($this->_allFetched) {
+            return $this->buffer;
+        }
+        $results = $this->statement->fetchAll($type);
+        if ($results !== false) {
+            $this->buffer = array_merge($this->buffer, $results);
+        }
+        $this->_allFetched = true;
+        $this->statement->closeCursor();
+
+        return $this->buffer;
+    }
+
+    /**
+     * @inheritDoc
+     */
+    public function rowCount(): int
+    {
+        if (!$this->_allFetched) {
+            $this->fetchAll(static::FETCH_TYPE_ASSOC);
+        }
+
+        return count($this->buffer);
+    }
+
+    /**
+     * Reset all properties
+     *
+     * @return void
+     */
+    protected function _reset(): void
+    {
+        $this->buffer = [];
+        $this->_allFetched = false;
+        $this->index = 0;
+    }
+
+    /**
+     * Returns the current key in the iterator
+     *
+     * @return mixed
+     */
+    #[\ReturnTypeWillChange]
+    public function key()
+    {
+        return $this->index;
+    }
+
+    /**
+     * Returns the current record in the iterator
+     *
+     * @return mixed
+     */
+    #[\ReturnTypeWillChange]
+    public function current()
+    {
+        return $this->buffer[$this->index];
+    }
+
+    /**
+     * Rewinds the collection
+     *
+     * @return void
+     */
+    public function rewind(): void
+    {
+        $this->index = 0;
+    }
+
+    /**
+     * Returns whether the iterator has more elements
+     *
+     * @return bool
+     */
+    public function valid(): bool
+    {
+        $old = $this->index;
+        $row = $this->fetch(self::FETCH_TYPE_ASSOC);
+
+        // Restore the index as fetch() increments during
+        // the cache scenario.
+        $this->index = $old;
+
+        return $row !== false;
+    }
+
+    /**
+     * Advances the iterator pointer to the next element
+     *
+     * @return void
+     */
+    public function next(): void
+    {
+        $this->index += 1;
+    }
+
+    /**
+     * Get the wrapped statement
+     *
+     * @return \Cake\Database\StatementInterface
+     */
+    public function getInnerStatement(): StatementInterface
+    {
+        return $this->statement;
+    }
+}
diff --git a/vendor/cakephp/database/Statement/CallbackStatement.php b/vendor/cakephp/database/Statement/CallbackStatement.php
new file mode 100644
index 0000000..a0b59c3
--- /dev/null
+++ b/vendor/cakephp/database/Statement/CallbackStatement.php
@@ -0,0 +1,77 @@
+_callback = $callback;
+    }
+
+    /**
+     * Fetch a row from the statement.
+     *
+     * The result will be processed by the callback when it is not `false`.
+     *
+     * @param string|int $type Either 'num' or 'assoc' to indicate the result format you would like.
+     * @return array|false
+     */
+    public function fetch($type = parent::FETCH_TYPE_NUM)
+    {
+        $callback = $this->_callback;
+        $row = $this->_statement->fetch($type);
+
+        return $row === false ? $row : $callback($row);
+    }
+
+    /**
+     * {@inheritDoc}
+     *
+     * Each row in the result will be processed by the callback when it is not `false.
+     */
+    public function fetchAll($type = parent::FETCH_TYPE_NUM)
+    {
+        $results = $this->_statement->fetchAll($type);
+
+        return $results !== false ? array_map($this->_callback, $results) : false;
+    }
+}
diff --git a/vendor/cakephp/database/Statement/MysqlStatement.php b/vendor/cakephp/database/Statement/MysqlStatement.php
new file mode 100644
index 0000000..2ad4ec0
--- /dev/null
+++ b/vendor/cakephp/database/Statement/MysqlStatement.php
@@ -0,0 +1,46 @@
+_driver->getConnection();
+
+        try {
+            $connection->setAttribute(PDO::MYSQL_ATTR_USE_BUFFERED_QUERY, $this->_bufferResults);
+            $result = $this->_statement->execute($params);
+        } finally {
+            $connection->setAttribute(PDO::MYSQL_ATTR_USE_BUFFERED_QUERY, true);
+        }
+
+        return $result;
+    }
+}
diff --git a/vendor/cakephp/database/Statement/PDOStatement.php b/vendor/cakephp/database/Statement/PDOStatement.php
new file mode 100644
index 0000000..6cbc827
--- /dev/null
+++ b/vendor/cakephp/database/Statement/PDOStatement.php
@@ -0,0 +1,176 @@
+_statement = $statement;
+        $this->_driver = $driver;
+    }
+
+    /**
+     * Magic getter to return PDOStatement::$queryString as read-only.
+     *
+     * @param string $property internal property to get
+     * @return string|null
+     */
+    public function __get(string $property)
+    {
+        if ($property === 'queryString' && isset($this->_statement->queryString)) {
+            return $this->_statement->queryString;
+        }
+
+        return null;
+    }
+
+    /**
+     * Assign a value to a positional or named variable in prepared query. If using
+     * positional variables you need to start with index one, if using named params then
+     * just use the name in any order.
+     *
+     * You can pass PDO compatible constants for binding values with a type or optionally
+     * any type name registered in the Type class. Any value will be converted to the valid type
+     * representation if needed.
+     *
+     * It is not allowed to combine positional and named variables in the same statement
+     *
+     * ### Examples:
+     *
+     * ```
+     * $statement->bindValue(1, 'a title');
+     * $statement->bindValue(2, 5, PDO::INT);
+     * $statement->bindValue('active', true, 'boolean');
+     * $statement->bindValue(5, new \DateTime(), 'date');
+     * ```
+     *
+     * @param string|int $column name or param position to be bound
+     * @param mixed $value The value to bind to variable in query
+     * @param string|int|null $type PDO type or name of configured Type class
+     * @return void
+     */
+    public function bindValue($column, $value, $type = 'string'): void
+    {
+        if ($type === null) {
+            $type = 'string';
+        }
+        if (!is_int($type)) {
+            [$value, $type] = $this->cast($value, $type);
+        }
+        $this->_statement->bindValue($column, $value, $type);
+    }
+
+    /**
+     * Returns the next row for the result set after executing this statement.
+     * Rows can be fetched to contain columns as names or positions. If no
+     * rows are left in result set, this method will return false
+     *
+     * ### Example:
+     *
+     * ```
+     *  $statement = $connection->prepare('SELECT id, title from articles');
+     *  $statement->execute();
+     *  print_r($statement->fetch('assoc')); // will show ['id' => 1, 'title' => 'a title']
+     * ```
+     *
+     * @param string|int $type 'num' for positional columns, assoc for named columns
+     * @return mixed Result array containing columns and values or false if no results
+     * are left
+     */
+    public function fetch($type = parent::FETCH_TYPE_NUM)
+    {
+        if ($type === static::FETCH_TYPE_NUM) {
+            return $this->_statement->fetch(PDO::FETCH_NUM);
+        }
+        if ($type === static::FETCH_TYPE_ASSOC) {
+            return $this->_statement->fetch(PDO::FETCH_ASSOC);
+        }
+        if ($type === static::FETCH_TYPE_OBJ) {
+            return $this->_statement->fetch(PDO::FETCH_OBJ);
+        }
+
+        if (!is_int($type)) {
+            throw new CakeException(sprintf(
+                'Fetch type for PDOStatement must be an integer, found `%s` instead',
+                getTypeName($type)
+            ));
+        }
+
+        return $this->_statement->fetch($type);
+    }
+
+    /**
+     * Returns an array with all rows resulting from executing this statement
+     *
+     * ### Example:
+     *
+     * ```
+     *  $statement = $connection->prepare('SELECT id, title from articles');
+     *  $statement->execute();
+     *  print_r($statement->fetchAll('assoc')); // will show [0 => ['id' => 1, 'title' => 'a title']]
+     * ```
+     *
+     * @param string|int $type num for fetching columns as positional keys or assoc for column names as keys
+     * @return array|false list of all results from database for this statement, false on failure
+     * @psalm-assert string $type
+     */
+    public function fetchAll($type = parent::FETCH_TYPE_NUM)
+    {
+        if ($type === static::FETCH_TYPE_NUM) {
+            return $this->_statement->fetchAll(PDO::FETCH_NUM);
+        }
+        if ($type === static::FETCH_TYPE_ASSOC) {
+            return $this->_statement->fetchAll(PDO::FETCH_ASSOC);
+        }
+        if ($type === static::FETCH_TYPE_OBJ) {
+            return $this->_statement->fetchAll(PDO::FETCH_OBJ);
+        }
+
+        if (!is_int($type)) {
+            throw new CakeException(sprintf(
+                'Fetch type for PDOStatement must be an integer, found `%s` instead',
+                getTypeName($type)
+            ));
+        }
+
+        return $this->_statement->fetchAll($type);
+    }
+}
diff --git a/vendor/cakephp/database/Statement/SqliteStatement.php b/vendor/cakephp/database/Statement/SqliteStatement.php
new file mode 100644
index 0000000..cc965a8
--- /dev/null
+++ b/vendor/cakephp/database/Statement/SqliteStatement.php
@@ -0,0 +1,70 @@
+_statement instanceof BufferedStatement) {
+            $this->_statement = $this->_statement->getInnerStatement();
+        }
+
+        if ($this->_bufferResults) {
+            $this->_statement = new BufferedStatement($this->_statement, $this->_driver);
+        }
+
+        return $this->_statement->execute($params);
+    }
+
+    /**
+     * Returns the number of rows returned of affected by last execution
+     *
+     * @return int
+     */
+    public function rowCount(): int
+    {
+        /** @psalm-suppress NoInterfaceProperties */
+        if (
+            $this->_statement->queryString &&
+            preg_match('/^(?:DELETE|UPDATE|INSERT)/i', $this->_statement->queryString)
+        ) {
+            $changes = $this->_driver->prepare('SELECT CHANGES()');
+            $changes->execute();
+            $row = $changes->fetch();
+            $changes->closeCursor();
+
+            if (!$row) {
+                return 0;
+            }
+
+            return (int)$row[0];
+        }
+
+        return parent::rowCount();
+    }
+}
diff --git a/vendor/cakephp/database/Statement/SqlserverStatement.php b/vendor/cakephp/database/Statement/SqlserverStatement.php
new file mode 100644
index 0000000..39f3be8
--- /dev/null
+++ b/vendor/cakephp/database/Statement/SqlserverStatement.php
@@ -0,0 +1,53 @@
+cast($value, $type);
+        }
+        if ($type === PDO::PARAM_LOB) {
+            $this->_statement->bindParam($column, $value, $type, 0, PDO::SQLSRV_ENCODING_BINARY);
+        } else {
+            $this->_statement->bindValue($column, $value, $type);
+        }
+    }
+}
diff --git a/vendor/cakephp/database/Statement/StatementDecorator.php b/vendor/cakephp/database/Statement/StatementDecorator.php
new file mode 100644
index 0000000..2c2f46b
--- /dev/null
+++ b/vendor/cakephp/database/Statement/StatementDecorator.php
@@ -0,0 +1,373 @@
+
+ */
+class StatementDecorator implements StatementInterface, Countable, IteratorAggregate
+{
+    use TypeConverterTrait;
+
+    /**
+     * Statement instance implementation, such as PDOStatement
+     * or any other custom implementation.
+     *
+     * @var \Cake\Database\StatementInterface
+     */
+    protected $_statement;
+
+    /**
+     * Reference to the driver object associated to this statement.
+     *
+     * @var \Cake\Database\DriverInterface
+     */
+    protected $_driver;
+
+    /**
+     * Whether this statement has already been executed
+     *
+     * @var bool
+     */
+    protected $_hasExecuted = false;
+
+    /**
+     * Constructor
+     *
+     * @param \Cake\Database\StatementInterface $statement Statement implementation
+     *  such as PDOStatement.
+     * @param \Cake\Database\DriverInterface $driver Driver instance
+     */
+    public function __construct(StatementInterface $statement, DriverInterface $driver)
+    {
+        $this->_statement = $statement;
+        $this->_driver = $driver;
+    }
+
+    /**
+     * Returns the connection driver.
+     *
+     * @return \Cake\Database\DriverInterface
+     */
+    protected function getDriver(): DriverInterface
+    {
+        return $this->_driver;
+    }
+
+    /**
+     * Magic getter to return $queryString as read-only.
+     *
+     * @param string $property internal property to get
+     * @return string|null
+     */
+    public function __get(string $property)
+    {
+        if ($property === 'queryString') {
+            /** @psalm-suppress NoInterfaceProperties */
+            return $this->_statement->queryString;
+        }
+
+        return null;
+    }
+
+    /**
+     * Assign a value to a positional or named variable in prepared query. If using
+     * positional variables you need to start with index one, if using named params then
+     * just use the name in any order.
+     *
+     * It is not allowed to combine positional and named variables in the same statement.
+     *
+     * ### Examples:
+     *
+     * ```
+     * $statement->bindValue(1, 'a title');
+     * $statement->bindValue('active', true, 'boolean');
+     * $statement->bindValue(5, new \DateTime(), 'date');
+     * ```
+     *
+     * @param string|int $column name or param position to be bound
+     * @param mixed $value The value to bind to variable in query
+     * @param string|int|null $type name of configured Type class
+     * @return void
+     */
+    public function bindValue($column, $value, $type = 'string'): void
+    {
+        $this->_statement->bindValue($column, $value, $type);
+    }
+
+    /**
+     * Closes a cursor in the database, freeing up any resources and memory
+     * allocated to it. In most cases you don't need to call this method, as it is
+     * automatically called after fetching all results from the result set.
+     *
+     * @return void
+     */
+    public function closeCursor(): void
+    {
+        $this->_statement->closeCursor();
+    }
+
+    /**
+     * Returns the number of columns this statement's results will contain.
+     *
+     * ### Example:
+     *
+     * ```
+     * $statement = $connection->prepare('SELECT id, title from articles');
+     * $statement->execute();
+     * echo $statement->columnCount(); // outputs 2
+     * ```
+     *
+     * @return int
+     */
+    public function columnCount(): int
+    {
+        return $this->_statement->columnCount();
+    }
+
+    /**
+     * Returns the error code for the last error that occurred when executing this statement.
+     *
+     * @return string|int
+     */
+    public function errorCode()
+    {
+        return $this->_statement->errorCode();
+    }
+
+    /**
+     * Returns the error information for the last error that occurred when executing
+     * this statement.
+     *
+     * @return array
+     */
+    public function errorInfo(): array
+    {
+        return $this->_statement->errorInfo();
+    }
+
+    /**
+     * Executes the statement by sending the SQL query to the database. It can optionally
+     * take an array or arguments to be bound to the query variables. Please note
+     * that binding parameters from this method will not perform any custom type conversion
+     * as it would normally happen when calling `bindValue`.
+     *
+     * @param array|null $params list of values to be bound to query
+     * @return bool true on success, false otherwise
+     */
+    public function execute(?array $params = null): bool
+    {
+        $this->_hasExecuted = true;
+
+        return $this->_statement->execute($params);
+    }
+
+    /**
+     * Returns the next row for the result set after executing this statement.
+     * Rows can be fetched to contain columns as names or positions. If no
+     * rows are left in result set, this method will return false.
+     *
+     * ### Example:
+     *
+     * ```
+     * $statement = $connection->prepare('SELECT id, title from articles');
+     * $statement->execute();
+     * print_r($statement->fetch('assoc')); // will show ['id' => 1, 'title' => 'a title']
+     * ```
+     *
+     * @param string|int $type 'num' for positional columns, assoc for named columns
+     * @return mixed Result array containing columns and values or false if no results
+     * are left
+     */
+    public function fetch($type = self::FETCH_TYPE_NUM)
+    {
+        return $this->_statement->fetch($type);
+    }
+
+    /**
+     * Returns the next row in a result set as an associative array. Calling this function is the same as calling
+     * $statement->fetch(StatementDecorator::FETCH_TYPE_ASSOC). If no results are found an empty array is returned.
+     *
+     * @return array
+     */
+    public function fetchAssoc(): array
+    {
+        $result = $this->fetch(static::FETCH_TYPE_ASSOC);
+
+        return $result ?: [];
+    }
+
+    /**
+     * Returns the value of the result at position.
+     *
+     * @param int $position The numeric position of the column to retrieve in the result
+     * @return mixed Returns the specific value of the column designated at $position
+     */
+    public function fetchColumn(int $position)
+    {
+        $result = $this->fetch(static::FETCH_TYPE_NUM);
+        if ($result && isset($result[$position])) {
+            return $result[$position];
+        }
+
+        return false;
+    }
+
+    /**
+     * Returns an array with all rows resulting from executing this statement.
+     *
+     * ### Example:
+     *
+     * ```
+     * $statement = $connection->prepare('SELECT id, title from articles');
+     * $statement->execute();
+     * print_r($statement->fetchAll('assoc')); // will show [0 => ['id' => 1, 'title' => 'a title']]
+     * ```
+     *
+     * @param string|int $type num for fetching columns as positional keys or assoc for column names as keys
+     * @return array|false List of all results from database for this statement. False on failure.
+     */
+    public function fetchAll($type = self::FETCH_TYPE_NUM)
+    {
+        return $this->_statement->fetchAll($type);
+    }
+
+    /**
+     * Returns the number of rows affected by this SQL statement.
+     *
+     * ### Example:
+     *
+     * ```
+     * $statement = $connection->prepare('SELECT id, title from articles');
+     * $statement->execute();
+     * print_r($statement->rowCount()); // will show 1
+     * ```
+     *
+     * @return int
+     */
+    public function rowCount(): int
+    {
+        return $this->_statement->rowCount();
+    }
+
+    /**
+     * Statements are iterable as arrays, this method will return
+     * the iterator object for traversing all items in the result.
+     *
+     * ### Example:
+     *
+     * ```
+     * $statement = $connection->prepare('SELECT id, title from articles');
+     * foreach ($statement as $row) {
+     *   //do stuff
+     * }
+     * ```
+     *
+     * @return \Cake\Database\StatementInterface
+     * @psalm-suppress ImplementedReturnTypeMismatch
+     */
+    #[\ReturnTypeWillChange]
+    public function getIterator()
+    {
+        if (!$this->_hasExecuted) {
+            $this->execute();
+        }
+
+        return $this->_statement;
+    }
+
+    /**
+     * Statements can be passed as argument for count() to return the number
+     * for affected rows from last execution.
+     *
+     * @return int
+     */
+    public function count(): int
+    {
+        return $this->rowCount();
+    }
+
+    /**
+     * Binds a set of values to statement object with corresponding type.
+     *
+     * @param array $params list of values to be bound
+     * @param array $types list of types to be used, keys should match those in $params
+     * @return void
+     */
+    public function bind(array $params, array $types): void
+    {
+        if (empty($params)) {
+            return;
+        }
+
+        $anonymousParams = is_int(key($params));
+        $offset = 1;
+        foreach ($params as $index => $value) {
+            $type = $types[$index] ?? null;
+            if ($anonymousParams) {
+                /** @psalm-suppress InvalidOperand */
+                $index += $offset;
+            }
+            $this->bindValue($index, $value, $type);
+        }
+    }
+
+    /**
+     * Returns the latest primary inserted using this statement.
+     *
+     * @param string|null $table table name or sequence to get last insert value from
+     * @param string|null $column the name of the column representing the primary key
+     * @return string|int
+     */
+    public function lastInsertId(?string $table = null, ?string $column = null)
+    {
+        if ($column && $this->columnCount()) {
+            $row = $this->fetch(static::FETCH_TYPE_ASSOC);
+
+            if ($row && isset($row[$column])) {
+                return $row[$column];
+            }
+        }
+
+        return $this->_driver->lastInsertId($table, $column);
+    }
+
+    /**
+     * Returns the statement object that was decorated by this class.
+     *
+     * @return \Cake\Database\StatementInterface
+     */
+    public function getInnerStatement()
+    {
+        return $this->_statement;
+    }
+}
diff --git a/vendor/cakephp/database/StatementInterface.php b/vendor/cakephp/database/StatementInterface.php
new file mode 100644
index 0000000..dc5bbc6
--- /dev/null
+++ b/vendor/cakephp/database/StatementInterface.php
@@ -0,0 +1,203 @@
+bindValue(1, 'a title');
+     * $statement->bindValue('active', true, 'boolean');
+     * $statement->bindValue(5, new \DateTime(), 'date');
+     * ```
+     *
+     * @param string|int $column name or param position to be bound
+     * @param mixed $value The value to bind to variable in query
+     * @param string|int|null $type name of configured Type class, or PDO type constant.
+     * @return void
+     */
+    public function bindValue($column, $value, $type = 'string'): void;
+
+    /**
+     * Closes a cursor in the database, freeing up any resources and memory
+     * allocated to it. In most cases you don't need to call this method, as it is
+     * automatically called after fetching all results from the result set.
+     *
+     * @return void
+     */
+    public function closeCursor(): void;
+
+    /**
+     * Returns the number of columns this statement's results will contain
+     *
+     * ### Example:
+     *
+     * ```
+     *  $statement = $connection->prepare('SELECT id, title from articles');
+     *  $statement->execute();
+     *  echo $statement->columnCount(); // outputs 2
+     * ```
+     *
+     * @return int
+     */
+    public function columnCount(): int;
+
+    /**
+     * Returns the error code for the last error that occurred when executing this statement
+     *
+     * @return string|int
+     */
+    public function errorCode();
+
+    /**
+     * Returns the error information for the last error that occurred when executing
+     * this statement
+     *
+     * @return array
+     */
+    public function errorInfo(): array;
+
+    /**
+     * Executes the statement by sending the SQL query to the database. It can optionally
+     * take an array or arguments to be bound to the query variables. Please note
+     * that binding parameters from this method will not perform any custom type conversion
+     * as it would normally happen when calling `bindValue`
+     *
+     * @param array|null $params list of values to be bound to query
+     * @return bool true on success, false otherwise
+     */
+    public function execute(?array $params = null): bool;
+
+    /**
+     * Returns the next row for the result set after executing this statement.
+     * Rows can be fetched to contain columns as names or positions. If no
+     * rows are left in result set, this method will return false
+     *
+     * ### Example:
+     *
+     * ```
+     *  $statement = $connection->prepare('SELECT id, title from articles');
+     *  $statement->execute();
+     *  print_r($statement->fetch('assoc')); // will show ['id' => 1, 'title' => 'a title']
+     * ```
+     *
+     * @param string|int $type 'num' for positional columns, assoc for named columns, or PDO fetch mode constants.
+     * @return mixed Result array containing columns and values or false if no results
+     * are left
+     */
+    public function fetch($type = 'num');
+
+    /**
+     * Returns an array with all rows resulting from executing this statement
+     *
+     * ### Example:
+     *
+     * ```
+     *  $statement = $connection->prepare('SELECT id, title from articles');
+     *  $statement->execute();
+     *  print_r($statement->fetchAll('assoc')); // will show [0 => ['id' => 1, 'title' => 'a title']]
+     * ```
+     *
+     * @param string|int $type num for fetching columns as positional keys or assoc for column names as keys
+     * @return array|false list of all results from database for this statement or false on failure.
+     */
+    public function fetchAll($type = 'num');
+
+    /**
+     * Returns the value of the result at position.
+     *
+     * @param int $position The numeric position of the column to retrieve in the result
+     * @return mixed Returns the specific value of the column designated at $position
+     */
+    public function fetchColumn(int $position);
+
+    /**
+     * Returns the number of rows affected by this SQL statement
+     *
+     * ### Example:
+     *
+     * ```
+     *  $statement = $connection->prepare('SELECT id, title from articles');
+     *  $statement->execute();
+     *  print_r($statement->rowCount()); // will show 1
+     * ```
+     *
+     * @return int
+     */
+    public function rowCount(): int;
+
+    /**
+     * Statements can be passed as argument for count()
+     * to return the number for affected rows from last execution
+     *
+     * @return int
+     */
+    public function count(): int;
+
+    /**
+     * Binds a set of values to statement object with corresponding type
+     *
+     * @param array $params list of values to be bound
+     * @param array $types list of types to be used, keys should match those in $params
+     * @return void
+     */
+    public function bind(array $params, array $types): void;
+
+    /**
+     * Returns the latest primary inserted using this statement
+     *
+     * @param string|null $table table name or sequence to get last insert value from
+     * @param string|null $column the name of the column representing the primary key
+     * @return string|int
+     */
+    public function lastInsertId(?string $table = null, ?string $column = null);
+}
diff --git a/vendor/cakephp/database/Type.php b/vendor/cakephp/database/Type.php
new file mode 100644
index 0000000..164419c
--- /dev/null
+++ b/vendor/cakephp/database/Type.php
@@ -0,0 +1,9 @@
+_name = $name;
+    }
+
+    /**
+     * @inheritDoc
+     */
+    public function getName(): ?string
+    {
+        return $this->_name;
+    }
+
+    /**
+     * @inheritDoc
+     */
+    public function getBaseType(): ?string
+    {
+        return $this->_name;
+    }
+
+    /**
+     * @inheritDoc
+     */
+    public function toStatement($value, DriverInterface $driver)
+    {
+        if ($value === null) {
+            return PDO::PARAM_NULL;
+        }
+
+        return PDO::PARAM_STR;
+    }
+
+    /**
+     * @inheritDoc
+     */
+    public function newId()
+    {
+        return null;
+    }
+}
diff --git a/vendor/cakephp/database/Type/BatchCastingInterface.php b/vendor/cakephp/database/Type/BatchCastingInterface.php
new file mode 100644
index 0000000..8761f1c
--- /dev/null
+++ b/vendor/cakephp/database/Type/BatchCastingInterface.php
@@ -0,0 +1,37 @@
+ $fields The field keys to cast
+     * @param \Cake\Database\DriverInterface $driver Object from which database preferences and configuration will be extracted.
+     * @return array
+     */
+    public function manyToPHP(array $values, array $fields, DriverInterface $driver): array;
+}
diff --git a/vendor/cakephp/database/Type/BinaryType.php b/vendor/cakephp/database/Type/BinaryType.php
new file mode 100644
index 0000000..e570f53
--- /dev/null
+++ b/vendor/cakephp/database/Type/BinaryType.php
@@ -0,0 +1,92 @@
+convertStringToBinaryUuid($value);
+    }
+
+    /**
+     * Generate a new binary UUID
+     *
+     * @return string A new primary key value.
+     */
+    public function newId(): string
+    {
+        return Text::uuid();
+    }
+
+    /**
+     * Convert binary uuid into resource handles
+     *
+     * @param mixed $value The value to convert.
+     * @param \Cake\Database\DriverInterface $driver The driver instance to convert with.
+     * @return resource|string|null
+     * @throws \Cake\Core\Exception\CakeException
+     */
+    public function toPHP($value, DriverInterface $driver)
+    {
+        if ($value === null) {
+            return null;
+        }
+        if (is_string($value)) {
+            return $this->convertBinaryUuidToString($value);
+        }
+        if (is_resource($value)) {
+            return $value;
+        }
+
+        throw new CakeException(sprintf('Unable to convert %s into binary uuid.', gettype($value)));
+    }
+
+    /**
+     * Get the correct PDO binding type for Binary data.
+     *
+     * @param mixed $value The value being bound.
+     * @param \Cake\Database\DriverInterface $driver The driver.
+     * @return int
+     */
+    public function toStatement($value, DriverInterface $driver): int
+    {
+        return PDO::PARAM_LOB;
+    }
+
+    /**
+     * Marshals flat data into PHP objects.
+     *
+     * Most useful for converting request data into PHP objects
+     * that make sense for the rest of the ORM/Database layers.
+     *
+     * @param mixed $value The value to convert.
+     * @return mixed Converted value.
+     */
+    public function marshal($value)
+    {
+        return $value;
+    }
+
+    /**
+     * Converts a binary uuid to a string representation
+     *
+     * @param mixed $binary The value to convert.
+     * @return string Converted value.
+     */
+    protected function convertBinaryUuidToString($binary): string
+    {
+        $string = unpack('H*', $binary);
+
+        $string = preg_replace(
+            '/([0-9a-f]{8})([0-9a-f]{4})([0-9a-f]{4})([0-9a-f]{4})([0-9a-f]{12})/',
+            '$1-$2-$3-$4-$5',
+            $string
+        );
+
+        return $string[1];
+    }
+
+    /**
+     * Converts a string UUID (36 or 32 char) to a binary representation.
+     *
+     * @param string $string The value to convert.
+     * @return string Converted value.
+     */
+    protected function convertStringToBinaryUuid($string): string
+    {
+        $string = str_replace('-', '', $string);
+
+        return pack('H*', $string);
+    }
+}
diff --git a/vendor/cakephp/database/Type/BoolType.php b/vendor/cakephp/database/Type/BoolType.php
new file mode 100644
index 0000000..0bb8b0a
--- /dev/null
+++ b/vendor/cakephp/database/Type/BoolType.php
@@ -0,0 +1,126 @@
+|null Array of column information, or `null` in case the column isn't processed by this type.
+     */
+    public function convertColumnDefinition(array $definition, DriverInterface $driver): ?array;
+}
diff --git a/vendor/cakephp/database/Type/DateTimeFractionalType.php b/vendor/cakephp/database/Type/DateTimeFractionalType.php
new file mode 100644
index 0000000..3cc149d
--- /dev/null
+++ b/vendor/cakephp/database/Type/DateTimeFractionalType.php
@@ -0,0 +1,42 @@
+
+     */
+    protected $_marshalFormats = [
+        'Y-m-d H:i',
+        'Y-m-d H:i:s',
+        'Y-m-d\TH:i',
+        'Y-m-d\TH:i:s',
+        'Y-m-d\TH:i:sP',
+    ];
+
+    /**
+     * Whether `marshal()` should use locale-aware parser with `_localeMarshalFormat`.
+     *
+     * @var bool
+     */
+    protected $_useLocaleMarshal = false;
+
+    /**
+     * The locale-aware format `marshal()` uses when `_useLocaleParser` is true.
+     *
+     * See `Cake\I18n\Time::parseDateTime()` for accepted formats.
+     *
+     * @var array|string|int
+     */
+    protected $_localeMarshalFormat;
+
+    /**
+     * The classname to use when creating objects.
+     *
+     * @var string
+     * @psalm-var class-string<\DateTime>|class-string<\DateTimeImmutable>
+     */
+    protected $_className;
+
+    /**
+     * Database time zone.
+     *
+     * @var \DateTimeZone|null
+     */
+    protected $dbTimezone;
+
+    /**
+     * User time zone.
+     *
+     * @var \DateTimeZone|null
+     */
+    protected $userTimezone;
+
+    /**
+     * Default time zone.
+     *
+     * @var \DateTimeZone
+     */
+    protected $defaultTimezone;
+
+    /**
+     * Whether database time zone is kept when converting
+     *
+     * @var bool
+     */
+    protected $keepDatabaseTimezone = false;
+
+    /**
+     * {@inheritDoc}
+     *
+     * @param string|null $name The name identifying this type
+     */
+    public function __construct(?string $name = null)
+    {
+        parent::__construct($name);
+
+        $this->defaultTimezone = new DateTimeZone(date_default_timezone_get());
+        $this->_setClassName(FrozenTime::class, DateTimeImmutable::class);
+    }
+
+    /**
+     * Convert DateTime instance into strings.
+     *
+     * @param mixed $value The value to convert.
+     * @param \Cake\Database\DriverInterface $driver The driver instance to convert with.
+     * @return string|null
+     */
+    public function toDatabase($value, DriverInterface $driver): ?string
+    {
+        if ($value === null || is_string($value)) {
+            return $value;
+        }
+        if (is_int($value)) {
+            $class = $this->_className;
+            $value = new $class('@' . $value);
+        }
+
+        if (
+            $this->dbTimezone !== null
+            && $this->dbTimezone->getName() !== $value->getTimezone()->getName()
+        ) {
+            if (!$value instanceof DateTimeImmutable) {
+                $value = clone $value;
+            }
+            $value = $value->setTimezone($this->dbTimezone);
+        }
+
+        return $value->format($this->_format);
+    }
+
+    /**
+     * Alias for `setDatabaseTimezone()`.
+     *
+     * @param \DateTimeZone|string|null $timezone Database timezone.
+     * @return $this
+     * @deprecated 4.1.0 Use {@link setDatabaseTimezone()} instead.
+     */
+    public function setTimezone($timezone)
+    {
+        deprecationWarning('DateTimeType::setTimezone() is deprecated. Use setDatabaseTimezone() instead.');
+
+        return $this->setDatabaseTimezone($timezone);
+    }
+
+    /**
+     * Set database timezone.
+     *
+     * This is the time zone used when converting database strings to DateTime
+     * instances and converting DateTime instances to database strings.
+     *
+     * @see DateTimeType::setKeepDatabaseTimezone
+     * @param \DateTimeZone|string|null $timezone Database timezone.
+     * @return $this
+     */
+    public function setDatabaseTimezone($timezone)
+    {
+        if (is_string($timezone)) {
+            $timezone = new DateTimeZone($timezone);
+        }
+        $this->dbTimezone = $timezone;
+
+        return $this;
+    }
+
+    /**
+     * Set user timezone.
+     *
+     * This is the time zone used when marshalling strings to DateTime instances.
+     *
+     * @param \DateTimeZone|string|null $timezone User timezone.
+     * @return $this
+     */
+    public function setUserTimezone($timezone)
+    {
+        if (is_string($timezone)) {
+            $timezone = new DateTimeZone($timezone);
+        }
+        $this->userTimezone = $timezone;
+
+        return $this;
+    }
+
+    /**
+     * {@inheritDoc}
+     *
+     * @param mixed $value Value to be converted to PHP equivalent
+     * @param \Cake\Database\DriverInterface $driver Object from which database preferences and configuration will be extracted
+     * @return \DateTimeInterface|null
+     */
+    public function toPHP($value, DriverInterface $driver)
+    {
+        if ($value === null) {
+            return null;
+        }
+
+        $class = $this->_className;
+        if (is_int($value)) {
+            $instance = new $class('@' . $value);
+        } elseif (strpos($value, '0000-00-00') === 0) {
+            return null;
+        } else {
+            $instance = new $class($value, $this->dbTimezone);
+        }
+
+        if (
+            !$this->keepDatabaseTimezone &&
+            $instance->getTimezone()->getName() !== $this->defaultTimezone->getName()
+        ) {
+            $instance = $instance->setTimezone($this->defaultTimezone);
+        }
+
+        if ($this->setToDateStart) {
+            $instance = $instance->setTime(0, 0, 0);
+        }
+
+        return $instance;
+    }
+
+    /**
+     * Set whether DateTime object created from database string is converted
+     * to default time zone.
+     *
+     * If your database date times are in a specific time zone that you want
+     * to keep in the DateTime instance then set this to true.
+     *
+     * When false, datetime timezones are converted to default time zone.
+     * This is default behavior.
+     *
+     * @param bool $keep If true, database time zone is kept when converting
+     *      to DateTime instances.
+     * @return $this
+     */
+    public function setKeepDatabaseTimezone(bool $keep)
+    {
+        $this->keepDatabaseTimezone = $keep;
+
+        return $this;
+    }
+
+    /**
+     * @inheritDoc
+     */
+    public function manyToPHP(array $values, array $fields, DriverInterface $driver): array
+    {
+        foreach ($fields as $field) {
+            if (!isset($values[$field])) {
+                continue;
+            }
+
+            $value = $values[$field];
+
+            $class = $this->_className;
+            if (is_int($value)) {
+                $instance = new $class('@' . $value);
+            } elseif (strpos($value, '0000-00-00') === 0) {
+                $values[$field] = null;
+                continue;
+            } else {
+                $instance = new $class($value, $this->dbTimezone);
+            }
+
+            if (
+                !$this->keepDatabaseTimezone &&
+                $instance->getTimezone()->getName() !== $this->defaultTimezone->getName()
+            ) {
+                $instance = $instance->setTimezone($this->defaultTimezone);
+            }
+
+            if ($this->setToDateStart) {
+                $instance = $instance->setTime(0, 0, 0);
+            }
+
+            $values[$field] = $instance;
+        }
+
+        return $values;
+    }
+
+    /**
+     * Convert request data into a datetime object.
+     *
+     * @param mixed $value Request data
+     * @return \DateTimeInterface|null
+     */
+    public function marshal($value): ?DateTimeInterface
+    {
+        if ($value instanceof DateTimeInterface) {
+            if ($value instanceof DateTime) {
+                $value = clone $value;
+            }
+
+            if ($value instanceof ChronosDate) {
+                return $value;
+            }
+
+            /** @var \Datetime|\DateTimeImmutable $value */
+            return $value->setTimezone($this->defaultTimezone);
+        }
+
+        /** @var class-string<\DateTimeInterface> $class */
+        $class = $this->_className;
+        try {
+            if ($value === '' || $value === null || is_bool($value)) {
+                return null;
+            }
+
+            if (is_int($value) || (is_string($value) && ctype_digit($value))) {
+                /** @var \DateTime|\DateTimeImmutable $dateTime */
+                $dateTime = new $class('@' . $value);
+
+                return $dateTime->setTimezone($this->defaultTimezone);
+            }
+
+            if (is_string($value)) {
+                if ($this->_useLocaleMarshal) {
+                    $dateTime = $this->_parseLocaleValue($value);
+                } else {
+                    $dateTime = $this->_parseValue($value);
+                }
+
+                /** @var \DateTime|\DateTimeImmutable $dateTime */
+                if ($dateTime !== null) {
+                    $dateTime = $dateTime->setTimezone($this->defaultTimezone);
+                }
+
+                return $dateTime;
+            }
+        } catch (Exception $e) {
+            return null;
+        }
+
+        if (is_array($value) && implode('', $value) === '') {
+            return null;
+        }
+        $value += ['hour' => 0, 'minute' => 0, 'second' => 0, 'microsecond' => 0];
+
+        $format = '';
+        if (
+            isset($value['year'], $value['month'], $value['day']) &&
+            (
+                is_numeric($value['year']) &&
+                is_numeric($value['month']) &&
+                is_numeric($value['day'])
+            )
+        ) {
+            $format .= sprintf('%d-%02d-%02d', $value['year'], $value['month'], $value['day']);
+        }
+
+        if (isset($value['meridian']) && (int)$value['hour'] === 12) {
+            $value['hour'] = 0;
+        }
+        if (isset($value['meridian'])) {
+            $value['hour'] = strtolower($value['meridian']) === 'am' ? $value['hour'] : $value['hour'] + 12;
+        }
+        $format .= sprintf(
+            '%s%02d:%02d:%02d.%06d',
+            empty($format) ? '' : ' ',
+            $value['hour'],
+            $value['minute'],
+            $value['second'],
+            $value['microsecond']
+        );
+
+        /** @var \DateTime|\DateTimeImmutable $dateTime */
+        $dateTime = new $class($format, $value['timezone'] ?? $this->userTimezone);
+
+        return $dateTime->setTimezone($this->defaultTimezone);
+    }
+
+    /**
+     * Sets whether to parse strings passed to `marshal()` using
+     * the locale-aware format set by `setLocaleFormat()`.
+     *
+     * @param bool $enable Whether to enable
+     * @return $this
+     */
+    public function useLocaleParser(bool $enable = true)
+    {
+        if ($enable === false) {
+            $this->_useLocaleMarshal = $enable;
+
+            return $this;
+        }
+        if (is_subclass_of($this->_className, I18nDateTimeInterface::class)) {
+            $this->_useLocaleMarshal = $enable;
+
+            return $this;
+        }
+        throw new RuntimeException(
+            sprintf('Cannot use locale parsing with the %s class', $this->_className)
+        );
+    }
+
+    /**
+     * Sets the locale-aware format used by `marshal()` when parsing strings.
+     *
+     * See `Cake\I18n\Time::parseDateTime()` for accepted formats.
+     *
+     * @param array|string $format The locale-aware format
+     * @see \Cake\I18n\Time::parseDateTime()
+     * @return $this
+     */
+    public function setLocaleFormat($format)
+    {
+        $this->_localeMarshalFormat = $format;
+
+        return $this;
+    }
+
+    /**
+     * Change the preferred class name to the FrozenTime implementation.
+     *
+     * @return $this
+     * @deprecated 4.3.0 This method is no longer needed as using immutable datetime class is the default behavior.
+     */
+    public function useImmutable()
+    {
+        deprecationWarning(
+            'Configuring immutable or mutable classes is deprecated and immutable'
+            . ' classes will be the permanent configuration in 5.0. Calling `useImmutable()` is unnecessary.'
+        );
+
+        $this->_setClassName(FrozenTime::class, DateTimeImmutable::class);
+
+        return $this;
+    }
+
+    /**
+     * Set the classname to use when building objects.
+     *
+     * @param string $class The classname to use.
+     * @param string $fallback The classname to use when the preferred class does not exist.
+     * @return void
+     * @psalm-param class-string<\DateTime>|class-string<\DateTimeImmutable> $class
+     * @psalm-param class-string<\DateTime>|class-string<\DateTimeImmutable> $fallback
+     */
+    protected function _setClassName(string $class, string $fallback): void
+    {
+        if (!class_exists($class)) {
+            $class = $fallback;
+        }
+        $this->_className = $class;
+    }
+
+    /**
+     * Get the classname used for building objects.
+     *
+     * @return string
+     * @psalm-return class-string<\DateTime>|class-string<\DateTimeImmutable>
+     */
+    public function getDateTimeClassName(): string
+    {
+        return $this->_className;
+    }
+
+    /**
+     * Change the preferred class name to the mutable Time implementation.
+     *
+     * @return $this
+     * @deprecated 4.3.0 Using mutable datetime objects is deprecated.
+     */
+    public function useMutable()
+    {
+        deprecationWarning(
+            'Configuring immutable or mutable classes is deprecated and immutable'
+            . ' classes will be the permanent configuration in 5.0. Calling `useImmutable()` is unnecessary.'
+        );
+
+        $this->_setClassName(Time::class, DateTime::class);
+
+        return $this;
+    }
+
+    /**
+     * Converts a string into a DateTime object after parsing it using the locale
+     * aware parser with the format set by `setLocaleFormat()`.
+     *
+     * @param string $value The value to parse and convert to an object.
+     * @return \Cake\I18n\I18nDateTimeInterface|null
+     */
+    protected function _parseLocaleValue(string $value): ?I18nDateTimeInterface
+    {
+        /** @psalm-var class-string<\Cake\I18n\I18nDateTimeInterface> $class */
+        $class = $this->_className;
+
+        return $class::parseDateTime($value, $this->_localeMarshalFormat, $this->userTimezone);
+    }
+
+    /**
+     * Converts a string into a DateTime object after parsing it using the
+     * formats in `_marshalFormats`.
+     *
+     * @param string $value The value to parse and convert to an object.
+     * @return \DateTimeInterface|null
+     */
+    protected function _parseValue(string $value): ?DateTimeInterface
+    {
+        $class = $this->_className;
+
+        foreach ($this->_marshalFormats as $format) {
+            try {
+                $dateTime = $class::createFromFormat($format, $value, $this->userTimezone);
+                // Check for false in case DateTime is used directly
+                if ($dateTime !== false) {
+                    return $dateTime;
+                }
+            } catch (InvalidArgumentException $e) {
+                // Chronos wraps DateTime::createFromFormat and throws
+                // exception if parse fails.
+                continue;
+            }
+        }
+
+        return null;
+    }
+
+    /**
+     * Casts given value to Statement equivalent
+     *
+     * @param mixed $value value to be converted to PDO statement
+     * @param \Cake\Database\DriverInterface $driver object from which database preferences and configuration will be extracted
+     * @return mixed
+     */
+    public function toStatement($value, DriverInterface $driver)
+    {
+        return PDO::PARAM_STR;
+    }
+}
diff --git a/vendor/cakephp/database/Type/DateType.php b/vendor/cakephp/database/Type/DateType.php
new file mode 100644
index 0000000..0cd63cd
--- /dev/null
+++ b/vendor/cakephp/database/Type/DateType.php
@@ -0,0 +1,174 @@
+_setClassName(FrozenDate::class, DateTimeImmutable::class);
+    }
+
+    /**
+     * Change the preferred class name to the FrozenDate implementation.
+     *
+     * @return $this
+     * @deprecated 4.3.0 This method is no longer needed as using immutable datetime class is the default behavior.
+     */
+    public function useImmutable()
+    {
+        deprecationWarning(
+            'Configuring immutable or mutable classes is deprecated and immutable'
+            . ' classes will be the permanent configuration in 5.0. Calling `useImmutable()` is unnecessary.'
+        );
+
+        $this->_setClassName(FrozenDate::class, DateTimeImmutable::class);
+
+        return $this;
+    }
+
+    /**
+     * Change the preferred class name to the mutable Date implementation.
+     *
+     * @return $this
+     * @deprecated 4.3.0 Using mutable datetime objects is deprecated.
+     */
+    public function useMutable()
+    {
+        deprecationWarning(
+            'Configuring immutable or mutable classes is deprecated and immutable'
+            . ' classes will be the permanent configuration in 5.0. Calling `useImmutable()` is unnecessary.'
+        );
+
+        $this->_setClassName(Date::class, DateTime::class);
+
+        return $this;
+    }
+
+    /**
+     * Convert request data into a datetime object.
+     *
+     * @param mixed $value Request data
+     * @return \DateTimeInterface|null
+     */
+    public function marshal($value): ?DateTimeInterface
+    {
+        if ($value instanceof DateTimeInterface) {
+            return new FrozenDate($value);
+        }
+
+        /** @var class-string<\Cake\Chronos\ChronosDate> $class */
+        $class = $this->_className;
+        try {
+            if ($value === '' || $value === null || is_bool($value)) {
+                return null;
+            }
+
+            if (is_int($value) || (is_string($value) && ctype_digit($value))) {
+                /** @var \Cake\I18n\FrozenDate|\DateTimeImmutable $dateTime */
+                $dateTime = new $class('@' . $value);
+
+                return $dateTime;
+            }
+
+            if (is_string($value)) {
+                if ($this->_useLocaleMarshal) {
+                    $dateTime = $this->_parseLocaleValue($value);
+                } else {
+                    $dateTime = $this->_parseValue($value);
+                }
+
+                return $dateTime;
+            }
+        } catch (Exception $e) {
+            return null;
+        }
+
+        if (is_array($value) && implode('', $value) === '') {
+            return null;
+        }
+        $format = '';
+        if (
+            isset($value['year'], $value['month'], $value['day']) &&
+            (
+                is_numeric($value['year']) &&
+                is_numeric($value['month']) &&
+                is_numeric($value['day'])
+            )
+        ) {
+            $format .= sprintf('%d-%02d-%02d', $value['year'], $value['month'], $value['day']);
+        }
+
+        if (empty($format)) {
+            // Invalid array format.
+            return null;
+        }
+
+        /** @var \Cake\I18n\FrozenDate|\DateTimeImmutable $dateTime */
+        $dateTime = new $class($format);
+
+        return $dateTime;
+    }
+
+    /**
+     * @inheritDoc
+     */
+    protected function _parseLocaleValue(string $value): ?I18nDateTimeInterface
+    {
+        /** @psalm-var class-string<\Cake\I18n\I18nDateTimeInterface> $class */
+        $class = $this->_className;
+
+        return $class::parseDate($value, $this->_localeMarshalFormat);
+    }
+}
diff --git a/vendor/cakephp/database/Type/DecimalType.php b/vendor/cakephp/database/Type/DecimalType.php
new file mode 100644
index 0000000..f06f6d7
--- /dev/null
+++ b/vendor/cakephp/database/Type/DecimalType.php
@@ -0,0 +1,190 @@
+_useLocaleParser) {
+            return $this->_parseValue($value);
+        }
+        if (is_numeric($value)) {
+            return (string)$value;
+        }
+        if (is_string($value) && preg_match('/^[0-9,. ]+$/', $value)) {
+            return $value;
+        }
+
+        return null;
+    }
+
+    /**
+     * Sets whether to parse numbers passed to the marshal() function
+     * by using a locale aware parser.
+     *
+     * @param bool $enable Whether to enable
+     * @return $this
+     * @throws \RuntimeException
+     */
+    public function useLocaleParser(bool $enable = true)
+    {
+        if ($enable === false) {
+            $this->_useLocaleParser = $enable;
+
+            return $this;
+        }
+        if (
+            static::$numberClass === Number::class ||
+            is_subclass_of(static::$numberClass, Number::class)
+        ) {
+            $this->_useLocaleParser = $enable;
+
+            return $this;
+        }
+        throw new RuntimeException(
+            sprintf('Cannot use locale parsing with the %s class', static::$numberClass)
+        );
+    }
+
+    /**
+     * Converts localized string into a decimal string after parsing it using
+     * the locale aware parser.
+     *
+     * @param string $value The value to parse and convert to an float.
+     * @return string
+     */
+    protected function _parseValue(string $value): string
+    {
+        /** @var \Cake\I18n\Number $class */
+        $class = static::$numberClass;
+
+        return (string)$class::parseFloat($value);
+    }
+}
diff --git a/vendor/cakephp/database/Type/ExpressionTypeCasterTrait.php b/vendor/cakephp/database/Type/ExpressionTypeCasterTrait.php
new file mode 100644
index 0000000..621bb9d
--- /dev/null
+++ b/vendor/cakephp/database/Type/ExpressionTypeCasterTrait.php
@@ -0,0 +1,80 @@
+toExpression($value);
+    }
+
+    /**
+     * Returns an array with the types that require values to
+     * be casted to expressions, out of the list of type names
+     * passed as parameter.
+     *
+     * @param array $types List of type names
+     * @return array
+     */
+    protected function _requiresToExpressionCasting(array $types): array
+    {
+        $result = [];
+        $types = array_filter($types);
+        foreach ($types as $k => $type) {
+            $object = TypeFactory::build($type);
+            if ($object instanceof ExpressionTypeInterface) {
+                $result[$k] = $object;
+            }
+        }
+
+        return $result;
+    }
+}
diff --git a/vendor/cakephp/database/Type/ExpressionTypeInterface.php b/vendor/cakephp/database/Type/ExpressionTypeInterface.php
new file mode 100644
index 0000000..7615cf9
--- /dev/null
+++ b/vendor/cakephp/database/Type/ExpressionTypeInterface.php
@@ -0,0 +1,36 @@
+_useLocaleParser) {
+            return $this->_parseValue($value);
+        }
+        if (is_numeric($value)) {
+            return (float)$value;
+        }
+        if (is_string($value) && preg_match('/^[0-9,. ]+$/', $value)) {
+            return $value;
+        }
+
+        return null;
+    }
+
+    /**
+     * Sets whether to parse numbers passed to the marshal() function
+     * by using a locale aware parser.
+     *
+     * @param bool $enable Whether to enable
+     * @return $this
+     */
+    public function useLocaleParser(bool $enable = true)
+    {
+        if ($enable === false) {
+            $this->_useLocaleParser = $enable;
+
+            return $this;
+        }
+        if (
+            static::$numberClass === Number::class ||
+            is_subclass_of(static::$numberClass, Number::class)
+        ) {
+            $this->_useLocaleParser = $enable;
+
+            return $this;
+        }
+        throw new RuntimeException(
+            sprintf('Cannot use locale parsing with the %s class', static::$numberClass)
+        );
+    }
+
+    /**
+     * Converts a string into a float point after parsing it using the locale
+     * aware parser.
+     *
+     * @param string $value The value to parse and convert to an float.
+     * @return float
+     */
+    protected function _parseValue(string $value): float
+    {
+        $class = static::$numberClass;
+
+        return $class::parseFloat($value);
+    }
+}
diff --git a/vendor/cakephp/database/Type/IntegerType.php b/vendor/cakephp/database/Type/IntegerType.php
new file mode 100644
index 0000000..973d7ca
--- /dev/null
+++ b/vendor/cakephp/database/Type/IntegerType.php
@@ -0,0 +1,129 @@
+checkNumeric($value);
+
+        return (int)$value;
+    }
+
+    /**
+     * {@inheritDoc}
+     *
+     * @param mixed $value The value to convert.
+     * @param \Cake\Database\DriverInterface $driver The driver instance to convert with.
+     * @return int|null
+     */
+    public function toPHP($value, DriverInterface $driver): ?int
+    {
+        if ($value === null) {
+            return null;
+        }
+
+        return (int)$value;
+    }
+
+    /**
+     * @inheritDoc
+     */
+    public function manyToPHP(array $values, array $fields, DriverInterface $driver): array
+    {
+        foreach ($fields as $field) {
+            if (!isset($values[$field])) {
+                continue;
+            }
+
+            $this->checkNumeric($values[$field]);
+
+            $values[$field] = (int)$values[$field];
+        }
+
+        return $values;
+    }
+
+    /**
+     * Get the correct PDO binding type for integer data.
+     *
+     * @param mixed $value The value being bound.
+     * @param \Cake\Database\DriverInterface $driver The driver.
+     * @return int
+     */
+    public function toStatement($value, DriverInterface $driver): int
+    {
+        return PDO::PARAM_INT;
+    }
+
+    /**
+     * Marshals request data into PHP integers.
+     *
+     * @param mixed $value The value to convert.
+     * @return int|null Converted value.
+     */
+    public function marshal($value): ?int
+    {
+        if ($value === null || $value === '') {
+            return null;
+        }
+        if (is_numeric($value)) {
+            return (int)$value;
+        }
+
+        return null;
+    }
+}
diff --git a/vendor/cakephp/database/Type/JsonType.php b/vendor/cakephp/database/Type/JsonType.php
new file mode 100644
index 0000000..5648d94
--- /dev/null
+++ b/vendor/cakephp/database/Type/JsonType.php
@@ -0,0 +1,124 @@
+_encodingOptions);
+    }
+
+    /**
+     * {@inheritDoc}
+     *
+     * @param mixed $value The value to convert.
+     * @param \Cake\Database\DriverInterface $driver The driver instance to convert with.
+     * @return array|string|null
+     */
+    public function toPHP($value, DriverInterface $driver)
+    {
+        if (!is_string($value)) {
+            return null;
+        }
+
+        return json_decode($value, true);
+    }
+
+    /**
+     * @inheritDoc
+     */
+    public function manyToPHP(array $values, array $fields, DriverInterface $driver): array
+    {
+        foreach ($fields as $field) {
+            if (!isset($values[$field])) {
+                continue;
+            }
+
+            $values[$field] = json_decode($values[$field], true);
+        }
+
+        return $values;
+    }
+
+    /**
+     * Get the correct PDO binding type for string data.
+     *
+     * @param mixed $value The value being bound.
+     * @param \Cake\Database\DriverInterface $driver The driver.
+     * @return int
+     */
+    public function toStatement($value, DriverInterface $driver): int
+    {
+        return PDO::PARAM_STR;
+    }
+
+    /**
+     * Marshals request data into a JSON compatible structure.
+     *
+     * @param mixed $value The value to convert.
+     * @return mixed Converted value.
+     */
+    public function marshal($value)
+    {
+        return $value;
+    }
+
+    /**
+     * Set json_encode options.
+     *
+     * @param int $options Encoding flags. Use JSON_* flags. Set `0` to reset.
+     * @return $this
+     * @see https://www.php.net/manual/en/function.json-encode.php
+     */
+    public function setEncodingOptions(int $options)
+    {
+        $this->_encodingOptions = $options;
+
+        return $this;
+    }
+}
diff --git a/vendor/cakephp/database/Type/OptionalConvertInterface.php b/vendor/cakephp/database/Type/OptionalConvertInterface.php
new file mode 100644
index 0000000..512683b
--- /dev/null
+++ b/vendor/cakephp/database/Type/OptionalConvertInterface.php
@@ -0,0 +1,32 @@
+__toString();
+        }
+
+        if (is_scalar($value)) {
+            return (string)$value;
+        }
+
+        throw new InvalidArgumentException(sprintf(
+            'Cannot convert value of type `%s` to string',
+            getTypeName($value)
+        ));
+    }
+
+    /**
+     * Convert string values to PHP strings.
+     *
+     * @param mixed $value The value to convert.
+     * @param \Cake\Database\DriverInterface $driver The driver instance to convert with.
+     * @return string|null
+     */
+    public function toPHP($value, DriverInterface $driver): ?string
+    {
+        if ($value === null) {
+            return null;
+        }
+
+        return (string)$value;
+    }
+
+    /**
+     * Get the correct PDO binding type for string data.
+     *
+     * @param mixed $value The value being bound.
+     * @param \Cake\Database\DriverInterface $driver The driver.
+     * @return int
+     */
+    public function toStatement($value, DriverInterface $driver): int
+    {
+        return PDO::PARAM_STR;
+    }
+
+    /**
+     * Marshals request data into PHP strings.
+     *
+     * @param mixed $value The value to convert.
+     * @return string|null Converted value.
+     */
+    public function marshal($value): ?string
+    {
+        if ($value === null || is_array($value)) {
+            return null;
+        }
+
+        return (string)$value;
+    }
+
+    /**
+     * {@inheritDoc}
+     *
+     * @return bool False as database results are returned already as strings
+     */
+    public function requiresToPhpCast(): bool
+    {
+        return false;
+    }
+}
diff --git a/vendor/cakephp/database/Type/TimeType.php b/vendor/cakephp/database/Type/TimeType.php
new file mode 100644
index 0000000..4c021e2
--- /dev/null
+++ b/vendor/cakephp/database/Type/TimeType.php
@@ -0,0 +1,52 @@
+ $class */
+        $class = $this->_className;
+
+        /** @psalm-suppress PossiblyInvalidArgument */
+        return $class::parseTime($value, $this->_localeMarshalFormat);
+    }
+}
diff --git a/vendor/cakephp/database/Type/UuidType.php b/vendor/cakephp/database/Type/UuidType.php
new file mode 100644
index 0000000..ce7f754
--- /dev/null
+++ b/vendor/cakephp/database/Type/UuidType.php
@@ -0,0 +1,67 @@
+toDatabase($value, $this->getDriver());
+            $type = $type->toStatement($value, $this->getDriver());
+        }
+
+        return [$value, $type];
+    }
+
+    /**
+     * Matches columns to corresponding types
+     *
+     * Both $columns and $types should either be numeric based or string key based at
+     * the same time.
+     *
+     * @param array $columns list or associative array of columns and parameters to be bound with types
+     * @param array $types list or associative array of types
+     * @return array
+     */
+    public function matchTypes(array $columns, array $types): array
+    {
+        if (!is_int(key($types))) {
+            $positions = array_intersect_key(array_flip($columns), $types);
+            $types = array_intersect_key($types, $positions);
+            $types = array_combine($positions, $types);
+        }
+
+        return $types;
+    }
+}
diff --git a/vendor/cakephp/database/TypeFactory.php b/vendor/cakephp/database/TypeFactory.php
new file mode 100644
index 0000000..617bad6
--- /dev/null
+++ b/vendor/cakephp/database/TypeFactory.php
@@ -0,0 +1,171 @@
+
+     * @psalm-var array>
+     */
+    protected static $_types = [
+        'tinyinteger' => Type\IntegerType::class,
+        'smallinteger' => Type\IntegerType::class,
+        'integer' => Type\IntegerType::class,
+        'biginteger' => Type\IntegerType::class,
+        'binary' => Type\BinaryType::class,
+        'binaryuuid' => Type\BinaryUuidType::class,
+        'boolean' => Type\BoolType::class,
+        'date' => Type\DateType::class,
+        'datetime' => Type\DateTimeType::class,
+        'datetimefractional' => Type\DateTimeFractionalType::class,
+        'decimal' => Type\DecimalType::class,
+        'float' => Type\FloatType::class,
+        'json' => Type\JsonType::class,
+        'string' => Type\StringType::class,
+        'char' => Type\StringType::class,
+        'text' => Type\StringType::class,
+        'time' => Type\TimeType::class,
+        'timestamp' => Type\DateTimeType::class,
+        'timestampfractional' => Type\DateTimeFractionalType::class,
+        'timestamptimezone' => Type\DateTimeTimezoneType::class,
+        'uuid' => Type\UuidType::class,
+    ];
+
+    /**
+     * Contains a map of type object instances to be reused if needed.
+     *
+     * @var array<\Cake\Database\TypeInterface>
+     */
+    protected static $_builtTypes = [];
+
+    /**
+     * Returns a Type object capable of converting a type identified by name.
+     *
+     * @param string $name type identifier
+     * @throws \InvalidArgumentException If type identifier is unknown
+     * @return \Cake\Database\TypeInterface
+     */
+    public static function build(string $name): TypeInterface
+    {
+        if (isset(static::$_builtTypes[$name])) {
+            return static::$_builtTypes[$name];
+        }
+        if (!isset(static::$_types[$name])) {
+            throw new InvalidArgumentException(sprintf('Unknown type "%s"', $name));
+        }
+
+        return static::$_builtTypes[$name] = new static::$_types[$name]($name);
+    }
+
+    /**
+     * Returns an arrays with all the mapped type objects, indexed by name.
+     *
+     * @return array<\Cake\Database\TypeInterface>
+     */
+    public static function buildAll(): array
+    {
+        $result = [];
+        foreach (static::$_types as $name => $type) {
+            $result[$name] = static::$_builtTypes[$name] ?? static::build($name);
+        }
+
+        return $result;
+    }
+
+    /**
+     * Set TypeInterface instance capable of converting a type identified by $name
+     *
+     * @param string $name The type identifier you want to set.
+     * @param \Cake\Database\TypeInterface $instance The type instance you want to set.
+     * @return void
+     */
+    public static function set(string $name, TypeInterface $instance): void
+    {
+        static::$_builtTypes[$name] = $instance;
+        static::$_types[$name] = get_class($instance);
+    }
+
+    /**
+     * Registers a new type identifier and maps it to a fully namespaced classname.
+     *
+     * @param string $type Name of type to map.
+     * @param string $className The classname to register.
+     * @return void
+     * @psalm-param class-string<\Cake\Database\TypeInterface> $className
+     */
+    public static function map(string $type, string $className): void
+    {
+        static::$_types[$type] = $className;
+        unset(static::$_builtTypes[$type]);
+    }
+
+    /**
+     * Set type to classname mapping.
+     *
+     * @param array $map List of types to be mapped.
+     * @return void
+     * @psalm-param array> $map
+     */
+    public static function setMap(array $map): void
+    {
+        static::$_types = $map;
+        static::$_builtTypes = [];
+    }
+
+    /**
+     * Get mapped class name for given type or map array.
+     *
+     * @param string|null $type Type name to get mapped class for or null to get map array.
+     * @return array|string|null Configured class name for given $type or map array.
+     */
+    public static function getMap(?string $type = null)
+    {
+        if ($type === null) {
+            return static::$_types;
+        }
+
+        return static::$_types[$type] ?? null;
+    }
+
+    /**
+     * Clears out all created instances and mapped types classes, useful for testing
+     *
+     * @return void
+     */
+    public static function clear(): void
+    {
+        static::$_types = [];
+        static::$_builtTypes = [];
+    }
+}
+
+// phpcs:disable
+class_alias(
+    'Cake\Database\TypeFactory',
+    'Cake\Database\Type'
+);
+// phpcs:enable
diff --git a/vendor/cakephp/database/TypeInterface.php b/vendor/cakephp/database/TypeInterface.php
new file mode 100644
index 0000000..fca0fdb
--- /dev/null
+++ b/vendor/cakephp/database/TypeInterface.php
@@ -0,0 +1,91 @@
+
+     */
+    protected $_defaults = [];
+
+    /**
+     * Array with the fields and the related types that override defaults this query might contain
+     *
+     * Used to avoid repetition when calling multiple functions inside this class that
+     * may require a custom type for a specific field.
+     *
+     * @var array
+     */
+    protected $_types = [];
+
+    /**
+     * Creates an instance with the given defaults
+     *
+     * @param array $defaults The defaults to use.
+     */
+    public function __construct(array $defaults = [])
+    {
+        $this->setDefaults($defaults);
+    }
+
+    /**
+     * Configures a map of fields and associated type.
+     *
+     * These values will be used as the default mapping of types for every function
+     * in this instance that supports a `$types` param.
+     *
+     * This method is useful when you want to avoid repeating type definitions
+     * as setting types overwrites the last set of types.
+     *
+     * ### Example
+     *
+     * ```
+     * $query->setDefaults(['created' => 'datetime', 'is_visible' => 'boolean']);
+     * ```
+     *
+     * This method will replace all the existing default mappings with the ones provided.
+     * To add into the mappings use `addDefaults()`.
+     *
+     * @param array $defaults Array where keys are field names / positions and values
+     * are the correspondent type.
+     * @return $this
+     */
+    public function setDefaults(array $defaults)
+    {
+        $this->_defaults = $defaults;
+
+        return $this;
+    }
+
+    /**
+     * Returns the currently configured types.
+     *
+     * @return array
+     */
+    public function getDefaults(): array
+    {
+        return $this->_defaults;
+    }
+
+    /**
+     * Add additional default types into the type map.
+     *
+     * If a key already exists it will not be overwritten.
+     *
+     * @param array $types The additional types to add.
+     * @return void
+     */
+    public function addDefaults(array $types): void
+    {
+        $this->_defaults += $types;
+    }
+
+    /**
+     * Sets a map of fields and their associated types for single-use.
+     *
+     * ### Example
+     *
+     * ```
+     * $query->setTypes(['created' => 'time']);
+     * ```
+     *
+     * This method will replace all the existing type maps with the ones provided.
+     *
+     * @param array $types Array where keys are field names / positions and values
+     * are the correspondent type.
+     * @return $this
+     */
+    public function setTypes(array $types)
+    {
+        $this->_types = $types;
+
+        return $this;
+    }
+
+    /**
+     * Gets a map of fields and their associated types for single-use.
+     *
+     * @return array
+     */
+    public function getTypes(): array
+    {
+        return $this->_types;
+    }
+
+    /**
+     * Returns the type of the given column. If there is no single use type is configured,
+     * the column type will be looked for inside the default mapping. If neither exist,
+     * null will be returned.
+     *
+     * @param string|int $column The type for a given column
+     * @return string|null
+     */
+    public function type($column): ?string
+    {
+        return $this->_types[$column] ?? $this->_defaults[$column] ?? null;
+    }
+
+    /**
+     * Returns an array of all types mapped types
+     *
+     * @return array
+     */
+    public function toArray(): array
+    {
+        return $this->_types + $this->_defaults;
+    }
+}
diff --git a/vendor/cakephp/database/TypeMapTrait.php b/vendor/cakephp/database/TypeMapTrait.php
new file mode 100644
index 0000000..402a9b5
--- /dev/null
+++ b/vendor/cakephp/database/TypeMapTrait.php
@@ -0,0 +1,89 @@
+_typeMap = is_array($typeMap) ? new TypeMap($typeMap) : $typeMap;
+
+        return $this;
+    }
+
+    /**
+     * Returns the existing type map.
+     *
+     * @return \Cake\Database\TypeMap
+     */
+    public function getTypeMap(): TypeMap
+    {
+        if ($this->_typeMap === null) {
+            $this->_typeMap = new TypeMap();
+        }
+
+        return $this->_typeMap;
+    }
+
+    /**
+     * Overwrite the default type mappings for fields
+     * in the implementing object.
+     *
+     * This method is useful if you need to set type mappings that are shared across
+     * multiple functions/expressions in a query.
+     *
+     * To add a default without overwriting existing ones
+     * use `getTypeMap()->addDefaults()`
+     *
+     * @param array $types The array of types to set.
+     * @return $this
+     * @see \Cake\Database\TypeMap::setDefaults()
+     */
+    public function setDefaultTypes(array $types)
+    {
+        $this->getTypeMap()->setDefaults($types);
+
+        return $this;
+    }
+
+    /**
+     * Gets default types of current type map.
+     *
+     * @return array
+     */
+    public function getDefaultTypes(): array
+    {
+        return $this->getTypeMap()->getDefaults();
+    }
+}
diff --git a/vendor/cakephp/database/TypedResultInterface.php b/vendor/cakephp/database/TypedResultInterface.php
new file mode 100644
index 0000000..434ff08
--- /dev/null
+++ b/vendor/cakephp/database/TypedResultInterface.php
@@ -0,0 +1,38 @@
+_returnType;
+    }
+
+    /**
+     * Sets the type of the value this object will generate.
+     *
+     * @param string $type The name of the type that is to be returned
+     * @return $this
+     */
+    public function setReturnType(string $type)
+    {
+        $this->_returnType = $type;
+
+        return $this;
+    }
+}
diff --git a/vendor/cakephp/database/ValueBinder.php b/vendor/cakephp/database/ValueBinder.php
new file mode 100644
index 0000000..0e5dd3d
--- /dev/null
+++ b/vendor/cakephp/database/ValueBinder.php
@@ -0,0 +1,163 @@
+_bindings[$param] = compact('value', 'type') + [
+            'placeholder' => is_int($param) ? $param : substr($param, 1),
+        ];
+    }
+
+    /**
+     * Creates a unique placeholder name if the token provided does not start with ":"
+     * otherwise, it will return the same string and internally increment the number
+     * of placeholders generated by this object.
+     *
+     * @param string $token string from which the placeholder will be derived from,
+     * if it starts with a colon, then the same string is returned
+     * @return string to be used as a placeholder in a query expression
+     */
+    public function placeholder(string $token): string
+    {
+        $number = $this->_bindingsCount++;
+        if ($token[0] !== ':' && $token !== '?') {
+            $token = sprintf(':%s%s', $token, $number);
+        }
+
+        return $token;
+    }
+
+    /**
+     * Creates unique named placeholders for each of the passed values
+     * and binds them with the specified type.
+     *
+     * @param iterable $values The list of values to be bound
+     * @param string|int|null $type The type with which all values will be bound
+     * @return array with the placeholders to insert in the query
+     */
+    public function generateManyNamed(iterable $values, $type = null): array
+    {
+        $placeholders = [];
+        foreach ($values as $k => $value) {
+            $param = $this->placeholder('c');
+            $this->_bindings[$param] = [
+                'value' => $value,
+                'type' => $type,
+                'placeholder' => substr($param, 1),
+            ];
+            $placeholders[$k] = $param;
+        }
+
+        return $placeholders;
+    }
+
+    /**
+     * Returns all values bound to this expression object at this nesting level.
+     * Subexpression bound values will not be returned with this function.
+     *
+     * @return array
+     */
+    public function bindings(): array
+    {
+        return $this->_bindings;
+    }
+
+    /**
+     * Clears any bindings that were previously registered
+     *
+     * @return void
+     */
+    public function reset(): void
+    {
+        $this->_bindings = [];
+        $this->_bindingsCount = 0;
+    }
+
+    /**
+     * Resets the bindings count without clearing previously bound values
+     *
+     * @return void
+     */
+    public function resetCount(): void
+    {
+        $this->_bindingsCount = 0;
+    }
+
+    /**
+     * Binds all the stored values in this object to the passed statement.
+     *
+     * @param \Cake\Database\StatementInterface $statement The statement to add parameters to.
+     * @return void
+     */
+    public function attachTo(StatementInterface $statement): void
+    {
+        $bindings = $this->bindings();
+        if (empty($bindings)) {
+            return;
+        }
+
+        foreach ($bindings as $b) {
+            $statement->bindValue($b['placeholder'], $b['value'], $b['type']);
+        }
+    }
+
+    /**
+     * Get verbose debugging data.
+     *
+     * @return array
+     */
+    public function __debugInfo(): array
+    {
+        return [
+            'bindings' => $this->bindings(),
+        ];
+    }
+}
diff --git a/vendor/cakephp/database/composer.json b/vendor/cakephp/database/composer.json
new file mode 100644
index 0000000..64c22e8
--- /dev/null
+++ b/vendor/cakephp/database/composer.json
@@ -0,0 +1,40 @@
+{
+    "name": "cakephp/database",
+    "description": "Flexible and powerful Database abstraction library with a familiar PDO-like API",
+    "type": "library",
+    "keywords": [
+        "cakephp",
+        "database",
+        "abstraction",
+        "database abstraction",
+        "pdo"
+    ],
+    "homepage": "https://cakephp.org",
+    "license": "MIT",
+    "authors": [
+        {
+            "name": "CakePHP Community",
+            "homepage": "https://github.com/cakephp/database/graphs/contributors"
+        }
+    ],
+    "support": {
+        "issues": "https://github.com/cakephp/cakephp/issues",
+        "forum": "https://stackoverflow.com/tags/cakephp",
+        "irc": "irc://irc.freenode.org/cakephp",
+        "source": "https://github.com/cakephp/database"
+    },
+    "require": {
+        "php": ">=7.4.0",
+        "cakephp/core": "^4.0",
+        "cakephp/datasource": "^4.0"
+    },
+    "suggest": {
+        "cakephp/i18n": "If you are using locale-aware datetime formats or Chronos types.",
+        "cakephp/log": "If you want to use query logging without providing a logger yourself."
+    },
+    "autoload": {
+        "psr-4": {
+            "Cake\\Database\\": "."
+        }
+    }
+}
diff --git a/vendor/cakephp/datasource/ConnectionInterface.php b/vendor/cakephp/datasource/ConnectionInterface.php
new file mode 100644
index 0000000..7efef43
--- /dev/null
+++ b/vendor/cakephp/datasource/ConnectionInterface.php
@@ -0,0 +1,154 @@
+
+     */
+    public function config(): array;
+
+    /**
+     * Executes a callable function inside a transaction, if any exception occurs
+     * while executing the passed callable, the transaction will be rolled back
+     * If the result of the callable function is `false`, the transaction will
+     * also be rolled back. Otherwise, the transaction is committed after executing
+     * the callback.
+     *
+     * The callback will receive the connection instance as its first argument.
+     *
+     * ### Example:
+     *
+     * ```
+     * $connection->transactional(function ($connection) {
+     *   $connection->newQuery()->delete('users')->execute();
+     * });
+     * ```
+     *
+     * @param callable $callback The callback to execute within a transaction.
+     * @return mixed The return value of the callback.
+     * @throws \Exception Will re-throw any exception raised in $callback after
+     *   rolling back the transaction.
+     */
+    public function transactional(callable $callback);
+
+    /**
+     * Run an operation with constraints disabled.
+     *
+     * Constraints should be re-enabled after the callback succeeds/fails.
+     *
+     * ### Example:
+     *
+     * ```
+     * $connection->disableConstraints(function ($connection) {
+     *   $connection->newQuery()->delete('users')->execute();
+     * });
+     * ```
+     *
+     * @param callable $callback The callback to execute within a transaction.
+     * @return mixed The return value of the callback.
+     * @throws \Exception Will re-throw any exception raised in $callback after
+     *   rolling back the transaction.
+     */
+    public function disableConstraints(callable $callback);
+
+    /**
+     * Enable/disable query logging
+     *
+     * @param bool $enable Enable/disable query logging
+     * @return $this
+     */
+    public function enableQueryLogging(bool $enable = true);
+
+    /**
+     * Disable query logging
+     *
+     * @return $this
+     */
+    public function disableQueryLogging();
+
+    /**
+     * Check if query logging is enabled.
+     *
+     * @return bool
+     */
+    public function isQueryLoggingEnabled(): bool;
+}
diff --git a/vendor/cakephp/datasource/ConnectionManager.php b/vendor/cakephp/datasource/ConnectionManager.php
new file mode 100644
index 0000000..8f244ea
--- /dev/null
+++ b/vendor/cakephp/datasource/ConnectionManager.php
@@ -0,0 +1,216 @@
+
+     */
+    protected static $_aliasMap = [];
+
+    /**
+     * An array mapping url schemes to fully qualified driver class names
+     *
+     * @var array
+     * @psalm-var array
+     */
+    protected static $_dsnClassMap = [
+        'mysql' => Mysql::class,
+        'postgres' => Postgres::class,
+        'sqlite' => Sqlite::class,
+        'sqlserver' => Sqlserver::class,
+    ];
+
+    /**
+     * The ConnectionRegistry used by the manager.
+     *
+     * @var \Cake\Datasource\ConnectionRegistry|null
+     */
+    protected static $_registry;
+
+    /**
+     * Configure a new connection object.
+     *
+     * The connection will not be constructed until it is first used.
+     *
+     * @param array|string $key The name of the connection config, or an array of multiple configs.
+     * @param array|null $config An array of name => config data for adapter.
+     * @return void
+     * @throws \Cake\Core\Exception\CakeException When trying to modify an existing config.
+     * @see \Cake\Core\StaticConfigTrait::config()
+     */
+    public static function setConfig($key, $config = null): void
+    {
+        if (is_array($config)) {
+            $config['name'] = $key;
+        }
+
+        static::_setConfig($key, $config);
+    }
+
+    /**
+     * Parses a DSN into a valid connection configuration
+     *
+     * This method allows setting a DSN using formatting similar to that used by PEAR::DB.
+     * The following is an example of its usage:
+     *
+     * ```
+     * $dsn = 'mysql://user:pass@localhost/database';
+     * $config = ConnectionManager::parseDsn($dsn);
+     *
+     * $dsn = 'Cake\Database\Driver\Mysql://localhost:3306/database?className=Cake\Database\Connection';
+     * $config = ConnectionManager::parseDsn($dsn);
+     *
+     * $dsn = 'Cake\Database\Connection://localhost:3306/database?driver=Cake\Database\Driver\Mysql';
+     * $config = ConnectionManager::parseDsn($dsn);
+     * ```
+     *
+     * For all classes, the value of `scheme` is set as the value of both the `className` and `driver`
+     * unless they have been otherwise specified.
+     *
+     * Note that query-string arguments are also parsed and set as values in the returned configuration.
+     *
+     * @param string $config The DSN string to convert to a configuration array
+     * @return array The configuration array to be stored after parsing the DSN
+     */
+    public static function parseDsn(string $config): array
+    {
+        $config = static::_parseDsn($config);
+
+        if (isset($config['path']) && empty($config['database'])) {
+            $config['database'] = substr($config['path'], 1);
+        }
+
+        if (empty($config['driver'])) {
+            $config['driver'] = $config['className'];
+            $config['className'] = Connection::class;
+        }
+
+        unset($config['path']);
+
+        return $config;
+    }
+
+    /**
+     * Set one or more connection aliases.
+     *
+     * Connection aliases allow you to rename active connections without overwriting
+     * the aliased connection. This is most useful in the test-suite for replacing
+     * connections with their test variant.
+     *
+     * Defined aliases will take precedence over normal connection names. For example,
+     * if you alias 'default' to 'test', fetching 'default' will always return the 'test'
+     * connection as long as the alias is defined.
+     *
+     * You can remove aliases with ConnectionManager::dropAlias().
+     *
+     * ### Usage
+     *
+     * ```
+     * // Make 'things' resolve to 'test_things' connection
+     * ConnectionManager::alias('test_things', 'things');
+     * ```
+     *
+     * @param string $source The existing connection to alias.
+     * @param string $alias The alias name that resolves to `$source`.
+     * @return void
+     */
+    public static function alias(string $source, string $alias): void
+    {
+        static::$_aliasMap[$alias] = $source;
+    }
+
+    /**
+     * Drop an alias.
+     *
+     * Removes an alias from ConnectionManager. Fetching the aliased
+     * connection may fail if there is no other connection with that name.
+     *
+     * @param string $alias The connection alias to drop
+     * @return void
+     */
+    public static function dropAlias(string $alias): void
+    {
+        unset(static::$_aliasMap[$alias]);
+    }
+
+    /**
+     * Returns the current connection aliases and what they alias.
+     *
+     * @return array
+     */
+    public static function aliases(): array
+    {
+        return static::$_aliasMap;
+    }
+
+    /**
+     * Get a connection.
+     *
+     * If the connection has not been constructed an instance will be added
+     * to the registry. This method will use any aliases that have been
+     * defined. If you want the original unaliased connections pass `false`
+     * as second parameter.
+     *
+     * @param string $name The connection name.
+     * @param bool $useAliases Whether connection aliases are used
+     * @return \Cake\Datasource\ConnectionInterface
+     * @throws \Cake\Datasource\Exception\MissingDatasourceConfigException When config
+     * data is missing.
+     */
+    public static function get(string $name, bool $useAliases = true)
+    {
+        if ($useAliases && isset(static::$_aliasMap[$name])) {
+            $name = static::$_aliasMap[$name];
+        }
+
+        if (!isset(static::$_config[$name])) {
+            throw new MissingDatasourceConfigException(['name' => $name]);
+        }
+
+        if (!isset(static::$_registry)) {
+            static::$_registry = new ConnectionRegistry();
+        }
+
+        return static::$_registry->{$name} ?? static::$_registry->load($name, static::$_config[$name]);
+    }
+}
diff --git a/vendor/cakephp/datasource/ConnectionRegistry.php b/vendor/cakephp/datasource/ConnectionRegistry.php
new file mode 100644
index 0000000..34a5aca
--- /dev/null
+++ b/vendor/cakephp/datasource/ConnectionRegistry.php
@@ -0,0 +1,104 @@
+
+ */
+class ConnectionRegistry extends ObjectRegistry
+{
+    /**
+     * Resolve a datasource classname.
+     *
+     * Part of the template method for Cake\Core\ObjectRegistry::load()
+     *
+     * @param string $class Partial classname to resolve.
+     * @return string|null Either the correct class name or null.
+     * @psalm-return class-string|null
+     */
+    protected function _resolveClassName(string $class): ?string
+    {
+        return App::className($class, 'Datasource');
+    }
+
+    /**
+     * Throws an exception when a datasource is missing
+     *
+     * Part of the template method for Cake\Core\ObjectRegistry::load()
+     *
+     * @param string $class The classname that is missing.
+     * @param string|null $plugin The plugin the datasource is missing in.
+     * @return void
+     * @throws \Cake\Datasource\Exception\MissingDatasourceException
+     */
+    protected function _throwMissingClassError(string $class, ?string $plugin): void
+    {
+        throw new MissingDatasourceException([
+            'class' => $class,
+            'plugin' => $plugin,
+        ]);
+    }
+
+    /**
+     * Create the connection object with the correct settings.
+     *
+     * Part of the template method for Cake\Core\ObjectRegistry::load()
+     *
+     * If a callable is passed as first argument, The returned value of this
+     * function will be the result of the callable.
+     *
+     * @param \Cake\Datasource\ConnectionInterface|callable|string $class The classname or object to make.
+     * @param string $alias The alias of the object.
+     * @param array $config An array of settings to use for the datasource.
+     * @return \Cake\Datasource\ConnectionInterface A connection with the correct settings.
+     */
+    protected function _create($class, string $alias, array $config)
+    {
+        if (is_callable($class)) {
+            return $class($alias);
+        }
+
+        if (is_object($class)) {
+            return $class;
+        }
+
+        unset($config['className']);
+
+        /** @var \Cake\Datasource\ConnectionInterface */
+        return new $class($config);
+    }
+
+    /**
+     * Remove a single adapter from the registry.
+     *
+     * @param string $name The adapter name.
+     * @return $this
+     */
+    public function unload(string $name)
+    {
+        unset($this->_loaded[$name]);
+
+        return $this;
+    }
+}
diff --git a/vendor/cakephp/datasource/EntityInterface.php b/vendor/cakephp/datasource/EntityInterface.php
new file mode 100644
index 0000000..5887670
--- /dev/null
+++ b/vendor/cakephp/datasource/EntityInterface.php
@@ -0,0 +1,288 @@
+
+ */
+interface EntityInterface extends ArrayAccess, JsonSerializable
+{
+    /**
+     * Sets hidden fields.
+     *
+     * @param array $fields An array of fields to hide from array exports.
+     * @param bool $merge Merge the new fields with the existing. By default false.
+     * @return $this
+     */
+    public function setHidden(array $fields, bool $merge = false);
+
+    /**
+     * Gets the hidden fields.
+     *
+     * @return array
+     */
+    public function getHidden(): array;
+
+    /**
+     * Sets the virtual fields on this entity.
+     *
+     * @param array $fields An array of fields to treat as virtual.
+     * @param bool $merge Merge the new fields with the existing. By default false.
+     * @return $this
+     */
+    public function setVirtual(array $fields, bool $merge = false);
+
+    /**
+     * Gets the virtual fields on this entity.
+     *
+     * @return array
+     */
+    public function getVirtual(): array;
+
+    /**
+     * Sets the dirty status of a single field.
+     *
+     * @param string $field the field to set or check status for
+     * @param bool $isDirty true means the field was changed, false means
+     * it was not changed. Default true.
+     * @return $this
+     */
+    public function setDirty(string $field, bool $isDirty = true);
+
+    /**
+     * Checks if the entity is dirty or if a single field of it is dirty.
+     *
+     * @param string|null $field The field to check the status for. Null for the whole entity.
+     * @return bool Whether the field was changed or not
+     */
+    public function isDirty(?string $field = null): bool;
+
+    /**
+     * Gets the dirty fields.
+     *
+     * @return array
+     */
+    public function getDirty(): array;
+
+    /**
+     * Returns whether this entity has errors.
+     *
+     * @param bool $includeNested true will check nested entities for hasErrors()
+     * @return bool
+     */
+    public function hasErrors(bool $includeNested = true): bool;
+
+    /**
+     * Returns all validation errors.
+     *
+     * @return array
+     */
+    public function getErrors(): array;
+
+    /**
+     * Returns validation errors of a field
+     *
+     * @param string $field Field name to get the errors from
+     * @return array
+     */
+    public function getError(string $field): array;
+
+    /**
+     * Sets error messages to the entity
+     *
+     * @param array $errors The array of errors to set.
+     * @param bool $overwrite Whether to overwrite pre-existing errors for $fields
+     * @return $this
+     */
+    public function setErrors(array $errors, bool $overwrite = false);
+
+    /**
+     * Sets errors for a single field
+     *
+     * @param string $field The field to get errors for, or the array of errors to set.
+     * @param array|string $errors The errors to be set for $field
+     * @param bool $overwrite Whether to overwrite pre-existing errors for $field
+     * @return $this
+     */
+    public function setError(string $field, $errors, bool $overwrite = false);
+
+    /**
+     * Stores whether a field value can be changed or set in this entity.
+     *
+     * @param array|string $field single or list of fields to change its accessibility
+     * @param bool $set true marks the field as accessible, false will
+     * mark it as protected.
+     * @return $this
+     */
+    public function setAccess($field, bool $set);
+
+    /**
+     * Checks if a field is accessible
+     *
+     * @param string $field Field name to check
+     * @return bool
+     */
+    public function isAccessible(string $field): bool;
+
+    /**
+     * Sets the source alias
+     *
+     * @param string $alias the alias of the repository
+     * @return $this
+     */
+    public function setSource(string $alias);
+
+    /**
+     * Returns the alias of the repository from which this entity came from.
+     *
+     * @return string
+     */
+    public function getSource(): string;
+
+    /**
+     * Returns an array with the requested original fields
+     * stored in this entity, indexed by field name.
+     *
+     * @param array $fields List of fields to be returned
+     * @return array
+     */
+    public function extractOriginal(array $fields): array;
+
+    /**
+     * Returns an array with only the original fields
+     * stored in this entity, indexed by field name.
+     *
+     * @param array $fields List of fields to be returned
+     * @return array
+     */
+    public function extractOriginalChanged(array $fields): array;
+
+    /**
+     * Sets one or multiple fields to the specified value
+     *
+     * @param array|string $field the name of field to set or a list of
+     * fields with their respective values
+     * @param mixed $value The value to set to the field or an array if the
+     * first argument is also an array, in which case will be treated as $options
+     * @param array $options Options to be used for setting the field. Allowed option
+     * keys are `setter` and `guard`
+     * @return $this
+     */
+    public function set($field, $value = null, array $options = []);
+
+    /**
+     * Returns the value of a field by name
+     *
+     * @param string $field the name of the field to retrieve
+     * @return mixed
+     */
+    public function &get(string $field);
+
+    /**
+     * Returns the original value of a field.
+     *
+     * @param string $field The name of the field.
+     * @return mixed
+     */
+    public function getOriginal(string $field);
+
+    /**
+     * Gets all original values of the entity.
+     *
+     * @return array
+     */
+    public function getOriginalValues(): array;
+
+    /**
+     * Returns whether this entity contains a field named $field
+     * and is not set to null.
+     *
+     * @param array|string $field The field to check.
+     * @return bool
+     */
+    public function has($field): bool;
+
+    /**
+     * Removes a field or list of fields from this entity
+     *
+     * @param array|string $field The field to unset.
+     * @return $this
+     */
+    public function unset($field);
+
+    /**
+     * Get the list of visible fields.
+     *
+     * @return array A list of fields that are 'visible' in all representations.
+     */
+    public function getVisible(): array;
+
+    /**
+     * Returns an array with all the visible fields set in this entity.
+     *
+     * *Note* hidden fields are not visible, and will not be output
+     * by toArray().
+     *
+     * @return array
+     */
+    public function toArray(): array;
+
+    /**
+     * Returns an array with the requested fields
+     * stored in this entity, indexed by field name
+     *
+     * @param array $fields list of fields to be returned
+     * @param bool $onlyDirty Return the requested field only if it is dirty
+     * @return array
+     */
+    public function extract(array $fields, bool $onlyDirty = false): array;
+
+    /**
+     * Sets the entire entity as clean, which means that it will appear as
+     * no fields being modified or added at all. This is an useful call
+     * for an initial object hydration
+     *
+     * @return void
+     */
+    public function clean(): void;
+
+    /**
+     * Set the status of this entity.
+     *
+     * Using `true` means that the entity has not been persisted in the database,
+     * `false` indicates that the entity has been persisted.
+     *
+     * @param bool $new Indicate whether this entity has been persisted.
+     * @return $this
+     */
+    public function setNew(bool $new);
+
+    /**
+     * Returns whether this entity has already been persisted.
+     *
+     * @return bool Whether the entity has been persisted.
+     */
+    public function isNew(): bool;
+}
diff --git a/vendor/cakephp/datasource/EntityTrait.php b/vendor/cakephp/datasource/EntityTrait.php
new file mode 100644
index 0000000..3cd54bb
--- /dev/null
+++ b/vendor/cakephp/datasource/EntityTrait.php
@@ -0,0 +1,1304 @@
+
+     */
+    protected $_fields = [];
+
+    /**
+     * Holds all fields that have been changed and their original values for this entity.
+     *
+     * @var array
+     */
+    protected $_original = [];
+
+    /**
+     * List of field names that should **not** be included in JSON or Array
+     * representations of this Entity.
+     *
+     * @var array
+     */
+    protected $_hidden = [];
+
+    /**
+     * List of computed or virtual fields that **should** be included in JSON or array
+     * representations of this Entity. If a field is present in both _hidden and _virtual
+     * the field will **not** be in the array/JSON versions of the entity.
+     *
+     * @var array
+     */
+    protected $_virtual = [];
+
+    /**
+     * Holds a list of the fields that were modified or added after this object
+     * was originally created.
+     *
+     * @var array
+     */
+    protected $_dirty = [];
+
+    /**
+     * Holds a cached list of getters/setters per class
+     *
+     * @var array>>
+     */
+    protected static $_accessors = [];
+
+    /**
+     * Indicates whether this entity is yet to be persisted.
+     * Entities default to assuming they are new. You can use Table::persisted()
+     * to set the new flag on an entity based on records in the database.
+     *
+     * @var bool
+     */
+    protected $_new = true;
+
+    /**
+     * List of errors per field as stored in this object.
+     *
+     * @var array
+     */
+    protected $_errors = [];
+
+    /**
+     * List of invalid fields and their data for errors upon validation/patching.
+     *
+     * @var array
+     */
+    protected $_invalid = [];
+
+    /**
+     * Map of fields in this entity that can be safely assigned, each
+     * field name points to a boolean indicating its status. An empty array
+     * means no fields are accessible
+     *
+     * The special field '\*' can also be mapped, meaning that any other field
+     * not defined in the map will take its value. For example, `'*' => true`
+     * means that any field not defined in the map will be accessible by default
+     *
+     * @var array
+     */
+    protected $_accessible = ['*' => true];
+
+    /**
+     * The alias of the repository this entity came from
+     *
+     * @var string
+     */
+    protected $_registryAlias = '';
+
+    /**
+     * Storing the current visitation status while recursing through entities getting errors.
+     *
+     * @var bool
+     */
+    protected $_hasBeenVisited = false;
+
+    /**
+     * Set to true in your entity's class definition or
+     * via application logic. When true. has() and related
+     * methods will use `array_key_exists` instead of `isset`
+     * to decide if fields are 'defined' in an entity.
+     *
+     * @var bool
+     */
+    protected $_hasAllowsNull = false;
+
+    /**
+     * Magic getter to access fields that have been set in this entity
+     *
+     * @param string $field Name of the field to access
+     * @return mixed
+     */
+    public function &__get(string $field)
+    {
+        return $this->get($field);
+    }
+
+    /**
+     * Magic setter to add or edit a field in this entity
+     *
+     * @param string $field The name of the field to set
+     * @param mixed $value The value to set to the field
+     * @return void
+     */
+    public function __set(string $field, $value): void
+    {
+        $this->set($field, $value);
+    }
+
+    /**
+     * Returns whether this entity contains a field named $field
+     * and is not set to null.
+     *
+     * @param string $field The field to check.
+     * @return bool
+     * @see \Cake\ORM\Entity::has()
+     */
+    public function __isset(string $field): bool
+    {
+        return $this->has($field);
+    }
+
+    /**
+     * Removes a field from this entity
+     *
+     * @param string $field The field to unset
+     * @return void
+     */
+    public function __unset(string $field): void
+    {
+        $this->unset($field);
+    }
+
+    /**
+     * Sets a single field inside this entity.
+     *
+     * ### Example:
+     *
+     * ```
+     * $entity->set('name', 'Andrew');
+     * ```
+     *
+     * It is also possible to mass-assign multiple fields to this entity
+     * with one call by passing a hashed array as fields in the form of
+     * field => value pairs
+     *
+     * ### Example:
+     *
+     * ```
+     * $entity->set(['name' => 'andrew', 'id' => 1]);
+     * echo $entity->name // prints andrew
+     * echo $entity->id // prints 1
+     * ```
+     *
+     * Some times it is handy to bypass setter functions in this entity when assigning
+     * fields. You can achieve this by disabling the `setter` option using the
+     * `$options` parameter:
+     *
+     * ```
+     * $entity->set('name', 'Andrew', ['setter' => false]);
+     * $entity->set(['name' => 'Andrew', 'id' => 1], ['setter' => false]);
+     * ```
+     *
+     * Mass assignment should be treated carefully when accepting user input, by default
+     * entities will guard all fields when fields are assigned in bulk. You can disable
+     * the guarding for a single set call with the `guard` option:
+     *
+     * ```
+     * $entity->set(['name' => 'Andrew', 'id' => 1], ['guard' => false]);
+     * ```
+     *
+     * You do not need to use the guard option when assigning fields individually:
+     *
+     * ```
+     * // No need to use the guard option.
+     * $entity->set('name', 'Andrew');
+     * ```
+     *
+     * @param array|string $field the name of field to set or a list of
+     * fields with their respective values
+     * @param mixed $value The value to set to the field or an array if the
+     * first argument is also an array, in which case will be treated as $options
+     * @param array $options Options to be used for setting the field. Allowed option
+     * keys are `setter` and `guard`
+     * @return $this
+     * @throws \InvalidArgumentException
+     */
+    public function set($field, $value = null, array $options = [])
+    {
+        if (is_string($field) && $field !== '') {
+            $guard = false;
+            $field = [$field => $value];
+        } else {
+            $guard = true;
+            $options = (array)$value;
+        }
+
+        if (!is_array($field)) {
+            throw new InvalidArgumentException('Cannot set an empty field');
+        }
+        $options += ['setter' => true, 'guard' => $guard];
+
+        foreach ($field as $name => $value) {
+            $name = (string)$name;
+            if ($options['guard'] === true && !$this->isAccessible($name)) {
+                continue;
+            }
+
+            $this->setDirty($name, true);
+
+            if (
+                !array_key_exists($name, $this->_original) &&
+                array_key_exists($name, $this->_fields) &&
+                $this->_fields[$name] !== $value
+            ) {
+                $this->_original[$name] = $this->_fields[$name];
+            }
+
+            if (!$options['setter']) {
+                $this->_fields[$name] = $value;
+                continue;
+            }
+
+            $setter = static::_accessor($name, 'set');
+            if ($setter) {
+                $value = $this->{$setter}($value);
+            }
+            $this->_fields[$name] = $value;
+        }
+
+        return $this;
+    }
+
+    /**
+     * Returns the value of a field by name
+     *
+     * @param string $field the name of the field to retrieve
+     * @return mixed
+     * @throws \InvalidArgumentException if an empty field name is passed
+     */
+    public function &get(string $field)
+    {
+        if ($field === '') {
+            throw new InvalidArgumentException('Cannot get an empty field');
+        }
+
+        $value = null;
+
+        if (isset($this->_fields[$field])) {
+            $value = &$this->_fields[$field];
+        }
+
+        $method = static::_accessor($field, 'get');
+        if ($method) {
+            $result = $this->{$method}($value);
+
+            return $result;
+        }
+
+        return $value;
+    }
+
+    /**
+     * Returns the value of an original field by name
+     *
+     * @param string $field the name of the field for which original value is retrieved.
+     * @return mixed
+     * @throws \InvalidArgumentException if an empty field name is passed.
+     */
+    public function getOriginal(string $field)
+    {
+        if ($field === '') {
+            throw new InvalidArgumentException('Cannot get an empty field');
+        }
+        if (array_key_exists($field, $this->_original)) {
+            return $this->_original[$field];
+        }
+
+        return $this->get($field);
+    }
+
+    /**
+     * Gets all original values of the entity.
+     *
+     * @return array
+     */
+    public function getOriginalValues(): array
+    {
+        $originals = $this->_original;
+        $originalKeys = array_keys($originals);
+        foreach ($this->_fields as $key => $value) {
+            if (!in_array($key, $originalKeys, true)) {
+                $originals[$key] = $value;
+            }
+        }
+
+        return $originals;
+    }
+
+    /**
+     * Returns whether this entity contains a field named $field
+     * that contains a non-null value.
+     *
+     * ### Example:
+     *
+     * ```
+     * $entity = new Entity(['id' => 1, 'name' => null]);
+     * $entity->has('id'); // true
+     * $entity->has('name'); // false
+     * $entity->has('last_name'); // false
+     * ```
+     *
+     * You can check multiple fields by passing an array:
+     *
+     * ```
+     * $entity->has(['name', 'last_name']);
+     * ```
+     *
+     * All fields must not be null to get a truthy result.
+     *
+     * When checking multiple fields. All fields must not be null
+     * in order for true to be returned.
+     *
+     * @param array|string $field The field or fields to check.
+     * @return bool
+     */
+    public function has($field): bool
+    {
+        foreach ((array)$field as $prop) {
+            if ($this->_hasAllowsNull) {
+                if (!array_key_exists($prop, $this->_fields) && !static::_accessor($prop, 'get')) {
+                    return false;
+                }
+            } elseif ($this->get($prop) === null) {
+                return false;
+            }
+        }
+
+        return true;
+    }
+
+    /**
+     * Checks that a field is empty
+     *
+     * This is not working like the PHP `empty()` function. The method will
+     * return true for:
+     *
+     * - `''` (empty string)
+     * - `null`
+     * - `[]`
+     *
+     * and false in all other cases.
+     *
+     * @param string $field The field to check.
+     * @return bool
+     */
+    public function isEmpty(string $field): bool
+    {
+        $value = $this->get($field);
+        if (
+            $value === null ||
+            (
+                is_array($value) &&
+                empty($value) ||
+                (
+                    is_string($value) &&
+                    $value === ''
+                )
+            )
+        ) {
+            return true;
+        }
+
+        return false;
+    }
+
+    /**
+     * Checks that a field has a value.
+     *
+     * This method will return true for
+     *
+     * - Non-empty strings
+     * - Non-empty arrays
+     * - Any object
+     * - Integer, even `0`
+     * - Float, even 0.0
+     *
+     * and false in all other cases.
+     *
+     * @param string $field The field to check.
+     * @return bool
+     */
+    public function hasValue(string $field): bool
+    {
+        return !$this->isEmpty($field);
+    }
+
+    /**
+     * Removes a field or list of fields from this entity
+     *
+     * ### Examples:
+     *
+     * ```
+     * $entity->unset('name');
+     * $entity->unset(['name', 'last_name']);
+     * ```
+     *
+     * @param array|string $field The field to unset.
+     * @return $this
+     */
+    public function unset($field)
+    {
+        $field = (array)$field;
+        foreach ($field as $p) {
+            unset($this->_fields[$p], $this->_original[$p], $this->_dirty[$p]);
+        }
+
+        return $this;
+    }
+
+    /**
+     * Removes a field or list of fields from this entity
+     *
+     * @deprecated 4.0.0 Use {@link unset()} instead. Will be removed in 5.0.
+     * @param array|string $field The field to unset.
+     * @return $this
+     */
+    public function unsetProperty($field)
+    {
+        deprecationWarning('EntityTrait::unsetProperty() is deprecated. Use unset() instead.');
+
+        return $this->unset($field);
+    }
+
+    /**
+     * Sets hidden fields.
+     *
+     * @param array $fields An array of fields to hide from array exports.
+     * @param bool $merge Merge the new fields with the existing. By default false.
+     * @return $this
+     */
+    public function setHidden(array $fields, bool $merge = false)
+    {
+        if ($merge === false) {
+            $this->_hidden = $fields;
+
+            return $this;
+        }
+
+        $fields = array_merge($this->_hidden, $fields);
+        $this->_hidden = array_unique($fields);
+
+        return $this;
+    }
+
+    /**
+     * Gets the hidden fields.
+     *
+     * @return array
+     */
+    public function getHidden(): array
+    {
+        return $this->_hidden;
+    }
+
+    /**
+     * Sets the virtual fields on this entity.
+     *
+     * @param array $fields An array of fields to treat as virtual.
+     * @param bool $merge Merge the new fields with the existing. By default false.
+     * @return $this
+     */
+    public function setVirtual(array $fields, bool $merge = false)
+    {
+        if ($merge === false) {
+            $this->_virtual = $fields;
+
+            return $this;
+        }
+
+        $fields = array_merge($this->_virtual, $fields);
+        $this->_virtual = array_unique($fields);
+
+        return $this;
+    }
+
+    /**
+     * Gets the virtual fields on this entity.
+     *
+     * @return array
+     */
+    public function getVirtual(): array
+    {
+        return $this->_virtual;
+    }
+
+    /**
+     * Gets the list of visible fields.
+     *
+     * The list of visible fields is all standard fields
+     * plus virtual fields minus hidden fields.
+     *
+     * @return array A list of fields that are 'visible' in all
+     *     representations.
+     */
+    public function getVisible(): array
+    {
+        $fields = array_keys($this->_fields);
+        $fields = array_merge($fields, $this->_virtual);
+
+        return array_diff($fields, $this->_hidden);
+    }
+
+    /**
+     * Returns an array with all the fields that have been set
+     * to this entity
+     *
+     * This method will recursively transform entities assigned to fields
+     * into arrays as well.
+     *
+     * @return array
+     */
+    public function toArray(): array
+    {
+        $result = [];
+        foreach ($this->getVisible() as $field) {
+            $value = $this->get($field);
+            if (is_array($value)) {
+                $result[$field] = [];
+                foreach ($value as $k => $entity) {
+                    if ($entity instanceof EntityInterface) {
+                        $result[$field][$k] = $entity->toArray();
+                    } else {
+                        $result[$field][$k] = $entity;
+                    }
+                }
+            } elseif ($value instanceof EntityInterface) {
+                $result[$field] = $value->toArray();
+            } else {
+                $result[$field] = $value;
+            }
+        }
+
+        return $result;
+    }
+
+    /**
+     * Returns the fields that will be serialized as JSON
+     *
+     * @return array
+     */
+    public function jsonSerialize(): array
+    {
+        return $this->extract($this->getVisible());
+    }
+
+    /**
+     * Implements isset($entity);
+     *
+     * @param string $offset The offset to check.
+     * @return bool Success
+     */
+    public function offsetExists($offset): bool
+    {
+        return $this->has($offset);
+    }
+
+    /**
+     * Implements $entity[$offset];
+     *
+     * @param string $offset The offset to get.
+     * @return mixed
+     */
+    #[\ReturnTypeWillChange]
+    public function &offsetGet($offset)
+    {
+        return $this->get($offset);
+    }
+
+    /**
+     * Implements $entity[$offset] = $value;
+     *
+     * @param string $offset The offset to set.
+     * @param mixed $value The value to set.
+     * @return void
+     */
+    public function offsetSet($offset, $value): void
+    {
+        $this->set($offset, $value);
+    }
+
+    /**
+     * Implements unset($result[$offset]);
+     *
+     * @param string $offset The offset to remove.
+     * @return void
+     */
+    public function offsetUnset($offset): void
+    {
+        $this->unset($offset);
+    }
+
+    /**
+     * Fetch accessor method name
+     * Accessor methods (available or not) are cached in $_accessors
+     *
+     * @param string $property the field name to derive getter name from
+     * @param string $type the accessor type ('get' or 'set')
+     * @return string method name or empty string (no method available)
+     */
+    protected static function _accessor(string $property, string $type): string
+    {
+        $class = static::class;
+
+        if (isset(static::$_accessors[$class][$type][$property])) {
+            return static::$_accessors[$class][$type][$property];
+        }
+
+        if (!empty(static::$_accessors[$class])) {
+            return static::$_accessors[$class][$type][$property] = '';
+        }
+
+        if (static::class === Entity::class) {
+            return '';
+        }
+
+        foreach (get_class_methods($class) as $method) {
+            $prefix = substr($method, 1, 3);
+            if ($method[0] !== '_' || ($prefix !== 'get' && $prefix !== 'set')) {
+                continue;
+            }
+            $field = lcfirst(substr($method, 4));
+            $snakeField = Inflector::underscore($field);
+            $titleField = ucfirst($field);
+            static::$_accessors[$class][$prefix][$snakeField] = $method;
+            static::$_accessors[$class][$prefix][$field] = $method;
+            static::$_accessors[$class][$prefix][$titleField] = $method;
+        }
+
+        if (!isset(static::$_accessors[$class][$type][$property])) {
+            static::$_accessors[$class][$type][$property] = '';
+        }
+
+        return static::$_accessors[$class][$type][$property];
+    }
+
+    /**
+     * Returns an array with the requested fields
+     * stored in this entity, indexed by field name
+     *
+     * @param array $fields list of fields to be returned
+     * @param bool $onlyDirty Return the requested field only if it is dirty
+     * @return array
+     */
+    public function extract(array $fields, bool $onlyDirty = false): array
+    {
+        $result = [];
+        foreach ($fields as $field) {
+            if (!$onlyDirty || $this->isDirty($field)) {
+                $result[$field] = $this->get($field);
+            }
+        }
+
+        return $result;
+    }
+
+    /**
+     * Returns an array with the requested original fields
+     * stored in this entity, indexed by field name.
+     *
+     * Fields that are unchanged from their original value will be included in the
+     * return of this method.
+     *
+     * @param array $fields List of fields to be returned
+     * @return array
+     */
+    public function extractOriginal(array $fields): array
+    {
+        $result = [];
+        foreach ($fields as $field) {
+            $result[$field] = $this->getOriginal($field);
+        }
+
+        return $result;
+    }
+
+    /**
+     * Returns an array with only the original fields
+     * stored in this entity, indexed by field name.
+     *
+     * This method will only return fields that have been modified since
+     * the entity was built. Unchanged fields will be omitted.
+     *
+     * @param array $fields List of fields to be returned
+     * @return array
+     */
+    public function extractOriginalChanged(array $fields): array
+    {
+        $result = [];
+        foreach ($fields as $field) {
+            $original = $this->getOriginal($field);
+            if ($original !== $this->get($field)) {
+                $result[$field] = $original;
+            }
+        }
+
+        return $result;
+    }
+
+    /**
+     * Sets the dirty status of a single field.
+     *
+     * @param string $field the field to set or check status for
+     * @param bool $isDirty true means the field was changed, false means
+     * it was not changed. Defaults to true.
+     * @return $this
+     */
+    public function setDirty(string $field, bool $isDirty = true)
+    {
+        if ($isDirty === false) {
+            unset($this->_dirty[$field]);
+
+            return $this;
+        }
+
+        $this->_dirty[$field] = true;
+        unset($this->_errors[$field], $this->_invalid[$field]);
+
+        return $this;
+    }
+
+    /**
+     * Checks if the entity is dirty or if a single field of it is dirty.
+     *
+     * @param string|null $field The field to check the status for. Null for the whole entity.
+     * @return bool Whether the field was changed or not
+     */
+    public function isDirty(?string $field = null): bool
+    {
+        if ($field === null) {
+            return !empty($this->_dirty);
+        }
+
+        return isset($this->_dirty[$field]);
+    }
+
+    /**
+     * Gets the dirty fields.
+     *
+     * @return array
+     */
+    public function getDirty(): array
+    {
+        return array_keys($this->_dirty);
+    }
+
+    /**
+     * Sets the entire entity as clean, which means that it will appear as
+     * no fields being modified or added at all. This is an useful call
+     * for an initial object hydration
+     *
+     * @return void
+     */
+    public function clean(): void
+    {
+        $this->_dirty = [];
+        $this->_errors = [];
+        $this->_invalid = [];
+        $this->_original = [];
+    }
+
+    /**
+     * Set the status of this entity.
+     *
+     * Using `true` means that the entity has not been persisted in the database,
+     * `false` that it already is.
+     *
+     * @param bool $new Indicate whether this entity has been persisted.
+     * @return $this
+     */
+    public function setNew(bool $new)
+    {
+        if ($new) {
+            foreach ($this->_fields as $k => $p) {
+                $this->_dirty[$k] = true;
+            }
+        }
+
+        $this->_new = $new;
+
+        return $this;
+    }
+
+    /**
+     * Returns whether this entity has already been persisted.
+     *
+     * @return bool Whether the entity has been persisted.
+     */
+    public function isNew(): bool
+    {
+        if (func_num_args()) {
+            deprecationWarning('Using isNew() as setter is deprecated. Use setNew() instead.');
+
+            $this->setNew(func_get_arg(0));
+        }
+
+        return $this->_new;
+    }
+
+    /**
+     * Returns whether this entity has errors.
+     *
+     * @param bool $includeNested true will check nested entities for hasErrors()
+     * @return bool
+     */
+    public function hasErrors(bool $includeNested = true): bool
+    {
+        if ($this->_hasBeenVisited) {
+            // While recursing through entities, each entity should only be visited once. See https://github.com/cakephp/cakephp/issues/17318
+            return false;
+        }
+
+        if (Hash::filter($this->_errors)) {
+            return true;
+        }
+
+        if ($includeNested === false) {
+            return false;
+        }
+
+        $this->_hasBeenVisited = true;
+        try {
+            foreach ($this->_fields as $field) {
+                if ($this->_readHasErrors($field)) {
+                    return true;
+                }
+            }
+        } finally {
+            $this->_hasBeenVisited = false;
+        }
+
+        return false;
+    }
+
+    /**
+     * Returns all validation errors.
+     *
+     * @return array
+     */
+    public function getErrors(): array
+    {
+        if ($this->_hasBeenVisited) {
+            // While recursing through entities, each entity should only be visited once. See https://github.com/cakephp/cakephp/issues/17318
+            return [];
+        }
+
+        $diff = array_diff_key($this->_fields, $this->_errors);
+
+        $this->_hasBeenVisited = true;
+        try {
+            $errors = $this->_errors + (new Collection($diff))
+                ->filter(function ($value) {
+                    return is_array($value) || $value instanceof EntityInterface;
+                })
+                ->map(function ($value) {
+                    return $this->_readError($value);
+                })
+                ->filter()
+                ->toArray();
+        } finally {
+            $this->_hasBeenVisited = false;
+        }
+
+        return $errors;
+    }
+
+    /**
+     * Returns validation errors of a field
+     *
+     * @param string $field Field name to get the errors from
+     * @return array
+     */
+    public function getError(string $field): array
+    {
+        $errors = $this->_errors[$field] ?? [];
+        if ($errors) {
+            return $errors;
+        }
+
+        return $this->_nestedErrors($field);
+    }
+
+    /**
+     * Sets error messages to the entity
+     *
+     * ## Example
+     *
+     * ```
+     * // Sets the error messages for multiple fields at once
+     * $entity->setErrors(['salary' => ['message'], 'name' => ['another message']]);
+     * ```
+     *
+     * @param array $errors The array of errors to set.
+     * @param bool $overwrite Whether to overwrite pre-existing errors for $fields
+     * @return $this
+     */
+    public function setErrors(array $errors, bool $overwrite = false)
+    {
+        if ($overwrite) {
+            foreach ($errors as $f => $error) {
+                $this->_errors[$f] = (array)$error;
+            }
+
+            return $this;
+        }
+
+        foreach ($errors as $f => $error) {
+            $this->_errors += [$f => []];
+
+            // String messages are appended to the list,
+            // while more complex error structures need their
+            // keys preserved for nested validator.
+            if (is_string($error)) {
+                $this->_errors[$f][] = $error;
+            } else {
+                foreach ($error as $k => $v) {
+                    $this->_errors[$f][$k] = $v;
+                }
+            }
+        }
+
+        return $this;
+    }
+
+    /**
+     * Sets errors for a single field
+     *
+     * ### Example
+     *
+     * ```
+     * // Sets the error messages for a single field
+     * $entity->setError('salary', ['must be numeric', 'must be a positive number']);
+     * ```
+     *
+     * @param string $field The field to get errors for, or the array of errors to set.
+     * @param array|string $errors The errors to be set for $field
+     * @param bool $overwrite Whether to overwrite pre-existing errors for $field
+     * @return $this
+     */
+    public function setError(string $field, $errors, bool $overwrite = false)
+    {
+        if (is_string($errors)) {
+            $errors = [$errors];
+        }
+
+        return $this->setErrors([$field => $errors], $overwrite);
+    }
+
+    /**
+     * Auxiliary method for getting errors in nested entities
+     *
+     * @param string $field the field in this entity to check for errors
+     * @return array errors in nested entity if any
+     */
+    protected function _nestedErrors(string $field): array
+    {
+        // Only one path element, check for nested entity with error.
+        if (strpos($field, '.') === false) {
+            return $this->_readError($this->get($field));
+        }
+        // Try reading the errors data with field as a simple path
+        $error = Hash::get($this->_errors, $field);
+        if ($error !== null) {
+            return $error;
+        }
+        $path = explode('.', $field);
+
+        // Traverse down the related entities/arrays for
+        // the relevant entity.
+        $entity = $this;
+        $len = count($path);
+        while ($len) {
+            $part = array_shift($path);
+            $len = count($path);
+            $val = null;
+            if ($entity instanceof EntityInterface) {
+                $val = $entity->get($part);
+            } elseif (is_array($entity)) {
+                $val = $entity[$part] ?? false;
+            }
+
+            if (
+                is_array($val) ||
+                $val instanceof Traversable ||
+                $val instanceof EntityInterface
+            ) {
+                $entity = $val;
+            } else {
+                $path[] = $part;
+                break;
+            }
+        }
+        if (count($path) <= 1) {
+            return $this->_readError($entity, array_pop($path));
+        }
+
+        return [];
+    }
+
+    /**
+     * Reads if there are errors for one or many objects.
+     *
+     * @param \Cake\Datasource\EntityInterface|array $object The object to read errors from.
+     * @return bool
+     */
+    protected function _readHasErrors($object): bool
+    {
+        if ($object instanceof EntityInterface && $object->hasErrors()) {
+            return true;
+        }
+
+        if (is_array($object)) {
+            foreach ($object as $value) {
+                if ($this->_readHasErrors($value)) {
+                    return true;
+                }
+            }
+        }
+
+        return false;
+    }
+
+    /**
+     * Read the error(s) from one or many objects.
+     *
+     * @param \Cake\Datasource\EntityInterface|iterable $object The object to read errors from.
+     * @param string|null $path The field name for errors.
+     * @return array
+     */
+    protected function _readError($object, $path = null): array
+    {
+        if ($path !== null && $object instanceof EntityInterface) {
+            return $object->getError($path);
+        }
+        if ($object instanceof EntityInterface) {
+            return $object->getErrors();
+        }
+        if (is_iterable($object)) {
+            $array = array_map(function ($val) {
+                if ($val instanceof EntityInterface) {
+                    return $val->getErrors();
+                }
+
+                return null;
+            }, (array)$object);
+
+            return array_filter($array);
+        }
+
+        return [];
+    }
+
+    /**
+     * Get a list of invalid fields and their data for errors upon validation/patching
+     *
+     * @return array
+     */
+    public function getInvalid(): array
+    {
+        return $this->_invalid;
+    }
+
+    /**
+     * Get a single value of an invalid field. Returns null if not set.
+     *
+     * @param string $field The name of the field.
+     * @return mixed|null
+     */
+    public function getInvalidField(string $field)
+    {
+        return $this->_invalid[$field] ?? null;
+    }
+
+    /**
+     * Set fields as invalid and not patchable into the entity.
+     *
+     * This is useful for batch operations when one needs to get the original value for an error message after patching.
+     * This value could not be patched into the entity and is simply copied into the _invalid property for debugging
+     * purposes or to be able to log it away.
+     *
+     * @param array $fields The values to set.
+     * @param bool $overwrite Whether to overwrite pre-existing values for $field.
+     * @return $this
+     */
+    public function setInvalid(array $fields, bool $overwrite = false)
+    {
+        foreach ($fields as $field => $value) {
+            if ($overwrite === true) {
+                $this->_invalid[$field] = $value;
+                continue;
+            }
+            $this->_invalid += [$field => $value];
+        }
+
+        return $this;
+    }
+
+    /**
+     * Sets a field as invalid and not patchable into the entity.
+     *
+     * @param string $field The value to set.
+     * @param mixed $value The invalid value to be set for $field.
+     * @return $this
+     */
+    public function setInvalidField(string $field, $value)
+    {
+        $this->_invalid[$field] = $value;
+
+        return $this;
+    }
+
+    /**
+     * Stores whether a field value can be changed or set in this entity.
+     * The special field `*` can also be marked as accessible or protected, meaning
+     * that any other field specified before will take its value. For example
+     * `$entity->setAccess('*', true)` means that any field not specified already
+     * will be accessible by default.
+     *
+     * You can also call this method with an array of fields, in which case they
+     * will each take the accessibility value specified in the second argument.
+     *
+     * ### Example:
+     *
+     * ```
+     * $entity->setAccess('id', true); // Mark id as not protected
+     * $entity->setAccess('author_id', false); // Mark author_id as protected
+     * $entity->setAccess(['id', 'user_id'], true); // Mark both fields as accessible
+     * $entity->setAccess('*', false); // Mark all fields as protected
+     * ```
+     *
+     * @param array|string $field Single or list of fields to change its accessibility
+     * @param bool $set True marks the field as accessible, false will
+     * mark it as protected.
+     * @return $this
+     */
+    public function setAccess($field, bool $set)
+    {
+        if ($field === '*') {
+            $this->_accessible = array_map(function ($p) use ($set) {
+                return $set;
+            }, $this->_accessible);
+            $this->_accessible['*'] = $set;
+
+            return $this;
+        }
+
+        foreach ((array)$field as $prop) {
+            $this->_accessible[$prop] = $set;
+        }
+
+        return $this;
+    }
+
+    /**
+     * Returns the raw accessible configuration for this entity.
+     * The `*` wildcard refers to all fields.
+     *
+     * @return array
+     */
+    public function getAccessible(): array
+    {
+        return $this->_accessible;
+    }
+
+    /**
+     * Checks if a field is accessible
+     *
+     * ### Example:
+     *
+     * ```
+     * $entity->isAccessible('id'); // Returns whether it can be set or not
+     * ```
+     *
+     * @param string $field Field name to check
+     * @return bool
+     */
+    public function isAccessible(string $field): bool
+    {
+        $value = $this->_accessible[$field] ?? null;
+
+        return ($value === null && !empty($this->_accessible['*'])) || $value;
+    }
+
+    /**
+     * Returns the alias of the repository from which this entity came from.
+     *
+     * @return string
+     */
+    public function getSource(): string
+    {
+        return $this->_registryAlias;
+    }
+
+    /**
+     * Sets the source alias
+     *
+     * @param string $alias the alias of the repository
+     * @return $this
+     */
+    public function setSource(string $alias)
+    {
+        $this->_registryAlias = $alias;
+
+        return $this;
+    }
+
+    /**
+     * Returns a string representation of this object in a human readable format.
+     *
+     * @return string
+     */
+    public function __toString(): string
+    {
+        return (string)json_encode($this, JSON_PRETTY_PRINT);
+    }
+
+    /**
+     * Returns an array that can be used to describe the internal state of this
+     * object.
+     *
+     * @return array
+     */
+    public function __debugInfo(): array
+    {
+        $fields = $this->_fields;
+        foreach ($this->_virtual as $field) {
+            $fields[$field] = $this->$field;
+        }
+
+        return $fields + [
+            '[new]' => $this->isNew(),
+            '[accessible]' => $this->_accessible,
+            '[dirty]' => $this->_dirty,
+            '[original]' => $this->_original,
+            '[virtual]' => $this->_virtual,
+            '[hasErrors]' => $this->hasErrors(),
+            '[errors]' => $this->_errors,
+            '[invalid]' => $this->_invalid,
+            '[repository]' => $this->_registryAlias,
+        ];
+    }
+}
diff --git a/vendor/cakephp/datasource/Exception/InvalidPrimaryKeyException.php b/vendor/cakephp/datasource/Exception/InvalidPrimaryKeyException.php
new file mode 100644
index 0000000..ac7a72b
--- /dev/null
+++ b/vendor/cakephp/datasource/Exception/InvalidPrimaryKeyException.php
@@ -0,0 +1,26 @@
+
+     */
+    protected static $_modelFactories = [];
+
+    /**
+     * Register a callable to generate repositories of a given type.
+     *
+     * @param string $type The name of the repository type the factory function is for.
+     * @param \Cake\Datasource\Locator\LocatorInterface|callable $factory The factory function used to create instances.
+     * @return void
+     */
+    public static function add(string $type, $factory): void
+    {
+        if ($factory instanceof LocatorInterface) {
+            static::$_modelFactories[$type] = $factory;
+
+            return;
+        }
+
+        if (is_callable($factory)) {
+            deprecationWarning(
+                'Using a callable as a locator has been deprecated.'
+                . ' Use an instance of Cake\Datasource\Locator\LocatorInterface instead.'
+            );
+
+            static::$_modelFactories[$type] = $factory;
+
+            return;
+        }
+
+        throw new InvalidArgumentException(sprintf(
+            '`$factory` must be an instance of Cake\Datasource\Locator\LocatorInterface or a callable.'
+            . ' Got type `%s` instead.',
+            getTypeName($factory)
+        ));
+    }
+
+    /**
+     * Drop a model factory.
+     *
+     * @param string $type The name of the repository type to drop the factory for.
+     * @return void
+     */
+    public static function drop(string $type): void
+    {
+        unset(static::$_modelFactories[$type]);
+    }
+
+    /**
+     * Get the factory for the specified repository type.
+     *
+     * @param string $type The repository type to get the factory for.
+     * @throws \InvalidArgumentException If the specified repository type has no factory.
+     * @return \Cake\Datasource\Locator\LocatorInterface|callable The factory for the repository type.
+     */
+    public static function get(string $type)
+    {
+        if (!isset(static::$_modelFactories['Table'])) {
+            static::$_modelFactories['Table'] = new TableLocator();
+        }
+
+        if (!isset(static::$_modelFactories[$type])) {
+            throw new InvalidArgumentException(sprintf(
+                'Unknown repository type "%s". Make sure you register a type before trying to use it.',
+                $type
+            ));
+        }
+
+        return static::$_modelFactories[$type];
+    }
+}
diff --git a/vendor/cakephp/datasource/FixtureInterface.php b/vendor/cakephp/datasource/FixtureInterface.php
new file mode 100644
index 0000000..64c28e4
--- /dev/null
+++ b/vendor/cakephp/datasource/FixtureInterface.php
@@ -0,0 +1,73 @@
+ $fields The values to set.
+     * @param bool $overwrite Whether to overwrite pre-existing values for $field.
+     * @return $this
+     */
+    public function setInvalid(array $fields, bool $overwrite = false);
+
+    /**
+     * Get a single value of an invalid field. Returns null if not set.
+     *
+     * @param string $field The name of the field.
+     * @return mixed|null
+     */
+    public function getInvalidField(string $field);
+
+    /**
+     * Sets a field as invalid and not patchable into the entity.
+     *
+     * @param string $field The value to set.
+     * @param mixed $value The invalid value to be set for $field.
+     * @return $this
+     */
+    public function setInvalidField(string $field, $value);
+}
diff --git a/vendor/cakephp/datasource/LICENSE.txt b/vendor/cakephp/datasource/LICENSE.txt
new file mode 100644
index 0000000..b938c9e
--- /dev/null
+++ b/vendor/cakephp/datasource/LICENSE.txt
@@ -0,0 +1,22 @@
+The MIT License (MIT)
+
+CakePHP(tm) : The Rapid Development PHP Framework (https://cakephp.org)
+Copyright (c) 2005-2020, Cake Software Foundation, Inc. (https://cakefoundation.org)
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
diff --git a/vendor/cakephp/datasource/Locator/AbstractLocator.php b/vendor/cakephp/datasource/Locator/AbstractLocator.php
new file mode 100644
index 0000000..1d925c0
--- /dev/null
+++ b/vendor/cakephp/datasource/Locator/AbstractLocator.php
@@ -0,0 +1,115 @@
+
+     */
+    protected $instances = [];
+
+    /**
+     * Contains a list of options that were passed to get() method.
+     *
+     * @var array
+     */
+    protected $options = [];
+
+    /**
+     * {@inheritDoc}
+     *
+     * @param string $alias The alias name you want to get.
+     * @param array $options The options you want to build the table with.
+     * @return \Cake\Datasource\RepositoryInterface
+     * @throws \RuntimeException When trying to get alias for which instance
+     *   has already been created with different options.
+     */
+    public function get(string $alias, array $options = [])
+    {
+        $storeOptions = $options;
+        unset($storeOptions['allowFallbackClass']);
+
+        if (isset($this->instances[$alias])) {
+            if (!empty($storeOptions) && isset($this->options[$alias]) && $this->options[$alias] !== $storeOptions) {
+                throw new RuntimeException(sprintf(
+                    'You cannot configure "%s", it already exists in the registry.',
+                    $alias
+                ));
+            }
+
+            return $this->instances[$alias];
+        }
+
+        $this->options[$alias] = $storeOptions;
+
+        return $this->instances[$alias] = $this->createInstance($alias, $options);
+    }
+
+    /**
+     * Create an instance of a given classname.
+     *
+     * @param string $alias Repository alias.
+     * @param array $options The options you want to build the instance with.
+     * @return \Cake\Datasource\RepositoryInterface
+     */
+    abstract protected function createInstance(string $alias, array $options);
+
+    /**
+     * @inheritDoc
+     */
+    public function set(string $alias, RepositoryInterface $repository)
+    {
+        return $this->instances[$alias] = $repository;
+    }
+
+    /**
+     * @inheritDoc
+     */
+    public function exists(string $alias): bool
+    {
+        return isset($this->instances[$alias]);
+    }
+
+    /**
+     * @inheritDoc
+     */
+    public function remove(string $alias): void
+    {
+        unset(
+            $this->instances[$alias],
+            $this->options[$alias]
+        );
+    }
+
+    /**
+     * @inheritDoc
+     */
+    public function clear(): void
+    {
+        $this->instances = [];
+        $this->options = [];
+    }
+}
diff --git a/vendor/cakephp/datasource/Locator/LocatorInterface.php b/vendor/cakephp/datasource/Locator/LocatorInterface.php
new file mode 100644
index 0000000..256ae0a
--- /dev/null
+++ b/vendor/cakephp/datasource/Locator/LocatorInterface.php
@@ -0,0 +1,68 @@
+ $options The options you want to build the table with.
+     * @return \Cake\Datasource\RepositoryInterface
+     * @throws \RuntimeException When trying to get alias for which instance
+     *   has already been created with different options.
+     */
+    public function get(string $alias, array $options = []);
+
+    /**
+     * Set a repository instance.
+     *
+     * @param string $alias The alias to set.
+     * @param \Cake\Datasource\RepositoryInterface $repository The repository to set.
+     * @return \Cake\Datasource\RepositoryInterface
+     */
+    public function set(string $alias, RepositoryInterface $repository);
+
+    /**
+     * Check to see if an instance exists in the registry.
+     *
+     * @param string $alias The alias to check for.
+     * @return bool
+     */
+    public function exists(string $alias): bool;
+
+    /**
+     * Removes an repository instance from the registry.
+     *
+     * @param string $alias The alias to remove.
+     * @return void
+     */
+    public function remove(string $alias): void;
+
+    /**
+     * Clears the registry of configuration and instances.
+     *
+     * @return void
+     */
+    public function clear(): void;
+}
diff --git a/vendor/cakephp/datasource/ModelAwareTrait.php b/vendor/cakephp/datasource/ModelAwareTrait.php
new file mode 100644
index 0000000..cfc71c8
--- /dev/null
+++ b/vendor/cakephp/datasource/ModelAwareTrait.php
@@ -0,0 +1,241 @@
+
+     */
+    protected $_modelFactories = [];
+
+    /**
+     * The model type to use.
+     *
+     * @var string
+     */
+    protected $_modelType = 'Table';
+
+    /**
+     * Set the modelClass property based on conventions.
+     *
+     * If the property is already set it will not be overwritten
+     *
+     * @param string $name Class name.
+     * @return void
+     */
+    protected function _setModelClass(string $name): void
+    {
+        if ($this->modelClass === null) {
+            $this->modelClass = $name;
+        }
+    }
+
+    /**
+     * Fetch or construct a model and set it to a property on this object.
+     *
+     * Uses a modelFactory based on `$modelType` to fetch and construct a `RepositoryInterface`
+     * and set it as a property on the current object. The default `modelType`
+     * can be defined with `setModelType()`.
+     *
+     * If a repository provider does not return an object a MissingModelException will
+     * be thrown.
+     *
+     * @param string|null $modelClass Name of model class to load. Defaults to $this->modelClass.
+     *  The name can be an alias like `'Post'` or FQCN like `App\Model\Table\PostsTable::class`.
+     * @param string|null $modelType The type of repository to load. Defaults to the getModelType() value.
+     * @return \Cake\Datasource\RepositoryInterface The model instance created.
+     * @throws \Cake\Datasource\Exception\MissingModelException If the model class cannot be found.
+     * @throws \UnexpectedValueException If $modelClass argument is not provided
+     *   and ModelAwareTrait::$modelClass property value is empty.
+     * @deprecated 4.3.0 Prefer `LocatorAwareTrait::fetchTable()` or `ModelAwareTrait::fetchModel()` instead.
+     */
+    public function loadModel(?string $modelClass = null, ?string $modelType = null): RepositoryInterface
+    {
+        $modelClass = $modelClass ?? $this->modelClass;
+        if (empty($modelClass)) {
+            throw new UnexpectedValueException('Default modelClass is empty');
+        }
+        $modelType = $modelType ?? $this->getModelType();
+
+        $options = [];
+        if (strpos($modelClass, '\\') === false) {
+            [, $alias] = pluginSplit($modelClass, true);
+        } else {
+            $options['className'] = $modelClass;
+            /** @psalm-suppress PossiblyFalseOperand */
+            $alias = substr(
+                $modelClass,
+                strrpos($modelClass, '\\') + 1,
+                -strlen($modelType)
+            );
+            $modelClass = $alias;
+        }
+        if (!property_exists($this, $alias)) {
+            deprecationWarning(
+                '4.5.0 - Dynamic properties will be removed in PHP 8.2. ' .
+                "Add `public \${$alias} = null;` to your class definition or use `#[AllowDynamicProperties]` attribute."
+            );
+        }
+
+        if (isset($this->{$alias})) {
+            return $this->{$alias};
+        }
+
+        $factory = $this->_modelFactories[$modelType] ?? FactoryLocator::get($modelType);
+        if ($factory instanceof LocatorInterface) {
+            $this->{$alias} = $factory->get($modelClass, $options);
+        } else {
+            $this->{$alias} = $factory($modelClass, $options);
+        }
+
+        if (!$this->{$alias}) {
+            throw new MissingModelException([$modelClass, $modelType]);
+        }
+
+        return $this->{$alias};
+    }
+
+    /**
+     * Fetch or construct a model instance from a locator.
+     *
+     * Uses a modelFactory based on `$modelType` to fetch and construct a `RepositoryInterface`
+     * and return it. The default `modelType` can be defined with `setModelType()`.
+     *
+     * Unlike `loadModel()` this method will *not* set an object property.
+     *
+     * If a repository provider does not return an object a MissingModelException will
+     * be thrown.
+     *
+     * @param string|null $modelClass Name of model class to load. Defaults to $this->modelClass.
+     *  The name can be an alias like `'Post'` or FQCN like `App\Model\Table\PostsTable::class`.
+     * @param string|null $modelType The type of repository to load. Defaults to the getModelType() value.
+     * @return \Cake\Datasource\RepositoryInterface The model instance created.
+     * @throws \Cake\Datasource\Exception\MissingModelException If the model class cannot be found.
+     * @throws \UnexpectedValueException If $modelClass argument is not provided
+     *   and ModelAwareTrait::$modelClass property value is empty.
+     */
+    public function fetchModel(?string $modelClass = null, ?string $modelType = null): RepositoryInterface
+    {
+        $modelClass = $modelClass ?? $this->modelClass;
+        if (empty($modelClass)) {
+            throw new UnexpectedValueException('Default modelClass is empty');
+        }
+        $modelType = $modelType ?? $this->getModelType();
+
+        $options = [];
+        if (strpos($modelClass, '\\') === false) {
+            [, $alias] = pluginSplit($modelClass, true);
+        } else {
+            $options['className'] = $modelClass;
+            /** @psalm-suppress PossiblyFalseOperand */
+            $alias = substr(
+                $modelClass,
+                strrpos($modelClass, '\\') + 1,
+                -strlen($modelType)
+            );
+            $modelClass = $alias;
+        }
+
+        $factory = $this->_modelFactories[$modelType] ?? FactoryLocator::get($modelType);
+        if ($factory instanceof LocatorInterface) {
+            $instance = $factory->get($modelClass, $options);
+        } else {
+            $instance = $factory($modelClass, $options);
+        }
+        if ($instance) {
+            return $instance;
+        }
+
+        throw new MissingModelException([$modelClass, $modelType]);
+    }
+
+    /**
+     * Override a existing callable to generate repositories of a given type.
+     *
+     * @param string $type The name of the repository type the factory function is for.
+     * @param \Cake\Datasource\Locator\LocatorInterface|callable $factory The factory function used to create instances.
+     * @return void
+     */
+    public function modelFactory(string $type, $factory): void
+    {
+        if (!$factory instanceof LocatorInterface && !is_callable($factory)) {
+            throw new InvalidArgumentException(sprintf(
+                '`$factory` must be an instance of Cake\Datasource\Locator\LocatorInterface or a callable.'
+                . ' Got type `%s` instead.',
+                getTypeName($factory)
+            ));
+        }
+
+        $this->_modelFactories[$type] = $factory;
+    }
+
+    /**
+     * Get the model type to be used by this class
+     *
+     * @return string
+     */
+    public function getModelType(): string
+    {
+        return $this->_modelType;
+    }
+
+    /**
+     * Set the model type to be used by this class
+     *
+     * @param string $modelType The model type
+     * @return $this
+     */
+    public function setModelType(string $modelType)
+    {
+        $this->_modelType = $modelType;
+
+        return $this;
+    }
+}
diff --git a/vendor/cakephp/datasource/Paginator.php b/vendor/cakephp/datasource/Paginator.php
new file mode 100644
index 0000000..926b231
--- /dev/null
+++ b/vendor/cakephp/datasource/Paginator.php
@@ -0,0 +1,10 @@
+
+     */
+    protected $_defaultConfig = [
+        'page' => 1,
+        'limit' => 20,
+        'maxLimit' => 100,
+        'allowedParameters' => ['limit', 'sort', 'page', 'direction'],
+        'sortableFields' => null,
+        'finder' => 'all',
+    ];
+
+    /**
+     * Paging params after pagination operation is done.
+     *
+     * @var array
+     */
+    protected $_pagingParams = [];
+
+    /**
+     * Handles automatic pagination of model records.
+     *
+     * ### Configuring pagination
+     *
+     * When calling `paginate()` you can use the $settings parameter to pass in
+     * pagination settings. These settings are used to build the queries made
+     * and control other pagination settings.
+     *
+     * If your settings contain a key with the current table's alias. The data
+     * inside that key will be used. Otherwise, the top level configuration will
+     * be used.
+     *
+     * ```
+     *  $settings = [
+     *    'limit' => 20,
+     *    'maxLimit' => 100
+     *  ];
+     *  $results = $paginator->paginate($table, $settings);
+     * ```
+     *
+     * The above settings will be used to paginate any repository. You can configure
+     * repository specific settings by keying the settings with the repository alias.
+     *
+     * ```
+     *  $settings = [
+     *    'Articles' => [
+     *      'limit' => 20,
+     *      'maxLimit' => 100
+     *    ],
+     *    'Comments' => [ ... ]
+     *  ];
+     *  $results = $paginator->paginate($table, $settings);
+     * ```
+     *
+     * This would allow you to have different pagination settings for
+     * `Articles` and `Comments` repositories.
+     *
+     * ### Controlling sort fields
+     *
+     * By default CakePHP will automatically allow sorting on any column on the
+     * repository object being paginated. Often times you will want to allow
+     * sorting on either associated columns or calculated fields. In these cases
+     * you will need to define an allowed list of all the columns you wish to allow
+     * sorting on. You can define the allowed sort fields in the `$settings` parameter:
+     *
+     * ```
+     * $settings = [
+     *   'Articles' => [
+     *     'finder' => 'custom',
+     *     'sortableFields' => ['title', 'author_id', 'comment_count'],
+     *   ]
+     * ];
+     * ```
+     *
+     * Passing an empty array as sortableFields disallows sorting altogether.
+     *
+     * ### Paginating with custom finders
+     *
+     * You can paginate with any find type defined on your table using the
+     * `finder` option.
+     *
+     * ```
+     *  $settings = [
+     *    'Articles' => [
+     *      'finder' => 'popular'
+     *    ]
+     *  ];
+     *  $results = $paginator->paginate($table, $settings);
+     * ```
+     *
+     * Would paginate using the `find('popular')` method.
+     *
+     * You can also pass an already created instance of a query to this method:
+     *
+     * ```
+     * $query = $this->Articles->find('popular')->matching('Tags', function ($q) {
+     *   return $q->where(['name' => 'CakePHP'])
+     * });
+     * $results = $paginator->paginate($query);
+     * ```
+     *
+     * ### Scoping Request parameters
+     *
+     * By using request parameter scopes you can paginate multiple queries in
+     * the same controller action:
+     *
+     * ```
+     * $articles = $paginator->paginate($articlesQuery, ['scope' => 'articles']);
+     * $tags = $paginator->paginate($tagsQuery, ['scope' => 'tags']);
+     * ```
+     *
+     * Each of the above queries will use different query string parameter sets
+     * for pagination data. An example URL paginating both results would be:
+     *
+     * ```
+     * /dashboard?articles[page]=1&tags[page]=2
+     * ```
+     *
+     * @param \Cake\Datasource\RepositoryInterface|\Cake\Datasource\QueryInterface $object The repository or query
+     *   to paginate.
+     * @param array $params Request params
+     * @param array $settings The settings/configuration used for pagination.
+     * @return \Cake\Datasource\ResultSetInterface Query results
+     * @throws \Cake\Datasource\Paging\Exception\PageOutOfBoundsException
+     */
+    public function paginate(object $object, array $params = [], array $settings = []): ResultSetInterface
+    {
+        $query = null;
+        if ($object instanceof QueryInterface) {
+            $query = $object;
+            $object = $query->getRepository();
+            if ($object === null) {
+                throw new CakeException('No repository set for query.');
+            }
+        }
+
+        $data = $this->extractData($object, $params, $settings);
+        $query = $this->getQuery($object, $query, $data);
+
+        $cleanQuery = clone $query;
+        $results = $query->all();
+        $data['numResults'] = count($results);
+        $data['count'] = $this->getCount($cleanQuery, $data);
+
+        $pagingParams = $this->buildParams($data);
+        $alias = $object->getAlias();
+        $this->_pagingParams = [$alias => $pagingParams];
+        if ($pagingParams['requestedPage'] > $pagingParams['page']) {
+            throw new PageOutOfBoundsException([
+                'requestedPage' => $pagingParams['requestedPage'],
+                'pagingParams' => $this->_pagingParams,
+            ]);
+        }
+
+        return $results;
+    }
+
+    /**
+     * Get query for fetching paginated results.
+     *
+     * @param \Cake\Datasource\RepositoryInterface $object Repository instance.
+     * @param \Cake\Datasource\QueryInterface|null $query Query Instance.
+     * @param array $data Pagination data.
+     * @return \Cake\Datasource\QueryInterface
+     */
+    protected function getQuery(RepositoryInterface $object, ?QueryInterface $query, array $data): QueryInterface
+    {
+        $options = $data['options'];
+        unset(
+            $options['scope'],
+            $options['sort'],
+            $options['direction'],
+        );
+
+        if ($query === null) {
+            $query = $object->find($data['finder'], $options);
+        } else {
+            $query->applyOptions($options);
+        }
+
+        return $query;
+    }
+
+    /**
+     * Get total count of records.
+     *
+     * @param \Cake\Datasource\QueryInterface $query Query instance.
+     * @param array $data Pagination data.
+     * @return int|null
+     */
+    protected function getCount(QueryInterface $query, array $data): ?int
+    {
+        return $query->count();
+    }
+
+    /**
+     * Extract pagination data needed
+     *
+     * @param \Cake\Datasource\RepositoryInterface $object The repository object.
+     * @param array $params Request params
+     * @param array $settings The settings/configuration used for pagination.
+     * @return array Array with keys 'defaults', 'options' and 'finder'
+     */
+    protected function extractData(RepositoryInterface $object, array $params, array $settings): array
+    {
+        $alias = $object->getAlias();
+        $defaults = $this->getDefaults($alias, $settings);
+
+        $validSettings = array_merge(
+            array_keys($this->_defaultConfig),
+            ['whitelist', 'sortWhitelist', 'order', 'scope']
+        );
+        $extraSettings = array_diff_key($defaults, array_flip($validSettings));
+        if ($extraSettings) {
+            deprecationWarning(
+                'Passing query options as paginator settings is deprecated.'
+                . ' Use a custom finder through `finder` config instead.'
+                . ' Extra keys found are: ' . implode(',', array_keys($extraSettings))
+            );
+        }
+
+        $options = $this->mergeOptions($params, $defaults);
+        $options = $this->validateSort($object, $options);
+        $options = $this->checkLimit($options);
+
+        $options += ['page' => 1, 'scope' => null];
+        $options['page'] = (int)$options['page'] < 1 ? 1 : (int)$options['page'];
+        [$finder, $options] = $this->_extractFinder($options);
+
+        return compact('defaults', 'options', 'finder');
+    }
+
+    /**
+     * Build pagination params.
+     *
+     * @param array $data Paginator data containing keys 'options',
+     *   'count', 'defaults', 'finder', 'numResults'.
+     * @return array Paging params.
+     */
+    protected function buildParams(array $data): array
+    {
+        $limit = $data['options']['limit'];
+
+        $paging = [
+            'count' => $data['count'],
+            'current' => $data['numResults'],
+            'perPage' => $limit,
+            'page' => $data['options']['page'],
+            'requestedPage' => $data['options']['page'],
+        ];
+
+        $paging = $this->addPageCountParams($paging, $data);
+        $paging = $this->addStartEndParams($paging, $data);
+        $paging = $this->addPrevNextParams($paging, $data);
+        $paging = $this->addSortingParams($paging, $data);
+
+        $paging += [
+            'limit' => $data['defaults']['limit'] != $limit ? $limit : null,
+            'scope' => $data['options']['scope'],
+            'finder' => $data['finder'],
+        ];
+
+        return $paging;
+    }
+
+    /**
+     * Add "page" and "pageCount" params.
+     *
+     * @param array $params Paging params.
+     * @param array $data Paginator data.
+     * @return array Updated params.
+     */
+    protected function addPageCountParams(array $params, array $data): array
+    {
+        $page = $params['page'];
+        $pageCount = 0;
+
+        if ($params['count'] !== null) {
+            $pageCount = max((int)ceil($params['count'] / $params['perPage']), 1);
+            $page = min($page, $pageCount);
+        } elseif ($params['current'] === 0 && $params['requestedPage'] > 1) {
+            $page = 1;
+        }
+
+        $params['page'] = $page;
+        $params['pageCount'] = $pageCount;
+
+        return $params;
+    }
+
+    /**
+     * Add "start" and "end" params.
+     *
+     * @param array $params Paging params.
+     * @param array $data Paginator data.
+     * @return array Updated params.
+     */
+    protected function addStartEndParams(array $params, array $data): array
+    {
+        $start = $end = 0;
+
+        if ($params['current'] > 0) {
+            $start = (($params['page'] - 1) * $params['perPage']) + 1;
+            $end = $start + $params['current'] - 1;
+        }
+
+        $params['start'] = $start;
+        $params['end'] = $end;
+
+        return $params;
+    }
+
+    /**
+     * Add "prevPage" and "nextPage" params.
+     *
+     * @param array $params Paginator params.
+     * @param array $data Paging data.
+     * @return array Updated params.
+     */
+    protected function addPrevNextParams(array $params, array $data): array
+    {
+        $params['prevPage'] = $params['page'] > 1;
+        if ($params['count'] === null) {
+            $params['nextPage'] = true;
+        } else {
+            $params['nextPage'] = $params['count'] > $params['page'] * $params['perPage'];
+        }
+
+        return $params;
+    }
+
+    /**
+     * Add sorting / ordering params.
+     *
+     * @param array $params Paginator params.
+     * @param array $data Paging data.
+     * @return array Updated params.
+     */
+    protected function addSortingParams(array $params, array $data): array
+    {
+        $defaults = $data['defaults'];
+        $order = (array)$data['options']['order'];
+        $sortDefault = $directionDefault = false;
+
+        if (!empty($defaults['order']) && count($defaults['order']) >= 1) {
+            $sortDefault = key($defaults['order']);
+            $directionDefault = current($defaults['order']);
+        }
+
+        $params += [
+            'sort' => $data['options']['sort'],
+            'direction' => isset($data['options']['sort']) && count($order) ? current($order) : null,
+            'sortDefault' => $sortDefault,
+            'directionDefault' => $directionDefault,
+            'completeSort' => $order,
+        ];
+
+        return $params;
+    }
+
+    /**
+     * Extracts the finder name and options out of the provided pagination options.
+     *
+     * @param array $options the pagination options.
+     * @return array An array containing in the first position the finder name
+     *   and in the second the options to be passed to it.
+     */
+    protected function _extractFinder(array $options): array
+    {
+        $type = !empty($options['finder']) ? $options['finder'] : 'all';
+        unset(
+            $options['finder'],
+            $options['maxLimit'],
+            $options['allowedParameters'],
+            $options['whitelist'],
+            $options['sortableFields'],
+            $options['sortWhitelist'],
+        );
+
+        if (is_array($type)) {
+            $options = (array)current($type) + $options;
+            $type = key($type);
+        }
+
+        return [$type, $options];
+    }
+
+    /**
+     * Get paging params after pagination operation.
+     *
+     * @return array
+     */
+    public function getPagingParams(): array
+    {
+        return $this->_pagingParams;
+    }
+
+    /**
+     * Shim method for reading the deprecated whitelist or allowedParameters options
+     *
+     * @return array
+     */
+    protected function getAllowedParameters(): array
+    {
+        $allowed = $this->getConfig('allowedParameters');
+        if (!$allowed) {
+            $allowed = [];
+        }
+        $whitelist = $this->getConfig('whitelist');
+        if ($whitelist) {
+            deprecationWarning('The `whitelist` option is deprecated. Use the `allowedParameters` option instead.');
+
+            return array_merge($allowed, $whitelist);
+        }
+
+        return $allowed;
+    }
+
+    /**
+     * Shim method for reading the deprecated sortWhitelist or sortableFields options.
+     *
+     * @param array $config The configuration data to coalesce and emit warnings on.
+     * @return array|null
+     */
+    protected function getSortableFields(array $config): ?array
+    {
+        $allowed = $config['sortableFields'] ?? null;
+        if ($allowed !== null) {
+            return $allowed;
+        }
+        $deprecated = $config['sortWhitelist'] ?? null;
+        if ($deprecated !== null) {
+            deprecationWarning('The `sortWhitelist` option is deprecated. Use `sortableFields` instead.');
+        }
+
+        return $deprecated;
+    }
+
+    /**
+     * Merges the various options that Paginator uses.
+     * Pulls settings together from the following places:
+     *
+     * - General pagination settings
+     * - Model specific settings.
+     * - Request parameters
+     *
+     * The result of this method is the aggregate of all the option sets
+     * combined together. You can change config value `allowedParameters` to modify
+     * which options/values can be set using request parameters.
+     *
+     * @param array $params Request params.
+     * @param array $settings The settings to merge with the request data.
+     * @return array Array of merged options.
+     */
+    public function mergeOptions(array $params, array $settings): array
+    {
+        if (!empty($settings['scope'])) {
+            $scope = $settings['scope'];
+            $params = !empty($params[$scope]) ? (array)$params[$scope] : [];
+        }
+
+        $allowed = $this->getAllowedParameters();
+        $params = array_intersect_key($params, array_flip($allowed));
+
+        return array_merge($settings, $params);
+    }
+
+    /**
+     * Get the settings for a $model. If there are no settings for a specific
+     * repository, the general settings will be used.
+     *
+     * @param string $alias Model name to get settings for.
+     * @param array $settings The settings which is used for combining.
+     * @return array An array of pagination settings for a model,
+     *   or the general settings.
+     */
+    public function getDefaults(string $alias, array $settings): array
+    {
+        if (isset($settings[$alias])) {
+            $settings = $settings[$alias];
+        }
+
+        $defaults = $this->getConfig();
+        $defaults['whitelist'] = $defaults['allowedParameters'] = $this->getAllowedParameters();
+
+        $maxLimit = $settings['maxLimit'] ?? $defaults['maxLimit'];
+        $limit = $settings['limit'] ?? $defaults['limit'];
+
+        if ($limit > $maxLimit) {
+            $limit = $maxLimit;
+        }
+
+        $settings['maxLimit'] = $maxLimit;
+        $settings['limit'] = $limit;
+
+        return $settings + $defaults;
+    }
+
+    /**
+     * Validate that the desired sorting can be performed on the $object.
+     *
+     * Only fields or virtualFields can be sorted on. The direction param will
+     * also be sanitized. Lastly sort + direction keys will be converted into
+     * the model friendly order key.
+     *
+     * You can use the allowedParameters option to control which columns/fields are
+     * available for sorting via URL parameters. This helps prevent users from ordering large
+     * result sets on un-indexed values.
+     *
+     * If you need to sort on associated columns or synthetic properties you
+     * will need to use the `sortableFields` option.
+     *
+     * Any columns listed in the allowed sort fields will be implicitly trusted.
+     * You can use this to sort on synthetic columns, or columns added in custom
+     * find operations that may not exist in the schema.
+     *
+     * The default order options provided to paginate() will be merged with the user's
+     * requested sorting field/direction.
+     *
+     * @param \Cake\Datasource\RepositoryInterface $object Repository object.
+     * @param array $options The pagination options being used for this request.
+     * @return array An array of options with sort + direction removed and
+     *   replaced with order if possible.
+     */
+    public function validateSort(RepositoryInterface $object, array $options): array
+    {
+        if (isset($options['sort'])) {
+            $direction = null;
+            if (isset($options['direction'])) {
+                $direction = strtolower($options['direction']);
+            }
+            if (!in_array($direction, ['asc', 'desc'], true)) {
+                $direction = 'asc';
+            }
+
+            $order = isset($options['order']) && is_array($options['order']) ? $options['order'] : [];
+            if ($order && $options['sort'] && strpos($options['sort'], '.') === false) {
+                $order = $this->_removeAliases($order, $object->getAlias());
+            }
+
+            $options['order'] = [$options['sort'] => $direction] + $order;
+        } else {
+            $options['sort'] = null;
+        }
+        unset($options['direction']);
+
+        if (empty($options['order'])) {
+            $options['order'] = [];
+        }
+        if (!is_array($options['order'])) {
+            return $options;
+        }
+
+        $sortAllowed = false;
+        $allowed = $this->getSortableFields($options);
+        if ($allowed !== null) {
+            $options['sortableFields'] = $options['sortWhitelist'] = $allowed;
+
+            $field = key($options['order']);
+            $sortAllowed = in_array($field, $allowed, true);
+            if (!$sortAllowed) {
+                $options['order'] = [];
+                $options['sort'] = null;
+
+                return $options;
+            }
+        }
+
+        if (
+            $options['sort'] === null
+            && count($options['order']) >= 1
+            && !is_numeric(key($options['order']))
+        ) {
+            $options['sort'] = key($options['order']);
+        }
+
+        $options['order'] = $this->_prefix($object, $options['order'], $sortAllowed);
+
+        return $options;
+    }
+
+    /**
+     * Remove alias if needed.
+     *
+     * @param array $fields Current fields
+     * @param string $model Current model alias
+     * @return array $fields Unaliased fields where applicable
+     */
+    protected function _removeAliases(array $fields, string $model): array
+    {
+        $result = [];
+        foreach ($fields as $field => $sort) {
+            if (is_int($field)) {
+                throw new CakeException(sprintf(
+                    'The `order` config must be an associative array. Found invalid value with numeric key: `%s`',
+                    $sort
+                ));
+            }
+
+            if (strpos($field, '.') === false) {
+                $result[$field] = $sort;
+                continue;
+            }
+
+            [$alias, $currentField] = explode('.', $field);
+
+            if ($alias === $model) {
+                $result[$currentField] = $sort;
+                continue;
+            }
+
+            $result[$field] = $sort;
+        }
+
+        return $result;
+    }
+
+    /**
+     * Prefixes the field with the table alias if possible.
+     *
+     * @param \Cake\Datasource\RepositoryInterface $object Repository object.
+     * @param array $order Order array.
+     * @param bool $allowed Whether the field was allowed.
+     * @return array Final order array.
+     */
+    protected function _prefix(RepositoryInterface $object, array $order, bool $allowed = false): array
+    {
+        $tableAlias = $object->getAlias();
+        $tableOrder = [];
+        foreach ($order as $key => $value) {
+            if (is_numeric($key)) {
+                $tableOrder[] = $value;
+                continue;
+            }
+            $field = $key;
+            $alias = $tableAlias;
+
+            if (strpos($key, '.') !== false) {
+                [$alias, $field] = explode('.', $key);
+            }
+            $correctAlias = ($tableAlias === $alias);
+
+            if ($correctAlias && $allowed) {
+                // Disambiguate fields in schema. As id is quite common.
+                if ($object->hasField($field)) {
+                    $field = $alias . '.' . $field;
+                }
+                $tableOrder[$field] = $value;
+            } elseif ($correctAlias && $object->hasField($field)) {
+                $tableOrder[$tableAlias . '.' . $field] = $value;
+            } elseif (!$correctAlias && $allowed) {
+                $tableOrder[$alias . '.' . $field] = $value;
+            }
+        }
+
+        return $tableOrder;
+    }
+
+    /**
+     * Check the limit parameter and ensure it's within the maxLimit bounds.
+     *
+     * @param array $options An array of options with a limit key to be checked.
+     * @return array An array of options for pagination.
+     */
+    public function checkLimit(array $options): array
+    {
+        $options['limit'] = (int)$options['limit'];
+        if ($options['limit'] < 1) {
+            $options['limit'] = 1;
+        }
+        $options['limit'] = max(min($options['limit'], $options['maxLimit']), 1);
+
+        return $options;
+    }
+}
+
+// phpcs:disable
+class_alias(
+    'Cake\Datasource\Paging\NumericPaginator',
+    'Cake\Datasource\Paginator'
+);
+// phpcs:enable
diff --git a/vendor/cakephp/datasource/Paging/PaginatorInterface.php b/vendor/cakephp/datasource/Paging/PaginatorInterface.php
new file mode 100644
index 0000000..4d30597
--- /dev/null
+++ b/vendor/cakephp/datasource/Paging/PaginatorInterface.php
@@ -0,0 +1,50 @@
+_key = $key;
+
+        if (!is_string($config) && !($config instanceof CacheInterface)) {
+            throw new RuntimeException('Cache configs must be strings or \Psr\SimpleCache\CacheInterface instances.');
+        }
+        $this->_config = $config;
+    }
+
+    /**
+     * Load the cached results from the cache or run the query.
+     *
+     * @param object $query The query the cache read is for.
+     * @return mixed|null Either the cached results or null.
+     */
+    public function fetch(object $query)
+    {
+        $key = $this->_resolveKey($query);
+        $storage = $this->_resolveCacher();
+        $result = $storage->get($key);
+        if (empty($result)) {
+            return null;
+        }
+
+        return $result;
+    }
+
+    /**
+     * Store the result set into the cache.
+     *
+     * @param object $query The query the cache read is for.
+     * @param \Traversable $results The result set to store.
+     * @return bool True if the data was successfully cached, false on failure
+     */
+    public function store(object $query, Traversable $results): bool
+    {
+        $key = $this->_resolveKey($query);
+        $storage = $this->_resolveCacher();
+
+        return $storage->set($key, $results);
+    }
+
+    /**
+     * Get/generate the cache key.
+     *
+     * @param object $query The query to generate a key for.
+     * @return string
+     * @throws \RuntimeException
+     */
+    protected function _resolveKey(object $query): string
+    {
+        if (is_string($this->_key)) {
+            return $this->_key;
+        }
+        $func = $this->_key;
+        $key = $func($query);
+        if (!is_string($key)) {
+            $msg = sprintf('Cache key functions must return a string. Got %s.', var_export($key, true));
+            throw new RuntimeException($msg);
+        }
+
+        return $key;
+    }
+
+    /**
+     * Get the cache engine.
+     *
+     * @return \Psr\SimpleCache\CacheInterface
+     */
+    protected function _resolveCacher()
+    {
+        if (is_string($this->_config)) {
+            return Cache::pool($this->_config);
+        }
+
+        return $this->_config;
+    }
+}
diff --git a/vendor/cakephp/datasource/QueryInterface.php b/vendor/cakephp/datasource/QueryInterface.php
new file mode 100644
index 0000000..fc7023a
--- /dev/null
+++ b/vendor/cakephp/datasource/QueryInterface.php
@@ -0,0 +1,406 @@
+ value array representing a single aliased field
+     * that can be passed directly to the select() method.
+     * The key will contain the alias and the value the actual field name.
+     *
+     * If the field is already aliased, then it will not be changed.
+     * If no $alias is passed, the default table for this query will be used.
+     *
+     * @param string $field The field to alias
+     * @param string|null $alias the alias used to prefix the field
+     * @return array
+     */
+    public function aliasField(string $field, ?string $alias = null): array;
+
+    /**
+     * Runs `aliasField()` for each field in the provided list and returns
+     * the result under a single array.
+     *
+     * @param array $fields The fields to alias
+     * @param string|null $defaultAlias The default alias
+     * @return array
+     */
+    public function aliasFields(array $fields, ?string $defaultAlias = null): array;
+
+    /**
+     * Fetch the results for this query.
+     *
+     * Will return either the results set through setResult(), or execute this query
+     * and return the ResultSetDecorator object ready for streaming of results.
+     *
+     * ResultSetDecorator is a traversable object that implements the methods found
+     * on Cake\Collection\Collection.
+     *
+     * @return \Cake\Datasource\ResultSetInterface
+     */
+    public function all(): ResultSetInterface;
+
+    /**
+     * Populates or adds parts to current query clauses using an array.
+     * This is handy for passing all query clauses at once. The option array accepts:
+     *
+     * - fields: Maps to the select method
+     * - conditions: Maps to the where method
+     * - limit: Maps to the limit method
+     * - order: Maps to the order method
+     * - offset: Maps to the offset method
+     * - group: Maps to the group method
+     * - having: Maps to the having method
+     * - contain: Maps to the contain options for eager loading
+     * - join: Maps to the join method
+     * - page: Maps to the page method
+     *
+     * ### Example:
+     *
+     * ```
+     * $query->applyOptions([
+     *   'fields' => ['id', 'name'],
+     *   'conditions' => [
+     *     'created >=' => '2013-01-01'
+     *   ],
+     *   'limit' => 10
+     * ]);
+     * ```
+     *
+     * Is equivalent to:
+     *
+     * ```
+     *  $query
+     *  ->select(['id', 'name'])
+     *  ->where(['created >=' => '2013-01-01'])
+     *  ->limit(10)
+     * ```
+     *
+     * @param array $options list of query clauses to apply new parts to.
+     * @return $this
+     */
+    public function applyOptions(array $options);
+
+    /**
+     * Apply custom finds to against an existing query object.
+     *
+     * Allows custom find methods to be combined and applied to each other.
+     *
+     * ```
+     * $repository->find('all')->find('recent');
+     * ```
+     *
+     * The above is an example of stacking multiple finder methods onto
+     * a single query.
+     *
+     * @param string $finder The finder method to use.
+     * @param array $options The options for the finder.
+     * @return static Returns a modified query.
+     */
+    public function find(string $finder, array $options = []);
+
+    /**
+     * Returns the first result out of executing this query, if the query has not been
+     * executed before, it will set the limit clause to 1 for performance reasons.
+     *
+     * ### Example:
+     *
+     * ```
+     * $singleUser = $query->select(['id', 'username'])->first();
+     * ```
+     *
+     * @return \Cake\Datasource\EntityInterface|array|null the first result from the ResultSet
+     */
+    public function first();
+
+    /**
+     * Returns the total amount of results for the query.
+     *
+     * @return int
+     */
+    public function count(): int;
+
+    /**
+     * Sets the number of records that should be retrieved from database,
+     * accepts an integer or an expression object that evaluates to an integer.
+     * In some databases, this operation might not be supported or will require
+     * the query to be transformed in order to limit the result set size.
+     *
+     * ### Examples
+     *
+     * ```
+     * $query->limit(10) // generates LIMIT 10
+     * $query->limit($query->newExpr()->add(['1 + 1'])); // LIMIT (1 + 1)
+     * ```
+     *
+     * @param \Cake\Database\ExpressionInterface|int|null $limit number of records to be returned
+     * @return $this
+     */
+    public function limit($limit);
+
+    /**
+     * Sets the number of records that should be skipped from the original result set
+     * This is commonly used for paginating large results. Accepts an integer or an
+     * expression object that evaluates to an integer.
+     *
+     * In some databases, this operation might not be supported or will require
+     * the query to be transformed in order to limit the result set size.
+     *
+     * ### Examples
+     *
+     * ```
+     *  $query->offset(10) // generates OFFSET 10
+     *  $query->offset($query->newExpr()->add(['1 + 1'])); // OFFSET (1 + 1)
+     * ```
+     *
+     * @param \Cake\Database\ExpressionInterface|int|null $offset number of records to be skipped
+     * @return $this
+     */
+    public function offset($offset);
+
+    /**
+     * Adds a single or multiple fields to be used in the ORDER clause for this query.
+     * Fields can be passed as an array of strings, array of expression
+     * objects, a single expression or a single string.
+     *
+     * If an array is passed, keys will be used as the field itself and the value will
+     * represent the order in which such field should be ordered. When called multiple
+     * times with the same fields as key, the last order definition will prevail over
+     * the others.
+     *
+     * By default this function will append any passed argument to the list of fields
+     * to be selected, unless the second argument is set to true.
+     *
+     * ### Examples:
+     *
+     * ```
+     * $query->order(['title' => 'DESC', 'author_id' => 'ASC']);
+     * ```
+     *
+     * Produces:
+     *
+     * `ORDER BY title DESC, author_id ASC`
+     *
+     * ```
+     * $query
+     *     ->order(['title' => $query->newExpr('DESC NULLS FIRST')])
+     *     ->order('author_id');
+     * ```
+     *
+     * Will generate:
+     *
+     * `ORDER BY title DESC NULLS FIRST, author_id`
+     *
+     * ```
+     * $expression = $query->newExpr()->add(['id % 2 = 0']);
+     * $query->order($expression)->order(['title' => 'ASC']);
+     * ```
+     *
+     * Will become:
+     *
+     * `ORDER BY (id %2 = 0), title ASC`
+     *
+     * If you need to set complex expressions as order conditions, you
+     * should use `orderAsc()` or `orderDesc()`.
+     *
+     * @param \Cake\Database\ExpressionInterface|\Closure|array|string $fields fields to be added to the list
+     * @param bool $overwrite whether to reset order with field list or not
+     * @return $this
+     */
+    public function order($fields, $overwrite = false);
+
+    /**
+     * Set the page of results you want.
+     *
+     * This method provides an easier to use interface to set the limit + offset
+     * in the record set you want as results. If empty the limit will default to
+     * the existing limit clause, and if that too is empty, then `25` will be used.
+     *
+     * Pages must start at 1.
+     *
+     * @param int $num The page number you want.
+     * @param int|null $limit The number of rows you want in the page. If null
+     *  the current limit clause will be used.
+     * @return $this
+     * @throws \InvalidArgumentException If page number < 1.
+     */
+    public function page(int $num, ?int $limit = null);
+
+    /**
+     * Returns an array representation of the results after executing the query.
+     *
+     * @return array
+     */
+    public function toArray(): array;
+
+    /**
+     * Set the default Table object that will be used by this query
+     * and form the `FROM` clause.
+     *
+     * @param \Cake\Datasource\RepositoryInterface $repository The default repository object to use
+     * @return $this
+     */
+    public function repository(RepositoryInterface $repository);
+
+    /**
+     * Returns the default repository object that will be used by this query,
+     * that is, the repository that will appear in the from clause.
+     *
+     * @return \Cake\Datasource\RepositoryInterface|null $repository The default repository object to use
+     */
+    public function getRepository(): ?RepositoryInterface;
+
+    /**
+     * Adds a condition or set of conditions to be used in the WHERE clause for this
+     * query. Conditions can be expressed as an array of fields as keys with
+     * comparison operators in it, the values for the array will be used for comparing
+     * the field to such literal. Finally, conditions can be expressed as a single
+     * string or an array of strings.
+     *
+     * When using arrays, each entry will be joined to the rest of the conditions using
+     * an AND operator. Consecutive calls to this function will also join the new
+     * conditions specified using the AND operator. Additionally, values can be
+     * expressed using expression objects which can include other query objects.
+     *
+     * Any conditions created with this methods can be used with any SELECT, UPDATE
+     * and DELETE type of queries.
+     *
+     * ### Conditions using operators:
+     *
+     * ```
+     *  $query->where([
+     *      'posted >=' => new DateTime('3 days ago'),
+     *      'title LIKE' => 'Hello W%',
+     *      'author_id' => 1,
+     *  ], ['posted' => 'datetime']);
+     * ```
+     *
+     * The previous example produces:
+     *
+     * `WHERE posted >= 2012-01-27 AND title LIKE 'Hello W%' AND author_id = 1`
+     *
+     * Second parameter is used to specify what type is expected for each passed
+     * key. Valid types can be used from the mapped with Database\Type class.
+     *
+     * ### Nesting conditions with conjunctions:
+     *
+     * ```
+     *  $query->where([
+     *      'author_id !=' => 1,
+     *      'OR' => ['published' => true, 'posted <' => new DateTime('now')],
+     *      'NOT' => ['title' => 'Hello']
+     *  ], ['published' => boolean, 'posted' => 'datetime']
+     * ```
+     *
+     * The previous example produces:
+     *
+     * `WHERE author_id = 1 AND (published = 1 OR posted < '2012-02-01') AND NOT (title = 'Hello')`
+     *
+     * You can nest conditions using conjunctions as much as you like. Sometimes, you
+     * may want to define 2 different options for the same key, in that case, you can
+     * wrap each condition inside a new array:
+     *
+     * `$query->where(['OR' => [['published' => false], ['published' => true]])`
+     *
+     * Keep in mind that every time you call where() with the third param set to false
+     * (default), it will join the passed conditions to the previous stored list using
+     * the AND operator. Also, using the same array key twice in consecutive calls to
+     * this method will not override the previous value.
+     *
+     * ### Using expressions objects:
+     *
+     * ```
+     *  $exp = $query->newExpr()->add(['id !=' => 100, 'author_id' != 1])->tieWith('OR');
+     *  $query->where(['published' => true], ['published' => 'boolean'])->where($exp);
+     * ```
+     *
+     * The previous example produces:
+     *
+     * `WHERE (id != 100 OR author_id != 1) AND published = 1`
+     *
+     * Other Query objects that be used as conditions for any field.
+     *
+     * ### Adding conditions in multiple steps:
+     *
+     * You can use callable functions to construct complex expressions, functions
+     * receive as first argument a new QueryExpression object and this query instance
+     * as second argument. Functions must return an expression object, that will be
+     * added the list of conditions for the query using the AND operator.
+     *
+     * ```
+     *  $query
+     *  ->where(['title !=' => 'Hello World'])
+     *  ->where(function ($exp, $query) {
+     *      $or = $exp->or(['id' => 1]);
+     *      $and = $exp->and(['id >' => 2, 'id <' => 10]);
+     *  return $or->add($and);
+     *  });
+     * ```
+     *
+     * * The previous example produces:
+     *
+     * `WHERE title != 'Hello World' AND (id = 1 OR (id > 2 AND id < 10))`
+     *
+     * ### Conditions as strings:
+     *
+     * ```
+     *  $query->where(['articles.author_id = authors.id', 'modified IS NULL']);
+     * ```
+     *
+     * The previous example produces:
+     *
+     * `WHERE articles.author_id = authors.id AND modified IS NULL`
+     *
+     * Please note that when using the array notation or the expression objects, all
+     * values will be correctly quoted and transformed to the correspondent database
+     * data type automatically for you, thus securing your application from SQL injections.
+     * If you use string conditions make sure that your values are correctly quoted.
+     * The safest thing you can do is to never use string conditions.
+     *
+     * @param \Closure|array|string|null $conditions The conditions to filter on.
+     * @param array $types Associative array of type names used to bind values to query
+     * @param bool $overwrite whether to reset conditions with passed list or not
+     * @return $this
+     */
+    public function where($conditions = null, array $types = [], bool $overwrite = false);
+}
diff --git a/vendor/cakephp/datasource/QueryTrait.php b/vendor/cakephp/datasource/QueryTrait.php
new file mode 100644
index 0000000..1552561
--- /dev/null
+++ b/vendor/cakephp/datasource/QueryTrait.php
@@ -0,0 +1,1465 @@
+
+     */
+    protected $_formatters = [];
+
+    /**
+     * A query cacher instance if this query has caching enabled.
+     *
+     * @var \Cake\Datasource\QueryCacher|null
+     */
+    protected $_cache;
+
+    /**
+     * Holds any custom options passed using applyOptions that could not be processed
+     * by any method in this class.
+     *
+     * @var array
+     */
+    protected $_options = [];
+
+    /**
+     * Whether the query is standalone or the product of an eager load operation.
+     *
+     * @var bool
+     */
+    protected $_eagerLoaded = false;
+
+    /**
+     * Set the default Table object that will be used by this query
+     * and form the `FROM` clause.
+     *
+     * @param \Cake\Datasource\RepositoryInterface|\Cake\ORM\Table $repository The default table object to use
+     * @return $this
+     * @deprecated 4.5.0 Use `setRepository()` instead.
+     */
+    public function repository(RepositoryInterface $repository)
+    {
+        deprecationWarning('`repository() method is deprecated. Use `setRepository()` instead.');
+
+        return $this->setRepository($repository);
+    }
+
+    /**
+     * Set the default Table object that will be used by this query
+     * and form the `FROM` clause.
+     *
+     * @param \Cake\Datasource\RepositoryInterface|\Cake\ORM\Table $repository The default table object to use
+     * @return $this
+     */
+    public function setRepository(RepositoryInterface $repository)
+    {
+        $this->_repository = $repository;
+
+        return $this;
+    }
+
+    /**
+     * Returns the default table object that will be used by this query,
+     * that is, the table that will appear in the from clause.
+     *
+     * @return \Cake\Datasource\RepositoryInterface
+     */
+    public function getRepository(): RepositoryInterface
+    {
+        return $this->_repository;
+    }
+
+    /**
+     * Set the result set for a query.
+     *
+     * Setting the resultset of a query will make execute() a no-op. Instead
+     * of executing the SQL query and fetching results, the ResultSet provided to this
+     * method will be returned.
+     *
+     * This method is most useful when combined with results stored in a persistent cache.
+     *
+     * @param iterable $results The results this query should return.
+     * @return $this
+     */
+    public function setResult(iterable $results)
+    {
+        $this->_results = $results;
+
+        return $this;
+    }
+
+    /**
+     * Executes this query and returns a results iterator. This function is required
+     * for implementing the IteratorAggregate interface and allows the query to be
+     * iterated without having to call execute() manually, thus making it look like
+     * a result set instead of the query itself.
+     *
+     * @return \Cake\Datasource\ResultSetInterface
+     * @psalm-suppress ImplementedReturnTypeMismatch
+     */
+    #[\ReturnTypeWillChange]
+    public function getIterator()
+    {
+        return $this->all();
+    }
+
+    /**
+     * Enable result caching for this query.
+     *
+     * If a query has caching enabled, it will do the following when executed:
+     *
+     * - Check the cache for $key. If there are results no SQL will be executed.
+     *   Instead the cached results will be returned.
+     * - When the cached data is stale/missing the result set will be cached as the query
+     *   is executed.
+     *
+     * ### Usage
+     *
+     * ```
+     * // Simple string key + config
+     * $query->cache('my_key', 'db_results');
+     *
+     * // Function to generate key.
+     * $query->cache(function ($q) {
+     *   $key = serialize($q->clause('select'));
+     *   $key .= serialize($q->clause('where'));
+     *   return md5($key);
+     * });
+     *
+     * // Using a pre-built cache engine.
+     * $query->cache('my_key', $engine);
+     *
+     * // Disable caching
+     * $query->cache(false);
+     * ```
+     *
+     * @param \Closure|string|false $key Either the cache key or a function to generate the cache key.
+     *   When using a function, this query instance will be supplied as an argument.
+     * @param \Psr\SimpleCache\CacheInterface|string $config Either the name of the cache config to use, or
+     *   a cache engine instance.
+     * @return $this
+     */
+    public function cache($key, $config = 'default')
+    {
+        if ($key === false) {
+            $this->_cache = null;
+
+            return $this;
+        }
+        $this->_cache = new QueryCacher($key, $config);
+
+        return $this;
+    }
+
+    /**
+     * Returns the current configured query `_eagerLoaded` value
+     *
+     * @return bool
+     */
+    public function isEagerLoaded(): bool
+    {
+        return $this->_eagerLoaded;
+    }
+
+    /**
+     * Sets the query instance to be an eager loaded query. If no argument is
+     * passed, the current configured query `_eagerLoaded` value is returned.
+     *
+     * @param bool $value Whether to eager load.
+     * @return $this
+     */
+    public function eagerLoaded(bool $value)
+    {
+        $this->_eagerLoaded = $value;
+
+        return $this;
+    }
+
+    /**
+     * Returns a key => value array representing a single aliased field
+     * that can be passed directly to the select() method.
+     * The key will contain the alias and the value the actual field name.
+     *
+     * If the field is already aliased, then it will not be changed.
+     * If no $alias is passed, the default table for this query will be used.
+     *
+     * @param string $field The field to alias
+     * @param string|null $alias the alias used to prefix the field
+     * @return array
+     */
+    public function aliasField(string $field, ?string $alias = null): array
+    {
+        if (strpos($field, '.') === false) {
+            $alias = $alias ?: $this->getRepository()->getAlias();
+            $aliasedField = $alias . '.' . $field;
+        } else {
+            $aliasedField = $field;
+            [$alias, $field] = explode('.', $field);
+        }
+
+        $key = sprintf('%s__%s', $alias, $field);
+
+        return [$key => $aliasedField];
+    }
+
+    /**
+     * Runs `aliasField()` for each field in the provided list and returns
+     * the result under a single array.
+     *
+     * @param array $fields The fields to alias
+     * @param string|null $defaultAlias The default alias
+     * @return array
+     */
+    public function aliasFields(array $fields, ?string $defaultAlias = null): array
+    {
+        $aliased = [];
+        foreach ($fields as $alias => $field) {
+            if (is_numeric($alias) && is_string($field)) {
+                $aliased += $this->aliasField($field, $defaultAlias);
+                continue;
+            }
+            $aliased[$alias] = $field;
+        }
+
+        return $aliased;
+    }
+
+    /**
+     * Fetch the results for this query.
+     *
+     * Will return either the results set through setResult(), or execute this query
+     * and return the ResultSetDecorator object ready for streaming of results.
+     *
+     * ResultSetDecorator is a traversable object that implements the methods found
+     * on Cake\Collection\Collection.
+     *
+     * @return \Cake\Datasource\ResultSetInterface
+     */
+    public function all(): ResultSetInterface
+    {
+        if ($this->_results !== null) {
+            return $this->_results;
+        }
+
+        $results = null;
+        if ($this->_cache) {
+            $results = $this->_cache->fetch($this);
+        }
+        if ($results === null) {
+            $results = $this->_decorateResults($this->_execute());
+            if ($this->_cache) {
+                $this->_cache->store($this, $results);
+            }
+        }
+        $this->_results = $results;
+
+        return $this->_results;
+    }
+
+    /**
+     * Returns an array representation of the results after executing the query.
+     *
+     * @return array
+     */
+    public function toArray(): array
+    {
+        return $this->all()->toArray();
+    }
+
+    /**
+     * Register a new MapReduce routine to be executed on top of the database results
+     * Both the mapper and caller callable should be invokable objects.
+     *
+     * The MapReduce routing will only be run when the query is executed and the first
+     * result is attempted to be fetched.
+     *
+     * If the third argument is set to true, it will erase previous map reducers
+     * and replace it with the arguments passed.
+     *
+     * @param callable|null $mapper The mapper callable.
+     * @param callable|null $reducer The reducing function.
+     * @param bool $overwrite Set to true to overwrite existing map + reduce functions.
+     * @return $this
+     * @see \Cake\Collection\Iterator\MapReduce for details on how to use emit data to the map reducer.
+     */
+    public function mapReduce(?callable $mapper = null, ?callable $reducer = null, bool $overwrite = false)
+    {
+        if ($overwrite) {
+            $this->_mapReduce = [];
+        }
+        if ($mapper === null) {
+            if (!$overwrite) {
+                throw new InvalidArgumentException('$mapper can be null only when $overwrite is true.');
+            }
+
+            return $this;
+        }
+        $this->_mapReduce[] = compact('mapper', 'reducer');
+
+        return $this;
+    }
+
+    /**
+     * Returns the list of previously registered map reduce routines.
+     *
+     * @return array
+     */
+    public function getMapReducers(): array
+    {
+        return $this->_mapReduce;
+    }
+
+    /**
+     * Registers a new formatter callback function that is to be executed when trying
+     * to fetch the results from the database.
+     *
+     * If the second argument is set to true, it will erase previous formatters
+     * and replace them with the passed first argument.
+     *
+     * Callbacks are required to return an iterator object, which will be used as
+     * the return value for this query's result. Formatter functions are applied
+     * after all the `MapReduce` routines for this query have been executed.
+     *
+     * Formatting callbacks will receive two arguments, the first one being an object
+     * implementing `\Cake\Collection\CollectionInterface`, that can be traversed and
+     * modified at will. The second one being the query instance on which the formatter
+     * callback is being applied.
+     *
+     * Usually the query instance received by the formatter callback is the same query
+     * instance on which the callback was attached to, except for in a joined
+     * association, in that case the callback will be invoked on the association source
+     * side query, and it will receive that query instance instead of the one on which
+     * the callback was originally attached to - see the examples below!
+     *
+     * ### Examples:
+     *
+     * Return all results from the table indexed by id:
+     *
+     * ```
+     * $query->select(['id', 'name'])->formatResults(function ($results) {
+     *     return $results->indexBy('id');
+     * });
+     * ```
+     *
+     * Add a new column to the ResultSet:
+     *
+     * ```
+     * $query->select(['name', 'birth_date'])->formatResults(function ($results) {
+     *     return $results->map(function ($row) {
+     *         $row['age'] = $row['birth_date']->diff(new DateTime)->y;
+     *
+     *         return $row;
+     *     });
+     * });
+     * ```
+     *
+     * Add a new column to the results with respect to the query's hydration configuration:
+     *
+     * ```
+     * $query->formatResults(function ($results, $query) {
+     *     return $results->map(function ($row) use ($query) {
+     *         $data = [
+     *             'bar' => 'baz',
+     *         ];
+     *
+     *         if ($query->isHydrationEnabled()) {
+     *             $row['foo'] = new Foo($data)
+     *         } else {
+     *             $row['foo'] = $data;
+     *         }
+     *
+     *         return $row;
+     *     });
+     * });
+     * ```
+     *
+     * Retaining access to the association target query instance of joined associations,
+     * by inheriting the contain callback's query argument:
+     *
+     * ```
+     * // Assuming a `Articles belongsTo Authors` association that uses the join strategy
+     *
+     * $articlesQuery->contain('Authors', function ($authorsQuery) {
+     *     return $authorsQuery->formatResults(function ($results, $query) use ($authorsQuery) {
+     *         // Here `$authorsQuery` will always be the instance
+     *         // where the callback was attached to.
+     *
+     *         // The instance passed to the callback in the second
+     *         // argument (`$query`), will be the one where the
+     *         // callback is actually being applied to, in this
+     *         // example that would be `$articlesQuery`.
+     *
+     *         // ...
+     *
+     *         return $results;
+     *     });
+     * });
+     * ```
+     *
+     * @param callable|null $formatter The formatting callable.
+     * @param int|bool $mode Whether to overwrite, append or prepend the formatter.
+     * @return $this
+     * @throws \InvalidArgumentException
+     */
+    public function formatResults(?callable $formatter = null, $mode = self::APPEND)
+    {
+        if ($mode === self::OVERWRITE) {
+            $this->_formatters = [];
+        }
+        if ($formatter === null) {
+            if ($mode !== self::OVERWRITE) {
+                throw new InvalidArgumentException('$formatter can be null only when $mode is overwrite.');
+            }
+
+            return $this;
+        }
+
+        if ($mode === self::PREPEND) {
+            array_unshift($this->_formatters, $formatter);
+
+            return $this;
+        }
+
+        $this->_formatters[] = $formatter;
+
+        return $this;
+    }
+
+    /**
+     * Returns the list of previously registered format routines.
+     *
+     * @return array
+     */
+    public function getResultFormatters(): array
+    {
+        return $this->_formatters;
+    }
+
+    /**
+     * Returns the first result out of executing this query, if the query has not been
+     * executed before, it will set the limit clause to 1 for performance reasons.
+     *
+     * ### Example:
+     *
+     * ```
+     * $singleUser = $query->select(['id', 'username'])->first();
+     * ```
+     *
+     * @return \Cake\Datasource\EntityInterface|array|null The first result from the ResultSet.
+     */
+    public function first()
+    {
+        if ($this->_dirty) {
+            $this->limit(1);
+        }
+
+        return $this->all()->first();
+    }
+
+    /**
+     * Get the first result from the executing query or raise an exception.
+     *
+     * @throws \Cake\Datasource\Exception\RecordNotFoundException When there is no first record.
+     * @return \Cake\Datasource\EntityInterface|array The first result from the ResultSet.
+     */
+    public function firstOrFail()
+    {
+        $entity = $this->first();
+        if (!$entity) {
+            $table = $this->getRepository();
+            throw new RecordNotFoundException(sprintf(
+                'Record not found in table "%s"',
+                $table->getTable()
+            ));
+        }
+
+        return $entity;
+    }
+
+    /**
+     * Returns an array with the custom options that were applied to this query
+     * and that were not already processed by another method in this class.
+     *
+     * ### Example:
+     *
+     * ```
+     *  $query->applyOptions(['doABarrelRoll' => true, 'fields' => ['id', 'name']);
+     *  $query->getOptions(); // Returns ['doABarrelRoll' => true]
+     * ```
+     *
+     * @see \Cake\Datasource\QueryInterface::applyOptions() to read about the options that will
+     * be processed by this class and not returned by this function
+     * @return array
+     * @see applyOptions()
+     */
+    public function getOptions(): array
+    {
+        return $this->_options;
+    }
+
+    /**
+     * Enables calling methods from the result set as if they were from this class
+     *
+     * @param string $method the method to call
+     * @param array $arguments list of arguments for the method to call
+     * @return mixed
+     * @throws \BadMethodCallException if no such method exists in result set
+     */
+    public function __call(string $method, array $arguments)
+    {
+        $resultSetClass = $this->_decoratorClass();
+        if (in_array($method, get_class_methods($resultSetClass), true)) {
+            deprecationWarning(sprintf(
+                'Calling `%s` methods, such as `%s()`, on queries is deprecated. ' .
+                'You must call `all()` first (for example, `all()->%s()`).',
+                ResultSetInterface::class,
+                $method,
+                $method,
+            ), 2);
+            $results = $this->all();
+
+            return $results->$method(...$arguments);
+        }
+        throw new BadMethodCallException(
+            sprintf('Unknown method "%s"', $method)
+        );
+    }
+
+    /**
+     * @param callable $callback The callback to apply
+     * @see \Cake\Collection\CollectionInterface::each()
+     * @return \Cake\Collection\CollectionInterface
+     * @deprecated
+     */
+    public function each(callable $callback): CollectionInterface
+    {
+        deprecationWarning(
+            '4.3.0 - Calling each() on a Query is deprecated. ' .
+            'Instead call `$query->all()->each(...)` instead.'
+        );
+
+        return $this->all()->each($callback);
+    }
+
+    /**
+     * @param ?callable $callback The callback to apply
+     * @see \Cake\Collection\CollectionInterface::filter()
+     * @return \Cake\Collection\CollectionInterface
+     * @deprecated
+     */
+    public function filter(?callable $callback = null): CollectionInterface
+    {
+        deprecationWarning(
+            '4.3.0 - Calling filter() on a Query is deprecated. ' .
+            'Instead call `$query->all()->filter(...)` instead.'
+        );
+
+        return $this->all()->filter($callback);
+    }
+
+    /**
+     * @param callable $callback The callback to apply
+     * @see \Cake\Collection\CollectionInterface::reject()
+     * @return \Cake\Collection\CollectionInterface
+     * @deprecated
+     */
+    public function reject(callable $callback): CollectionInterface
+    {
+        deprecationWarning(
+            '4.3.0 - Calling reject() on a Query is deprecated. ' .
+            'Instead call `$query->all()->reject(...)` instead.'
+        );
+
+        return $this->all()->reject($callback);
+    }
+
+    /**
+     * @param callable $callback The callback to apply
+     * @see \Cake\Collection\CollectionInterface::every()
+     * @return bool
+     * @deprecated
+     */
+    public function every(callable $callback): bool
+    {
+        deprecationWarning(
+            '4.3.0 - Calling every() on a Query is deprecated. ' .
+            'Instead call `$query->all()->every(...)` instead.'
+        );
+
+        return $this->all()->every($callback);
+    }
+
+    /**
+     * @param callable $callback The callback to apply
+     * @see \Cake\Collection\CollectionInterface::some()
+     * @return bool
+     * @deprecated
+     */
+    public function some(callable $callback): bool
+    {
+        deprecationWarning(
+            '4.3.0 - Calling some() on a Query is deprecated. ' .
+            'Instead call `$query->all()->some(...)` instead.'
+        );
+
+        return $this->all()->some($callback);
+    }
+
+    /**
+     * @param mixed $value The value to check.
+     * @see \Cake\Collection\CollectionInterface::contains()
+     * @return bool
+     * @deprecated
+     */
+    public function contains($value): bool
+    {
+        deprecationWarning(
+            '4.3.0 - Calling contains() on a Query is deprecated. ' .
+            'Instead call `$query->all()->contains(...)` instead.'
+        );
+
+        return $this->all()->contains($value);
+    }
+
+    /**
+     * @param callable $callback The callback to apply
+     * @see \Cake\Collection\CollectionInterface::map()
+     * @return \Cake\Collection\CollectionInterface
+     * @deprecated
+     */
+    public function map(callable $callback): CollectionInterface
+    {
+        deprecationWarning(
+            '4.3.0 - Calling map() on a Query is deprecated. ' .
+            'Instead call `$query->all()->map(...)` instead.'
+        );
+
+        return $this->all()->map($callback);
+    }
+
+    /**
+     * @param callable $callback The callback to apply
+     * @param mixed $initial The initial value
+     * @see \Cake\Collection\CollectionInterface::reduce()
+     * @return mixed
+     * @deprecated
+     */
+    public function reduce(callable $callback, $initial = null)
+    {
+        deprecationWarning(
+            '4.3.0 - Calling reduce() on a Query is deprecated. ' .
+            'Instead call `$query->all()->reduce(...)` instead.'
+        );
+
+        return $this->all()->reduce($callback, $initial);
+    }
+
+    /**
+     * @param callable|string $path The path to extract
+     * @see \Cake\Collection\CollectionInterface::extract()
+     * @return \Cake\Collection\CollectionInterface
+     * @deprecated
+     */
+    public function extract($path): CollectionInterface
+    {
+        deprecationWarning(
+            '4.3.0 - Calling extract() on a Query is deprecated. ' .
+            'Instead call `$query->all()->extract(...)` instead.'
+        );
+
+        return $this->all()->extract($path);
+    }
+
+    /**
+     * @param callable|string $path The path to max
+     * @param int $sort The SORT_ constant to order by.
+     * @see \Cake\Collection\CollectionInterface::max()
+     * @return mixed
+     * @deprecated
+     */
+    public function max($path, int $sort = \SORT_NUMERIC)
+    {
+        deprecationWarning(
+            '4.3.0 - Calling max() on a Query is deprecated. ' .
+            'Instead call `$query->all()->max(...)` instead.'
+        );
+
+        return $this->all()->max($path, $sort);
+    }
+
+    /**
+     * @param callable|string $path The path to max
+     * @param int $sort The SORT_ constant to order by.
+     * @see \Cake\Collection\CollectionInterface::min()
+     * @return mixed
+     * @deprecated
+     */
+    public function min($path, int $sort = \SORT_NUMERIC)
+    {
+        deprecationWarning(
+            '4.3.0 - Calling min() on a Query is deprecated. ' .
+            'Instead call `$query->all()->min(...)` instead.'
+        );
+
+        return $this->all()->min($path, $sort);
+    }
+
+    /**
+     * @param callable|string|null $path the path to average
+     * @see \Cake\Collection\CollectionInterface::avg()
+     * @return float|int|null
+     * @deprecated
+     */
+    public function avg($path = null)
+    {
+        deprecationwarning(
+            '4.3.0 - calling avg() on a query is deprecated. ' .
+            'instead call `$query->all()->avg(...)` instead.'
+        );
+
+        return $this->all()->avg($path);
+    }
+
+    /**
+     * @param callable|string|null $path the path to average
+     * @see \Cake\Collection\CollectionInterface::median()
+     * @return float|int|null
+     * @deprecated
+     */
+    public function median($path = null)
+    {
+        deprecationwarning(
+            '4.3.0 - calling median() on a query is deprecated. ' .
+            'instead call `$query->all()->median(...)` instead.'
+        );
+
+        return $this->all()->median($path);
+    }
+
+    /**
+     * @param callable|string $path the path to average
+     * @param int $order The \SORT_ constant for the direction you want results in.
+     * @param int $sort The \SORT_ method to use.
+     * @see \Cake\Collection\CollectionInterface::sortBy()
+     * @return \Cake\Collection\CollectionInterface
+     * @deprecated
+     */
+    public function sortBy($path, int $order = SORT_DESC, int $sort = \SORT_NUMERIC): CollectionInterface
+    {
+        deprecationwarning(
+            '4.3.0 - calling sortBy() on a query is deprecated. ' .
+            'instead call `$query->all()->sortBy(...)` instead.'
+        );
+
+        return $this->all()->sortBy($path, $order, $sort);
+    }
+
+    /**
+     * @param callable|string $path The path to group by
+     * @see \Cake\Collection\CollectionInterface::groupBy()
+     * @return \Cake\Collection\CollectionInterface
+     * @deprecated
+     */
+    public function groupBy($path): CollectionInterface
+    {
+        deprecationWarning(
+            '4.3.0 - Calling groupBy() on a Query is deprecated. ' .
+            'Instead call `$query->all()->groupBy(...)` instead.'
+        );
+
+        return $this->all()->groupBy($path);
+    }
+
+    /**
+     * @param string|callable $path The path to extract
+     * @see \Cake\Collection\CollectionInterface::indexBy()
+     * @return \Cake\Collection\CollectionInterface
+     * @deprecated
+     */
+    public function indexBy($path): CollectionInterface
+    {
+        deprecationWarning(
+            '4.3.0 - Calling indexBy() on a Query is deprecated. ' .
+            'Instead call `$query->all()->indexBy(...)` instead.'
+        );
+
+        return $this->all()->indexBy($path);
+    }
+
+    /**
+     * @param string|callable $path The path to count by
+     * @see \Cake\Collection\CollectionInterface::countBy()
+     * @return \Cake\Collection\CollectionInterface
+     * @deprecated
+     */
+    public function countBy($path): CollectionInterface
+    {
+        deprecationWarning(
+            '4.3.0 - Calling countBy() on a Query is deprecated. ' .
+            'Instead call `$query->all()->countBy(...)` instead.'
+        );
+
+        return $this->all()->countBy($path);
+    }
+
+    /**
+     * @param string|callable $path The path to sum
+     * @see \Cake\Collection\CollectionInterface::sumOf()
+     * @return int|float
+     * @deprecated
+     */
+    public function sumOf($path = null)
+    {
+        deprecationWarning(
+            '4.3.0 - Calling sumOf() on a Query is deprecated. ' .
+                'Instead call `$query->all()->sumOf(...)` instead.'
+        );
+
+        return $this->all()->sumOf($path);
+    }
+
+    /**
+     * @see \Cake\Collection\CollectionInterface::shuffle()
+     * @return \Cake\Collection\CollectionInterface
+     * @deprecated
+     */
+    public function shuffle(): CollectionInterface
+    {
+        deprecationWarning(
+            '4.3.0 - Calling shuffle() on a Query is deprecated. ' .
+            'Instead call `$query->all()->shuffle(...)` instead.'
+        );
+
+        return $this->all()->shuffle();
+    }
+
+    /**
+     * @param int $length The number of samples to select
+     * @see \Cake\Collection\CollectionInterface::sample()
+     * @return \Cake\Collection\CollectionInterface
+     * @deprecated
+     */
+    public function sample(int $length = 10): CollectionInterface
+    {
+        deprecationWarning(
+            '4.3.0 - Calling sample() on a Query is deprecated. ' .
+            'Instead call `$query->all()->sample(...)` instead.'
+        );
+
+        return $this->all()->sample($length);
+    }
+
+    /**
+     * @param int $length The number of elements to take
+     * @param int $offset The offset of the first element to take.
+     * @see \Cake\Collection\CollectionInterface::take()
+     * @return \Cake\Collection\CollectionInterface
+     * @deprecated
+     */
+    public function take(int $length = 1, int $offset = 0): CollectionInterface
+    {
+        deprecationWarning(
+            '4.3.0 - Calling take() on a Query is deprecated. ' .
+            'Instead call `$query->all()->take(...)` instead.'
+        );
+
+        return $this->all()->take($length, $offset);
+    }
+
+    /**
+     * @param int $length The number of items to take.
+     * @see \Cake\Collection\CollectionInterface::takeLast()
+     * @return \Cake\Collection\CollectionInterface
+     * @deprecated
+     */
+    public function takeLast(int $length): CollectionInterface
+    {
+        deprecationWarning(
+            '4.3.0 - Calling takeLast() on a Query is deprecated. ' .
+            'Instead call `$query->all()->takeLast(...)` instead.'
+        );
+
+        return $this->all()->takeLast($length);
+    }
+
+    /**
+     * @param int $length The number of items to skip
+     * @see \Cake\Collection\CollectionInterface::skip()
+     * @return \Cake\Collection\CollectionInterface
+     * @deprecated
+     */
+    public function skip(int $length): CollectionInterface
+    {
+        deprecationWarning(
+            '4.3.0 - Calling skip() on a Query is deprecated. ' .
+            'Instead call `$query->all()->skip(...)` instead.'
+        );
+
+        return $this->all()->skip($length);
+    }
+
+    /**
+     * @param array $conditions The conditions to use.
+     * @see \Cake\Collection\CollectionInterface::match()
+     * @return \Cake\Collection\CollectionInterface
+     * @deprecated
+     */
+    public function match(array $conditions): CollectionInterface
+    {
+        deprecationWarning(
+            '4.3.0 - Calling match() on a Query is deprecated. ' .
+            'Instead call `$query->all()->match(...)` instead.'
+        );
+
+        return $this->all()->match($conditions);
+    }
+
+    /**
+     * @param array $conditions The conditions to apply
+     * @see \Cake\Collection\CollectionInterface::firstMatch()
+     * @return mixed
+     * @deprecated
+     */
+    public function firstMatch(array $conditions)
+    {
+        deprecationWarning(
+            '4.3.0 - Calling firstMatch() on a Query is deprecated. ' .
+            'Instead call `$query->all()->firstMatch(...)` instead.'
+        );
+
+        return $this->all()->firstMatch($conditions);
+    }
+
+    /**
+     * @see \Cake\Collection\CollectionInterface::last()
+     * @deprecated
+     * @return mixed
+     */
+    public function last()
+    {
+        deprecationWarning(
+            '4.3.0 - Calling last() on a Query is deprecated. ' .
+            'Instead call `$query->all()->last(...)` instead.'
+        );
+
+        return $this->all()->last();
+    }
+
+    /**
+     * @param mixed $items The items to append
+     * @see \Cake\Collection\CollectionInterface::append()
+     * @return \Cake\Collection\CollectionInterface
+     * @deprecated
+     */
+    public function append($items): CollectionInterface
+    {
+        deprecationWarning(
+            '4.3.0 - Calling append() on a Query is deprecated. ' .
+            'Instead call `$query->all()->append(...)` instead.'
+        );
+
+        return $this->all()->append($items);
+    }
+
+    /**
+     * @param mixed $item The item to apply
+     * @param mixed $key The key to append with
+     * @see \Cake\Collection\CollectionInterface::appendItem()
+     * @return \Cake\Collection\CollectionInterface
+     * @deprecated
+     */
+    public function appendItem($item, $key = null): CollectionInterface
+    {
+        deprecationWarning(
+            '4.3.0 - Calling appendItem() on a Query is deprecated. ' .
+            'Instead call `$query->all()->appendItem(...)` instead.'
+        );
+
+        return $this->all()->appendItem($item, $key);
+    }
+
+    /**
+     * @param mixed $items The items to prepend.
+     * @see \Cake\Collection\CollectionInterface::prepend()
+     * @return \Cake\Collection\CollectionInterface
+     * @deprecated
+     */
+    public function prepend($items): CollectionInterface
+    {
+        deprecationWarning(
+            '4.3.0 - Calling prepend() on a Query is deprecated. ' .
+            'Instead call `$query->all()->prepend(...)` instead.'
+        );
+
+        return $this->all()->prepend($items);
+    }
+
+    /**
+     * @param mixed $item The item to prepend
+     * @param mixed $key The key to use.
+     * @see \Cake\Collection\CollectionInterface::prependItem()
+     * @return \Cake\Collection\CollectionInterface
+     * @deprecated
+     */
+    public function prependItem($item, $key = null): CollectionInterface
+    {
+        deprecationWarning(
+            '4.3.0 - Calling prependItem() on a Query is deprecated. ' .
+            'Instead call `$query->all()->prependItem(...)` instead.'
+        );
+
+        return $this->all()->prependItem($item, $key);
+    }
+
+    /**
+     * @param callable|string $keyPath The path for keys
+     * @param callable|string $valuePath The path for values
+     * @param callable|string|null $groupPath The path for grouping
+     * @see \Cake\Collection\CollectionInterface::combine()
+     * @return \Cake\Collection\CollectionInterface
+     * @deprecated
+     */
+    public function combine($keyPath, $valuePath, $groupPath = null): CollectionInterface
+    {
+        deprecationWarning(
+            '4.3.0 - Calling combine() on a Query is deprecated. ' .
+            'Instead call `$query->all()->combine(...)` instead.'
+        );
+
+        return $this->all()->combine($keyPath, $valuePath, $groupPath);
+    }
+
+    /**
+     * @param callable|string $idPath The path to ids
+     * @param callable|string $parentPath The path to parents
+     * @param string $nestingKey Key used for nesting children.
+     * @see \Cake\Collection\CollectionInterface::nest()
+     * @return \Cake\Collection\CollectionInterface
+     * @deprecated
+     */
+    public function nest($idPath, $parentPath, string $nestingKey = 'children'): CollectionInterface
+    {
+        deprecationWarning(
+            '4.3.0 - Calling nest() on a Query is deprecated. ' .
+            'Instead call `$query->all()->nest(...)` instead.'
+        );
+
+        return $this->all()->nest($idPath, $parentPath, $nestingKey);
+    }
+
+    /**
+     * @param string $path The path to insert on
+     * @param mixed $values The values to insert.
+     * @see \Cake\Collection\CollectionInterface::insert()
+     * @return \Cake\Collection\CollectionInterface
+     * @deprecated
+     */
+    public function insert(string $path, $values): CollectionInterface
+    {
+        deprecationWarning(
+            '4.3.0 - Calling insert() on a Query is deprecated. ' .
+            'Instead call `$query->all()->insert(...)` instead.'
+        );
+
+        return $this->all()->insert($path, $values);
+    }
+
+    /**
+     * @see \Cake\Collection\CollectionInterface::toList()
+     * @return array
+     * @deprecated
+     */
+    public function toList(): array
+    {
+        deprecationWarning(
+            '4.3.0 - Calling toList() on a Query is deprecated. ' .
+            'Instead call `$query->all()->toList(...)` instead.'
+        );
+
+        return $this->all()->toList();
+    }
+
+    /**
+     * @param bool $keepKeys Whether or not keys should be kept
+     * @see \Cake\Collection\CollectionInterface::compile()
+     * @return \Cake\Collection\CollectionInterface
+     * @deprecated
+     */
+    public function compile(bool $keepKeys = true): CollectionInterface
+    {
+        deprecationWarning(
+            '4.3.0 - Calling compile() on a Query is deprecated. ' .
+            'Instead call `$query->all()->compile(...)` instead.'
+        );
+
+        return $this->all()->compile($keepKeys);
+    }
+
+    /**
+     * @see \Cake\Collection\CollectionInterface::lazy()
+     * @return \Cake\Collection\CollectionInterface
+     * @deprecated
+     */
+    public function lazy(): CollectionInterface
+    {
+        deprecationWarning(
+            '4.3.0 - Calling lazy() on a Query is deprecated. ' .
+            'Instead call `$query->all()->lazy(...)` instead.'
+        );
+
+        return $this->all()->lazy();
+    }
+
+    /**
+     * @see \Cake\Collection\CollectionInterface::buffered()
+     * @return \Cake\Collection\CollectionInterface
+     * @deprecated
+     */
+    public function buffered(): CollectionInterface
+    {
+        deprecationWarning(
+            '4.3.0 - Calling buffered() on a Query is deprecated. ' .
+            'Instead call `$query->all()->buffered(...)` instead.'
+        );
+
+        return $this->all()->buffered();
+    }
+
+    /**
+     * @param string|int $order The order in which to return the elements
+     * @param callable|string $nestingKey The key name under which children are nested
+     * @see \Cake\Collection\CollectionInterface::listNested()
+     * @return \Cake\Collection\CollectionInterface
+     * @deprecated
+     */
+    public function listNested($order = 'desc', $nestingKey = 'children'): CollectionInterface
+    {
+        deprecationWarning(
+            '4.3.0 - Calling listNested() on a Query is deprecated. ' .
+            'Instead call `$query->all()->listNested(...)` instead.'
+        );
+
+        return $this->all()->listNested($order, $nestingKey);
+    }
+
+    /**
+     * @param callable|array $condition the method that will receive each of the elements and
+     *   returns true when the iteration should be stopped.
+     * @see \Cake\Collection\CollectionInterface::stopWhen()
+     * @return \Cake\Collection\CollectionInterface
+     * @deprecated
+     */
+    public function stopWhen($condition): CollectionInterface
+    {
+        deprecationWarning(
+            '4.3.0 - Calling stopWhen() on a Query is deprecated. ' .
+            'Instead call `$query->all()->stopWhen(...)` instead.'
+        );
+
+        return $this->all()->stopWhen($condition);
+    }
+
+    /**
+     * @param callable|null $callback A callable function that will receive each of
+     *  items in the collection.
+     * @see \Cake\Collection\CollectionInterface::unfold()
+     * @return \Cake\Collection\CollectionInterface
+     * @deprecated
+     */
+    public function unfold(?callable $callback = null): CollectionInterface
+    {
+        deprecationWarning(
+            '4.3.0 - Calling unfold() on a Query is deprecated. ' .
+            'Instead call `$query->all()->unfold(...)` instead.'
+        );
+
+        return $this->all()->unfold($callback);
+    }
+
+    /**
+     * @param callable $callback A callable function that will receive each of
+     *  items in the collection.
+     * @see \Cake\Collection\CollectionInterface::through()
+     * @return \Cake\Collection\CollectionInterface
+     * @deprecated
+     */
+    public function through(callable $callback): CollectionInterface
+    {
+        deprecationWarning(
+            '4.3.0 - Calling through() on a Query is deprecated. ' .
+            'Instead call `$query->all()->through(...)` instead.'
+        );
+
+        return $this->all()->through($callback);
+    }
+
+    /**
+     * @param iterable ...$items The collections to zip.
+     * @see \Cake\Collection\CollectionInterface::zip()
+     * @return \Cake\Collection\CollectionInterface
+     * @deprecated
+     */
+    public function zip(iterable $items): CollectionInterface
+    {
+        deprecationWarning(
+            '4.3.0 - Calling zip() on a Query is deprecated. ' .
+            'Instead call `$query->all()->zip(...)` instead.'
+        );
+
+        return $this->all()->zip($items);
+    }
+
+    /**
+     * @param iterable ...$items The collections to zip.
+     * @param callable $callback The function to use for zipping the elements together.
+     * @see \Cake\Collection\CollectionInterface::zipWith()
+     * @return \Cake\Collection\CollectionInterface
+     * @deprecated
+     */
+    public function zipWith(iterable $items, $callback): CollectionInterface
+    {
+        deprecationWarning(
+            '4.3.0 - Calling zipWith() on a Query is deprecated. ' .
+            'Instead call `$query->all()->zipWith(...)` instead.'
+        );
+
+        return $this->all()->zipWith($items, $callback);
+    }
+
+    /**
+     * @param int $chunkSize The maximum size for each chunk
+     * @see \Cake\Collection\CollectionInterface::chunk()
+     * @return \Cake\Collection\CollectionInterface
+     * @deprecated
+     */
+    public function chunk(int $chunkSize): CollectionInterface
+    {
+        deprecationWarning(
+            '4.3.0 - Calling chunk() on a Query is deprecated. ' .
+            'Instead call `$query->all()->chunk(...)` instead.'
+        );
+
+        return $this->all()->chunk($chunkSize);
+    }
+
+    /**
+     * @param int $chunkSize The maximum size for each chunk
+     * @param bool $keepKeys If the keys of the array should be kept
+     * @see \Cake\Collection\CollectionInterface::chunkWithKeys()
+     * @return \Cake\Collection\CollectionInterface
+     * @deprecated
+     */
+    public function chunkWithKeys(int $chunkSize, bool $keepKeys = true): CollectionInterface
+    {
+        deprecationWarning(
+            '4.3.0 - Calling chunkWithKeys() on a Query is deprecated. ' .
+            'Instead call `$query->all()->chunkWithKeys(...)` instead.'
+        );
+
+        return $this->all()->chunkWithKeys($chunkSize, $keepKeys);
+    }
+
+    /**
+     * @see \Cake\Collection\CollectionInterface::isEmpty()
+     * @return bool
+     * @deprecated
+     */
+    public function isEmpty(): bool
+    {
+        deprecationWarning(
+            '4.3.0 - Calling isEmpty() on a Query is deprecated. ' .
+            'Instead call `$query->all()->isEmpty(...)` instead.'
+        );
+
+        return $this->all()->isEmpty();
+    }
+
+    /**
+     * @see \Cake\Collection\CollectionInterface::unwrap()
+     * @return \Traversable
+     * @deprecated
+     */
+    public function unwrap(): Traversable
+    {
+        deprecationWarning(
+            '4.3.0 - Calling unwrap() on a Query is deprecated. ' .
+            'Instead call `$query->all()->unwrap(...)` instead.'
+        );
+
+        return $this->all()->unwrap();
+    }
+
+    /**
+     * @see \Cake\Collection\CollectionInterface::transpose()
+     * @return \Cake\Collection\CollectionInterface
+     * @deprecated
+     */
+    public function transpose(): CollectionInterface
+    {
+        deprecationWarning(
+            '4.3.0 - Calling transpose() on a Query is deprecated. ' .
+            'Instead call `$query->all()->transpose(...)` instead.'
+        );
+
+        return $this->all()->transpose();
+    }
+
+    /**
+     * @see \Cake\Collection\CollectionInterface::count()
+     * @return int
+     * @deprecated
+     */
+    public function count(): int
+    {
+        deprecationWarning(
+            '4.3.0 - Calling count() on a Query is deprecated. ' .
+            'Instead call `$query->all()->count(...)` instead.'
+        );
+
+        return $this->all()->count();
+    }
+
+    /**
+     * @see \Cake\Collection\CollectionInterface::countKeys()
+     * @return int
+     * @deprecated
+     */
+    public function countKeys(): int
+    {
+        deprecationWarning(
+            '4.3.0 - Calling countKeys() on a Query is deprecated. ' .
+            'Instead call `$query->all()->countKeys(...)` instead.'
+        );
+
+        return $this->all()->countKeys();
+    }
+
+    /**
+     * @param callable|null $operation A callable that allows you to customize the product result.
+     * @param callable|null $filter A filtering callback that must return true for a result to be part
+     *   of the final results.
+     * @see \Cake\Collection\CollectionInterface::cartesianProduct()
+     * @return \Cake\Collection\CollectionInterface
+     * @deprecated
+     */
+    public function cartesianProduct(?callable $operation = null, ?callable $filter = null): CollectionInterface
+    {
+        deprecationWarning(
+            '4.3.0 - Calling cartesianProduct() on a Query is deprecated. ' .
+            'Instead call `$query->all()->cartesianProduct(...)` instead.'
+        );
+
+        return $this->all()->cartesianProduct($operation, $filter);
+    }
+
+    /**
+     * Populates or adds parts to current query clauses using an array.
+     * This is handy for passing all query clauses at once.
+     *
+     * @param array $options the options to be applied
+     * @return $this
+     */
+    abstract public function applyOptions(array $options);
+
+    /**
+     * Executes this query and returns a traversable object containing the results
+     *
+     * @return \Cake\Datasource\ResultSetInterface
+     */
+    abstract protected function _execute(): ResultSetInterface;
+
+    /**
+     * Decorates the results iterator with MapReduce routines and formatters
+     *
+     * @param \Traversable $result Original results
+     * @return \Cake\Datasource\ResultSetInterface
+     */
+    protected function _decorateResults(Traversable $result): ResultSetInterface
+    {
+        $decorator = $this->_decoratorClass();
+        foreach ($this->_mapReduce as $functions) {
+            $result = new MapReduce($result, $functions['mapper'], $functions['reducer']);
+        }
+
+        if (!empty($this->_mapReduce)) {
+            $result = new $decorator($result);
+        }
+
+        foreach ($this->_formatters as $formatter) {
+            $result = $formatter($result, $this);
+        }
+
+        if (!empty($this->_formatters) && !($result instanceof $decorator)) {
+            $result = new $decorator($result);
+        }
+
+        return $result;
+    }
+
+    /**
+     * Returns the name of the class to be used for decorating results
+     *
+     * @return string
+     * @psalm-return class-string<\Cake\Datasource\ResultSetInterface>
+     */
+    protected function _decoratorClass(): string
+    {
+        return ResultSetDecorator::class;
+    }
+}
diff --git a/vendor/cakephp/datasource/README.md b/vendor/cakephp/datasource/README.md
new file mode 100644
index 0000000..38626ea
--- /dev/null
+++ b/vendor/cakephp/datasource/README.md
@@ -0,0 +1,82 @@
+[![Total Downloads](https://img.shields.io/packagist/dt/cakephp/datasource.svg?style=flat-square)](https://packagist.org/packages/cakephp/datasource)
+[![License](https://img.shields.io/badge/license-MIT-blue.svg?style=flat-square)](LICENSE.txt)
+
+# CakePHP Datasource Library
+
+This library contains interfaces for implementing Repositories and Entities using any data source,
+a class for managing connections to datasources and traits to help you quickly implement the
+interfaces provided by this package.
+
+## Repositories
+
+A repository is a class capable of interfacing with a data source using operations such as
+`find`, `save` and  `delete` by using intermediate query objects for expressing commands to
+the data store and returning Entities as the single result unit of such system.
+
+In the case of a Relational database, a Repository would be a `Table`, which can be return single
+or multiple `Entity` objects by using a `Query`.
+
+This library exposes the following interfaces for creating a system that implements the
+repository pattern and is compatible with the CakePHP framework:
+
+* `RepositoryInterface` - Describes the methods for a base repository class.
+* `EntityInterface` - Describes the methods for a single result object.
+* `ResultSetInterface` - Represents the idea of a collection of Entities as a result of a query.
+
+Additionally, this package provides a few traits and classes you can use in your own implementations:
+
+* `EntityTrait` - Contains the default implementation for the `EntityInterface`.
+* `QueryTrait` - Exposes the methods for creating a query object capable of returning decoratable collections.
+* `ResultSetDecorator` - Decorates any traversable object, so it complies with `ResultSetInterface`.
+
+
+## Connections
+
+This library contains a couple of utility classes meant to create and manage
+connection objects. Connections are typically used in repositories for
+interfacing with the actual data source system.
+
+The `ConnectionManager` class acts as a registry to access database connections
+your application has. It provides a place that other objects can get references
+to existing connections. Creating connections with the `ConnectionManager` is
+easy:
+
+```php
+use Cake\Datasource\ConnectionManager;
+
+ConnectionManager::config('connection-one', [
+    'className' => 'MyApp\Connections\CustomConnection',
+    'param1' => 'value',
+    'param2' => 'another value'
+]);
+
+ConnectionManager::config('connection-two', [
+    'className' => 'MyApp\Connections\CustomConnection',
+    'param1' => 'different value',
+    'param2' => 'another value'
+]);
+```
+
+When requested, the `ConnectionManager` will instantiate
+`MyApp\Connections\CustomConnection` by passing `param1` and `param2` inside an
+array as the first argument of the constructor.
+
+Once configured connections can be fetched using `ConnectionManager::get()`.
+This method will construct and load a connection if it has not been built
+before, or return the existing known connection:
+
+```php
+use Cake\Datasource\ConnectionManager;
+$conn = ConnectionManager::get('master');
+```
+
+It is also possible to store connection objects by passing the instance directly to the manager:
+
+```php
+use Cake\Datasource\ConnectionManager;
+$conn = ConnectionManager::config('other', $connectionInstance);
+```
+
+## Documentation
+
+Please make sure you check the [official API documentation](https://api.cakephp.org/4.x/namespace-Cake.Datasource.html)
diff --git a/vendor/cakephp/datasource/RepositoryInterface.php b/vendor/cakephp/datasource/RepositoryInterface.php
new file mode 100644
index 0000000..93a0041
--- /dev/null
+++ b/vendor/cakephp/datasource/RepositoryInterface.php
@@ -0,0 +1,252 @@
+ $options An array that will be passed to Query::applyOptions()
+     * @return \Cake\Datasource\QueryInterface
+     */
+    public function find(string $type = 'all', array $options = []);
+
+    /**
+     * Returns a single record after finding it by its primary key, if no record is
+     * found this method throws an exception.
+     *
+     * ### Example:
+     *
+     * ```
+     * $id = 10;
+     * $article = $articles->get($id);
+     *
+     * $article = $articles->get($id, ['contain' => ['Comments]]);
+     * ```
+     *
+     * @param mixed $primaryKey primary key value to find
+     * @param array $options options accepted by `Table::find()`
+     * @throws \Cake\Datasource\Exception\RecordNotFoundException if the record with such id
+     * could not be found
+     * @return \Cake\Datasource\EntityInterface
+     * @see \Cake\Datasource\RepositoryInterface::find()
+     */
+    public function get($primaryKey, array $options = []): EntityInterface;
+
+    /**
+     * Creates a new Query instance for this repository
+     *
+     * @return \Cake\Datasource\QueryInterface
+     */
+    public function query();
+
+    /**
+     * Update all matching records.
+     *
+     * Sets the $fields to the provided values based on $conditions.
+     * This method will *not* trigger beforeSave/afterSave events. If you need those
+     * first load a collection of records and update them.
+     *
+     * @param \Cake\Database\Expression\QueryExpression|\Closure|array|string $fields A hash of field => new value.
+     * @param mixed $conditions Conditions to be used, accepts anything Query::where()
+     * can take.
+     * @return int Count Returns the affected rows.
+     */
+    public function updateAll($fields, $conditions): int;
+
+    /**
+     * Deletes all records matching the provided conditions.
+     *
+     * This method will *not* trigger beforeDelete/afterDelete events. If you
+     * need those first load a collection of records and delete them.
+     *
+     * This method will *not* execute on associations' `cascade` attribute. You should
+     * use database foreign keys + ON CASCADE rules if you need cascading deletes combined
+     * with this method.
+     *
+     * @param mixed $conditions Conditions to be used, accepts anything Query::where()
+     * can take.
+     * @return int Returns the number of affected rows.
+     * @see \Cake\Datasource\RepositoryInterface::delete()
+     */
+    public function deleteAll($conditions): int;
+
+    /**
+     * Returns true if there is any record in this repository matching the specified
+     * conditions.
+     *
+     * @param array $conditions list of conditions to pass to the query
+     * @return bool
+     */
+    public function exists($conditions): bool;
+
+    /**
+     * Persists an entity based on the fields that are marked as dirty and
+     * returns the same entity after a successful save or false in case
+     * of any error.
+     *
+     * @param \Cake\Datasource\EntityInterface $entity the entity to be saved
+     * @param \ArrayAccess|array $options The options to use when saving.
+     * @return \Cake\Datasource\EntityInterface|false
+     */
+    public function save(EntityInterface $entity, $options = []);
+
+    /**
+     * Delete a single entity.
+     *
+     * Deletes an entity and possibly related associations from the database
+     * based on the 'dependent' option used when defining the association.
+     *
+     * @param \Cake\Datasource\EntityInterface $entity The entity to remove.
+     * @param \ArrayAccess|array $options The options for the delete.
+     * @return bool success
+     */
+    public function delete(EntityInterface $entity, $options = []): bool;
+
+    /**
+     * This creates a new entity object.
+     *
+     * Careful: This does not trigger any field validation.
+     * This entity can be persisted without validation error as empty record.
+     * Always patch in required fields before saving.
+     *
+     * @return \Cake\Datasource\EntityInterface
+     */
+    public function newEmptyEntity(): EntityInterface;
+
+    /**
+     * Create a new entity + associated entities from an array.
+     *
+     * This is most useful when hydrating request data back into entities.
+     * For example, in your controller code:
+     *
+     * ```
+     * $article = $this->Articles->newEntity($this->request->getData());
+     * ```
+     *
+     * The hydrated entity will correctly do an insert/update based
+     * on the primary key data existing in the database when the entity
+     * is saved. Until the entity is saved, it will be a detached record.
+     *
+     * @param array $data The data to build an entity with.
+     * @param array $options A list of options for the object hydration.
+     * @return \Cake\Datasource\EntityInterface
+     */
+    public function newEntity(array $data, array $options = []): EntityInterface;
+
+    /**
+     * Create a list of entities + associated entities from an array.
+     *
+     * This is most useful when hydrating request data back into entities.
+     * For example, in your controller code:
+     *
+     * ```
+     * $articles = $this->Articles->newEntities($this->request->getData());
+     * ```
+     *
+     * The hydrated entities can then be iterated and saved.
+     *
+     * @param array $data The data to build an entity with.
+     * @param array $options A list of options for the objects hydration.
+     * @return array<\Cake\Datasource\EntityInterface> An array of hydrated records.
+     */
+    public function newEntities(array $data, array $options = []): array;
+
+    /**
+     * Merges the passed `$data` into `$entity` respecting the accessible
+     * fields configured on the entity. Returns the same entity after being
+     * altered.
+     *
+     * This is most useful when editing an existing entity using request data:
+     *
+     * ```
+     * $article = $this->Articles->patchEntity($article, $this->request->getData());
+     * ```
+     *
+     * @param \Cake\Datasource\EntityInterface $entity the entity that will get the
+     * data merged in
+     * @param array $data key value list of fields to be merged into the entity
+     * @param array $options A list of options for the object hydration.
+     * @return \Cake\Datasource\EntityInterface
+     */
+    public function patchEntity(EntityInterface $entity, array $data, array $options = []): EntityInterface;
+
+    /**
+     * Merges each of the elements passed in `$data` into the entities
+     * found in `$entities` respecting the accessible fields configured on the entities.
+     * Merging is done by matching the primary key in each of the elements in `$data`
+     * and `$entities`.
+     *
+     * This is most useful when editing a list of existing entities using request data:
+     *
+     * ```
+     * $article = $this->Articles->patchEntities($articles, $this->request->getData());
+     * ```
+     *
+     * @param iterable<\Cake\Datasource\EntityInterface> $entities the entities that will get the
+     * data merged in
+     * @param array $data list of arrays to be merged into the entities
+     * @param array $options A list of options for the objects hydration.
+     * @return array<\Cake\Datasource\EntityInterface>
+     */
+    public function patchEntities(iterable $entities, array $data, array $options = []): array;
+}
diff --git a/vendor/cakephp/datasource/ResultSetDecorator.php b/vendor/cakephp/datasource/ResultSetDecorator.php
new file mode 100644
index 0000000..85d98b6
--- /dev/null
+++ b/vendor/cakephp/datasource/ResultSetDecorator.php
@@ -0,0 +1,61 @@
+
+ */
+class ResultSetDecorator extends Collection implements ResultSetInterface
+{
+    /**
+     * Make this object countable.
+     *
+     * Part of the Countable interface. Calling this method
+     * will convert the underlying traversable object into an array and
+     * get the count of the underlying data.
+     *
+     * @return int
+     */
+    public function count(): int
+    {
+        $iterator = $this->getInnerIterator();
+        if ($iterator instanceof Countable) {
+            return $iterator->count();
+        }
+
+        return count($this->toArray());
+    }
+
+    /**
+     * @inheritDoc
+     */
+    public function __debugInfo(): array
+    {
+        $parentInfo = parent::__debugInfo();
+        $limit = Configure::read('App.ResultSetDebugLimit', 10);
+
+        return array_merge($parentInfo, ['items' => $this->take($limit)->toArray()]);
+    }
+}
diff --git a/vendor/cakephp/datasource/ResultSetInterface.php b/vendor/cakephp/datasource/ResultSetInterface.php
new file mode 100644
index 0000000..c193fac
--- /dev/null
+++ b/vendor/cakephp/datasource/ResultSetInterface.php
@@ -0,0 +1,30 @@
+
+     */
+    protected $options = [];
+
+    /**
+     * Rule callable
+     *
+     * @var callable
+     */
+    protected $rule;
+
+    /**
+     * Constructor
+     *
+     * ### Options
+     *
+     * - `errorField` The field errors should be set onto.
+     * - `message` The error message.
+     *
+     * Individual rules may have additional options that can be
+     * set here. Any options will be passed into the rule as part of the
+     * rule $scope.
+     *
+     * @param callable $rule The rule to be invoked.
+     * @param ?string $name The name of the rule. Used in error messages.
+     * @param array $options The options for the rule. See above.
+     */
+    public function __construct(callable $rule, ?string $name, array $options = [])
+    {
+        $this->rule = $rule;
+        $this->name = $name;
+        $this->options = $options;
+    }
+
+    /**
+     * Set options for the rule invocation.
+     *
+     * Old options will be merged with the new ones.
+     *
+     * @param array $options The options to set.
+     * @return $this
+     */
+    public function setOptions(array $options)
+    {
+        $this->options = $options + $this->options;
+
+        return $this;
+    }
+
+    /**
+     * Set the rule name.
+     *
+     * Only truthy names will be set.
+     *
+     * @param string|null $name The name to set.
+     * @return $this
+     */
+    public function setName(?string $name)
+    {
+        if ($name) {
+            $this->name = $name;
+        }
+
+        return $this;
+    }
+
+    /**
+     * Invoke the rule.
+     *
+     * @param \Cake\Datasource\EntityInterface $entity The entity the rule
+     *   should apply to.
+     * @param array $scope The rule's scope/options.
+     * @return bool Whether the rule passed.
+     */
+    public function __invoke(EntityInterface $entity, array $scope): bool
+    {
+        $rule = $this->rule;
+        $pass = $rule($entity, $this->options + $scope);
+        if ($pass === true || empty($this->options['errorField'])) {
+            return $pass === true;
+        }
+
+        $message = $this->options['message'] ?? 'invalid';
+        if (is_string($pass)) {
+            $message = $pass;
+        }
+        if ($this->name) {
+            $message = [$this->name => $message];
+        } else {
+            $message = [$message];
+        }
+        $errorField = $this->options['errorField'];
+        $entity->setError($errorField, $message);
+
+        if ($entity instanceof InvalidPropertyInterface && isset($entity->{$errorField})) {
+            $invalidValue = $entity->{$errorField};
+            $entity->setInvalidField($errorField, $invalidValue);
+        }
+
+        /** @phpstan-ignore-next-line */
+        return $pass === true;
+    }
+}
diff --git a/vendor/cakephp/datasource/RulesAwareTrait.php b/vendor/cakephp/datasource/RulesAwareTrait.php
new file mode 100644
index 0000000..5c01614
--- /dev/null
+++ b/vendor/cakephp/datasource/RulesAwareTrait.php
@@ -0,0 +1,120 @@
+rulesChecker();
+        $options = $options ?: new ArrayObject();
+        $options = is_array($options) ? new ArrayObject($options) : $options;
+        $hasEvents = ($this instanceof EventDispatcherInterface);
+
+        if ($hasEvents) {
+            $event = $this->dispatchEvent(
+                'Model.beforeRules',
+                compact('entity', 'options', 'operation')
+            );
+            if ($event->isStopped()) {
+                return $event->getResult();
+            }
+        }
+
+        $result = $rules->check($entity, $operation, $options->getArrayCopy());
+
+        if ($hasEvents) {
+            $event = $this->dispatchEvent(
+                'Model.afterRules',
+                compact('entity', 'options', 'result', 'operation')
+            );
+
+            if ($event->isStopped()) {
+                return $event->getResult();
+            }
+        }
+
+        return $result;
+    }
+
+    /**
+     * Returns the RulesChecker for this instance.
+     *
+     * A RulesChecker object is used to test an entity for validity
+     * on rules that may involve complex logic or data that
+     * needs to be fetched from relevant datasources.
+     *
+     * @see \Cake\Datasource\RulesChecker
+     * @return \Cake\Datasource\RulesChecker
+     */
+    public function rulesChecker(): RulesChecker
+    {
+        if ($this->_rulesChecker !== null) {
+            return $this->_rulesChecker;
+        }
+        /** @psalm-var class-string<\Cake\Datasource\RulesChecker> $class */
+        $class = defined('static::RULES_CLASS') ? static::RULES_CLASS : RulesChecker::class;
+        /** @psalm-suppress ArgumentTypeCoercion */
+        $this->_rulesChecker = $this->buildRules(new $class(['repository' => $this]));
+        $this->dispatchEvent('Model.buildRules', ['rules' => $this->_rulesChecker]);
+
+        return $this->_rulesChecker;
+    }
+
+    /**
+     * Returns a RulesChecker object after modifying the one that was supplied.
+     *
+     * Subclasses should override this method in order to initialize the rules to be applied to
+     * entities saved by this instance.
+     *
+     * @param \Cake\Datasource\RulesChecker $rules The rules object to be modified.
+     * @return \Cake\Datasource\RulesChecker
+     */
+    public function buildRules(RulesChecker $rules): RulesChecker
+    {
+        return $rules;
+    }
+}
diff --git a/vendor/cakephp/datasource/RulesChecker.php b/vendor/cakephp/datasource/RulesChecker.php
new file mode 100644
index 0000000..c523eba
--- /dev/null
+++ b/vendor/cakephp/datasource/RulesChecker.php
@@ -0,0 +1,330 @@
+
+     */
+    protected $_rules = [];
+
+    /**
+     * The list of rules to check during create operations
+     *
+     * @var array<\Cake\Datasource\RuleInvoker>
+     */
+    protected $_createRules = [];
+
+    /**
+     * The list of rules to check during update operations
+     *
+     * @var array<\Cake\Datasource\RuleInvoker>
+     */
+    protected $_updateRules = [];
+
+    /**
+     * The list of rules to check during delete operations
+     *
+     * @var array<\Cake\Datasource\RuleInvoker>
+     */
+    protected $_deleteRules = [];
+
+    /**
+     * List of options to pass to every callable rule
+     *
+     * @var array
+     */
+    protected $_options = [];
+
+    /**
+     * Whether to use I18n functions for translating default error messages
+     *
+     * @var bool
+     */
+    protected $_useI18n = false;
+
+    /**
+     * Constructor. Takes the options to be passed to all rules.
+     *
+     * @param array $options The options to pass to every rule
+     */
+    public function __construct(array $options = [])
+    {
+        $this->_options = $options;
+        $this->_useI18n = function_exists('\Cake\I18n\__d');
+    }
+
+    /**
+     * Adds a rule that will be applied to the entity both on create and update
+     * operations.
+     *
+     * ### Options
+     *
+     * The options array accept the following special keys:
+     *
+     * - `errorField`: The name of the entity field that will be marked as invalid
+     *    if the rule does not pass.
+     * - `message`: The error message to set to `errorField` if the rule does not pass.
+     *
+     * @param callable $rule A callable function or object that will return whether
+     * the entity is valid or not.
+     * @param array|string|null $name The alias for a rule, or an array of options.
+     * @param array $options List of extra options to pass to the rule callable as
+     * second argument.
+     * @return $this
+     */
+    public function add(callable $rule, $name = null, array $options = [])
+    {
+        $this->_rules[] = $this->_addError($rule, $name, $options);
+
+        return $this;
+    }
+
+    /**
+     * Adds a rule that will be applied to the entity on create operations.
+     *
+     * ### Options
+     *
+     * The options array accept the following special keys:
+     *
+     * - `errorField`: The name of the entity field that will be marked as invalid
+     *    if the rule does not pass.
+     * - `message`: The error message to set to `errorField` if the rule does not pass.
+     *
+     * @param callable $rule A callable function or object that will return whether
+     * the entity is valid or not.
+     * @param array|string|null $name The alias for a rule or an array of options.
+     * @param array $options List of extra options to pass to the rule callable as
+     * second argument.
+     * @return $this
+     */
+    public function addCreate(callable $rule, $name = null, array $options = [])
+    {
+        $this->_createRules[] = $this->_addError($rule, $name, $options);
+
+        return $this;
+    }
+
+    /**
+     * Adds a rule that will be applied to the entity on update operations.
+     *
+     * ### Options
+     *
+     * The options array accept the following special keys:
+     *
+     * - `errorField`: The name of the entity field that will be marked as invalid
+     *    if the rule does not pass.
+     * - `message`: The error message to set to `errorField` if the rule does not pass.
+     *
+     * @param callable $rule A callable function or object that will return whether
+     * the entity is valid or not.
+     * @param array|string|null $name The alias for a rule, or an array of options.
+     * @param array $options List of extra options to pass to the rule callable as
+     * second argument.
+     * @return $this
+     */
+    public function addUpdate(callable $rule, $name = null, array $options = [])
+    {
+        $this->_updateRules[] = $this->_addError($rule, $name, $options);
+
+        return $this;
+    }
+
+    /**
+     * Adds a rule that will be applied to the entity on delete operations.
+     *
+     * ### Options
+     *
+     * The options array accept the following special keys:
+     *
+     * - `errorField`: The name of the entity field that will be marked as invalid
+     *    if the rule does not pass.
+     * - `message`: The error message to set to `errorField` if the rule does not pass.
+     *
+     * @param callable $rule A callable function or object that will return whether
+     * the entity is valid or not.
+     * @param array|string|null $name The alias for a rule, or an array of options.
+     * @param array $options List of extra options to pass to the rule callable as
+     * second argument.
+     * @return $this
+     */
+    public function addDelete(callable $rule, $name = null, array $options = [])
+    {
+        $this->_deleteRules[] = $this->_addError($rule, $name, $options);
+
+        return $this;
+    }
+
+    /**
+     * Runs each of the rules by passing the provided entity and returns true if all
+     * of them pass. The rules to be applied are depended on the $mode parameter which
+     * can only be RulesChecker::CREATE, RulesChecker::UPDATE or RulesChecker::DELETE
+     *
+     * @param \Cake\Datasource\EntityInterface $entity The entity to check for validity.
+     * @param string $mode Either 'create, 'update' or 'delete'.
+     * @param array $options Extra options to pass to checker functions.
+     * @return bool
+     * @throws \InvalidArgumentException if an invalid mode is passed.
+     */
+    public function check(EntityInterface $entity, string $mode, array $options = []): bool
+    {
+        if ($mode === self::CREATE) {
+            return $this->checkCreate($entity, $options);
+        }
+
+        if ($mode === self::UPDATE) {
+            return $this->checkUpdate($entity, $options);
+        }
+
+        if ($mode === self::DELETE) {
+            return $this->checkDelete($entity, $options);
+        }
+
+        throw new InvalidArgumentException('Wrong checking mode: ' . $mode);
+    }
+
+    /**
+     * Runs each of the rules by passing the provided entity and returns true if all
+     * of them pass. The rules selected will be only those specified to be run on 'create'
+     *
+     * @param \Cake\Datasource\EntityInterface $entity The entity to check for validity.
+     * @param array $options Extra options to pass to checker functions.
+     * @return bool
+     */
+    public function checkCreate(EntityInterface $entity, array $options = []): bool
+    {
+        return $this->_checkRules($entity, $options, array_merge($this->_rules, $this->_createRules));
+    }
+
+    /**
+     * Runs each of the rules by passing the provided entity and returns true if all
+     * of them pass. The rules selected will be only those specified to be run on 'update'
+     *
+     * @param \Cake\Datasource\EntityInterface $entity The entity to check for validity.
+     * @param array $options Extra options to pass to checker functions.
+     * @return bool
+     */
+    public function checkUpdate(EntityInterface $entity, array $options = []): bool
+    {
+        return $this->_checkRules($entity, $options, array_merge($this->_rules, $this->_updateRules));
+    }
+
+    /**
+     * Runs each of the rules by passing the provided entity and returns true if all
+     * of them pass. The rules selected will be only those specified to be run on 'delete'
+     *
+     * @param \Cake\Datasource\EntityInterface $entity The entity to check for validity.
+     * @param array $options Extra options to pass to checker functions.
+     * @return bool
+     */
+    public function checkDelete(EntityInterface $entity, array $options = []): bool
+    {
+        return $this->_checkRules($entity, $options, $this->_deleteRules);
+    }
+
+    /**
+     * Used by top level functions checkDelete, checkCreate and checkUpdate, this function
+     * iterates an array containing the rules to be checked and checks them all.
+     *
+     * @param \Cake\Datasource\EntityInterface $entity The entity to check for validity.
+     * @param array $options Extra options to pass to checker functions.
+     * @param array<\Cake\Datasource\RuleInvoker> $rules The list of rules that must be checked.
+     * @return bool
+     */
+    protected function _checkRules(EntityInterface $entity, array $options = [], array $rules = []): bool
+    {
+        $success = true;
+        $options += $this->_options;
+        foreach ($rules as $rule) {
+            $success = $rule($entity, $options) && $success;
+        }
+
+        return $success;
+    }
+
+    /**
+     * Utility method for decorating any callable so that if it returns false, the correct
+     * property in the entity is marked as invalid.
+     *
+     * @param callable|\Cake\Datasource\RuleInvoker $rule The rule to decorate
+     * @param array|string|null $name The alias for a rule or an array of options
+     * @param array $options The options containing the error message and field.
+     * @return \Cake\Datasource\RuleInvoker
+     */
+    protected function _addError(callable $rule, $name = null, array $options = []): RuleInvoker
+    {
+        if (is_array($name)) {
+            $options = $name;
+            $name = null;
+        }
+
+        if (!($rule instanceof RuleInvoker)) {
+            $rule = new RuleInvoker($rule, $name, $options);
+        } else {
+            $rule->setOptions($options)->setName($name);
+        }
+
+        return $rule;
+    }
+}
diff --git a/vendor/cakephp/datasource/SchemaInterface.php b/vendor/cakephp/datasource/SchemaInterface.php
new file mode 100644
index 0000000..08ab8be
--- /dev/null
+++ b/vendor/cakephp/datasource/SchemaInterface.php
@@ -0,0 +1,166 @@
+|string $attrs The attributes for the column or the type name.
+     * @return $this
+     */
+    public function addColumn(string $name, $attrs);
+
+    /**
+     * Get column data in the table.
+     *
+     * @param string $name The column name.
+     * @return array|null Column data or null.
+     */
+    public function getColumn(string $name): ?array;
+
+    /**
+     * Returns true if a column exists in the schema.
+     *
+     * @param string $name Column name.
+     * @return bool
+     */
+    public function hasColumn(string $name): bool;
+
+    /**
+     * Remove a column from the table schema.
+     *
+     * If the column is not defined in the table, no error will be raised.
+     *
+     * @param string $name The name of the column
+     * @return $this
+     */
+    public function removeColumn(string $name);
+
+    /**
+     * Get the column names in the table.
+     *
+     * @return array
+     */
+    public function columns(): array;
+
+    /**
+     * Returns column type or null if a column does not exist.
+     *
+     * @param string $name The column to get the type of.
+     * @return string|null
+     */
+    public function getColumnType(string $name): ?string;
+
+    /**
+     * Sets the type of a column.
+     *
+     * @param string $name The column to set the type of.
+     * @param string $type The type to set the column to.
+     * @return $this
+     */
+    public function setColumnType(string $name, string $type);
+
+    /**
+     * Returns the base type name for the provided column.
+     * This represent the database type a more complex class is
+     * based upon.
+     *
+     * @param string $column The column name to get the base type from
+     * @return string|null The base type name
+     */
+    public function baseColumnType(string $column): ?string;
+
+    /**
+     * Check whether a field is nullable
+     *
+     * Missing columns are nullable.
+     *
+     * @param string $name The column to get the type of.
+     * @return bool Whether the field is nullable.
+     */
+    public function isNullable(string $name): bool;
+
+    /**
+     * Returns an array where the keys are the column names in the schema
+     * and the values the database type they have.
+     *
+     * @return array
+     */
+    public function typeMap(): array;
+
+    /**
+     * Get a hash of columns and their default values.
+     *
+     * @return array
+     */
+    public function defaultValues(): array;
+
+    /**
+     * Sets the options for a table.
+     *
+     * Table options allow you to set platform specific table level options.
+     * For example the engine type in MySQL.
+     *
+     * @param array $options The options to set, or null to read options.
+     * @return $this
+     */
+    public function setOptions(array $options);
+
+    /**
+     * Gets the options for a table.
+     *
+     * Table options allow you to set platform specific table level options.
+     * For example the engine type in MySQL.
+     *
+     * @return array An array of options.
+     */
+    public function getOptions(): array;
+}
diff --git a/vendor/cakephp/datasource/SimplePaginator.php b/vendor/cakephp/datasource/SimplePaginator.php
new file mode 100644
index 0000000..134b0bd
--- /dev/null
+++ b/vendor/cakephp/datasource/SimplePaginator.php
@@ -0,0 +1,10 @@
+=7.4.0",
+        "cakephp/core": "^4.0",
+        "psr/log": "^1.0 || ^2.0",
+        "psr/simple-cache": "^1.0 || ^2.0"
+    },
+    "suggest": {
+        "cakephp/utility": "If you decide to use EntityTrait.",
+        "cakephp/collection": "If you decide to use ResultSetInterface.",
+        "cakephp/cache": "If you decide to use Query caching."
+    },
+    "autoload": {
+        "psr-4": {
+            "Cake\\Datasource\\": "."
+        }
+    }
+}
diff --git a/vendor/cakephp/utility/CookieCryptTrait.php b/vendor/cakephp/utility/CookieCryptTrait.php
new file mode 100644
index 0000000..a57bfc0
--- /dev/null
+++ b/vendor/cakephp/utility/CookieCryptTrait.php
@@ -0,0 +1,192 @@
+
+     */
+    protected $_validCiphers = ['aes'];
+
+    /**
+     * Returns the encryption key to be used.
+     *
+     * @return string
+     */
+    abstract protected function _getCookieEncryptionKey(): string;
+
+    /**
+     * Encrypts $value using public $type method in Security class
+     *
+     * @param array|string $value Value to encrypt
+     * @param string|false $encrypt Encryption mode to use. False
+     *   disabled encryption.
+     * @param string|null $key Used as the security salt if specified.
+     * @return string Encoded values
+     */
+    protected function _encrypt($value, $encrypt, ?string $key = null): string
+    {
+        if (is_array($value)) {
+            $value = $this->_implode($value);
+        }
+        if ($encrypt === false) {
+            return $value;
+        }
+        $this->_checkCipher($encrypt);
+        $prefix = 'Q2FrZQ==.';
+        $cipher = '';
+        if ($key === null) {
+            $key = $this->_getCookieEncryptionKey();
+        }
+        if ($encrypt === 'aes') {
+            $cipher = Security::encrypt($value, $key);
+        }
+
+        return $prefix . base64_encode($cipher);
+    }
+
+    /**
+     * Helper method for validating encryption cipher names.
+     *
+     * @param string $encrypt The cipher name.
+     * @return void
+     * @throws \RuntimeException When an invalid cipher is provided.
+     */
+    protected function _checkCipher(string $encrypt): void
+    {
+        if (!in_array($encrypt, $this->_validCiphers, true)) {
+            $msg = sprintf(
+                'Invalid encryption cipher. Must be one of %s or false.',
+                implode(', ', $this->_validCiphers)
+            );
+            throw new RuntimeException($msg);
+        }
+    }
+
+    /**
+     * Decrypts $value using public $type method in Security class
+     *
+     * @param array|string $values Values to decrypt
+     * @param string|false $mode Encryption mode
+     * @param string|null $key Used as the security salt if specified.
+     * @return array|string Decrypted values
+     */
+    protected function _decrypt($values, $mode, ?string $key = null)
+    {
+        if (is_string($values)) {
+            return $this->_decode($values, $mode, $key);
+        }
+
+        $decrypted = [];
+        foreach ($values as $name => $value) {
+            $decrypted[$name] = $this->_decode($value, $mode, $key);
+        }
+
+        return $decrypted;
+    }
+
+    /**
+     * Decodes and decrypts a single value.
+     *
+     * @param string $value The value to decode & decrypt.
+     * @param string|false $encrypt The encryption cipher to use.
+     * @param string|null $key Used as the security salt if specified.
+     * @return array|string Decoded values.
+     */
+    protected function _decode(string $value, $encrypt, ?string $key)
+    {
+        if (!$encrypt) {
+            return $this->_explode($value);
+        }
+        $this->_checkCipher($encrypt);
+        $prefix = 'Q2FrZQ==.';
+        $prefixLength = strlen($prefix);
+
+        if (strncmp($value, $prefix, $prefixLength) !== 0) {
+            return '';
+        }
+
+        $value = base64_decode(substr($value, $prefixLength), true);
+
+        if ($value === false || $value === '') {
+            return '';
+        }
+
+        if ($key === null) {
+            $key = $this->_getCookieEncryptionKey();
+        }
+        if ($encrypt === 'aes') {
+            $value = Security::decrypt($value, $key);
+        }
+
+        if ($value === null) {
+            return '';
+        }
+
+        return $this->_explode($value);
+    }
+
+    /**
+     * Implode method to keep keys are multidimensional arrays
+     *
+     * @param array $array Map of key and values
+     * @return string A JSON encoded string.
+     */
+    protected function _implode(array $array): string
+    {
+        return json_encode($array);
+    }
+
+    /**
+     * Explode method to return array from string set in CookieComponent::_implode()
+     * Maintains reading backwards compatibility with 1.x CookieComponent::_implode().
+     *
+     * @param string $string A string containing JSON encoded data, or a bare string.
+     * @return array|string Map of key and values
+     */
+    protected function _explode(string $string)
+    {
+        $first = substr($string, 0, 1);
+        if ($first === '{' || $first === '[') {
+            $ret = json_decode($string, true);
+
+            return $ret ?? $string;
+        }
+        $array = [];
+        foreach (explode(',', $string) as $pair) {
+            $key = explode('|', $pair);
+            if (!isset($key[1])) {
+                return $key[0];
+            }
+            $array[$key[0]] = $key[1];
+        }
+
+        return $array;
+    }
+}
diff --git a/vendor/cakephp/utility/Crypto/OpenSsl.php b/vendor/cakephp/utility/Crypto/OpenSsl.php
new file mode 100644
index 0000000..99590d3
--- /dev/null
+++ b/vendor/cakephp/utility/Crypto/OpenSsl.php
@@ -0,0 +1,79 @@
+|string|int|null $path The path being searched for. Either a dot
+     *   separated string, or an array of path segments.
+     * @param mixed $default The return value when the path does not exist
+     * @throws \InvalidArgumentException
+     * @return mixed The value fetched from the array, or null.
+     * @link https://book.cakephp.org/4/en/core-libraries/hash.html#Cake\Utility\Hash::get
+     */
+    public static function get($data, $path, $default = null)
+    {
+        if (!(is_array($data) || $data instanceof ArrayAccess)) {
+            throw new InvalidArgumentException(
+                'Invalid data type, must be an array or \ArrayAccess instance.'
+            );
+        }
+
+        if (empty($data) || $path === null) {
+            return $default;
+        }
+
+        if (is_string($path) || is_numeric($path)) {
+            $parts = explode('.', (string)$path);
+        } else {
+            if (!is_array($path)) {
+                throw new InvalidArgumentException(sprintf(
+                    'Invalid Parameter %s, should be dot separated path or array.',
+                    $path
+                ));
+            }
+
+            $parts = $path;
+        }
+
+        switch (count($parts)) {
+            case 1:
+                return $data[$parts[0]] ?? $default;
+            case 2:
+                return $data[$parts[0]][$parts[1]] ?? $default;
+            case 3:
+                return $data[$parts[0]][$parts[1]][$parts[2]] ?? $default;
+            default:
+                foreach ($parts as $key) {
+                    if ((is_array($data) || $data instanceof ArrayAccess) && isset($data[$key])) {
+                        $data = $data[$key];
+                    } else {
+                        return $default;
+                    }
+                }
+        }
+
+        return $data;
+    }
+
+    /**
+     * Gets the values from an array matching the $path expression.
+     * The path expression is a dot separated expression, that can contain a set
+     * of patterns and expressions:
+     *
+     * - `{n}` Matches any numeric key, or integer.
+     * - `{s}` Matches any string key.
+     * - `{*}` Matches any value.
+     * - `Foo` Matches any key with the exact same value.
+     *
+     * There are a number of attribute operators:
+     *
+     *  - `=`, `!=` Equality.
+     *  - `>`, `<`, `>=`, `<=` Value comparison.
+     *  - `=/.../` Regular expression pattern match.
+     *
+     * Given a set of User array data, from a `$usersTable->find('all')` call:
+     *
+     * - `1.User.name` Get the name of the user at index 1.
+     * - `{n}.User.name` Get the name of every user in the set of users.
+     * - `{n}.User[id].name` Get the name of every user with an id key.
+     * - `{n}.User[id>=2].name` Get the name of every user with an id key greater than or equal to 2.
+     * - `{n}.User[username=/^paul/]` Get User elements with username matching `^paul`.
+     * - `{n}.User[id=1].name` Get the Users name with id matching `1`.
+     *
+     * @param \ArrayAccess|array $data The data to extract from.
+     * @param string $path The path to extract.
+     * @return \ArrayAccess|array An array of the extracted values. Returns an empty array
+     *   if there are no matches.
+     * @link https://book.cakephp.org/4/en/core-libraries/hash.html#Cake\Utility\Hash::extract
+     */
+    public static function extract($data, string $path)
+    {
+        if (!(is_array($data) || $data instanceof ArrayAccess)) {
+            throw new InvalidArgumentException(
+                'Invalid data type, must be an array or \ArrayAccess instance.'
+            );
+        }
+
+        if (empty($path)) {
+            return $data;
+        }
+
+        // Simple paths.
+        if (!preg_match('/[{\[]/', $path)) {
+            $data = static::get($data, $path);
+            if ($data !== null && !(is_array($data) || $data instanceof ArrayAccess)) {
+                return [$data];
+            }
+
+            return $data !== null ? (array)$data : [];
+        }
+
+        if (strpos($path, '[') === false) {
+            $tokens = explode('.', $path);
+        } else {
+            $tokens = Text::tokenize($path, '.', '[', ']');
+        }
+
+        $_key = '__set_item__';
+
+        $context = [$_key => [$data]];
+
+        foreach ($tokens as $token) {
+            $next = [];
+
+            [$token, $conditions] = self::_splitConditions($token);
+
+            foreach ($context[$_key] as $item) {
+                if (is_object($item) && method_exists($item, 'toArray')) {
+                    /** @var \Cake\Datasource\EntityInterface $item */
+                    $item = $item->toArray();
+                }
+                foreach ((array)$item as $k => $v) {
+                    if (static::_matchToken($k, $token)) {
+                        $next[] = $v;
+                    }
+                }
+            }
+
+            // Filter for attributes.
+            if ($conditions) {
+                $filter = [];
+                foreach ($next as $item) {
+                    if (
+                        (
+                            is_array($item) ||
+                            $item instanceof ArrayAccess
+                        ) &&
+                        static::_matches($item, $conditions)
+                    ) {
+                        $filter[] = $item;
+                    }
+                }
+                $next = $filter;
+            }
+            $context = [$_key => $next];
+        }
+
+        return $context[$_key];
+    }
+
+    /**
+     * Split token conditions
+     *
+     * @param string $token the token being splitted.
+     * @return array [token, conditions] with token splitted
+     */
+    protected static function _splitConditions(string $token): array
+    {
+        $conditions = false;
+        $position = strpos($token, '[');
+        if ($position !== false) {
+            $conditions = substr($token, $position);
+            $token = substr($token, 0, $position);
+        }
+
+        return [$token, $conditions];
+    }
+
+    /**
+     * Check a key against a token.
+     *
+     * @param mixed $key The key in the array being searched.
+     * @param string $token The token being matched.
+     * @return bool
+     */
+    protected static function _matchToken($key, string $token): bool
+    {
+        switch ($token) {
+            case '{n}':
+                return is_numeric($key);
+            case '{s}':
+                return is_string($key);
+            case '{*}':
+                return true;
+            default:
+                return is_numeric($token) ? ($key == $token) : $key === $token;
+        }
+    }
+
+    /**
+     * Checks whether $data matches the attribute patterns
+     *
+     * @param \ArrayAccess|array $data Array of data to match.
+     * @param string $selector The patterns to match.
+     * @return bool Fitness of expression.
+     */
+    protected static function _matches($data, string $selector): bool
+    {
+        preg_match_all(
+            '/(\[ (?P[^=>[><]) \s* (?P(?:\/.*?\/ | [^\]]+)) )? \])/x',
+            $selector,
+            $conditions,
+            PREG_SET_ORDER
+        );
+
+        foreach ($conditions as $cond) {
+            $attr = $cond['attr'];
+            $op = $cond['op'] ?? null;
+            $val = $cond['val'] ?? null;
+
+            // Presence test.
+            if (empty($op) && empty($val) && !isset($data[$attr])) {
+                return false;
+            }
+
+            if (is_array($data)) {
+                $attrPresent = array_key_exists($attr, $data);
+            } else {
+                $attrPresent = $data->offsetExists($attr);
+            }
+            // Empty attribute = fail.
+            if (!$attrPresent) {
+                return false;
+            }
+
+            $prop = $data[$attr] ?? '';
+            $isBool = is_bool($prop);
+            if ($isBool && is_numeric($val)) {
+                $prop = $prop ? '1' : '0';
+            } elseif ($isBool) {
+                $prop = $prop ? 'true' : 'false';
+            } elseif (is_numeric($prop)) {
+                $prop = (string)$prop;
+            }
+
+            // Pattern matches and other operators.
+            if ($op === '=' && $val && $val[0] === '/') {
+                if (!preg_match($val, $prop)) {
+                    return false;
+                }
+                // phpcs:disable
+            } elseif (
+                ($op === '=' && $prop != $val) ||
+                ($op === '!=' && $prop == $val) ||
+                ($op === '>' && $prop <= $val) ||
+                ($op === '<' && $prop >= $val) ||
+                ($op === '>=' && $prop < $val) ||
+                ($op === '<=' && $prop > $val)
+                // phpcs:enable
+            ) {
+                return false;
+            }
+        }
+
+        return true;
+    }
+
+    /**
+     * Insert $values into an array with the given $path. You can use
+     * `{n}` and `{s}` elements to insert $data multiple times.
+     *
+     * @param array $data The data to insert into.
+     * @param string $path The path to insert at.
+     * @param mixed $values The values to insert.
+     * @return array The data with $values inserted.
+     * @link https://book.cakephp.org/4/en/core-libraries/hash.html#Cake\Utility\Hash::insert
+     */
+    public static function insert(array $data, string $path, $values = null): array
+    {
+        $noTokens = strpos($path, '[') === false;
+        if ($noTokens && strpos($path, '.') === false) {
+            $data[$path] = $values;
+
+            return $data;
+        }
+
+        if ($noTokens) {
+            $tokens = explode('.', $path);
+        } else {
+            $tokens = Text::tokenize($path, '.', '[', ']');
+        }
+
+        if ($noTokens && strpos($path, '{') === false) {
+            return static::_simpleOp('insert', $data, $tokens, $values);
+        }
+
+        $token = array_shift($tokens);
+        $nextPath = implode('.', $tokens);
+
+        [$token, $conditions] = static::_splitConditions($token);
+
+        foreach ($data as $k => $v) {
+            if (static::_matchToken($k, $token)) {
+                if (!$conditions || static::_matches($v, $conditions)) {
+                    $data[$k] = $nextPath
+                        ? static::insert($v, $nextPath, $values)
+                        : array_merge($v, (array)$values);
+                }
+            }
+        }
+
+        return $data;
+    }
+
+    /**
+     * Perform a simple insert/remove operation.
+     *
+     * @param string $op The operation to do.
+     * @param array $data The data to operate on.
+     * @param array $path The path to work on.
+     * @param mixed $values The values to insert when doing inserts.
+     * @return array data.
+     */
+    protected static function _simpleOp(string $op, array $data, array $path, $values = null): array
+    {
+        $_list = &$data;
+
+        $count = count($path);
+        $last = $count - 1;
+        foreach ($path as $i => $key) {
+            if ($op === 'insert') {
+                if ($i === $last) {
+                    $_list[$key] = $values;
+
+                    return $data;
+                }
+                $_list[$key] = $_list[$key] ?? [];
+                $_list = &$_list[$key];
+                if (!is_array($_list)) {
+                    $_list = [];
+                }
+            } elseif ($op === 'remove') {
+                if ($i === $last) {
+                    if (is_array($_list)) {
+                        unset($_list[$key]);
+                    }
+
+                    return $data;
+                }
+                if (!isset($_list[$key])) {
+                    return $data;
+                }
+                $_list = &$_list[$key];
+            }
+        }
+
+        return $data;
+    }
+
+    /**
+     * Remove data matching $path from the $data array.
+     * You can use `{n}` and `{s}` to remove multiple elements
+     * from $data.
+     *
+     * @param array $data The data to operate on
+     * @param string $path A path expression to use to remove.
+     * @return array The modified array.
+     * @link https://book.cakephp.org/4/en/core-libraries/hash.html#Cake\Utility\Hash::remove
+     */
+    public static function remove(array $data, string $path): array
+    {
+        $noTokens = strpos($path, '[') === false;
+        $noExpansion = strpos($path, '{') === false;
+
+        if ($noExpansion && $noTokens && strpos($path, '.') === false) {
+            unset($data[$path]);
+
+            return $data;
+        }
+
+        $tokens = $noTokens ? explode('.', $path) : Text::tokenize($path, '.', '[', ']');
+
+        if ($noExpansion && $noTokens) {
+            return static::_simpleOp('remove', $data, $tokens);
+        }
+
+        $token = array_shift($tokens);
+        $nextPath = implode('.', $tokens);
+
+        [$token, $conditions] = self::_splitConditions($token);
+
+        foreach ($data as $k => $v) {
+            $match = static::_matchToken($k, $token);
+            if ($match && is_array($v)) {
+                if ($conditions) {
+                    if (static::_matches($v, $conditions)) {
+                        if ($nextPath !== '') {
+                            $data[$k] = static::remove($v, $nextPath);
+                        } else {
+                            unset($data[$k]);
+                        }
+                    }
+                } else {
+                    $data[$k] = static::remove($v, $nextPath);
+                }
+                if (empty($data[$k])) {
+                    unset($data[$k]);
+                }
+            } elseif ($match && $nextPath === '') {
+                unset($data[$k]);
+            }
+        }
+
+        return $data;
+    }
+
+    /**
+     * Creates an associative array using `$keyPath` as the path to build its keys, and optionally
+     * `$valuePath` as path to get the values. If `$valuePath` is not specified, all values will be initialized
+     * to null (useful for Hash::merge). You can optionally group the values by what is obtained when
+     * following the path specified in `$groupPath`.
+     *
+     * @param array $data Array from where to extract keys and values
+     * @param array|string|null $keyPath A dot-separated string.
+     * @param array|string|null $valuePath A dot-separated string.
+     * @param string|null $groupPath A dot-separated string.
+     * @return array Combined array
+     * @link https://book.cakephp.org/4/en/core-libraries/hash.html#Cake\Utility\Hash::combine
+     * @throws \RuntimeException When keys and values count is unequal.
+     */
+    public static function combine(array $data, $keyPath, $valuePath = null, ?string $groupPath = null): array
+    {
+        if (empty($data)) {
+            return [];
+        }
+
+        if (is_array($keyPath)) {
+            $format = array_shift($keyPath);
+            /** @var array $keys */
+            $keys = static::format($data, $keyPath, $format);
+        } elseif ($keyPath === null) {
+            $keys = $keyPath;
+        } else {
+            /** @var array $keys */
+            $keys = static::extract($data, $keyPath);
+        }
+        if ($keyPath !== null && empty($keys)) {
+            return [];
+        }
+
+        $vals = null;
+        if (!empty($valuePath) && is_array($valuePath)) {
+            $format = array_shift($valuePath);
+            /** @var array $vals */
+            $vals = static::format($data, $valuePath, $format);
+        } elseif (!empty($valuePath)) {
+            /** @var array $vals */
+            $vals = static::extract($data, $valuePath);
+        }
+        if (empty($vals)) {
+            $vals = array_fill(0, $keys === null ? count($data) : count($keys), null);
+        }
+
+        if (is_array($keys) && count($keys) !== count($vals)) {
+            throw new RuntimeException(
+                'Hash::combine() needs an equal number of keys + values.'
+            );
+        }
+
+        if ($groupPath !== null) {
+            $group = static::extract($data, $groupPath);
+            if (!empty($group)) {
+                $c = is_array($keys) ? count($keys) : count($vals);
+                $out = [];
+                for ($i = 0; $i < $c; $i++) {
+                    $group[$i] = $group[$i] ?? 0;
+                    $out[$group[$i]] = $out[$group[$i]] ?? [];
+                    if ($keys === null) {
+                        $out[$group[$i]][] = $vals[$i];
+                    } else {
+                        $out[$group[$i]][$keys[$i]] = $vals[$i];
+                    }
+                }
+
+                return $out;
+            }
+        }
+        if (empty($vals)) {
+            return [];
+        }
+
+        return array_combine($keys ?? range(0, count($vals) - 1), $vals);
+    }
+
+    /**
+     * Returns a formatted series of values extracted from `$data`, using
+     * `$format` as the format and `$paths` as the values to extract.
+     *
+     * Usage:
+     *
+     * ```
+     * $result = Hash::format($users, ['{n}.User.id', '{n}.User.name'], '%s : %s');
+     * ```
+     *
+     * The `$format` string can use any format options that `vsprintf()` and `sprintf()` do.
+     *
+     * @param array $data Source array from which to extract the data
+     * @param array $paths An array containing one or more Hash::extract()-style key paths
+     * @param string $format Format string into which values will be inserted, see sprintf()
+     * @return array|null An array of strings extracted from `$path` and formatted with `$format`
+     * @link https://book.cakephp.org/4/en/core-libraries/hash.html#Cake\Utility\Hash::format
+     * @see sprintf()
+     * @see \Cake\Utility\Hash::extract()
+     */
+    public static function format(array $data, array $paths, string $format): ?array
+    {
+        $extracted = [];
+        $count = count($paths);
+
+        if (!$count) {
+            return null;
+        }
+
+        for ($i = 0; $i < $count; $i++) {
+            $extracted[] = static::extract($data, $paths[$i]);
+        }
+        $out = [];
+        /** @var array $data */
+        $data = $extracted;
+        $count = count($data[0]);
+
+        $countTwo = count($data);
+        for ($j = 0; $j < $count; $j++) {
+            $args = [];
+            for ($i = 0; $i < $countTwo; $i++) {
+                if (array_key_exists($j, $data[$i])) {
+                    $args[] = $data[$i][$j];
+                }
+            }
+            $out[] = vsprintf($format, $args);
+        }
+
+        return $out;
+    }
+
+    /**
+     * Determines if one array contains the exact keys and values of another.
+     *
+     * @param array $data The data to search through.
+     * @param array $needle The values to file in $data
+     * @return bool true If $data contains $needle, false otherwise
+     * @link https://book.cakephp.org/4/en/core-libraries/hash.html#Cake\Utility\Hash::contains
+     */
+    public static function contains(array $data, array $needle): bool
+    {
+        if (empty($data) || empty($needle)) {
+            return false;
+        }
+        $stack = [];
+
+        while (!empty($needle)) {
+            $key = key($needle);
+            $val = $needle[$key];
+            unset($needle[$key]);
+
+            if (array_key_exists($key, $data) && is_array($val)) {
+                $next = $data[$key];
+                unset($data[$key]);
+
+                if (!empty($val)) {
+                    $stack[] = [$val, $next];
+                }
+            } elseif (!array_key_exists($key, $data) || $data[$key] != $val) {
+                return false;
+            }
+
+            if (empty($needle) && !empty($stack)) {
+                [$needle, $data] = array_pop($stack);
+            }
+        }
+
+        return true;
+    }
+
+    /**
+     * Test whether a given path exists in $data.
+     * This method uses the same path syntax as Hash::extract()
+     *
+     * Checking for paths that could target more than one element will
+     * make sure that at least one matching element exists.
+     *
+     * @param array $data The data to check.
+     * @param string $path The path to check for.
+     * @return bool Existence of path.
+     * @see \Cake\Utility\Hash::extract()
+     * @link https://book.cakephp.org/4/en/core-libraries/hash.html#Cake\Utility\Hash::check
+     */
+    public static function check(array $data, string $path): bool
+    {
+        $results = static::extract($data, $path);
+        if (!is_array($results)) {
+            return false;
+        }
+
+        return count($results) > 0;
+    }
+
+    /**
+     * Recursively filters a data set.
+     *
+     * @param array $data Either an array to filter, or value when in callback
+     * @param callable|array $callback A function to filter the data with. Defaults to
+     *   `static::_filter()` Which strips out all non-zero empty values.
+     * @return array Filtered array
+     * @link https://book.cakephp.org/4/en/core-libraries/hash.html#Cake\Utility\Hash::filter
+     */
+    public static function filter(array $data, $callback = [Hash::class, '_filter']): array
+    {
+        foreach ($data as $k => $v) {
+            if (is_array($v)) {
+                $data[$k] = static::filter($v, $callback);
+            }
+        }
+
+        return array_filter($data, $callback);
+    }
+
+    /**
+     * Callback function for filtering.
+     *
+     * @param mixed $var Array to filter.
+     * @return bool
+     */
+    protected static function _filter($var): bool
+    {
+        return $var === 0 || $var === 0.0 || $var === '0' || !empty($var);
+    }
+
+    /**
+     * Collapses a multi-dimensional array into a single dimension, using a delimited array path for
+     * each array element's key, i.e. [['Foo' => ['Bar' => 'Far']]] becomes
+     * ['0.Foo.Bar' => 'Far'].)
+     *
+     * @param array $data Array to flatten
+     * @param string $separator String used to separate array key elements in a path, defaults to '.'
+     * @return array
+     * @link https://book.cakephp.org/4/en/core-libraries/hash.html#Cake\Utility\Hash::flatten
+     */
+    public static function flatten(array $data, string $separator = '.'): array
+    {
+        $result = [];
+        $stack = [];
+        $path = '';
+
+        reset($data);
+        while (!empty($data)) {
+            $key = key($data);
+            $element = $data[$key];
+            unset($data[$key]);
+
+            if (is_array($element) && !empty($element)) {
+                if (!empty($data)) {
+                    $stack[] = [$data, $path];
+                }
+                $data = $element;
+                reset($data);
+                $path .= $key . $separator;
+            } else {
+                $result[$path . $key] = $element;
+            }
+
+            if (empty($data) && !empty($stack)) {
+                [$data, $path] = array_pop($stack);
+                reset($data);
+            }
+        }
+
+        return $result;
+    }
+
+    /**
+     * Expands a flat array to a nested array.
+     *
+     * For example, unflattens an array that was collapsed with `Hash::flatten()`
+     * into a multi-dimensional array. So, `['0.Foo.Bar' => 'Far']` becomes
+     * `[['Foo' => ['Bar' => 'Far']]]`.
+     *
+     * @phpstan-param non-empty-string $separator
+     * @param array $data Flattened array
+     * @param string $separator The delimiter used
+     * @return array
+     * @link https://book.cakephp.org/4/en/core-libraries/hash.html#Cake\Utility\Hash::expand
+     */
+    public static function expand(array $data, string $separator = '.'): array
+    {
+        $hash = [];
+        foreach ($data as $path => $value) {
+            $keys = explode($separator, (string)$path);
+            if (count($keys) === 1) {
+                $hash[$path] = $value;
+                continue;
+            }
+
+            $valueKey = end($keys);
+            $keys = array_slice($keys, 0, -1);
+
+            $keyHash = &$hash;
+            foreach ($keys as $key) {
+                if (!array_key_exists($key, $keyHash)) {
+                    $keyHash[$key] = [];
+                }
+                $keyHash = &$keyHash[$key];
+            }
+            $keyHash[$valueKey] = $value;
+        }
+
+        return $hash;
+    }
+
+    /**
+     * This function can be thought of as a hybrid between PHP's `array_merge` and `array_merge_recursive`.
+     *
+     * The difference between this method and the built-in ones, is that if an array key contains another array, then
+     * Hash::merge() will behave in a recursive fashion (unlike `array_merge`). But it will not act recursively for
+     * keys that contain scalar values (unlike `array_merge_recursive`).
+     *
+     * This function will work with an unlimited amount of arguments and typecasts non-array parameters into arrays.
+     *
+     * @param array $data Array to be merged
+     * @param mixed $merge Array to merge with. The argument and all trailing arguments will be array cast when merged
+     * @return array Merged array
+     * @link https://book.cakephp.org/4/en/core-libraries/hash.html#Cake\Utility\Hash::merge
+     */
+    public static function merge(array $data, $merge): array
+    {
+        $args = array_slice(func_get_args(), 1);
+        $return = $data;
+        $stack = [];
+
+        foreach ($args as &$curArg) {
+            $stack[] = [(array)$curArg, &$return];
+        }
+        unset($curArg);
+        static::_merge($stack, $return);
+
+        return $return;
+    }
+
+    /**
+     * Merge helper function to reduce duplicated code between merge() and expand().
+     *
+     * @param array $stack The stack of operations to work with.
+     * @param array $return The return value to operate on.
+     * @return void
+     */
+    protected static function _merge(array $stack, array &$return): void
+    {
+        while (!empty($stack)) {
+            foreach ($stack as $curKey => &$curMerge) {
+                foreach ($curMerge[0] as $key => &$val) {
+                    if (!is_array($curMerge[1])) {
+                        continue;
+                    }
+
+                    if (
+                        !empty($curMerge[1][$key])
+                        && (array)$curMerge[1][$key] === $curMerge[1][$key]
+                        && (array)$val === $val
+                    ) {
+                        // Recurse into the current merge data as it is an array.
+                        $stack[] = [&$val, &$curMerge[1][$key]];
+                    } elseif ((int)$key === $key && isset($curMerge[1][$key])) {
+                        $curMerge[1][] = $val;
+                    } else {
+                        $curMerge[1][$key] = $val;
+                    }
+                }
+                unset($stack[$curKey]);
+            }
+            unset($curMerge);
+        }
+    }
+
+    /**
+     * Checks to see if all the values in the array are numeric
+     *
+     * @param array $data The array to check.
+     * @return bool true if values are numeric, false otherwise
+     * @link https://book.cakephp.org/4/en/core-libraries/hash.html#Cake\Utility\Hash::numeric
+     */
+    public static function numeric(array $data): bool
+    {
+        if (empty($data)) {
+            return false;
+        }
+
+        return $data === array_filter($data, 'is_numeric');
+    }
+
+    /**
+     * Counts the dimensions of an array.
+     * Only considers the dimension of the first element in the array.
+     *
+     * If you have an un-even or heterogeneous array, consider using Hash::maxDimensions()
+     * to get the dimensions of the array.
+     *
+     * @param array $data Array to count dimensions on
+     * @return int The number of dimensions in $data
+     * @link https://book.cakephp.org/4/en/core-libraries/hash.html#Cake\Utility\Hash::dimensions
+     */
+    public static function dimensions(array $data): int
+    {
+        if (empty($data)) {
+            return 0;
+        }
+        reset($data);
+        $depth = 1;
+        while ($elem = array_shift($data)) {
+            if (is_array($elem)) {
+                $depth++;
+                $data = $elem;
+            } else {
+                break;
+            }
+        }
+
+        return $depth;
+    }
+
+    /**
+     * Counts the dimensions of *all* array elements. Useful for finding the maximum
+     * number of dimensions in a mixed array.
+     *
+     * @param array $data Array to count dimensions on
+     * @return int The maximum number of dimensions in $data
+     * @link https://book.cakephp.org/4/en/core-libraries/hash.html#Cake\Utility\Hash::maxDimensions
+     */
+    public static function maxDimensions(array $data): int
+    {
+        $depth = [];
+        if (!empty($data)) {
+            foreach ($data as $value) {
+                if (is_array($value)) {
+                    $depth[] = static::maxDimensions($value) + 1;
+                } else {
+                    $depth[] = 1;
+                }
+            }
+        }
+
+        return empty($depth) ? 0 : max($depth);
+    }
+
+    /**
+     * Map a callback across all elements in a set.
+     * Can be provided a path to only modify slices of the set.
+     *
+     * @param array $data The data to map over, and extract data out of.
+     * @param string $path The path to extract for mapping over.
+     * @param callable $function The function to call on each extracted value.
+     * @return array An array of the modified values.
+     * @link https://book.cakephp.org/4/en/core-libraries/hash.html#Cake\Utility\Hash::map
+     */
+    public static function map(array $data, string $path, callable $function): array
+    {
+        $values = (array)static::extract($data, $path);
+
+        return array_map($function, $values);
+    }
+
+    /**
+     * Reduce a set of extracted values using `$function`.
+     *
+     * @param array $data The data to reduce.
+     * @param string $path The path to extract from $data.
+     * @param callable $function The function to call on each extracted value.
+     * @return mixed The reduced value.
+     * @link https://book.cakephp.org/4/en/core-libraries/hash.html#Cake\Utility\Hash::reduce
+     */
+    public static function reduce(array $data, string $path, callable $function)
+    {
+        $values = (array)static::extract($data, $path);
+
+        return array_reduce($values, $function);
+    }
+
+    /**
+     * Apply a callback to a set of extracted values using `$function`.
+     * The function will get the extracted values as the first argument.
+     *
+     * ### Example
+     *
+     * You can easily count the results of an extract using apply().
+     * For example to count the comments on an Article:
+     *
+     * ```
+     * $count = Hash::apply($data, 'Article.Comment.{n}', 'count');
+     * ```
+     *
+     * You could also use a function like `array_sum` to sum the results.
+     *
+     * ```
+     * $total = Hash::apply($data, '{n}.Item.price', 'array_sum');
+     * ```
+     *
+     * @param array $data The data to reduce.
+     * @param string $path The path to extract from $data.
+     * @param callable $function The function to call on each extracted value.
+     * @return mixed The results of the applied method.
+     * @link https://book.cakephp.org/4/en/core-libraries/hash.html#Cake\Utility\Hash::apply
+     */
+    public static function apply(array $data, string $path, callable $function)
+    {
+        $values = (array)static::extract($data, $path);
+
+        return $function($values);
+    }
+
+    /**
+     * Sorts an array by any value, determined by a Set-compatible path
+     *
+     * ### Sort directions
+     *
+     * - `asc` or \SORT_ASC Sort ascending.
+     * - `desc` or \SORT_DESC Sort descending.
+     *
+     * ### Sort types
+     *
+     * - `regular` For regular sorting (don't change types)
+     * - `numeric` Compare values numerically
+     * - `string` Compare values as strings
+     * - `locale` Compare items as strings, based on the current locale
+     * - `natural` Compare items as strings using "natural ordering" in a human friendly way
+     *   Will sort foo10 below foo2 as an example.
+     *
+     * To do case insensitive sorting, pass the type as an array as follows:
+     *
+     * ```
+     * Hash::sort($data, 'some.attribute', 'asc', ['type' => 'regular', 'ignoreCase' => true]);
+     * ```
+     *
+     * When using the array form, `type` defaults to 'regular'. The `ignoreCase` option
+     * defaults to `false`.
+     *
+     * @param array $data An array of data to sort
+     * @param string $path A Set-compatible path to the array value
+     * @param string|int $dir See directions above. Defaults to 'asc'.
+     * @param array|string $type See direction types above. Defaults to 'regular'.
+     * @return array Sorted array of data
+     * @link https://book.cakephp.org/4/en/core-libraries/hash.html#Cake\Utility\Hash::sort
+     */
+    public static function sort(array $data, string $path, $dir = 'asc', $type = 'regular'): array
+    {
+        if (empty($data)) {
+            return [];
+        }
+        $originalKeys = array_keys($data);
+        $numeric = is_numeric(implode('', $originalKeys));
+        if ($numeric) {
+            $data = array_values($data);
+        }
+        /** @var array $sortValues */
+        $sortValues = static::extract($data, $path);
+        $dataCount = count($data);
+
+        // Make sortValues match the data length, as some keys could be missing
+        // the sorted value path.
+        $missingData = count($sortValues) < $dataCount;
+        if ($missingData && $numeric) {
+            // Get the path without the leading '{n}.'
+            $itemPath = substr($path, 4);
+            foreach ($data as $key => $value) {
+                $sortValues[$key] = static::get($value, $itemPath);
+            }
+        } elseif ($missingData) {
+            $sortValues = array_pad($sortValues, $dataCount, null);
+        }
+        $result = static::_squash($sortValues);
+        /** @var array $keys */
+        $keys = static::extract($result, '{n}.id');
+        /** @var array $values */
+        $values = static::extract($result, '{n}.value');
+
+        if (is_string($dir)) {
+            $dir = strtolower($dir);
+        }
+        if (!in_array($dir, [\SORT_ASC, \SORT_DESC], true)) {
+            $dir = $dir === 'asc' ? \SORT_ASC : \SORT_DESC;
+        }
+
+        $ignoreCase = false;
+
+        // $type can be overloaded for case insensitive sort
+        if (is_array($type)) {
+            $type += ['ignoreCase' => false, 'type' => 'regular'];
+            $ignoreCase = $type['ignoreCase'];
+            $type = $type['type'];
+        }
+        $type = strtolower($type);
+
+        if ($type === 'numeric') {
+            $type = \SORT_NUMERIC;
+        } elseif ($type === 'string') {
+            $type = \SORT_STRING;
+        } elseif ($type === 'natural') {
+            $type = \SORT_NATURAL;
+        } elseif ($type === 'locale') {
+            $type = \SORT_LOCALE_STRING;
+        } else {
+            $type = \SORT_REGULAR;
+        }
+        if ($ignoreCase) {
+            $values = array_map('mb_strtolower', $values);
+        }
+        array_multisort($values, $dir, $type, $keys, $dir, $type);
+        $sorted = [];
+        $keys = array_unique($keys);
+
+        foreach ($keys as $k) {
+            if ($numeric) {
+                $sorted[] = $data[$k];
+                continue;
+            }
+            if (isset($originalKeys[$k])) {
+                $sorted[$originalKeys[$k]] = $data[$originalKeys[$k]];
+            } else {
+                $sorted[$k] = $data[$k];
+            }
+        }
+
+        return $sorted;
+    }
+
+    /**
+     * Helper method for sort()
+     * Squashes an array to a single hash so it can be sorted.
+     *
+     * @param array $data The data to squash.
+     * @param mixed $key The key for the data.
+     * @return array
+     */
+    protected static function _squash(array $data, $key = null): array
+    {
+        $stack = [];
+        foreach ($data as $k => $r) {
+            $id = $k;
+            if ($key !== null) {
+                $id = $key;
+            }
+            if (is_array($r) && !empty($r)) {
+                $stack = array_merge($stack, static::_squash($r, $id));
+            } else {
+                $stack[] = ['id' => $id, 'value' => $r];
+            }
+        }
+
+        return $stack;
+    }
+
+    /**
+     * Computes the difference between two complex arrays.
+     * This method differs from the built-in array_diff() in that it will preserve keys
+     * and work on multi-dimensional arrays.
+     *
+     * @param array $data First value
+     * @param array $compare Second value
+     * @return array Returns the key => value pairs that are not common in $data and $compare
+     *    The expression for this function is ($data - $compare) + ($compare - ($data - $compare))
+     * @link https://book.cakephp.org/4/en/core-libraries/hash.html#Cake\Utility\Hash::diff
+     */
+    public static function diff(array $data, array $compare): array
+    {
+        if (empty($data)) {
+            return $compare;
+        }
+        if (empty($compare)) {
+            return $data;
+        }
+        $intersection = array_intersect_key($data, $compare);
+        while (($key = key($intersection)) !== null) {
+            if ($data[$key] == $compare[$key]) {
+                unset($data[$key], $compare[$key]);
+            }
+            next($intersection);
+        }
+
+        return $data + $compare;
+    }
+
+    /**
+     * Merges the difference between $data and $compare onto $data.
+     *
+     * @param array $data The data to append onto.
+     * @param array $compare The data to compare and append onto.
+     * @return array The merged array.
+     * @link https://book.cakephp.org/4/en/core-libraries/hash.html#Cake\Utility\Hash::mergeDiff
+     */
+    public static function mergeDiff(array $data, array $compare): array
+    {
+        if (empty($data) && !empty($compare)) {
+            return $compare;
+        }
+        if (empty($compare)) {
+            return $data;
+        }
+        foreach ($compare as $key => $value) {
+            if (!array_key_exists($key, $data)) {
+                $data[$key] = $value;
+            } elseif (is_array($value) && is_array($data[$key])) {
+                $data[$key] = static::mergeDiff($data[$key], $value);
+            }
+        }
+
+        return $data;
+    }
+
+    /**
+     * Normalizes an array, and converts it to a standard format.
+     *
+     * @param array $data List to normalize
+     * @param bool $assoc If true, $data will be converted to an associative array.
+     * @param mixed $default The default value to use when a top level numeric key is converted to associative form.
+     * @return array
+     * @link https://book.cakephp.org/4/en/core-libraries/hash.html#Cake\Utility\Hash::normalize
+     */
+    public static function normalize(array $data, bool $assoc = true, $default = null): array
+    {
+        $keys = array_keys($data);
+        $count = count($keys);
+        $numeric = true;
+
+        if (!$assoc) {
+            for ($i = 0; $i < $count; $i++) {
+                if (!is_int($keys[$i])) {
+                    $numeric = false;
+                    break;
+                }
+            }
+        }
+        if (!$numeric || $assoc) {
+            $newList = [];
+            for ($i = 0; $i < $count; $i++) {
+                if (is_int($keys[$i])) {
+                    $newList[$data[$keys[$i]]] = $default;
+                } else {
+                    $newList[$keys[$i]] = $data[$keys[$i]];
+                }
+            }
+            $data = $newList;
+        }
+
+        return $data;
+    }
+
+    /**
+     * Takes in a flat array and returns a nested array
+     *
+     * ### Options:
+     *
+     * - `children` The key name to use in the resultset for children.
+     * - `idPath` The path to a key that identifies each entry. Should be
+     *   compatible with Hash::extract(). Defaults to `{n}.$alias.id`
+     * - `parentPath` The path to a key that identifies the parent of each entry.
+     *   Should be compatible with Hash::extract(). Defaults to `{n}.$alias.parent_id`
+     * - `root` The id of the desired top-most result.
+     *
+     * @param array $data The data to nest.
+     * @param array $options Options are:
+     * @return array of results, nested
+     * @see \Cake\Utility\Hash::extract()
+     * @throws \InvalidArgumentException When providing invalid data.
+     * @link https://book.cakephp.org/4/en/core-libraries/hash.html#Cake\Utility\Hash::nest
+     */
+    public static function nest(array $data, array $options = []): array
+    {
+        if (!$data) {
+            return $data;
+        }
+
+        $alias = key(current($data));
+        $options += [
+            'idPath' => "{n}.$alias.id",
+            'parentPath' => "{n}.$alias.parent_id",
+            'children' => 'children',
+            'root' => null,
+        ];
+
+        $return = $idMap = [];
+        /** @var array $ids */
+        $ids = static::extract($data, $options['idPath']);
+
+        $idKeys = explode('.', $options['idPath']);
+        array_shift($idKeys);
+
+        $parentKeys = explode('.', $options['parentPath']);
+        array_shift($parentKeys);
+
+        foreach ($data as $result) {
+            $result[$options['children']] = [];
+
+            $id = static::get($result, $idKeys);
+            $parentId = static::get($result, $parentKeys);
+
+            if (isset($idMap[$id][$options['children']])) {
+                $idMap[$id] = array_merge($result, $idMap[$id]);
+            } else {
+                $idMap[$id] = array_merge($result, [$options['children'] => []]);
+            }
+            if (!$parentId || !in_array($parentId, $ids)) {
+                $return[] = &$idMap[$id];
+            } else {
+                $idMap[$parentId][$options['children']][] = &$idMap[$id];
+            }
+        }
+
+        if (!$return) {
+            throw new InvalidArgumentException('Invalid data array to nest.');
+        }
+
+        if ($options['root']) {
+            $root = $options['root'];
+        } else {
+            $root = static::get($return[0], $parentKeys);
+        }
+
+        foreach ($return as $i => $result) {
+            $id = static::get($result, $idKeys);
+            $parentId = static::get($result, $parentKeys);
+            if ($id !== $root && $parentId != $root) {
+                unset($return[$i]);
+            }
+        }
+
+        return array_values($return);
+    }
+}
diff --git a/vendor/cakephp/utility/Inflector.php b/vendor/cakephp/utility/Inflector.php
new file mode 100644
index 0000000..9cb8c1f
--- /dev/null
+++ b/vendor/cakephp/utility/Inflector.php
@@ -0,0 +1,524 @@
+
+     */
+    protected static $_plural = [
+        '/(s)tatus$/i' => '\1tatuses',
+        '/(quiz)$/i' => '\1zes',
+        '/^(ox)$/i' => '\1\2en',
+        '/([m|l])ouse$/i' => '\1ice',
+        '/(matr|vert)(ix|ex)$/i' => '\1ices',
+        '/(x|ch|ss|sh)$/i' => '\1es',
+        '/([^aeiouy]|qu)y$/i' => '\1ies',
+        '/(hive)$/i' => '\1s',
+        '/(chef)$/i' => '\1s',
+        '/(?:([^f])fe|([lre])f)$/i' => '\1\2ves',
+        '/sis$/i' => 'ses',
+        '/([ti])um$/i' => '\1a',
+        '/(p)erson$/i' => '\1eople',
+        '/(? '\1en',
+        '/(c)hild$/i' => '\1hildren',
+        '/(buffal|tomat)o$/i' => '\1\2oes',
+        '/(alumn|bacill|cact|foc|fung|nucle|radi|stimul|syllab|termin)us$/i' => '\1i',
+        '/us$/i' => 'uses',
+        '/(alias)$/i' => '\1es',
+        '/(ax|cris|test)is$/i' => '\1es',
+        '/s$/' => 's',
+        '/^$/' => '',
+        '/$/' => 's',
+    ];
+
+    /**
+     * Singular inflector rules
+     *
+     * @var array
+     */
+    protected static $_singular = [
+        '/(s)tatuses$/i' => '\1\2tatus',
+        '/^(.*)(menu)s$/i' => '\1\2',
+        '/(quiz)zes$/i' => '\\1',
+        '/(matr)ices$/i' => '\1ix',
+        '/(vert|ind)ices$/i' => '\1ex',
+        '/^(ox)en/i' => '\1',
+        '/(alias|lens)(es)*$/i' => '\1',
+        '/(alumn|bacill|cact|foc|fung|nucle|radi|stimul|syllab|termin|viri?)i$/i' => '\1us',
+        '/([ftw]ax)es/i' => '\1',
+        '/(cris|ax|test)es$/i' => '\1is',
+        '/(shoe)s$/i' => '\1',
+        '/(o)es$/i' => '\1',
+        '/ouses$/' => 'ouse',
+        '/([^a])uses$/' => '\1us',
+        '/([m|l])ice$/i' => '\1ouse',
+        '/(x|ch|ss|sh)es$/i' => '\1',
+        '/(m)ovies$/i' => '\1\2ovie',
+        '/(s)eries$/i' => '\1\2eries',
+        '/(s)pecies$/i' => '\1\2pecies',
+        '/([^aeiouy]|qu)ies$/i' => '\1y',
+        '/(tive)s$/i' => '\1',
+        '/(hive)s$/i' => '\1',
+        '/(drive)s$/i' => '\1',
+        '/([le])ves$/i' => '\1f',
+        '/([^rfoa])ves$/i' => '\1fe',
+        '/(^analy)ses$/i' => '\1sis',
+        '/(analy|diagno|^ba|(p)arenthe|(p)rogno|(s)ynop|(t)he)ses$/i' => '\1\2sis',
+        '/([ti])a$/i' => '\1um',
+        '/(p)eople$/i' => '\1\2erson',
+        '/(m)en$/i' => '\1an',
+        '/(c)hildren$/i' => '\1\2hild',
+        '/(n)ews$/i' => '\1\2ews',
+        '/eaus$/' => 'eau',
+        '/^(.*us)$/' => '\\1',
+        '/s$/i' => '',
+    ];
+
+    /**
+     * Irregular rules
+     *
+     * @var array
+     */
+    protected static $_irregular = [
+        'atlas' => 'atlases',
+        'beef' => 'beefs',
+        'brief' => 'briefs',
+        'brother' => 'brothers',
+        'cafe' => 'cafes',
+        'child' => 'children',
+        'cookie' => 'cookies',
+        'corpus' => 'corpuses',
+        'cow' => 'cows',
+        'criterion' => 'criteria',
+        'ganglion' => 'ganglions',
+        'genie' => 'genies',
+        'genus' => 'genera',
+        'graffito' => 'graffiti',
+        'hoof' => 'hoofs',
+        'loaf' => 'loaves',
+        'man' => 'men',
+        'money' => 'monies',
+        'mongoose' => 'mongooses',
+        'move' => 'moves',
+        'mythos' => 'mythoi',
+        'niche' => 'niches',
+        'numen' => 'numina',
+        'occiput' => 'occiputs',
+        'octopus' => 'octopuses',
+        'opus' => 'opuses',
+        'ox' => 'oxen',
+        'penis' => 'penises',
+        'person' => 'people',
+        'sex' => 'sexes',
+        'soliloquy' => 'soliloquies',
+        'testis' => 'testes',
+        'trilby' => 'trilbys',
+        'turf' => 'turfs',
+        'potato' => 'potatoes',
+        'hero' => 'heroes',
+        'tooth' => 'teeth',
+        'goose' => 'geese',
+        'foot' => 'feet',
+        'foe' => 'foes',
+        'sieve' => 'sieves',
+        'cache' => 'caches',
+    ];
+
+    /**
+     * Words that should not be inflected
+     *
+     * @var array
+     */
+    protected static $_uninflected = [
+        '.*[nrlm]ese', '.*data', '.*deer', '.*fish', '.*measles', '.*ois',
+        '.*pox', '.*sheep', 'people', 'feedback', 'stadia', '.*?media',
+        'chassis', 'clippers', 'debris', 'diabetes', 'equipment', 'gallows',
+        'graffiti', 'headquarters', 'information', 'innings', 'news', 'nexus',
+        'pokemon', 'proceedings', 'research', 'sea[- ]bass', 'series', 'species', 'weather',
+    ];
+
+    /**
+     * Method cache array.
+     *
+     * @var array
+     */
+    protected static $_cache = [];
+
+    /**
+     * The initial state of Inflector so reset() works.
+     *
+     * @var array
+     */
+    protected static $_initialState = [];
+
+    /**
+     * Cache inflected values, and return if already available
+     *
+     * @param string $type Inflection type
+     * @param string $key Original value
+     * @param string|false $value Inflected value
+     * @return string|false Inflected value on cache hit or false on cache miss.
+     */
+    protected static function _cache(string $type, string $key, $value = false)
+    {
+        $key = '_' . $key;
+        $type = '_' . $type;
+        if ($value !== false) {
+            static::$_cache[$type][$key] = $value;
+
+            return $value;
+        }
+        if (!isset(static::$_cache[$type][$key])) {
+            return false;
+        }
+
+        return static::$_cache[$type][$key];
+    }
+
+    /**
+     * Clears Inflectors inflected value caches. And resets the inflection
+     * rules to the initial values.
+     *
+     * @return void
+     */
+    public static function reset(): void
+    {
+        if (empty(static::$_initialState)) {
+            static::$_initialState = get_class_vars(self::class);
+
+            return;
+        }
+        foreach (static::$_initialState as $key => $val) {
+            if ($key !== '_initialState') {
+                static::${$key} = $val;
+            }
+        }
+    }
+
+    /**
+     * Adds custom inflection $rules, of either 'plural', 'singular',
+     * 'uninflected' or 'irregular' $type.
+     *
+     * ### Usage:
+     *
+     * ```
+     * Inflector::rules('plural', ['/^(inflect)or$/i' => '\1ables']);
+     * Inflector::rules('irregular', ['red' => 'redlings']);
+     * Inflector::rules('uninflected', ['dontinflectme']);
+     * ```
+     *
+     * @param string $type The type of inflection, either 'plural', 'singular',
+     *    or 'uninflected'.
+     * @param array $rules Array of rules to be added.
+     * @param bool $reset If true, will unset default inflections for all
+     *        new rules that are being defined in $rules.
+     * @return void
+     */
+    public static function rules(string $type, array $rules, bool $reset = false): void
+    {
+        $var = '_' . $type;
+
+        if ($reset) {
+            static::${$var} = $rules;
+        } elseif ($type === 'uninflected') {
+            static::$_uninflected = array_merge(
+                $rules,
+                static::$_uninflected
+            );
+        } else {
+            static::${$var} = $rules + static::${$var};
+        }
+
+        static::$_cache = [];
+    }
+
+    /**
+     * Return $word in plural form.
+     *
+     * @param string $word Word in singular
+     * @return string Word in plural
+     * @link https://book.cakephp.org/4/en/core-libraries/inflector.html#creating-plural-singular-forms
+     */
+    public static function pluralize(string $word): string
+    {
+        if (isset(static::$_cache['pluralize'][$word])) {
+            return static::$_cache['pluralize'][$word];
+        }
+
+        if (!isset(static::$_cache['irregular']['pluralize'])) {
+            $words = array_keys(static::$_irregular);
+            static::$_cache['irregular']['pluralize'] = '/(.*?(?:\\b|_))(' . implode('|', $words) . ')$/i';
+
+            $upperWords = array_map('ucfirst', $words);
+            static::$_cache['irregular']['upperPluralize'] = '/(.*?(?:\\b|[a-z]))(' . implode('|', $upperWords) . ')$/';
+        }
+
+        if (
+            preg_match(static::$_cache['irregular']['pluralize'], $word, $regs) ||
+            preg_match(static::$_cache['irregular']['upperPluralize'], $word, $regs)
+        ) {
+            static::$_cache['pluralize'][$word] = $regs[1] . substr($regs[2], 0, 1) .
+                substr(static::$_irregular[strtolower($regs[2])], 1);
+
+            return static::$_cache['pluralize'][$word];
+        }
+
+        if (!isset(static::$_cache['uninflected'])) {
+            static::$_cache['uninflected'] = '/^(' . implode('|', static::$_uninflected) . ')$/i';
+        }
+
+        if (preg_match(static::$_cache['uninflected'], $word, $regs)) {
+            static::$_cache['pluralize'][$word] = $word;
+
+            return $word;
+        }
+
+        foreach (static::$_plural as $rule => $replacement) {
+            if (preg_match($rule, $word)) {
+                static::$_cache['pluralize'][$word] = preg_replace($rule, $replacement, $word);
+
+                return static::$_cache['pluralize'][$word];
+            }
+        }
+
+        return $word;
+    }
+
+    /**
+     * Return $word in singular form.
+     *
+     * @param string $word Word in plural
+     * @return string Word in singular
+     * @link https://book.cakephp.org/4/en/core-libraries/inflector.html#creating-plural-singular-forms
+     */
+    public static function singularize(string $word): string
+    {
+        if (isset(static::$_cache['singularize'][$word])) {
+            return static::$_cache['singularize'][$word];
+        }
+
+        if (!isset(static::$_cache['irregular']['singular'])) {
+            $wordList = array_values(static::$_irregular);
+            static::$_cache['irregular']['singular'] = '/(.*?(?:\\b|_))(' . implode('|', $wordList) . ')$/i';
+
+            $upperWordList = array_map('ucfirst', $wordList);
+            static::$_cache['irregular']['singularUpper'] = '/(.*?(?:\\b|[a-z]))(' .
+                implode('|', $upperWordList) .
+                ')$/';
+        }
+
+        if (
+            preg_match(static::$_cache['irregular']['singular'], $word, $regs) ||
+            preg_match(static::$_cache['irregular']['singularUpper'], $word, $regs)
+        ) {
+            $suffix = array_search(strtolower($regs[2]), static::$_irregular, true);
+            $suffix = $suffix ? substr($suffix, 1) : '';
+            static::$_cache['singularize'][$word] = $regs[1] . substr($regs[2], 0, 1) . $suffix;
+
+            return static::$_cache['singularize'][$word];
+        }
+
+        if (!isset(static::$_cache['uninflected'])) {
+            static::$_cache['uninflected'] = '/^(' . implode('|', static::$_uninflected) . ')$/i';
+        }
+
+        if (preg_match(static::$_cache['uninflected'], $word, $regs)) {
+            static::$_cache['pluralize'][$word] = $word;
+
+            return $word;
+        }
+
+        foreach (static::$_singular as $rule => $replacement) {
+            if (preg_match($rule, $word)) {
+                static::$_cache['singularize'][$word] = preg_replace($rule, $replacement, $word);
+
+                return static::$_cache['singularize'][$word];
+            }
+        }
+        static::$_cache['singularize'][$word] = $word;
+
+        return $word;
+    }
+
+    /**
+     * Returns the input lower_case_delimited_string as a CamelCasedString.
+     *
+     * @param string $string String to camelize
+     * @param string $delimiter the delimiter in the input string
+     * @return string CamelizedStringLikeThis.
+     * @link https://book.cakephp.org/4/en/core-libraries/inflector.html#creating-camelcase-and-under-scored-forms
+     */
+    public static function camelize(string $string, string $delimiter = '_'): string
+    {
+        $cacheKey = __FUNCTION__ . $delimiter;
+
+        $result = static::_cache($cacheKey, $string);
+
+        if ($result === false) {
+            $result = str_replace(' ', '', static::humanize($string, $delimiter));
+            static::_cache($cacheKey, $string, $result);
+        }
+
+        return $result;
+    }
+
+    /**
+     * Returns the input CamelCasedString as an underscored_string.
+     *
+     * Also replaces dashes with underscores
+     *
+     * @param string $string CamelCasedString to be "underscorized"
+     * @return string underscore_version of the input string
+     * @link https://book.cakephp.org/4/en/core-libraries/inflector.html#creating-camelcase-and-under-scored-forms
+     */
+    public static function underscore(string $string): string
+    {
+        return static::delimit(str_replace('-', '_', $string), '_');
+    }
+
+    /**
+     * Returns the input CamelCasedString as an dashed-string.
+     *
+     * Also replaces underscores with dashes
+     *
+     * @param string $string The string to dasherize.
+     * @return string Dashed version of the input string
+     */
+    public static function dasherize(string $string): string
+    {
+        return static::delimit(str_replace('_', '-', $string), '-');
+    }
+
+    /**
+     * Returns the input lower_case_delimited_string as 'A Human Readable String'.
+     * (Underscores are replaced by spaces and capitalized following words.)
+     *
+     * @param string $string String to be humanized
+     * @param string $delimiter the character to replace with a space
+     * @return string Human-readable string
+     * @link https://book.cakephp.org/4/en/core-libraries/inflector.html#creating-human-readable-forms
+     */
+    public static function humanize(string $string, string $delimiter = '_'): string
+    {
+        $cacheKey = __FUNCTION__ . $delimiter;
+
+        $result = static::_cache($cacheKey, $string);
+
+        if ($result === false) {
+            $result = explode(' ', str_replace($delimiter, ' ', $string));
+            foreach ($result as &$word) {
+                $word = mb_strtoupper(mb_substr($word, 0, 1)) . mb_substr($word, 1);
+            }
+            $result = implode(' ', $result);
+            static::_cache($cacheKey, $string, $result);
+        }
+
+        return $result;
+    }
+
+    /**
+     * Expects a CamelCasedInputString, and produces a lower_case_delimited_string
+     *
+     * @param string $string String to delimit
+     * @param string $delimiter the character to use as a delimiter
+     * @return string delimited string
+     */
+    public static function delimit(string $string, string $delimiter = '_'): string
+    {
+        $cacheKey = __FUNCTION__ . $delimiter;
+
+        $result = static::_cache($cacheKey, $string);
+
+        if ($result === false) {
+            $result = mb_strtolower(preg_replace('/(?<=\\w)([A-Z])/', $delimiter . '\\1', $string));
+            static::_cache($cacheKey, $string, $result);
+        }
+
+        return $result;
+    }
+
+    /**
+     * Returns corresponding table name for given model $className. ("people" for the model class "Person").
+     *
+     * @param string $className Name of class to get database table name for
+     * @return string Name of the database table for given class
+     * @link https://book.cakephp.org/4/en/core-libraries/inflector.html#creating-table-and-class-name-forms
+     */
+    public static function tableize(string $className): string
+    {
+        $result = static::_cache(__FUNCTION__, $className);
+
+        if ($result === false) {
+            $result = static::pluralize(static::underscore($className));
+            static::_cache(__FUNCTION__, $className, $result);
+        }
+
+        return $result;
+    }
+
+    /**
+     * Returns Cake model class name ("Person" for the database table "people".) for given database table.
+     *
+     * @param string $tableName Name of database table to get class name for
+     * @return string Class name
+     * @link https://book.cakephp.org/4/en/core-libraries/inflector.html#creating-table-and-class-name-forms
+     */
+    public static function classify(string $tableName): string
+    {
+        $result = static::_cache(__FUNCTION__, $tableName);
+
+        if ($result === false) {
+            $result = static::camelize(static::singularize($tableName));
+            static::_cache(__FUNCTION__, $tableName, $result);
+        }
+
+        return $result;
+    }
+
+    /**
+     * Returns camelBacked version of an underscored string.
+     *
+     * @param string $string String to convert.
+     * @return string in variable form
+     * @link https://book.cakephp.org/4/en/core-libraries/inflector.html#creating-variable-names
+     */
+    public static function variable(string $string): string
+    {
+        $result = static::_cache(__FUNCTION__, $string);
+
+        if ($result === false) {
+            $camelized = static::camelize(static::underscore($string));
+            $replace = strtolower(substr($camelized, 0, 1));
+            $result = $replace . substr($camelized, 1);
+            static::_cache(__FUNCTION__, $string, $result);
+        }
+
+        return $result;
+    }
+}
diff --git a/vendor/cakephp/utility/LICENSE.txt b/vendor/cakephp/utility/LICENSE.txt
new file mode 100644
index 0000000..b938c9e
--- /dev/null
+++ b/vendor/cakephp/utility/LICENSE.txt
@@ -0,0 +1,22 @@
+The MIT License (MIT)
+
+CakePHP(tm) : The Rapid Development PHP Framework (https://cakephp.org)
+Copyright (c) 2005-2020, Cake Software Foundation, Inc. (https://cakefoundation.org)
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
diff --git a/vendor/cakephp/utility/MergeVariablesTrait.php b/vendor/cakephp/utility/MergeVariablesTrait.php
new file mode 100644
index 0000000..39bafb8
--- /dev/null
+++ b/vendor/cakephp/utility/MergeVariablesTrait.php
@@ -0,0 +1,118 @@
+ $properties An array of properties and the merge strategy for them.
+     * @param array $options The options to use when merging properties.
+     * @return void
+     */
+    protected function _mergeVars(array $properties, array $options = []): void
+    {
+        $class = static::class;
+        $parents = [];
+        while (true) {
+            $parent = get_parent_class($class);
+            if (!$parent) {
+                break;
+            }
+            $parents[] = $parent;
+            $class = $parent;
+        }
+        foreach ($properties as $property) {
+            if (!property_exists($this, $property)) {
+                continue;
+            }
+            $thisValue = $this->{$property};
+            if ($thisValue === null || $thisValue === false) {
+                continue;
+            }
+            $this->_mergeProperty($property, $parents, $options);
+        }
+    }
+
+    /**
+     * Merge a single property with the values declared in all parent classes.
+     *
+     * @param string $property The name of the property being merged.
+     * @param array $parentClasses An array of classes you want to merge with.
+     * @param array $options Options for merging the property, see _mergeVars()
+     * @return void
+     */
+    protected function _mergeProperty(string $property, array $parentClasses, array $options): void
+    {
+        $thisValue = $this->{$property};
+        $isAssoc = false;
+        if (
+            isset($options['associative']) &&
+            in_array($property, (array)$options['associative'], true)
+        ) {
+            $isAssoc = true;
+        }
+
+        if ($isAssoc) {
+            $thisValue = Hash::normalize($thisValue);
+        }
+        foreach ($parentClasses as $class) {
+            $parentProperties = get_class_vars($class);
+            if (empty($parentProperties[$property])) {
+                continue;
+            }
+            $parentProperty = $parentProperties[$property];
+            if (!is_array($parentProperty)) {
+                continue;
+            }
+            $thisValue = $this->_mergePropertyData($thisValue, $parentProperty, $isAssoc);
+        }
+        $this->{$property} = $thisValue;
+    }
+
+    /**
+     * Merge each of the keys in a property together.
+     *
+     * @param array $current The current merged value.
+     * @param array $parent The parent class' value.
+     * @param bool $isAssoc Whether the merging should be done in associative mode.
+     * @return array The updated value.
+     */
+    protected function _mergePropertyData(array $current, array $parent, bool $isAssoc)
+    {
+        if (!$isAssoc) {
+            return array_merge($parent, $current);
+        }
+        $parent = Hash::normalize($parent);
+        foreach ($parent as $key => $value) {
+            if (!isset($current[$key])) {
+                $current[$key] = $value;
+            }
+        }
+
+        return $current;
+    }
+}
diff --git a/vendor/cakephp/utility/README.md b/vendor/cakephp/utility/README.md
new file mode 100644
index 0000000..45601b8
--- /dev/null
+++ b/vendor/cakephp/utility/README.md
@@ -0,0 +1,91 @@
+[![Total Downloads](https://img.shields.io/packagist/dt/cakephp/utility.svg?style=flat-square)](https://packagist.org/packages/cakephp/utility)
+[![License](https://img.shields.io/badge/license-MIT-blue.svg?style=flat-square)](LICENSE.txt)
+
+# CakePHP Utility Classes
+
+This library provides a range of utility classes that are used throughout the CakePHP framework
+
+## What's in the toolbox?
+
+### Hash
+
+A ``Hash`` (as in PHP arrays) class, capable of extracting data using an intuitive DSL:
+
+```php
+$things = [
+    ['name' => 'Mark', 'age' => 15],
+    ['name' => 'Susan', 'age' => 30],
+    ['name' => 'Lucy', 'age' => 25]
+];
+
+$bigPeople = Hash::extract($things, '{n}[age>21].name');
+
+// $bigPeople will contain ['Susan', 'Lucy']
+```
+
+Check the [official Hash class documentation](https://book.cakephp.org/4/en/core-libraries/hash.html)
+
+### Inflector
+
+The Inflector class takes a string and can manipulate it to handle word variations
+such as pluralizations or camelizing.
+
+```php
+echo Inflector::pluralize('Apple'); // echoes Apples
+
+echo Inflector::singularize('People'); // echoes Person
+```
+
+Check the [official Inflector class documentation](https://book.cakephp.org/4/en/core-libraries/inflector.html)
+
+### Text
+
+The Text class includes convenience methods for creating and manipulating strings.
+
+```php
+Text::insert(
+    'My name is :name and I am :age years old.',
+    ['name' => 'Bob', 'age' => '65']
+);
+// Returns: "My name is Bob and I am 65 years old."
+
+$text = 'This is the song that never ends.';
+$result = Text::wrap($text, 22);
+
+// Returns
+This is the song
+that never ends.
+```
+
+Check the [official Text class documentation](https://book.cakephp.org/4/en/core-libraries/text.html)
+
+### Security
+
+The security library handles basic security measures such as providing methods for hashing and encrypting data.
+
+```php
+$key = 'wt1U5MACWJFTXGenFoZoiLwQGrLgdbHA';
+$result = Security::encrypt($value, $key);
+
+Security::decrypt($result, $key);
+```
+
+Check the [official Security class documentation](https://book.cakephp.org/4/en/core-libraries/security.html)
+
+### Xml
+
+The Xml class allows you to easily transform arrays into SimpleXMLElement or DOMDocument objects
+and back into arrays again
+
+```php
+$data = [
+    'post' => [
+        'id' => 1,
+        'title' => 'Best post',
+        'body' => ' ... '
+    ]
+];
+$xml = Xml::build($data);
+```
+
+Check the [official Xml class documentation](https://book.cakephp.org/4/en/core-libraries/xml.html)
diff --git a/vendor/cakephp/utility/Security.php b/vendor/cakephp/utility/Security.php
new file mode 100644
index 0000000..a46d322
--- /dev/null
+++ b/vendor/cakephp/utility/Security.php
@@ -0,0 +1,309 @@
+encrypt($plain, $key);
+        $hmac = hash_hmac('sha256', $ciphertext, $key);
+
+        return $hmac . $ciphertext;
+    }
+
+    /**
+     * Check the encryption key for proper length.
+     *
+     * @param string $key Key to check.
+     * @param string $method The method the key is being checked for.
+     * @return void
+     * @throws \InvalidArgumentException When key length is not 256 bit/32 bytes
+     */
+    protected static function _checkKey(string $key, string $method): void
+    {
+        if (mb_strlen($key, '8bit') < 32) {
+            throw new InvalidArgumentException(
+                sprintf('Invalid key for %s, key must be at least 256 bits (32 bytes) long.', $method)
+            );
+        }
+    }
+
+    /**
+     * Decrypt a value using AES-256.
+     *
+     * @param string $cipher The ciphertext to decrypt.
+     * @param string $key The 256 bit/32 byte key to use as a cipher key.
+     * @param string|null $hmacSalt The salt to use for the HMAC process.
+     *   Leave null to use value of Security::getSalt().
+     * @return string|null Decrypted data. Any trailing null bytes will be removed.
+     * @throws \InvalidArgumentException On invalid data or key.
+     */
+    public static function decrypt(string $cipher, string $key, ?string $hmacSalt = null): ?string
+    {
+        self::_checkKey($key, 'decrypt()');
+        if (empty($cipher)) {
+            throw new InvalidArgumentException('The data to decrypt cannot be empty.');
+        }
+        if ($hmacSalt === null) {
+            $hmacSalt = static::getSalt();
+        }
+
+        // Generate the encryption and hmac key.
+        $key = mb_substr(hash('sha256', $key . $hmacSalt), 0, 32, '8bit');
+
+        // Split out hmac for comparison
+        $macSize = 64;
+        $hmac = mb_substr($cipher, 0, $macSize, '8bit');
+        $cipher = mb_substr($cipher, $macSize, null, '8bit');
+
+        $compareHmac = hash_hmac('sha256', $cipher, $key);
+        if (!static::constantEquals($hmac, $compareHmac)) {
+            return null;
+        }
+
+        $crypto = static::engine();
+
+        return $crypto->decrypt($cipher, $key);
+    }
+
+    /**
+     * A timing attack resistant comparison that prefers native PHP implementations.
+     *
+     * @param mixed $original The original value.
+     * @param mixed $compare The comparison value.
+     * @return bool
+     * @since 3.6.2
+     */
+    public static function constantEquals($original, $compare): bool
+    {
+        return is_string($original) && is_string($compare) && hash_equals($original, $compare);
+    }
+
+    /**
+     * Gets the HMAC salt to be used for encryption/decryption
+     * routines.
+     *
+     * @return string The currently configured salt
+     */
+    public static function getSalt(): string
+    {
+        if (static::$_salt === null) {
+            throw new RuntimeException(
+                'Salt not set. Use Security::setSalt() to set one, ideally in `config/bootstrap.php`.'
+            );
+        }
+
+        return static::$_salt;
+    }
+
+    /**
+     * Sets the HMAC salt to be used for encryption/decryption
+     * routines.
+     *
+     * @param string $salt The salt to use for encryption routines.
+     * @return void
+     */
+    public static function setSalt(string $salt): void
+    {
+        static::$_salt = $salt;
+    }
+}
diff --git a/vendor/cakephp/utility/Text.php b/vendor/cakephp/utility/Text.php
new file mode 100644
index 0000000..7116b0d
--- /dev/null
+++ b/vendor/cakephp/utility/Text.php
@@ -0,0 +1,1180 @@
+
+     */
+    protected static $_defaultHtmlNoCount = [
+        'style',
+        'script',
+    ];
+
+    /**
+     * Generate a random UUID version 4
+     *
+     * Warning: This method should not be used as a random seed for any cryptographic operations.
+     * Instead, you should use `Security::randomBytes()` or `Security::randomString()` instead.
+     *
+     * It should also not be used to create identifiers that have security implications, such as
+     * 'unguessable' URL identifiers. Instead, you should use {@link \Cake\Utility\Security::randomBytes()}` for that.
+     *
+     * @see https://www.ietf.org/rfc/rfc4122.txt
+     * @return string RFC 4122 UUID
+     * @copyright Matt Farina MIT License https://github.com/lootils/uuid/blob/master/LICENSE
+     */
+    public static function uuid(): string
+    {
+        return sprintf(
+            '%04x%04x-%04x-%04x-%04x-%04x%04x%04x',
+            // 32 bits for "time_low"
+            random_int(0, 65535),
+            random_int(0, 65535),
+            // 16 bits for "time_mid"
+            random_int(0, 65535),
+            // 12 bits before the 0100 of (version) 4 for "time_hi_and_version"
+            random_int(0, 4095) | 0x4000,
+            // 16 bits, 8 bits for "clk_seq_hi_res",
+            // 8 bits for "clk_seq_low",
+            // two most significant bits holds zero and one for variant DCE1.1
+            random_int(0, 0x3fff) | 0x8000,
+            // 48 bits for "node"
+            random_int(0, 65535),
+            random_int(0, 65535),
+            random_int(0, 65535)
+        );
+    }
+
+    /**
+     * Tokenizes a string using $separator, ignoring any instance of $separator that appears between
+     * $leftBound and $rightBound.
+     *
+     * @param string $data The data to tokenize.
+     * @param string $separator The token to split the data on.
+     * @param string $leftBound The left boundary to ignore separators in.
+     * @param string $rightBound The right boundary to ignore separators in.
+     * @return array Array of tokens in $data.
+     */
+    public static function tokenize(
+        string $data,
+        string $separator = ',',
+        string $leftBound = '(',
+        string $rightBound = ')'
+    ): array {
+        if (empty($data)) {
+            return [];
+        }
+
+        $depth = 0;
+        $offset = 0;
+        $buffer = '';
+        $results = [];
+        $length = mb_strlen($data);
+        $open = false;
+
+        while ($offset <= $length) {
+            $tmpOffset = -1;
+            $offsets = [
+                mb_strpos($data, $separator, $offset),
+                mb_strpos($data, $leftBound, $offset),
+                mb_strpos($data, $rightBound, $offset),
+            ];
+            for ($i = 0; $i < 3; $i++) {
+                if ($offsets[$i] !== false && ($offsets[$i] < $tmpOffset || $tmpOffset === -1)) {
+                    $tmpOffset = $offsets[$i];
+                }
+            }
+            if ($tmpOffset !== -1) {
+                $buffer .= mb_substr($data, $offset, $tmpOffset - $offset);
+                $char = mb_substr($data, $tmpOffset, 1);
+                if (!$depth && $char === $separator) {
+                    $results[] = $buffer;
+                    $buffer = '';
+                } else {
+                    $buffer .= $char;
+                }
+                if ($leftBound !== $rightBound) {
+                    if ($char === $leftBound) {
+                        $depth++;
+                    }
+                    if ($char === $rightBound) {
+                        $depth--;
+                    }
+                } else {
+                    if ($char === $leftBound) {
+                        if (!$open) {
+                            $depth++;
+                            $open = true;
+                        } else {
+                            $depth--;
+                            $open = false;
+                        }
+                    }
+                }
+                $tmpOffset += 1;
+                $offset = $tmpOffset;
+            } else {
+                $results[] = $buffer . mb_substr($data, $offset);
+                $offset = $length + 1;
+            }
+        }
+        if (empty($results) && !empty($buffer)) {
+            $results[] = $buffer;
+        }
+
+        if (!empty($results)) {
+            return array_map('trim', $results);
+        }
+
+        return [];
+    }
+
+    /**
+     * Replaces variable placeholders inside a $str with any given $data. Each key in the $data array
+     * corresponds to a variable placeholder name in $str.
+     * Example:
+     * ```
+     * Text::insert(':name is :age years old.', ['name' => 'Bob', 'age' => '65']);
+     * ```
+     * Returns: Bob is 65 years old.
+     *
+     * Available $options are:
+     *
+     * - before: The character or string in front of the name of the variable placeholder (Defaults to `:`)
+     * - after: The character or string after the name of the variable placeholder (Defaults to null)
+     * - escape: The character or string used to escape the before character / string (Defaults to `\`)
+     * - format: A regex to use for matching variable placeholders. Default is: `/(? val array where each key stands for a placeholder variable name
+     *     to be replaced with val
+     * @param array $options An array of options, see description above
+     * @return string
+     */
+    public static function insert(string $str, array $data, array $options = []): string
+    {
+        $defaults = [
+            'before' => ':', 'after' => '', 'escape' => '\\', 'format' => null, 'clean' => false,
+        ];
+        $options += $defaults;
+        if (empty($data)) {
+            return $options['clean'] ? static::cleanInsert($str, $options) : $str;
+        }
+
+        if (strpos($str, '?') !== false && is_numeric(key($data))) {
+            deprecationWarning(
+                'Using Text::insert() with `?` placeholders is deprecated. ' .
+                'Use sprintf() with `%s` placeholders instead.'
+            );
+
+            $offset = 0;
+            while (($pos = strpos($str, '?', $offset)) !== false) {
+                $val = array_shift($data);
+                $offset = $pos + strlen($val);
+                $str = substr_replace($str, $val, $pos, 1);
+            }
+
+            return $options['clean'] ? static::cleanInsert($str, $options) : $str;
+        }
+
+        $format = $options['format'];
+        if ($format === null) {
+            $format = sprintf(
+                '/(? $tempData */
+        $tempData = array_combine($dataKeys, $hashKeys);
+        krsort($tempData);
+
+        foreach ($tempData as $key => $hashVal) {
+            $key = sprintf($format, preg_quote($key, '/'));
+            $str = preg_replace($key, $hashVal, $str);
+        }
+        /** @var array $dataReplacements */
+        $dataReplacements = array_combine($hashKeys, array_values($data));
+        foreach ($dataReplacements as $tmpHash => $tmpValue) {
+            $tmpValue = is_array($tmpValue) ? '' : (string)$tmpValue;
+            $str = str_replace($tmpHash, $tmpValue, $str);
+        }
+
+        if (!isset($options['format']) && isset($options['before'])) {
+            $str = str_replace($options['escape'] . $options['before'], $options['before'], $str);
+        }
+
+        return $options['clean'] ? static::cleanInsert($str, $options) : $str;
+    }
+
+    /**
+     * Cleans up a Text::insert() formatted string with given $options depending on the 'clean' key in
+     * $options. The default method used is text but html is also available. The goal of this function
+     * is to replace all whitespace and unneeded markup around placeholders that did not get replaced
+     * by Text::insert().
+     *
+     * @param string $str String to clean.
+     * @param array $options Options list.
+     * @return string
+     * @see \Cake\Utility\Text::insert()
+     */
+    public static function cleanInsert(string $str, array $options): string
+    {
+        $clean = $options['clean'];
+        if (!$clean) {
+            return $str;
+        }
+        if ($clean === true) {
+            $clean = ['method' => 'text'];
+        }
+        if (!is_array($clean)) {
+            $clean = ['method' => $options['clean']];
+        }
+        switch ($clean['method']) {
+            case 'html':
+                $clean += [
+                    'word' => '[\w,.]+',
+                    'andText' => true,
+                    'replacement' => '',
+                ];
+                $kleenex = sprintf(
+                    '/[\s]*[a-z]+=(")(%s%s%s[\s]*)+\\1/i',
+                    preg_quote($options['before'], '/'),
+                    $clean['word'],
+                    preg_quote($options['after'], '/')
+                );
+                $str = preg_replace($kleenex, $clean['replacement'], $str);
+                if ($clean['andText']) {
+                    $options['clean'] = ['method' => 'text'];
+                    $str = static::cleanInsert($str, $options);
+                }
+                break;
+            case 'text':
+                $clean += [
+                    'word' => '[\w,.]+',
+                    'gap' => '[\s]*(?:(?:and|or)[\s]*)?',
+                    'replacement' => '',
+                ];
+
+                $kleenex = sprintf(
+                    '/(%s%s%s%s|%s%s%s%s)/',
+                    preg_quote($options['before'], '/'),
+                    $clean['word'],
+                    preg_quote($options['after'], '/'),
+                    $clean['gap'],
+                    $clean['gap'],
+                    preg_quote($options['before'], '/'),
+                    $clean['word'],
+                    preg_quote($options['after'], '/')
+                );
+                $str = preg_replace($kleenex, $clean['replacement'], $str);
+                break;
+        }
+
+        return $str;
+    }
+
+    /**
+     * Wraps text to a specific width, can optionally wrap at word breaks.
+     *
+     * ### Options
+     *
+     * - `width` The width to wrap to. Defaults to 72.
+     * - `wordWrap` Only wrap on words breaks (spaces) Defaults to true.
+     * - `indent` String to indent with. Defaults to null.
+     * - `indentAt` 0 based index to start indenting at. Defaults to 0.
+     *
+     * @param string $text The text to format.
+     * @param array|int $options Array of options to use, or an integer to wrap the text to.
+     * @return string Formatted text.
+     */
+    public static function wrap(string $text, $options = []): string
+    {
+        if (is_numeric($options)) {
+            $options = ['width' => $options];
+        }
+        $options += ['width' => 72, 'wordWrap' => true, 'indent' => null, 'indentAt' => 0];
+        if ($options['wordWrap']) {
+            $wrapped = self::wordWrap($text, $options['width'], "\n");
+        } else {
+            $wrapped = trim(chunk_split($text, $options['width'] - 1, "\n"));
+        }
+        if (!empty($options['indent'])) {
+            $chunks = explode("\n", $wrapped);
+            for ($i = $options['indentAt'], $len = count($chunks); $i < $len; $i++) {
+                $chunks[$i] = $options['indent'] . $chunks[$i];
+            }
+            $wrapped = implode("\n", $chunks);
+        }
+
+        return $wrapped;
+    }
+
+    /**
+     * Wraps a complete block of text to a specific width, can optionally wrap
+     * at word breaks.
+     *
+     * ### Options
+     *
+     * - `width` The width to wrap to. Defaults to 72.
+     * - `wordWrap` Only wrap on words breaks (spaces) Defaults to true.
+     * - `indent` String to indent with. Defaults to null.
+     * - `indentAt` 0 based index to start indenting at. Defaults to 0.
+     *
+     * @param string $text The text to format.
+     * @param array|int $options Array of options to use, or an integer to wrap the text to.
+     * @return string Formatted text.
+     */
+    public static function wrapBlock(string $text, $options = []): string
+    {
+        if (is_numeric($options)) {
+            $options = ['width' => $options];
+        }
+        $options += ['width' => 72, 'wordWrap' => true, 'indent' => null, 'indentAt' => 0];
+
+        $wrapped = self::wrap($text, $options);
+
+        if (!empty($options['indent'])) {
+            $indentationLength = mb_strlen($options['indent']);
+            $chunks = explode("\n", $wrapped);
+            $count = count($chunks);
+            if ($count < 2) {
+                return $wrapped;
+            }
+            $toRewrap = '';
+            for ($i = $options['indentAt']; $i < $count; $i++) {
+                $toRewrap .= mb_substr($chunks[$i], $indentationLength) . ' ';
+                unset($chunks[$i]);
+            }
+            $options['width'] -= $indentationLength;
+            $options['indentAt'] = 0;
+            $rewrapped = self::wrap($toRewrap, $options);
+            $newChunks = explode("\n", $rewrapped);
+
+            $chunks = array_merge($chunks, $newChunks);
+            $wrapped = implode("\n", $chunks);
+        }
+
+        return $wrapped;
+    }
+
+    /**
+     * Unicode and newline aware version of wordwrap.
+     *
+     * @phpstan-param non-empty-string $break
+     * @param string $text The text to format.
+     * @param int $width The width to wrap to. Defaults to 72.
+     * @param string $break The line is broken using the optional break parameter. Defaults to '\n'.
+     * @param bool $cut If the cut is set to true, the string is always wrapped at the specified width.
+     * @return string Formatted text.
+     */
+    public static function wordWrap(string $text, int $width = 72, string $break = "\n", bool $cut = false): string
+    {
+        $paragraphs = explode($break, $text);
+        foreach ($paragraphs as &$paragraph) {
+            $paragraph = static::_wordWrap($paragraph, $width, $break, $cut);
+        }
+
+        return implode($break, $paragraphs);
+    }
+
+    /**
+     * Unicode aware version of wordwrap as helper method.
+     *
+     * @param string $text The text to format.
+     * @param int $width The width to wrap to. Defaults to 72.
+     * @param string $break The line is broken using the optional break parameter. Defaults to '\n'.
+     * @param bool $cut If the cut is set to true, the string is always wrapped at the specified width.
+     * @return string Formatted text.
+     */
+    protected static function _wordWrap(string $text, int $width = 72, string $break = "\n", bool $cut = false): string
+    {
+        $parts = [];
+        if ($cut) {
+            while (mb_strlen($text) > 0) {
+                $part = mb_substr($text, 0, $width);
+                $parts[] = trim($part);
+                $text = trim(mb_substr($text, mb_strlen($part)));
+            }
+
+            return implode($break, $parts);
+        }
+
+        while (mb_strlen($text) > 0) {
+            if ($width >= mb_strlen($text)) {
+                $parts[] = trim($text);
+                break;
+            }
+
+            $part = mb_substr($text, 0, $width);
+            $nextChar = mb_substr($text, $width, 1);
+            if ($nextChar !== ' ') {
+                $breakAt = mb_strrpos($part, ' ');
+                if ($breakAt === false) {
+                    $breakAt = mb_strpos($text, ' ', $width);
+                }
+                if ($breakAt === false) {
+                    $parts[] = trim($text);
+                    break;
+                }
+                $part = mb_substr($text, 0, $breakAt);
+            }
+
+            $part = trim($part);
+            $parts[] = $part;
+            $text = trim(mb_substr($text, mb_strlen($part)));
+        }
+
+        return implode($break, $parts);
+    }
+
+    /**
+     * Highlights a given phrase in a text. You can specify any expression in highlighter that
+     * may include the \1 expression to include the $phrase found.
+     *
+     * ### Options:
+     *
+     * - `format` The piece of HTML with that the phrase will be highlighted
+     * - `html` If true, will ignore any HTML tags, ensuring that only the correct text is highlighted
+     * - `regex` A custom regex rule that is used to match words, default is '|$tag|iu'
+     * - `limit` A limit, optional, defaults to -1 (none)
+     *
+     * @param string $text Text to search the phrase in.
+     * @param array|string $phrase The phrase or phrases that will be searched.
+     * @param array $options An array of HTML attributes and options.
+     * @return string The highlighted text
+     * @link https://book.cakephp.org/4/en/core-libraries/text.html#highlighting-substrings
+     */
+    public static function highlight(string $text, $phrase, array $options = []): string
+    {
+        if (empty($phrase)) {
+            return $text;
+        }
+
+        $defaults = [
+            'format' => '\1',
+            'html' => false,
+            'regex' => '|%s|iu',
+            'limit' => -1,
+        ];
+        $options += $defaults;
+
+        if (is_array($phrase)) {
+            $replace = [];
+            $with = [];
+
+            foreach ($phrase as $key => $segment) {
+                $segment = '(' . preg_quote($segment, '|') . ')';
+                if ($options['html']) {
+                    $segment = "(?![^<]+>)$segment(?![^<]+>)";
+                }
+
+                $with[] = is_array($options['format']) ? $options['format'][$key] : $options['format'];
+                $replace[] = sprintf($options['regex'], $segment);
+            }
+
+            return preg_replace($replace, $with, $text, $options['limit']);
+        }
+
+        $phrase = '(' . preg_quote($phrase, '|') . ')';
+        if ($options['html']) {
+            $phrase = "(?![^<]+>)$phrase(?![^<]+>)";
+        }
+
+        return preg_replace(
+            sprintf($options['regex'], $phrase),
+            $options['format'],
+            $text,
+            $options['limit']
+        );
+    }
+
+    /**
+     * Truncates text starting from the end.
+     *
+     * Cuts a string to the length of $length and replaces the first characters
+     * with the ellipsis if the text is longer than length.
+     *
+     * ### Options:
+     *
+     * - `ellipsis` Will be used as beginning and prepended to the trimmed string
+     * - `exact` If false, $text will not be cut mid-word
+     *
+     * @param string $text String to truncate.
+     * @param int $length Length of returned string, including ellipsis.
+     * @param array $options An array of options.
+     * @return string Trimmed string.
+     */
+    public static function tail(string $text, int $length = 100, array $options = []): string
+    {
+        $default = [
+            'ellipsis' => '...', 'exact' => true,
+        ];
+        $options += $default;
+        $ellipsis = $options['ellipsis'];
+
+        if (mb_strlen($text) <= $length) {
+            return $text;
+        }
+
+        $truncate = mb_substr($text, mb_strlen($text) - $length + mb_strlen($ellipsis));
+        if (!$options['exact']) {
+            $spacepos = mb_strpos($truncate, ' ');
+            $truncate = $spacepos === false ? '' : trim(mb_substr($truncate, $spacepos));
+        }
+
+        return $ellipsis . $truncate;
+    }
+
+    /**
+     * Truncates text.
+     *
+     * Cuts a string to the length of $length and replaces the last characters
+     * with the ellipsis if the text is longer than length.
+     *
+     * ### Options:
+     *
+     * - `ellipsis` Will be used as ending and appended to the trimmed string
+     * - `exact` If false, $text will not be cut mid-word
+     * - `html` If true, HTML tags would be handled correctly
+     * - `trimWidth` If true, $text will be truncated with the width
+     *
+     * @param string $text String to truncate.
+     * @param int $length Length of returned string, including ellipsis.
+     * @param array $options An array of HTML attributes and options.
+     * @return string Trimmed string.
+     * @link https://book.cakephp.org/4/en/core-libraries/text.html#truncating-text
+     */
+    public static function truncate(string $text, int $length = 100, array $options = []): string
+    {
+        $default = [
+            'ellipsis' => '...', 'exact' => true, 'html' => false, 'trimWidth' => false,
+        ];
+        if (!empty($options['html']) && strtolower((string)mb_internal_encoding()) === 'utf-8') {
+            $default['ellipsis'] = "\xe2\x80\xa6";
+        }
+        $options += $default;
+
+        $prefix = '';
+        $suffix = $options['ellipsis'];
+
+        if ($options['html']) {
+            $ellipsisLength = self::_strlen(strip_tags($options['ellipsis']), $options);
+
+            $truncateLength = 0;
+            $totalLength = 0;
+            $openTags = [];
+            $truncate = '';
+
+            preg_match_all('/(<\/?([\w+]+)[^>]*>)?([^<>]*)/', $text, $tags, PREG_SET_ORDER);
+            foreach ($tags as $tag) {
+                $contentLength = 0;
+                if (!in_array($tag[2], static::$_defaultHtmlNoCount, true)) {
+                    $contentLength = self::_strlen($tag[3], $options);
+                }
+
+                if ($truncate === '') {
+                    if (
+                        !preg_match(
+                            '/img|br|input|hr|area|base|basefont|col|frame|isindex|link|meta|param/i',
+                            $tag[2]
+                        )
+                    ) {
+                        if (preg_match('/<[\w]+[^>]*>/', $tag[0])) {
+                            array_unshift($openTags, $tag[2]);
+                        } elseif (preg_match('/<\/([\w]+)[^>]*>/', $tag[0], $closeTag)) {
+                            $pos = array_search($closeTag[1], $openTags, true);
+                            if ($pos !== false) {
+                                array_splice($openTags, $pos, 1);
+                            }
+                        }
+                    }
+
+                    $prefix .= $tag[1];
+
+                    if ($totalLength + $contentLength + $ellipsisLength > $length) {
+                        $truncate = $tag[3];
+                        $truncateLength = $length - $totalLength;
+                    } else {
+                        $prefix .= $tag[3];
+                    }
+                }
+
+                $totalLength += $contentLength;
+                if ($totalLength > $length) {
+                    break;
+                }
+            }
+
+            if ($totalLength <= $length) {
+                return $text;
+            }
+
+            $text = $truncate;
+            $length = $truncateLength;
+
+            foreach ($openTags as $tag) {
+                $suffix .= '';
+            }
+        } else {
+            if (self::_strlen($text, $options) <= $length) {
+                return $text;
+            }
+            $ellipsisLength = self::_strlen($options['ellipsis'], $options);
+        }
+
+        $result = self::_substr($text, 0, $length - $ellipsisLength, $options);
+
+        if (!$options['exact']) {
+            if (self::_substr($text, $length - $ellipsisLength, 1, $options) !== ' ') {
+                $result = self::_removeLastWord($result);
+            }
+
+            // If result is empty, then we don't need to count ellipsis in the cut.
+            if ($result === '') {
+                $result = self::_substr($text, 0, $length, $options);
+            }
+        }
+
+        return $prefix . $result . $suffix;
+    }
+
+    /**
+     * Truncate text with specified width.
+     *
+     * @param string $text String to truncate.
+     * @param int $length Length of returned string, including ellipsis.
+     * @param array $options An array of HTML attributes and options.
+     * @return string Trimmed string.
+     * @see \Cake\Utility\Text::truncate()
+     */
+    public static function truncateByWidth(string $text, int $length = 100, array $options = []): string
+    {
+        return static::truncate($text, $length, ['trimWidth' => true] + $options);
+    }
+
+    /**
+     * Get string length.
+     *
+     * ### Options:
+     *
+     * - `html` If true, HTML entities will be handled as decoded characters.
+     * - `trimWidth` If true, the width will return.
+     *
+     * @param string $text The string being checked for length
+     * @param array $options An array of options.
+     * @return int
+     */
+    protected static function _strlen(string $text, array $options): int
+    {
+        if (empty($options['trimWidth'])) {
+            $strlen = 'mb_strlen';
+        } else {
+            $strlen = 'mb_strwidth';
+        }
+
+        if (empty($options['html'])) {
+            return $strlen($text);
+        }
+
+        $pattern = '/&[0-9a-z]{2,8};|&#[0-9]{1,7};|&#x[0-9a-f]{1,6};/i';
+        $replace = preg_replace_callback(
+            $pattern,
+            function ($match) use ($strlen) {
+                $utf8 = html_entity_decode($match[0], ENT_HTML5 | ENT_QUOTES, 'UTF-8');
+
+                return str_repeat(' ', $strlen($utf8, 'UTF-8'));
+            },
+            $text
+        );
+
+        return $strlen($replace);
+    }
+
+    /**
+     * Return part of a string.
+     *
+     * ### Options:
+     *
+     * - `html` If true, HTML entities will be handled as decoded characters.
+     * - `trimWidth` If true, will be truncated with specified width.
+     *
+     * @param string $text The input string.
+     * @param int $start The position to begin extracting.
+     * @param int|null $length The desired length.
+     * @param array $options An array of options.
+     * @return string
+     */
+    protected static function _substr(string $text, int $start, ?int $length, array $options): string
+    {
+        if (empty($options['trimWidth'])) {
+            $substr = 'mb_substr';
+        } else {
+            $substr = 'mb_strimwidth';
+        }
+
+        $maxPosition = self::_strlen($text, ['trimWidth' => false] + $options);
+        if ($start < 0) {
+            $start += $maxPosition;
+            if ($start < 0) {
+                $start = 0;
+            }
+        }
+        if ($start >= $maxPosition) {
+            return '';
+        }
+
+        if ($length === null) {
+            $length = self::_strlen($text, $options);
+        }
+
+        if ($length < 0) {
+            $text = self::_substr($text, $start, null, $options);
+            $start = 0;
+            $length += self::_strlen($text, $options);
+        }
+
+        if ($length <= 0) {
+            return '';
+        }
+
+        if (empty($options['html'])) {
+            return (string)$substr($text, $start, $length);
+        }
+
+        $totalOffset = 0;
+        $totalLength = 0;
+        $result = '';
+
+        $pattern = '/(&[0-9a-z]{2,8};|&#[0-9]{1,7};|&#x[0-9a-f]{1,6};)/i';
+        $parts = preg_split($pattern, $text, -1, PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY);
+        foreach ($parts as $part) {
+            $offset = 0;
+
+            if ($totalOffset < $start) {
+                $len = self::_strlen($part, ['trimWidth' => false] + $options);
+                if ($totalOffset + $len <= $start) {
+                    $totalOffset += $len;
+                    continue;
+                }
+
+                $offset = $start - $totalOffset;
+                $totalOffset = $start;
+            }
+
+            $len = self::_strlen($part, $options);
+            if ($offset !== 0 || $totalLength + $len > $length) {
+                if (
+                    strpos($part, '&') === 0
+                    && preg_match($pattern, $part)
+                    && $part !== html_entity_decode($part, ENT_HTML5 | ENT_QUOTES, 'UTF-8')
+                ) {
+                    // Entities cannot be passed substr.
+                    continue;
+                }
+
+                $part = $substr($part, $offset, $length - $totalLength);
+                $len = self::_strlen($part, $options);
+            }
+
+            $result .= $part;
+            $totalLength += $len;
+            if ($totalLength >= $length) {
+                break;
+            }
+        }
+
+        return $result;
+    }
+
+    /**
+     * Removes the last word from the input text.
+     *
+     * @param string $text The input text
+     * @return string
+     */
+    protected static function _removeLastWord(string $text): string
+    {
+        $spacepos = mb_strrpos($text, ' ');
+
+        if ($spacepos !== false) {
+            $lastWord = mb_substr($text, $spacepos);
+
+            // Some languages are written without word separation.
+            // We recognize a string as a word if it doesn't contain any full-width characters.
+            if (mb_strwidth($lastWord) === mb_strlen($lastWord)) {
+                $text = mb_substr($text, 0, $spacepos);
+            }
+
+            return $text;
+        }
+
+        return '';
+    }
+
+    /**
+     * Extracts an excerpt from the text surrounding the phrase with a number of characters on each side
+     * determined by radius.
+     *
+     * @param string $text String to search the phrase in
+     * @param string $phrase Phrase that will be searched for
+     * @param int $radius The amount of characters that will be returned on each side of the founded phrase
+     * @param string $ellipsis Ending that will be appended
+     * @return string Modified string
+     * @link https://book.cakephp.org/4/en/core-libraries/text.html#extracting-an-excerpt
+     */
+    public static function excerpt(string $text, string $phrase, int $radius = 100, string $ellipsis = '...'): string
+    {
+        if (empty($text) || empty($phrase)) {
+            return static::truncate($text, $radius * 2, ['ellipsis' => $ellipsis]);
+        }
+
+        $append = $prepend = $ellipsis;
+
+        $phraseLen = mb_strlen($phrase);
+        $textLen = mb_strlen($text);
+
+        $pos = mb_stripos($text, $phrase);
+        if ($pos === false) {
+            return mb_substr($text, 0, $radius) . $ellipsis;
+        }
+
+        $startPos = $pos - $radius;
+        if ($startPos <= 0) {
+            $startPos = 0;
+            $prepend = '';
+        }
+
+        $endPos = $pos + $phraseLen + $radius;
+        if ($endPos >= $textLen) {
+            $endPos = $textLen;
+            $append = '';
+        }
+
+        $excerpt = mb_substr($text, $startPos, $endPos - $startPos);
+
+        return $prepend . $excerpt . $append;
+    }
+
+    /**
+     * Creates a comma separated list where the last two items are joined with 'and', forming natural language.
+     *
+     * @param array $list The list to be joined.
+     * @param string|null $and The word used to join the last and second last items together with. Defaults to 'and'.
+     * @param string $separator The separator used to join all the other items together. Defaults to ', '.
+     * @return string The glued together string.
+     * @link https://book.cakephp.org/4/en/core-libraries/text.html#converting-an-array-to-sentence-form
+     */
+    public static function toList(array $list, ?string $and = null, string $separator = ', '): string
+    {
+        if ($and === null) {
+            $and = __d('cake', 'and');
+        }
+        if (count($list) > 1) {
+            return implode($separator, array_slice($list, 0, -1)) . ' ' . $and . ' ' . array_pop($list);
+        }
+
+        return (string)array_pop($list);
+    }
+
+    /**
+     * Check if the string contain multibyte characters
+     *
+     * @param string $string value to test
+     * @return bool
+     */
+    public static function isMultibyte(string $string): bool
+    {
+        $length = strlen($string);
+
+        for ($i = 0; $i < $length; $i++) {
+            $value = ord($string[$i]);
+            if ($value > 128) {
+                return true;
+            }
+        }
+
+        return false;
+    }
+
+    /**
+     * Converts a multibyte character string
+     * to the decimal value of the character
+     *
+     * @param string $string String to convert.
+     * @return array
+     */
+    public static function utf8(string $string): array
+    {
+        $map = [];
+
+        $values = [];
+        $find = 1;
+        $length = strlen($string);
+
+        for ($i = 0; $i < $length; $i++) {
+            $value = ord($string[$i]);
+
+            if ($value < 128) {
+                $map[] = $value;
+            } else {
+                if (empty($values)) {
+                    $find = $value < 224 ? 2 : 3;
+                }
+                $values[] = $value;
+
+                if (count($values) === $find) {
+                    if ($find === 3) {
+                        $map[] = (($values[0] % 16) * 4096) + (($values[1] % 64) * 64) + ($values[2] % 64);
+                    } else {
+                        $map[] = (($values[0] % 32) * 64) + ($values[1] % 64);
+                    }
+                    $values = [];
+                    $find = 1;
+                }
+            }
+        }
+
+        return $map;
+    }
+
+    /**
+     * Converts the decimal value of a multibyte character string
+     * to a string
+     *
+     * @param array $array Array
+     * @return string
+     */
+    public static function ascii(array $array): string
+    {
+        $ascii = '';
+
+        foreach ($array as $utf8) {
+            if ($utf8 < 128) {
+                $ascii .= chr($utf8);
+            } elseif ($utf8 < 2048) {
+                $ascii .= chr(192 + (($utf8 - ($utf8 % 64)) / 64));
+                $ascii .= chr(128 + ($utf8 % 64));
+            } else {
+                $ascii .= chr(224 + (($utf8 - ($utf8 % 4096)) / 4096));
+                $ascii .= chr(128 + ((($utf8 % 4096) - ($utf8 % 64)) / 64));
+                $ascii .= chr(128 + ($utf8 % 64));
+            }
+        }
+
+        return $ascii;
+    }
+
+    /**
+     * Converts filesize from human readable string to bytes
+     *
+     * @param string $size Size in human readable string like '5MB', '5M', '500B', '50kb' etc.
+     * @param mixed $default Value to be returned when invalid size was used, for example 'Unknown type'
+     * @return mixed Number of bytes as integer on success, `$default` on failure if not false
+     * @throws \InvalidArgumentException On invalid Unit type.
+     * @link https://book.cakephp.org/4/en/core-libraries/text.html#Cake\Utility\Text::parseFileSize
+     */
+    public static function parseFileSize(string $size, $default = false)
+    {
+        if (ctype_digit($size)) {
+            return (int)$size;
+        }
+        $size = strtoupper($size);
+
+        $l = -2;
+        $i = array_search(substr($size, -2), ['KB', 'MB', 'GB', 'TB', 'PB'], true);
+        if ($i === false) {
+            $l = -1;
+            $i = array_search(substr($size, -1), ['K', 'M', 'G', 'T', 'P'], true);
+        }
+        if ($i !== false) {
+            $size = (float)substr($size, 0, $l);
+
+            return (int)($size * pow(1024, $i + 1));
+        }
+
+        if (substr($size, -1) === 'B' && ctype_digit(substr($size, 0, -1))) {
+            $size = substr($size, 0, -1);
+
+            return (int)$size;
+        }
+
+        if ($default !== false) {
+            return $default;
+        }
+        throw new InvalidArgumentException('No unit type.');
+    }
+
+    /**
+     * Get the default transliterator.
+     *
+     * @return \Transliterator|null Either a Transliterator instance, or `null`
+     *   in case no transliterator has been set yet.
+     */
+    public static function getTransliterator(): ?Transliterator
+    {
+        return static::$_defaultTransliterator;
+    }
+
+    /**
+     * Set the default transliterator.
+     *
+     * @param \Transliterator $transliterator A `Transliterator` instance.
+     * @return void
+     */
+    public static function setTransliterator(Transliterator $transliterator): void
+    {
+        static::$_defaultTransliterator = $transliterator;
+    }
+
+    /**
+     * Get default transliterator identifier string.
+     *
+     * @return string Transliterator identifier.
+     */
+    public static function getTransliteratorId(): string
+    {
+        return static::$_defaultTransliteratorId;
+    }
+
+    /**
+     * Set default transliterator identifier string.
+     *
+     * @param string $transliteratorId Transliterator identifier.
+     * @return void
+     */
+    public static function setTransliteratorId(string $transliteratorId): void
+    {
+        $transliterator = transliterator_create($transliteratorId);
+        if ($transliterator === null) {
+            throw new CakeException('Unable to create transliterator for id: ' . $transliteratorId);
+        }
+
+        static::setTransliterator($transliterator);
+        static::$_defaultTransliteratorId = $transliteratorId;
+    }
+
+    /**
+     * Transliterate string.
+     *
+     * @param string $string String to transliterate.
+     * @param \Transliterator|string|null $transliterator Either a Transliterator
+     *   instance, or a transliterator identifier string. If `null`, the default
+     *   transliterator (identifier) set via `setTransliteratorId()` or
+     *   `setTransliterator()` will be used.
+     * @return string
+     * @see https://secure.php.net/manual/en/transliterator.transliterate.php
+     */
+    public static function transliterate(string $string, $transliterator = null): string
+    {
+        if (empty($transliterator)) {
+            $transliterator = static::$_defaultTransliterator ?: static::$_defaultTransliteratorId;
+        }
+
+        $return = transliterator_transliterate($transliterator, $string);
+        if ($return === false) {
+            throw new CakeException(sprintf('Unable to transliterate string: %s', $string));
+        }
+
+        return $return;
+    }
+
+    /**
+     * Returns a string with all spaces converted to dashes (by default),
+     * characters transliterated to ASCII characters, and non word characters removed.
+     *
+     * ### Options:
+     *
+     * - `replacement`: Replacement string. Default '-'.
+     * - `transliteratorId`: A valid transliterator id string.
+     *   If `null` (default) the transliterator (identifier) set via
+     *   `setTransliteratorId()` or `setTransliterator()` will be used.
+     *   If `false` no transliteration will be done, only non words will be removed.
+     * - `preserve`: Specific non-word character to preserve. Default `null`.
+     *   For e.g. this option can be set to '.' to generate clean file names.
+     *
+     * @param string $string the string you want to slug
+     * @param array|string $options If string it will be use as replacement character
+     *   or an array of options.
+     * @return string
+     * @see setTransliterator()
+     * @see setTransliteratorId()
+     */
+    public static function slug(string $string, $options = []): string
+    {
+        if (is_string($options)) {
+            $options = ['replacement' => $options];
+        }
+        $options += [
+            'replacement' => '-',
+            'transliteratorId' => null,
+            'preserve' => null,
+        ];
+
+        if ($options['transliteratorId'] !== false) {
+            $string = static::transliterate($string, $options['transliteratorId']);
+        }
+
+        $regex = '^\p{Ll}\p{Lm}\p{Lo}\p{Lt}\p{Lu}\p{Nd}';
+        if ($options['preserve']) {
+            $regex .= preg_quote($options['preserve'], '/');
+        }
+        $quotedReplacement = preg_quote((string)$options['replacement'], '/');
+        $map = [
+            '/[' . $regex . ']/mu' => $options['replacement'],
+            sprintf('/^[%s]+|[%s]+$/', $quotedReplacement, $quotedReplacement) => '',
+        ];
+        if (is_string($options['replacement']) && $options['replacement'] !== '') {
+            $map[sprintf('/[%s]+/mu', $quotedReplacement)] = $options['replacement'];
+        }
+
+        return preg_replace(array_keys($map), $map, $string);
+    }
+}
diff --git a/vendor/cakephp/utility/Xml.php b/vendor/cakephp/utility/Xml.php
new file mode 100644
index 0000000..53ddfbd
--- /dev/null
+++ b/vendor/cakephp/utility/Xml.php
@@ -0,0 +1,502 @@
+text');
+     * ```
+     *
+     * Building XML from string (output DOMDocument):
+     *
+     * ```
+     * $xml = Xml::build('text', ['return' => 'domdocument']);
+     * ```
+     *
+     * Building XML from a file path:
+     *
+     * ```
+     * $xml = Xml::build('/path/to/an/xml/file.xml', ['readFile' => true]);
+     * ```
+     *
+     * Building XML from a remote URL:
+     *
+     * ```
+     * use Cake\Http\Client;
+     *
+     * $http = new Client();
+     * $response = $http->get('http://example.com/example.xml');
+     * $xml = Xml::build($response->body());
+     * ```
+     *
+     * Building from an array:
+     *
+     * ```
+     *  $value = [
+     *      'tags' => [
+     *          'tag' => [
+     *              [
+     *                  'id' => '1',
+     *                  'name' => 'defect'
+     *              ],
+     *              [
+     *                  'id' => '2',
+     *                  'name' => 'enhancement'
+     *              ]
+     *          ]
+     *      ]
+     *  ];
+     * $xml = Xml::build($value);
+     * ```
+     *
+     * When building XML from an array ensure that there is only one top level element.
+     *
+     * ### Options
+     *
+     * - `return` Can be 'simplexml' to return object of SimpleXMLElement or 'domdocument' to return DOMDocument.
+     * - `loadEntities` Defaults to false. Set to true to enable loading of ` $options The options to use
+     * @return \SimpleXMLElement|\DOMDocument SimpleXMLElement or DOMDocument
+     * @throws \Cake\Utility\Exception\XmlException
+     */
+    public static function build($input, array $options = [])
+    {
+        $defaults = [
+            'return' => 'simplexml',
+            'loadEntities' => false,
+            'readFile' => false,
+            'parseHuge' => false,
+        ];
+        $options += $defaults;
+
+        if (is_array($input) || is_object($input)) {
+            return static::fromArray($input, $options);
+        }
+
+        if ($options['readFile'] && file_exists($input)) {
+            return static::_loadXml(file_get_contents($input), $options);
+        }
+
+        if (!is_string($input)) {
+            $type = gettype($input);
+            throw new XmlException("Invalid input. {$type} cannot be parsed as XML.");
+        }
+
+        if (strpos($input, '<') !== false) {
+            return static::_loadXml($input, $options);
+        }
+
+        throw new XmlException('XML cannot be read.');
+    }
+
+    /**
+     * Parse the input data and create either a SimpleXmlElement object or a DOMDocument.
+     *
+     * @param string $input The input to load.
+     * @param array $options The options to use. See Xml::build()
+     * @return \SimpleXMLElement|\DOMDocument
+     * @throws \Cake\Utility\Exception\XmlException
+     */
+    protected static function _loadXml(string $input, array $options)
+    {
+        return static::load(
+            $input,
+            $options,
+            function ($input, $options, $flags) {
+                if ($options['return'] === 'simplexml' || $options['return'] === 'simplexmlelement') {
+                    $flags |= LIBXML_NOCDATA;
+                    $xml = new SimpleXMLElement($input, $flags);
+                } else {
+                    $xml = new DOMDocument();
+                    $xml->loadXML($input, $flags);
+                }
+
+                return $xml;
+            }
+        );
+    }
+
+    /**
+     * Parse the input html string and create either a SimpleXmlElement object or a DOMDocument.
+     *
+     * @param string $input The input html string to load.
+     * @param array $options The options to use. See Xml::build()
+     * @return \SimpleXMLElement|\DOMDocument
+     * @throws \Cake\Utility\Exception\XmlException
+     */
+    public static function loadHtml(string $input, array $options = [])
+    {
+        $defaults = [
+            'return' => 'simplexml',
+            'loadEntities' => false,
+        ];
+        $options += $defaults;
+
+        return static::load(
+            $input,
+            $options,
+            function ($input, $options, $flags) {
+                $xml = new DOMDocument();
+                $xml->loadHTML($input, $flags);
+
+                if ($options['return'] === 'simplexml' || $options['return'] === 'simplexmlelement') {
+                    $xml = simplexml_import_dom($xml);
+                }
+
+                return $xml;
+            }
+        );
+    }
+
+    /**
+     * Parse the input data and create either a SimpleXmlElement object or a DOMDocument.
+     *
+     * @param string $input The input to load.
+     * @param array $options The options to use. See Xml::build()
+     * @param \Closure $callable Closure that should return SimpleXMLElement or DOMDocument instance.
+     * @return \SimpleXMLElement|\DOMDocument
+     * @throws \Cake\Utility\Exception\XmlException
+     */
+    protected static function load(string $input, array $options, Closure $callable)
+    {
+        $flags = 0;
+        if (!empty($options['parseHuge'])) {
+            $flags |= LIBXML_PARSEHUGE;
+        }
+
+        $internalErrors = libxml_use_internal_errors(true);
+        if (LIBXML_VERSION < 20900 && !$options['loadEntities']) {
+            $previousDisabledEntityLoader = libxml_disable_entity_loader(true);
+        } elseif ($options['loadEntities']) {
+            $flags |= LIBXML_NOENT;
+        }
+
+        try {
+            return $callable($input, $options, $flags);
+        } catch (Exception $e) {
+            throw new XmlException('Xml cannot be read. ' . $e->getMessage(), null, $e);
+        } finally {
+            if (isset($previousDisabledEntityLoader)) {
+                libxml_disable_entity_loader($previousDisabledEntityLoader);
+            }
+            libxml_use_internal_errors($internalErrors);
+        }
+    }
+
+    /**
+     * Transform an array into a SimpleXMLElement
+     *
+     * ### Options
+     *
+     * - `format` If create children ('tags') or attributes ('attributes').
+     * - `pretty` Returns formatted Xml when set to `true`. Defaults to `false`
+     * - `version` Version of XML document. Default is 1.0.
+     * - `encoding` Encoding of XML document. If null remove from XML header.
+     *    Defaults to the application's encoding
+     * - `return` If return object of SimpleXMLElement ('simplexml')
+     *   or DOMDocument ('domdocument'). Default is SimpleXMLElement.
+     *
+     * Using the following data:
+     *
+     * ```
+     * $value = [
+     *    'root' => [
+     *        'tag' => [
+     *            'id' => 1,
+     *            'value' => 'defect',
+     *            '@' => 'description'
+     *         ]
+     *     ]
+     * ];
+     * ```
+     *
+     * Calling `Xml::fromArray($value, 'tags');` Will generate:
+     *
+     * `1defectdescription`
+     *
+     * And calling `Xml::fromArray($value, 'attributes');` Will generate:
+     *
+     * `description`
+     *
+     * @param object|array $input Array with data or a collection instance.
+     * @param array $options The options to use.
+     * @return \SimpleXMLElement|\DOMDocument SimpleXMLElement or DOMDocument
+     * @throws \Cake\Utility\Exception\XmlException
+     */
+    public static function fromArray($input, array $options = [])
+    {
+        if (is_object($input) && method_exists($input, 'toArray') && is_callable([$input, 'toArray'])) {
+            $input = $input->toArray();
+        }
+        if (!is_array($input) || count($input) !== 1) {
+            throw new XmlException('Invalid input.');
+        }
+        $key = key($input);
+        if (is_int($key)) {
+            throw new XmlException('The key of input must be alphanumeric');
+        }
+
+        $defaults = [
+            'format' => 'tags',
+            'version' => '1.0',
+            'encoding' => mb_internal_encoding(),
+            'return' => 'simplexml',
+            'pretty' => false,
+        ];
+        $options += $defaults;
+
+        $dom = new DOMDocument($options['version'], $options['encoding']);
+        if ($options['pretty']) {
+            $dom->formatOutput = true;
+        }
+        self::_fromArray($dom, $dom, $input, $options['format']);
+
+        $options['return'] = strtolower($options['return']);
+        if ($options['return'] === 'simplexml' || $options['return'] === 'simplexmlelement') {
+            return new SimpleXMLElement($dom->saveXML());
+        }
+
+        return $dom;
+    }
+
+    /**
+     * Recursive method to create children from array
+     *
+     * @param \DOMDocument $dom Handler to DOMDocument
+     * @param \DOMDocument|\DOMElement $node Handler to DOMElement (child)
+     * @param array $data Array of data to append to the $node.
+     * @param string $format Either 'attributes' or 'tags'. This determines where nested keys go.
+     * @return void
+     * @throws \Cake\Utility\Exception\XmlException
+     */
+    protected static function _fromArray(DOMDocument $dom, $node, &$data, $format): void
+    {
+        if (empty($data) || !is_array($data)) {
+            return;
+        }
+        foreach ($data as $key => $value) {
+            if (is_string($key)) {
+                if (is_object($value) && method_exists($value, 'toArray') && is_callable([$value, 'toArray'])) {
+                    $value = $value->toArray();
+                }
+
+                if (!is_array($value)) {
+                    if (is_bool($value)) {
+                        $value = (int)$value;
+                    } elseif ($value === null) {
+                        $value = '';
+                    }
+                    $isNamespace = strpos($key, 'xmlns:');
+                    if ($isNamespace !== false) {
+                        /** @psalm-suppress PossiblyUndefinedMethod */
+                        $node->setAttributeNS('http://www.w3.org/2000/xmlns/', $key, (string)$value);
+                        continue;
+                    }
+                    if ($key[0] !== '@' && $format === 'tags') {
+                        if (!is_numeric($value)) {
+                            // Escape special characters
+                            // https://www.w3.org/TR/REC-xml/#syntax
+                            // https://bugs.php.net/bug.php?id=36795
+                            $child = $dom->createElement($key, '');
+                            $child->appendChild(new DOMText((string)$value));
+                        } else {
+                            $child = $dom->createElement($key, (string)$value);
+                        }
+                        $node->appendChild($child);
+                    } else {
+                        if ($key[0] === '@') {
+                            $key = substr($key, 1);
+                        }
+                        $attribute = $dom->createAttribute($key);
+                        $attribute->appendChild($dom->createTextNode((string)$value));
+                        $node->appendChild($attribute);
+                    }
+                } else {
+                    if ($key[0] === '@') {
+                        throw new XmlException('Invalid array');
+                    }
+                    if (is_numeric(implode('', array_keys($value)))) {
+// List
+                        foreach ($value as $item) {
+                            $itemData = compact('dom', 'node', 'key', 'format');
+                            $itemData['value'] = $item;
+                            static::_createChild($itemData);
+                        }
+                    } else {
+// Struct
+                        static::_createChild(compact('dom', 'node', 'key', 'value', 'format'));
+                    }
+                }
+            } else {
+                throw new XmlException('Invalid array');
+            }
+        }
+    }
+
+    /**
+     * Helper to _fromArray(). It will create children of arrays
+     *
+     * @param array $data Array with information to create children
+     * @return void
+     */
+    protected static function _createChild(array $data): void
+    {
+        $data += [
+            'dom' => null,
+            'node' => null,
+            'key' => null,
+            'value' => null,
+            'format' => null,
+        ];
+
+        $value = $data['value'];
+        $dom = $data['dom'];
+        $key = $data['key'];
+        $format = $data['format'];
+        $node = $data['node'];
+
+        $childNS = $childValue = null;
+        if (is_object($value) && method_exists($value, 'toArray') && is_callable([$value, 'toArray'])) {
+            $value = $value->toArray();
+        }
+        if (is_array($value)) {
+            if (isset($value['@'])) {
+                $childValue = (string)$value['@'];
+                unset($value['@']);
+            }
+            if (isset($value['xmlns:'])) {
+                $childNS = $value['xmlns:'];
+                unset($value['xmlns:']);
+            }
+        } elseif (!empty($value) || $value === 0 || $value === '0') {
+            $childValue = (string)$value;
+        }
+
+        $child = $dom->createElement($key);
+        if ($childValue !== null) {
+            $child->appendChild($dom->createTextNode($childValue));
+        }
+        if ($childNS) {
+            $child->setAttribute('xmlns', $childNS);
+        }
+
+        static::_fromArray($dom, $child, $value, $format);
+        $node->appendChild($child);
+    }
+
+    /**
+     * Returns this XML structure as an array.
+     *
+     * @param \SimpleXMLElement|\DOMDocument|\DOMNode $obj SimpleXMLElement, DOMDocument or DOMNode instance
+     * @return array Array representation of the XML structure.
+     * @throws \Cake\Utility\Exception\XmlException
+     */
+    public static function toArray($obj): array
+    {
+        if ($obj instanceof DOMNode) {
+            $obj = simplexml_import_dom($obj);
+        }
+        if (!($obj instanceof SimpleXMLElement)) {
+            throw new XmlException('The input is not instance of SimpleXMLElement, DOMDocument or DOMNode.');
+        }
+        $result = [];
+        $namespaces = array_merge(['' => ''], $obj->getNamespaces(true));
+        static::_toArray($obj, $result, '', array_keys($namespaces));
+
+        return $result;
+    }
+
+    /**
+     * Recursive method to toArray
+     *
+     * @param \SimpleXMLElement $xml SimpleXMLElement object
+     * @param array $parentData Parent array with data
+     * @param string $ns Namespace of current child
+     * @param array $namespaces List of namespaces in XML
+     * @return void
+     */
+    protected static function _toArray(SimpleXMLElement $xml, array &$parentData, string $ns, array $namespaces): void
+    {
+        $data = [];
+
+        foreach ($namespaces as $namespace) {
+            /**
+             * @psalm-suppress PossiblyNullIterator
+             * @var string $key
+             */
+            foreach ($xml->attributes($namespace, true) as $key => $value) {
+                if (!empty($namespace)) {
+                    $key = $namespace . ':' . $key;
+                }
+                $data['@' . $key] = (string)$value;
+            }
+
+            foreach ($xml->children($namespace, true) as $child) {
+                static::_toArray($child, $data, $namespace, $namespaces);
+            }
+        }
+
+        $asString = trim((string)$xml);
+        if (empty($data)) {
+            $data = $asString;
+        } elseif ($asString !== '') {
+            $data['@'] = $asString;
+        }
+
+        if (!empty($ns)) {
+            $ns .= ':';
+        }
+        $name = $ns . $xml->getName();
+        if (isset($parentData[$name])) {
+            if (!is_array($parentData[$name]) || !isset($parentData[$name][0])) {
+                $parentData[$name] = [$parentData[$name]];
+            }
+            $parentData[$name][] = $data;
+        } else {
+            $parentData[$name] = $data;
+        }
+    }
+}
diff --git a/vendor/cakephp/utility/bootstrap.php b/vendor/cakephp/utility/bootstrap.php
new file mode 100644
index 0000000..d335b75
--- /dev/null
+++ b/vendor/cakephp/utility/bootstrap.php
@@ -0,0 +1,21 @@
+=7.4.0",
+        "cakephp/core": "^4.0"
+    },
+    "suggest": {
+        "ext-intl": "To use Text::transliterate() or Text::slug()",
+        "lib-ICU": "To use Text::transliterate() or Text::slug()"
+    },
+    "autoload": {
+        "psr-4": {
+            "Cake\\Utility\\": "."
+        },
+        "files": [
+            "bootstrap.php"
+        ]
+    }
+}
diff --git a/vendor/composer/autoload_classmap.php b/vendor/composer/autoload_classmap.php
index cae0fc2..afeafbd 100644
--- a/vendor/composer/autoload_classmap.php
+++ b/vendor/composer/autoload_classmap.php
@@ -7,9 +7,11 @@ $baseDir = dirname($vendorDir);
 
 return array(
     'Attribute' => $vendorDir . '/symfony/polyfill-php80/Resources/stubs/Attribute.php',
+    'CURLStringFile' => $vendorDir . '/symfony/polyfill-php81/Resources/stubs/CURLStringFile.php',
     'Composer\\InstalledVersions' => $vendorDir . '/composer/InstalledVersions.php',
     'Normalizer' => $vendorDir . '/symfony/polyfill-intl-normalizer/Resources/stubs/Normalizer.php',
     'PhpToken' => $vendorDir . '/symfony/polyfill-php80/Resources/stubs/PhpToken.php',
+    'ReturnTypeWillChange' => $vendorDir . '/symfony/polyfill-php81/Resources/stubs/ReturnTypeWillChange.php',
     'Stringable' => $vendorDir . '/symfony/polyfill-php80/Resources/stubs/Stringable.php',
     'UnhandledMatchError' => $vendorDir . '/symfony/polyfill-php80/Resources/stubs/UnhandledMatchError.php',
     'ValueError' => $vendorDir . '/symfony/polyfill-php80/Resources/stubs/ValueError.php',
diff --git a/vendor/composer/autoload_files.php b/vendor/composer/autoload_files.php
index e1e4010..0ac7bfb 100644
--- a/vendor/composer/autoload_files.php
+++ b/vendor/composer/autoload_files.php
@@ -10,17 +10,20 @@ return array(
     '60799491728b879e74601d83e38b2cad' => $vendorDir . '/illuminate/collections/helpers.php',
     'a4a119a56e50fbb293281d9a48007e0e' => $vendorDir . '/symfony/polyfill-php80/bootstrap.php',
     'a1105708a18b76903365ca1c4aa61b02' => $vendorDir . '/symfony/translation/Resources/functions.php',
-    '72579e7bd17821bb1321b87411366eae' => $vendorDir . '/illuminate/support/helpers.php',
-    '7b11c4dc42b3b3023073cb14e519683c' => $vendorDir . '/ralouphie/getallheaders/src/getallheaders.php',
     '320cde22f66dd4f5d3fd621d3e88b98f' => $vendorDir . '/symfony/polyfill-ctype/bootstrap.php',
+    '72579e7bd17821bb1321b87411366eae' => $vendorDir . '/illuminate/support/helpers.php',
+    '72142d7b40a3a0b14e91825290b5ad82' => $vendorDir . '/cakephp/core/functions.php',
     '8825ede83f2f289127722d4e842cf7e8' => $vendorDir . '/symfony/polyfill-intl-grapheme/bootstrap.php',
     'e69f7f6ee287b969198c3c9d6777bd38' => $vendorDir . '/symfony/polyfill-intl-normalizer/bootstrap.php',
-    '253c157292f75eb38082b5acb06f3f01' => $vendorDir . '/nikic/fast-route/src/functions.php',
     '6e3fae29631ef280660b3cdad06f25a8' => $vendorDir . '/symfony/deprecation-contracts/function.php',
     'b6b991a57620e2fb6b2f66f03fe9ddc2' => $vendorDir . '/symfony/string/Resources/functions.php',
-    '667aeda72477189d0494fecd327c3641' => $vendorDir . '/symfony/var-dumper/Resources/functions/dump.php',
+    '7b11c4dc42b3b3023073cb14e519683c' => $vendorDir . '/ralouphie/getallheaders/src/getallheaders.php',
+    '253c157292f75eb38082b5acb06f3f01' => $vendorDir . '/nikic/fast-route/src/functions.php',
+    '23c18046f52bef3eea034657bafda50f' => $vendorDir . '/symfony/polyfill-php81/bootstrap.php',
+    '948ad5488880985ff1c06721a4e447fe' => $vendorDir . '/cakephp/utility/bootstrap.php',
     '37a3dc5111fe8f707ab4c132ef1dbc62' => $vendorDir . '/guzzlehttp/guzzle/src/functions_include.php',
     '2df68f9e79c919e2d88506611769ed2e' => $vendorDir . '/respect/stringifier/src/stringify.php',
     'ef65a1626449d89d0811cf9befce46f0' => $vendorDir . '/illuminate/events/functions.php',
+    '667aeda72477189d0494fecd327c3641' => $vendorDir . '/symfony/var-dumper/Resources/functions/dump.php',
     '95be378d57853025f7e71d1bb3087e6e' => $baseDir . '/support/helpers.php',
 );
diff --git a/vendor/composer/autoload_psr4.php b/vendor/composer/autoload_psr4.php
index 13d60ea..af7a94f 100644
--- a/vendor/composer/autoload_psr4.php
+++ b/vendor/composer/autoload_psr4.php
@@ -15,7 +15,7 @@ return array(
     'Workerman\\' => array($vendorDir . '/workerman/workerman'),
     'Webman\\Console\\' => array($vendorDir . '/webman/console/src'),
     'Webman\\' => array($vendorDir . '/workerman/webman-framework/src'),
-    'WebmanTech\\Debugbar\\' => array($vendorDir . '/webman-tech/debugbar/src'),
+    'Symfony\\Polyfill\\Php81\\' => array($vendorDir . '/symfony/polyfill-php81'),
     'Symfony\\Polyfill\\Php80\\' => array($vendorDir . '/symfony/polyfill-php80'),
     'Symfony\\Polyfill\\Mbstring\\' => array($vendorDir . '/symfony/polyfill-mbstring'),
     'Symfony\\Polyfill\\Intl\\Normalizer\\' => array($vendorDir . '/symfony/polyfill-intl-normalizer'),
@@ -28,7 +28,9 @@ return array(
     'Symfony\\Component\\VarDumper\\' => array($vendorDir . '/symfony/var-dumper'),
     'Symfony\\Component\\Translation\\' => array($vendorDir . '/symfony/translation'),
     'Symfony\\Component\\String\\' => array($vendorDir . '/symfony/string'),
+    'Symfony\\Component\\Filesystem\\' => array($vendorDir . '/symfony/filesystem'),
     'Symfony\\Component\\Console\\' => array($vendorDir . '/symfony/console'),
+    'Symfony\\Component\\Config\\' => array($vendorDir . '/symfony/config'),
     'Symfony\\Component\\Cache\\' => array($vendorDir . '/symfony/cache'),
     'Support\\View\\' => array($vendorDir . '/workerman/webman-framework/src/support/view'),
     'Support\\Exception\\' => array($vendorDir . '/workerman/webman-framework/src/support/exception'),
@@ -43,6 +45,7 @@ return array(
     'Psr\\Container\\' => array($vendorDir . '/psr/container/src'),
     'Psr\\Clock\\' => array($vendorDir . '/psr/clock/src'),
     'Psr\\Cache\\' => array($vendorDir . '/psr/cache/src'),
+    'Phinx\\' => array($vendorDir . '/robmorgan/phinx/src/Phinx'),
     'Monolog\\' => array($vendorDir . '/monolog/monolog/src/Monolog'),
     'MaxMind\\WebService\\' => array($vendorDir . '/maxmind/web-service-common/src/WebService'),
     'MaxMind\\Exception\\' => array($vendorDir . '/maxmind/web-service-common/src/Exception'),
@@ -51,7 +54,9 @@ return array(
     'Illuminate\\Support\\' => array($vendorDir . '/illuminate/collections', $vendorDir . '/illuminate/conditionable', $vendorDir . '/illuminate/macroable', $vendorDir . '/illuminate/support'),
     'Illuminate\\Redis\\' => array($vendorDir . '/illuminate/redis'),
     'Illuminate\\Pipeline\\' => array($vendorDir . '/illuminate/pipeline'),
+    'Illuminate\\Pagination\\' => array($vendorDir . '/illuminate/pagination'),
     'Illuminate\\Events\\' => array($vendorDir . '/illuminate/events'),
+    'Illuminate\\Database\\' => array($vendorDir . '/illuminate/database'),
     'Illuminate\\Contracts\\' => array($vendorDir . '/illuminate/contracts'),
     'Illuminate\\Container\\' => array($vendorDir . '/illuminate/container'),
     'Illuminate\\Bus\\' => array($vendorDir . '/illuminate/bus'),
@@ -61,10 +66,14 @@ return array(
     'GeoIp2\\' => array($vendorDir . '/geoip2/geoip2/src'),
     'FastRoute\\' => array($vendorDir . '/nikic/fast-route/src'),
     'Doctrine\\Inflector\\' => array($vendorDir . '/doctrine/inflector/lib/Doctrine/Inflector'),
-    'DebugBar\\' => array($vendorDir . '/maximebf/debugbar/src/DebugBar'),
     'Composer\\CaBundle\\' => array($vendorDir . '/composer/ca-bundle/src'),
     'Carbon\\Doctrine\\' => array($vendorDir . '/carbonphp/carbon-doctrine-types/src/Carbon/Doctrine'),
     'Carbon\\' => array($vendorDir . '/nesbot/carbon/src/Carbon'),
+    'Cake\\Utility\\' => array($vendorDir . '/cakephp/utility'),
+    'Cake\\Datasource\\' => array($vendorDir . '/cakephp/datasource'),
+    'Cake\\Database\\' => array($vendorDir . '/cakephp/database'),
+    'Cake\\Core\\' => array($vendorDir . '/cakephp/core'),
+    'Brick\\Math\\' => array($vendorDir . '/brick/math/src'),
     'App\\' => array($baseDir . '/app'),
     '' => array($baseDir . '/'),
 );
diff --git a/vendor/composer/autoload_static.php b/vendor/composer/autoload_static.php
index 0842f31..6a3af87 100644
--- a/vendor/composer/autoload_static.php
+++ b/vendor/composer/autoload_static.php
@@ -11,18 +11,21 @@ class ComposerStaticInitfdb689ed918f2ee4ecdf1e51d93bd946
         '60799491728b879e74601d83e38b2cad' => __DIR__ . '/..' . '/illuminate/collections/helpers.php',
         'a4a119a56e50fbb293281d9a48007e0e' => __DIR__ . '/..' . '/symfony/polyfill-php80/bootstrap.php',
         'a1105708a18b76903365ca1c4aa61b02' => __DIR__ . '/..' . '/symfony/translation/Resources/functions.php',
-        '72579e7bd17821bb1321b87411366eae' => __DIR__ . '/..' . '/illuminate/support/helpers.php',
-        '7b11c4dc42b3b3023073cb14e519683c' => __DIR__ . '/..' . '/ralouphie/getallheaders/src/getallheaders.php',
         '320cde22f66dd4f5d3fd621d3e88b98f' => __DIR__ . '/..' . '/symfony/polyfill-ctype/bootstrap.php',
+        '72579e7bd17821bb1321b87411366eae' => __DIR__ . '/..' . '/illuminate/support/helpers.php',
+        '72142d7b40a3a0b14e91825290b5ad82' => __DIR__ . '/..' . '/cakephp/core/functions.php',
         '8825ede83f2f289127722d4e842cf7e8' => __DIR__ . '/..' . '/symfony/polyfill-intl-grapheme/bootstrap.php',
         'e69f7f6ee287b969198c3c9d6777bd38' => __DIR__ . '/..' . '/symfony/polyfill-intl-normalizer/bootstrap.php',
-        '253c157292f75eb38082b5acb06f3f01' => __DIR__ . '/..' . '/nikic/fast-route/src/functions.php',
         '6e3fae29631ef280660b3cdad06f25a8' => __DIR__ . '/..' . '/symfony/deprecation-contracts/function.php',
         'b6b991a57620e2fb6b2f66f03fe9ddc2' => __DIR__ . '/..' . '/symfony/string/Resources/functions.php',
-        '667aeda72477189d0494fecd327c3641' => __DIR__ . '/..' . '/symfony/var-dumper/Resources/functions/dump.php',
+        '7b11c4dc42b3b3023073cb14e519683c' => __DIR__ . '/..' . '/ralouphie/getallheaders/src/getallheaders.php',
+        '253c157292f75eb38082b5acb06f3f01' => __DIR__ . '/..' . '/nikic/fast-route/src/functions.php',
+        '23c18046f52bef3eea034657bafda50f' => __DIR__ . '/..' . '/symfony/polyfill-php81/bootstrap.php',
+        '948ad5488880985ff1c06721a4e447fe' => __DIR__ . '/..' . '/cakephp/utility/bootstrap.php',
         '37a3dc5111fe8f707ab4c132ef1dbc62' => __DIR__ . '/..' . '/guzzlehttp/guzzle/src/functions_include.php',
         '2df68f9e79c919e2d88506611769ed2e' => __DIR__ . '/..' . '/respect/stringifier/src/stringify.php',
         'ef65a1626449d89d0811cf9befce46f0' => __DIR__ . '/..' . '/illuminate/events/functions.php',
+        '667aeda72477189d0494fecd327c3641' => __DIR__ . '/..' . '/symfony/var-dumper/Resources/functions/dump.php',
         '95be378d57853025f7e71d1bb3087e6e' => __DIR__ . '/../..' . '/support/helpers.php',
     );
 
@@ -50,10 +53,10 @@ class ComposerStaticInitfdb689ed918f2ee4ecdf1e51d93bd946
             'Workerman\\' => 10,
             'Webman\\Console\\' => 15,
             'Webman\\' => 7,
-            'WebmanTech\\Debugbar\\' => 20,
         ),
         'S' => 
         array (
+            'Symfony\\Polyfill\\Php81\\' => 23,
             'Symfony\\Polyfill\\Php80\\' => 23,
             'Symfony\\Polyfill\\Mbstring\\' => 26,
             'Symfony\\Polyfill\\Intl\\Normalizer\\' => 33,
@@ -66,7 +69,9 @@ class ComposerStaticInitfdb689ed918f2ee4ecdf1e51d93bd946
             'Symfony\\Component\\VarDumper\\' => 28,
             'Symfony\\Component\\Translation\\' => 30,
             'Symfony\\Component\\String\\' => 25,
+            'Symfony\\Component\\Filesystem\\' => 29,
             'Symfony\\Component\\Console\\' => 26,
+            'Symfony\\Component\\Config\\' => 25,
             'Symfony\\Component\\Cache\\' => 24,
             'Support\\View\\' => 13,
             'Support\\Exception\\' => 18,
@@ -87,6 +92,7 @@ class ComposerStaticInitfdb689ed918f2ee4ecdf1e51d93bd946
             'Psr\\Container\\' => 14,
             'Psr\\Clock\\' => 10,
             'Psr\\Cache\\' => 10,
+            'Phinx\\' => 6,
         ),
         'M' => 
         array (
@@ -104,7 +110,9 @@ class ComposerStaticInitfdb689ed918f2ee4ecdf1e51d93bd946
             'Illuminate\\Support\\' => 19,
             'Illuminate\\Redis\\' => 17,
             'Illuminate\\Pipeline\\' => 20,
+            'Illuminate\\Pagination\\' => 22,
             'Illuminate\\Events\\' => 18,
+            'Illuminate\\Database\\' => 20,
             'Illuminate\\Contracts\\' => 21,
             'Illuminate\\Container\\' => 21,
             'Illuminate\\Bus\\' => 15,
@@ -123,13 +131,20 @@ class ComposerStaticInitfdb689ed918f2ee4ecdf1e51d93bd946
         'D' => 
         array (
             'Doctrine\\Inflector\\' => 19,
-            'DebugBar\\' => 9,
         ),
         'C' => 
         array (
             'Composer\\CaBundle\\' => 18,
             'Carbon\\Doctrine\\' => 16,
             'Carbon\\' => 7,
+            'Cake\\Utility\\' => 13,
+            'Cake\\Datasource\\' => 16,
+            'Cake\\Database\\' => 14,
+            'Cake\\Core\\' => 10,
+        ),
+        'B' => 
+        array (
+            'Brick\\Math\\' => 11,
         ),
         'A' => 
         array (
@@ -174,9 +189,9 @@ class ComposerStaticInitfdb689ed918f2ee4ecdf1e51d93bd946
         array (
             0 => __DIR__ . '/..' . '/workerman/webman-framework/src',
         ),
-        'WebmanTech\\Debugbar\\' => 
+        'Symfony\\Polyfill\\Php81\\' => 
         array (
-            0 => __DIR__ . '/..' . '/webman-tech/debugbar/src',
+            0 => __DIR__ . '/..' . '/symfony/polyfill-php81',
         ),
         'Symfony\\Polyfill\\Php80\\' => 
         array (
@@ -226,10 +241,18 @@ class ComposerStaticInitfdb689ed918f2ee4ecdf1e51d93bd946
         array (
             0 => __DIR__ . '/..' . '/symfony/string',
         ),
+        'Symfony\\Component\\Filesystem\\' => 
+        array (
+            0 => __DIR__ . '/..' . '/symfony/filesystem',
+        ),
         'Symfony\\Component\\Console\\' => 
         array (
             0 => __DIR__ . '/..' . '/symfony/console',
         ),
+        'Symfony\\Component\\Config\\' => 
+        array (
+            0 => __DIR__ . '/..' . '/symfony/config',
+        ),
         'Symfony\\Component\\Cache\\' => 
         array (
             0 => __DIR__ . '/..' . '/symfony/cache',
@@ -287,6 +310,10 @@ class ComposerStaticInitfdb689ed918f2ee4ecdf1e51d93bd946
         array (
             0 => __DIR__ . '/..' . '/psr/cache/src',
         ),
+        'Phinx\\' => 
+        array (
+            0 => __DIR__ . '/..' . '/robmorgan/phinx/src/Phinx',
+        ),
         'Monolog\\' => 
         array (
             0 => __DIR__ . '/..' . '/monolog/monolog/src/Monolog',
@@ -323,10 +350,18 @@ class ComposerStaticInitfdb689ed918f2ee4ecdf1e51d93bd946
         array (
             0 => __DIR__ . '/..' . '/illuminate/pipeline',
         ),
+        'Illuminate\\Pagination\\' => 
+        array (
+            0 => __DIR__ . '/..' . '/illuminate/pagination',
+        ),
         'Illuminate\\Events\\' => 
         array (
             0 => __DIR__ . '/..' . '/illuminate/events',
         ),
+        'Illuminate\\Database\\' => 
+        array (
+            0 => __DIR__ . '/..' . '/illuminate/database',
+        ),
         'Illuminate\\Contracts\\' => 
         array (
             0 => __DIR__ . '/..' . '/illuminate/contracts',
@@ -363,10 +398,6 @@ class ComposerStaticInitfdb689ed918f2ee4ecdf1e51d93bd946
         array (
             0 => __DIR__ . '/..' . '/doctrine/inflector/lib/Doctrine/Inflector',
         ),
-        'DebugBar\\' => 
-        array (
-            0 => __DIR__ . '/..' . '/maximebf/debugbar/src/DebugBar',
-        ),
         'Composer\\CaBundle\\' => 
         array (
             0 => __DIR__ . '/..' . '/composer/ca-bundle/src',
@@ -379,6 +410,26 @@ class ComposerStaticInitfdb689ed918f2ee4ecdf1e51d93bd946
         array (
             0 => __DIR__ . '/..' . '/nesbot/carbon/src/Carbon',
         ),
+        'Cake\\Utility\\' => 
+        array (
+            0 => __DIR__ . '/..' . '/cakephp/utility',
+        ),
+        'Cake\\Datasource\\' => 
+        array (
+            0 => __DIR__ . '/..' . '/cakephp/datasource',
+        ),
+        'Cake\\Database\\' => 
+        array (
+            0 => __DIR__ . '/..' . '/cakephp/database',
+        ),
+        'Cake\\Core\\' => 
+        array (
+            0 => __DIR__ . '/..' . '/cakephp/core',
+        ),
+        'Brick\\Math\\' => 
+        array (
+            0 => __DIR__ . '/..' . '/brick/math/src',
+        ),
         'App\\' => 
         array (
             0 => __DIR__ . '/../..' . '/app',
@@ -391,9 +442,11 @@ class ComposerStaticInitfdb689ed918f2ee4ecdf1e51d93bd946
 
     public static $classMap = array (
         'Attribute' => __DIR__ . '/..' . '/symfony/polyfill-php80/Resources/stubs/Attribute.php',
+        'CURLStringFile' => __DIR__ . '/..' . '/symfony/polyfill-php81/Resources/stubs/CURLStringFile.php',
         'Composer\\InstalledVersions' => __DIR__ . '/..' . '/composer/InstalledVersions.php',
         'Normalizer' => __DIR__ . '/..' . '/symfony/polyfill-intl-normalizer/Resources/stubs/Normalizer.php',
         'PhpToken' => __DIR__ . '/..' . '/symfony/polyfill-php80/Resources/stubs/PhpToken.php',
+        'ReturnTypeWillChange' => __DIR__ . '/..' . '/symfony/polyfill-php81/Resources/stubs/ReturnTypeWillChange.php',
         'Stringable' => __DIR__ . '/..' . '/symfony/polyfill-php80/Resources/stubs/Stringable.php',
         'UnhandledMatchError' => __DIR__ . '/..' . '/symfony/polyfill-php80/Resources/stubs/UnhandledMatchError.php',
         'ValueError' => __DIR__ . '/..' . '/symfony/polyfill-php80/Resources/stubs/ValueError.php',
diff --git a/vendor/composer/installed.json b/vendor/composer/installed.json
index d9cdd5c..75223d7 100644
--- a/vendor/composer/installed.json
+++ b/vendor/composer/installed.json
@@ -1,5 +1,338 @@
 {
     "packages": [
+        {
+            "name": "brick/math",
+            "version": "0.11.0",
+            "version_normalized": "0.11.0.0",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/brick/math.git",
+                "reference": "0ad82ce168c82ba30d1c01ec86116ab52f589478"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/brick/math/zipball/0ad82ce168c82ba30d1c01ec86116ab52f589478",
+                "reference": "0ad82ce168c82ba30d1c01ec86116ab52f589478",
+                "shasum": "",
+                "mirrors": [
+                    {
+                        "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
+                        "preferred": true
+                    }
+                ]
+            },
+            "require": {
+                "php": "^8.0"
+            },
+            "require-dev": {
+                "php-coveralls/php-coveralls": "^2.2",
+                "phpunit/phpunit": "^9.0",
+                "vimeo/psalm": "5.0.0"
+            },
+            "time": "2023-01-15T23:15:59+00:00",
+            "type": "library",
+            "installation-source": "dist",
+            "autoload": {
+                "psr-4": {
+                    "Brick\\Math\\": "src/"
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "description": "Arbitrary-precision arithmetic library",
+            "keywords": [
+                "Arbitrary-precision",
+                "BigInteger",
+                "BigRational",
+                "arithmetic",
+                "bigdecimal",
+                "bignum",
+                "brick",
+                "math"
+            ],
+            "support": {
+                "issues": "https://github.com/brick/math/issues",
+                "source": "https://github.com/brick/math/tree/0.11.0"
+            },
+            "funding": [
+                {
+                    "url": "https://github.com/BenMorel",
+                    "type": "github"
+                }
+            ],
+            "install-path": "../brick/math"
+        },
+        {
+            "name": "cakephp/core",
+            "version": "4.5.3",
+            "version_normalized": "4.5.3.0",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/cakephp/core.git",
+                "reference": "c2f4dff110d41e475d1041f2abe236f1c62d0cd0"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/cakephp/core/zipball/c2f4dff110d41e475d1041f2abe236f1c62d0cd0",
+                "reference": "c2f4dff110d41e475d1041f2abe236f1c62d0cd0",
+                "shasum": "",
+                "mirrors": [
+                    {
+                        "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
+                        "preferred": true
+                    }
+                ]
+            },
+            "require": {
+                "cakephp/utility": "^4.0",
+                "php": ">=7.4.0"
+            },
+            "provide": {
+                "psr/container-implementation": "^1.0 || ^2.0"
+            },
+            "suggest": {
+                "cakephp/cache": "To use Configure::store() and restore().",
+                "cakephp/event": "To use PluginApplicationInterface or plugin applications.",
+                "league/container": "To use Container and ServiceProvider classes"
+            },
+            "time": "2023-10-21T13:30:46+00:00",
+            "type": "library",
+            "installation-source": "dist",
+            "autoload": {
+                "files": [
+                    "functions.php"
+                ],
+                "psr-4": {
+                    "Cake\\Core\\": "."
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "CakePHP Community",
+                    "homepage": "https://github.com/cakephp/core/graphs/contributors"
+                }
+            ],
+            "description": "CakePHP Framework Core classes",
+            "homepage": "https://cakephp.org",
+            "keywords": [
+                "cakephp",
+                "core",
+                "framework"
+            ],
+            "support": {
+                "forum": "https://stackoverflow.com/tags/cakephp",
+                "irc": "irc://irc.freenode.org/cakephp",
+                "issues": "https://github.com/cakephp/cakephp/issues",
+                "source": "https://github.com/cakephp/core"
+            },
+            "install-path": "../cakephp/core"
+        },
+        {
+            "name": "cakephp/database",
+            "version": "4.5.3",
+            "version_normalized": "4.5.3.0",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/cakephp/database.git",
+                "reference": "317739cc32060ef19b6c19c87ac6b64848d78e27"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/cakephp/database/zipball/317739cc32060ef19b6c19c87ac6b64848d78e27",
+                "reference": "317739cc32060ef19b6c19c87ac6b64848d78e27",
+                "shasum": "",
+                "mirrors": [
+                    {
+                        "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
+                        "preferred": true
+                    }
+                ]
+            },
+            "require": {
+                "cakephp/core": "^4.0",
+                "cakephp/datasource": "^4.0",
+                "php": ">=7.4.0"
+            },
+            "suggest": {
+                "cakephp/i18n": "If you are using locale-aware datetime formats or Chronos types.",
+                "cakephp/log": "If you want to use query logging without providing a logger yourself."
+            },
+            "time": "2023-12-07T12:23:54+00:00",
+            "type": "library",
+            "installation-source": "dist",
+            "autoload": {
+                "psr-4": {
+                    "Cake\\Database\\": "."
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "CakePHP Community",
+                    "homepage": "https://github.com/cakephp/database/graphs/contributors"
+                }
+            ],
+            "description": "Flexible and powerful Database abstraction library with a familiar PDO-like API",
+            "homepage": "https://cakephp.org",
+            "keywords": [
+                "abstraction",
+                "cakephp",
+                "database",
+                "database abstraction",
+                "pdo"
+            ],
+            "support": {
+                "forum": "https://stackoverflow.com/tags/cakephp",
+                "irc": "irc://irc.freenode.org/cakephp",
+                "issues": "https://github.com/cakephp/cakephp/issues",
+                "source": "https://github.com/cakephp/database"
+            },
+            "install-path": "../cakephp/database"
+        },
+        {
+            "name": "cakephp/datasource",
+            "version": "4.5.3",
+            "version_normalized": "4.5.3.0",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/cakephp/datasource.git",
+                "reference": "5d11a35ffc09dee744faaab7f758aeb42c17cfec"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/cakephp/datasource/zipball/5d11a35ffc09dee744faaab7f758aeb42c17cfec",
+                "reference": "5d11a35ffc09dee744faaab7f758aeb42c17cfec",
+                "shasum": "",
+                "mirrors": [
+                    {
+                        "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
+                        "preferred": true
+                    }
+                ]
+            },
+            "require": {
+                "cakephp/core": "^4.0",
+                "php": ">=7.4.0",
+                "psr/log": "^1.0 || ^2.0",
+                "psr/simple-cache": "^1.0 || ^2.0"
+            },
+            "suggest": {
+                "cakephp/cache": "If you decide to use Query caching.",
+                "cakephp/collection": "If you decide to use ResultSetInterface.",
+                "cakephp/utility": "If you decide to use EntityTrait."
+            },
+            "time": "2023-11-05T07:32:10+00:00",
+            "type": "library",
+            "installation-source": "dist",
+            "autoload": {
+                "psr-4": {
+                    "Cake\\Datasource\\": "."
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "CakePHP Community",
+                    "homepage": "https://github.com/cakephp/datasource/graphs/contributors"
+                }
+            ],
+            "description": "Provides connection managing and traits for Entities and Queries that can be reused for different datastores",
+            "homepage": "https://cakephp.org",
+            "keywords": [
+                "cakephp",
+                "connection management",
+                "datasource",
+                "entity",
+                "query"
+            ],
+            "support": {
+                "forum": "https://stackoverflow.com/tags/cakephp",
+                "irc": "irc://irc.freenode.org/cakephp",
+                "issues": "https://github.com/cakephp/cakephp/issues",
+                "source": "https://github.com/cakephp/datasource"
+            },
+            "install-path": "../cakephp/datasource"
+        },
+        {
+            "name": "cakephp/utility",
+            "version": "4.5.3",
+            "version_normalized": "4.5.3.0",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/cakephp/utility.git",
+                "reference": "9fb72974e91e81f1545a15a6d45f50c82cd77def"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/cakephp/utility/zipball/9fb72974e91e81f1545a15a6d45f50c82cd77def",
+                "reference": "9fb72974e91e81f1545a15a6d45f50c82cd77def",
+                "shasum": "",
+                "mirrors": [
+                    {
+                        "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
+                        "preferred": true
+                    }
+                ]
+            },
+            "require": {
+                "cakephp/core": "^4.0",
+                "php": ">=7.4.0"
+            },
+            "suggest": {
+                "ext-intl": "To use Text::transliterate() or Text::slug()",
+                "lib-ICU": "To use Text::transliterate() or Text::slug()"
+            },
+            "time": "2023-04-11T21:22:06+00:00",
+            "type": "library",
+            "installation-source": "dist",
+            "autoload": {
+                "files": [
+                    "bootstrap.php"
+                ],
+                "psr-4": {
+                    "Cake\\Utility\\": "."
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "CakePHP Community",
+                    "homepage": "https://github.com/cakephp/utility/graphs/contributors"
+                }
+            ],
+            "description": "CakePHP Utility classes such as Inflector, String, Hash, and Security",
+            "homepage": "https://cakephp.org",
+            "keywords": [
+                "cakephp",
+                "hash",
+                "inflector",
+                "security",
+                "string",
+                "utility"
+            ],
+            "support": {
+                "forum": "https://stackoverflow.com/tags/cakephp",
+                "irc": "irc://irc.freenode.org/cakephp",
+                "issues": "https://github.com/cakephp/cakephp/issues",
+                "source": "https://github.com/cakephp/utility"
+            },
+            "install-path": "../cakephp/utility"
+        },
         {
             "name": "carbonphp/carbon-doctrine-types",
             "version": "2.1.0",
@@ -153,18 +486,24 @@
         },
         {
             "name": "doctrine/inflector",
-            "version": "2.0.9",
-            "version_normalized": "2.0.9.0",
+            "version": "2.0.8",
+            "version_normalized": "2.0.8.0",
             "source": {
                 "type": "git",
                 "url": "https://github.com/doctrine/inflector.git",
-                "reference": "2930cd5ef353871c821d5c43ed030d39ac8cfe65"
+                "reference": "f9301a5b2fb1216b2b08f02ba04dc45423db6bff"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/doctrine/inflector/zipball/2930cd5ef353871c821d5c43ed030d39ac8cfe65",
-                "reference": "2930cd5ef353871c821d5c43ed030d39ac8cfe65",
-                "shasum": ""
+                "url": "https://api.github.com/repos/doctrine/inflector/zipball/f9301a5b2fb1216b2b08f02ba04dc45423db6bff",
+                "reference": "f9301a5b2fb1216b2b08f02ba04dc45423db6bff",
+                "shasum": "",
+                "mirrors": [
+                    {
+                        "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
+                        "preferred": true
+                    }
+                ]
             },
             "require": {
                 "php": "^7.2 || ^8.0"
@@ -177,7 +516,7 @@
                 "phpunit/phpunit": "^8.5 || ^9.5",
                 "vimeo/psalm": "^4.25 || ^5.4"
             },
-            "time": "2024-01-15T18:05:13+00:00",
+            "time": "2023-06-16T13:40:37+00:00",
             "type": "library",
             "installation-source": "dist",
             "autoload": {
@@ -227,7 +566,7 @@
             ],
             "support": {
                 "issues": "https://github.com/doctrine/inflector/issues",
-                "source": "https://github.com/doctrine/inflector/tree/2.0.9"
+                "source": "https://github.com/doctrine/inflector/tree/2.0.8"
             },
             "funding": [
                 {
@@ -910,6 +1249,85 @@
             },
             "install-path": "../illuminate/contracts"
         },
+        {
+            "name": "illuminate/database",
+            "version": "v9.52.16",
+            "version_normalized": "9.52.16.0",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/illuminate/database.git",
+                "reference": "93cfc8e1f9ac147e6a2851ecabe8d8f21ad85182"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/illuminate/database/zipball/93cfc8e1f9ac147e6a2851ecabe8d8f21ad85182",
+                "reference": "93cfc8e1f9ac147e6a2851ecabe8d8f21ad85182",
+                "shasum": "",
+                "mirrors": [
+                    {
+                        "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
+                        "preferred": true
+                    }
+                ]
+            },
+            "require": {
+                "brick/math": "^0.9.3|^0.10.2|^0.11",
+                "ext-pdo": "*",
+                "illuminate/collections": "^9.0",
+                "illuminate/container": "^9.0",
+                "illuminate/contracts": "^9.0",
+                "illuminate/macroable": "^9.0",
+                "illuminate/support": "^9.0",
+                "php": "^8.0.2",
+                "symfony/console": "^6.0.9"
+            },
+            "suggest": {
+                "doctrine/dbal": "Required to rename columns and drop SQLite columns (^2.13.3|^3.1.4).",
+                "ext-filter": "Required to use the Postgres database driver.",
+                "fakerphp/faker": "Required to use the eloquent factory builder (^1.21).",
+                "illuminate/console": "Required to use the database commands (^9.0).",
+                "illuminate/events": "Required to use the observers with Eloquent (^9.0).",
+                "illuminate/filesystem": "Required to use the migrations (^9.0).",
+                "illuminate/pagination": "Required to paginate the result set (^9.0).",
+                "symfony/finder": "Required to use Eloquent model factories (^6.0)."
+            },
+            "time": "2023-06-11T21:17:10+00:00",
+            "type": "library",
+            "extra": {
+                "branch-alias": {
+                    "dev-master": "9.x-dev"
+                }
+            },
+            "installation-source": "dist",
+            "autoload": {
+                "psr-4": {
+                    "Illuminate\\Database\\": ""
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "Taylor Otwell",
+                    "email": "taylor@laravel.com"
+                }
+            ],
+            "description": "The Illuminate Database package.",
+            "homepage": "https://laravel.com",
+            "keywords": [
+                "database",
+                "laravel",
+                "orm",
+                "sql"
+            ],
+            "support": {
+                "issues": "https://github.com/laravel/framework/issues",
+                "source": "https://github.com/laravel/framework"
+            },
+            "install-path": "../illuminate/database"
+        },
         {
             "name": "illuminate/events",
             "version": "v9.52.16",
@@ -1017,6 +1435,65 @@
             },
             "install-path": "../illuminate/macroable"
         },
+        {
+            "name": "illuminate/pagination",
+            "version": "v9.52.16",
+            "version_normalized": "9.52.16.0",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/illuminate/pagination.git",
+                "reference": "0c913d6af303ae0060d94d74d68d537637f7e6d4"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/illuminate/pagination/zipball/0c913d6af303ae0060d94d74d68d537637f7e6d4",
+                "reference": "0c913d6af303ae0060d94d74d68d537637f7e6d4",
+                "shasum": "",
+                "mirrors": [
+                    {
+                        "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
+                        "preferred": true
+                    }
+                ]
+            },
+            "require": {
+                "ext-filter": "*",
+                "illuminate/collections": "^9.0",
+                "illuminate/contracts": "^9.0",
+                "illuminate/support": "^9.0",
+                "php": "^8.0.2"
+            },
+            "time": "2023-02-06T02:52:41+00:00",
+            "type": "library",
+            "extra": {
+                "branch-alias": {
+                    "dev-master": "9.x-dev"
+                }
+            },
+            "installation-source": "dist",
+            "autoload": {
+                "psr-4": {
+                    "Illuminate\\Pagination\\": ""
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "Taylor Otwell",
+                    "email": "taylor@laravel.com"
+                }
+            ],
+            "description": "The Illuminate Pagination package.",
+            "homepage": "https://laravel.com",
+            "support": {
+                "issues": "https://github.com/laravel/framework/issues",
+                "source": "https://github.com/laravel/framework"
+            },
+            "install-path": "../illuminate/pagination"
+        },
         {
             "name": "illuminate/pipeline",
             "version": "v9.52.16",
@@ -1223,75 +1700,6 @@
             "description": "Webman plugin laysense/dns. You can making a DNS Server with Webman now",
             "install-path": "../laysense/dns"
         },
-        {
-            "name": "maximebf/debugbar",
-            "version": "v1.19.1",
-            "version_normalized": "1.19.1.0",
-            "source": {
-                "type": "git",
-                "url": "https://github.com/maximebf/php-debugbar.git",
-                "reference": "03dd40a1826f4d585ef93ef83afa2a9874a00523"
-            },
-            "dist": {
-                "type": "zip",
-                "url": "https://api.github.com/repos/maximebf/php-debugbar/zipball/03dd40a1826f4d585ef93ef83afa2a9874a00523",
-                "reference": "03dd40a1826f4d585ef93ef83afa2a9874a00523",
-                "shasum": ""
-            },
-            "require": {
-                "php": "^7.1|^8",
-                "psr/log": "^1|^2|^3",
-                "symfony/var-dumper": "^4|^5|^6"
-            },
-            "require-dev": {
-                "phpunit/phpunit": ">=7.5.20 <10.0",
-                "twig/twig": "^1.38|^2.7|^3.0"
-            },
-            "suggest": {
-                "kriswallsmith/assetic": "The best way to manage assets",
-                "monolog/monolog": "Log using Monolog",
-                "predis/predis": "Redis storage"
-            },
-            "time": "2023-10-12T08:10:52+00:00",
-            "type": "library",
-            "extra": {
-                "branch-alias": {
-                    "dev-master": "1.18-dev"
-                }
-            },
-            "installation-source": "dist",
-            "autoload": {
-                "psr-4": {
-                    "DebugBar\\": "src/DebugBar/"
-                }
-            },
-            "notification-url": "https://packagist.org/downloads/",
-            "license": [
-                "MIT"
-            ],
-            "authors": [
-                {
-                    "name": "Maxime Bouroumeau-Fuseau",
-                    "email": "maxime.bouroumeau@gmail.com",
-                    "homepage": "http://maximebf.com"
-                },
-                {
-                    "name": "Barry vd. Heuvel",
-                    "email": "barryvdh@gmail.com"
-                }
-            ],
-            "description": "Debug bar in the browser for php application",
-            "homepage": "https://github.com/maximebf/php-debugbar",
-            "keywords": [
-                "debug",
-                "debugbar"
-            ],
-            "support": {
-                "issues": "https://github.com/maximebf/php-debugbar/issues",
-                "source": "https://github.com/maximebf/php-debugbar/tree/v1.19.1"
-            },
-            "install-path": "../maximebf/debugbar"
-        },
         {
             "name": "maxmind-db/reader",
             "version": "v1.11.1",
@@ -1523,18 +1931,24 @@
         },
         {
             "name": "nesbot/carbon",
-            "version": "2.72.2",
-            "version_normalized": "2.72.2.0",
+            "version": "2.72.3",
+            "version_normalized": "2.72.3.0",
             "source": {
                 "type": "git",
                 "url": "https://github.com/briannesbitt/Carbon.git",
-                "reference": "3e7edc41b58d65509baeb0d4a14c8fa41d627130"
+                "reference": "0c6fd108360c562f6e4fd1dedb8233b423e91c83"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/briannesbitt/Carbon/zipball/3e7edc41b58d65509baeb0d4a14c8fa41d627130",
-                "reference": "3e7edc41b58d65509baeb0d4a14c8fa41d627130",
-                "shasum": ""
+                "url": "https://api.github.com/repos/briannesbitt/Carbon/zipball/0c6fd108360c562f6e4fd1dedb8233b423e91c83",
+                "reference": "0c6fd108360c562f6e4fd1dedb8233b423e91c83",
+                "shasum": "",
+                "mirrors": [
+                    {
+                        "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
+                        "preferred": true
+                    }
+                ]
             },
             "require": {
                 "carbonphp/carbon-doctrine-types": "*",
@@ -1561,7 +1975,7 @@
                 "phpunit/phpunit": "^7.5.20 || ^8.5.26 || ^9.5.20",
                 "squizlabs/php_codesniffer": "^3.4"
             },
-            "time": "2024-01-19T00:21:53+00:00",
+            "time": "2024-01-25T10:35:09+00:00",
             "bin": [
                 "bin/carbon"
             ],
@@ -2020,27 +2434,33 @@
         },
         {
             "name": "psr/log",
-            "version": "3.0.0",
-            "version_normalized": "3.0.0.0",
+            "version": "2.0.0",
+            "version_normalized": "2.0.0.0",
             "source": {
                 "type": "git",
                 "url": "https://github.com/php-fig/log.git",
-                "reference": "fe5ea303b0887d5caefd3d431c3e61ad47037001"
+                "reference": "ef29f6d262798707a9edd554e2b82517ef3a9376"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/php-fig/log/zipball/fe5ea303b0887d5caefd3d431c3e61ad47037001",
-                "reference": "fe5ea303b0887d5caefd3d431c3e61ad47037001",
-                "shasum": ""
+                "url": "https://api.github.com/repos/php-fig/log/zipball/ef29f6d262798707a9edd554e2b82517ef3a9376",
+                "reference": "ef29f6d262798707a9edd554e2b82517ef3a9376",
+                "shasum": "",
+                "mirrors": [
+                    {
+                        "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
+                        "preferred": true
+                    }
+                ]
             },
             "require": {
                 "php": ">=8.0.0"
             },
-            "time": "2021-07-14T16:46:02+00:00",
+            "time": "2021-07-14T16:41:46+00:00",
             "type": "library",
             "extra": {
                 "branch-alias": {
-                    "dev-master": "3.x-dev"
+                    "dev-master": "2.0.x-dev"
                 }
             },
             "installation-source": "dist",
@@ -2067,23 +2487,23 @@
                 "psr-3"
             ],
             "support": {
-                "source": "https://github.com/php-fig/log/tree/3.0.0"
+                "source": "https://github.com/php-fig/log/tree/2.0.0"
             },
             "install-path": "../psr/log"
         },
         {
             "name": "psr/simple-cache",
-            "version": "3.0.0",
-            "version_normalized": "3.0.0.0",
+            "version": "2.0.0",
+            "version_normalized": "2.0.0.0",
             "source": {
                 "type": "git",
                 "url": "https://github.com/php-fig/simple-cache.git",
-                "reference": "764e0b3939f5ca87cb904f570ef9be2d78a07865"
+                "reference": "8707bf3cea6f710bf6ef05491234e3ab06f6432a"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/php-fig/simple-cache/zipball/764e0b3939f5ca87cb904f570ef9be2d78a07865",
-                "reference": "764e0b3939f5ca87cb904f570ef9be2d78a07865",
+                "url": "https://api.github.com/repos/php-fig/simple-cache/zipball/8707bf3cea6f710bf6ef05491234e3ab06f6432a",
+                "reference": "8707bf3cea6f710bf6ef05491234e3ab06f6432a",
                 "shasum": "",
                 "mirrors": [
                     {
@@ -2095,11 +2515,11 @@
             "require": {
                 "php": ">=8.0.0"
             },
-            "time": "2021-10-29T13:26:27+00:00",
+            "time": "2021-10-29T13:22:09+00:00",
             "type": "library",
             "extra": {
                 "branch-alias": {
-                    "dev-master": "3.0.x-dev"
+                    "dev-master": "2.0.x-dev"
                 }
             },
             "installation-source": "dist",
@@ -2127,7 +2547,7 @@
                 "simple-cache"
             ],
             "support": {
-                "source": "https://github.com/php-fig/simple-cache/tree/3.0.0"
+                "source": "https://github.com/php-fig/simple-cache/tree/2.0.0"
             },
             "install-path": "../psr/simple-cache"
         },
@@ -2241,6 +2661,101 @@
             },
             "install-path": "../respect/stringifier"
         },
+        {
+            "name": "robmorgan/phinx",
+            "version": "0.14.0",
+            "version_normalized": "0.14.0.0",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/cakephp/phinx.git",
+                "reference": "7bc24bae664b2124f3d5b8d1e98fdb8abaf70e87"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/cakephp/phinx/zipball/7bc24bae664b2124f3d5b8d1e98fdb8abaf70e87",
+                "reference": "7bc24bae664b2124f3d5b8d1e98fdb8abaf70e87",
+                "shasum": "",
+                "mirrors": [
+                    {
+                        "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
+                        "preferred": true
+                    }
+                ]
+            },
+            "require": {
+                "cakephp/database": "^4.0",
+                "php-64bit": ">=7.3",
+                "psr/container": "^1.0 || ^2.0",
+                "symfony/config": "^3.4|^4.0|^5.0|^6.0",
+                "symfony/console": "^3.4|^4.0|^5.0|^6.0"
+            },
+            "require-dev": {
+                "cakephp/cakephp-codesniffer": "^4.0",
+                "ext-json": "*",
+                "ext-pdo": "*",
+                "phpunit/phpunit": "^9.5",
+                "sebastian/comparator": ">=1.2.3",
+                "symfony/yaml": "^3.4|^4.0|^5.0"
+            },
+            "suggest": {
+                "ext-json": "Install if using JSON configuration format",
+                "ext-pdo": "PDO extension is needed",
+                "symfony/yaml": "Install if using YAML configuration format"
+            },
+            "time": "2023-09-07T14:26:14+00:00",
+            "bin": [
+                "bin/phinx"
+            ],
+            "type": "library",
+            "installation-source": "dist",
+            "autoload": {
+                "psr-4": {
+                    "Phinx\\": "src/Phinx/"
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "Rob Morgan",
+                    "email": "robbym@gmail.com",
+                    "homepage": "https://robmorgan.id.au",
+                    "role": "Lead Developer"
+                },
+                {
+                    "name": "Woody Gilk",
+                    "email": "woody.gilk@gmail.com",
+                    "homepage": "https://shadowhand.me",
+                    "role": "Developer"
+                },
+                {
+                    "name": "Richard Quadling",
+                    "email": "rquadling@gmail.com",
+                    "role": "Developer"
+                },
+                {
+                    "name": "CakePHP Community",
+                    "homepage": "https://github.com/cakephp/phinx/graphs/contributors",
+                    "role": "Developer"
+                }
+            ],
+            "description": "Phinx makes it ridiculously easy to manage the database migrations for your PHP app.",
+            "homepage": "https://phinx.org",
+            "keywords": [
+                "database",
+                "database migrations",
+                "db",
+                "migrations",
+                "phinx"
+            ],
+            "support": {
+                "issues": "https://github.com/cakephp/phinx/issues",
+                "source": "https://github.com/cakephp/phinx/tree/0.14.0"
+            },
+            "install-path": "../robmorgan/phinx"
+        },
         {
             "name": "symfony/cache",
             "version": "v6.0.19",
@@ -2425,6 +2940,93 @@
             ],
             "install-path": "../symfony/cache-contracts"
         },
+        {
+            "name": "symfony/config",
+            "version": "v6.0.19",
+            "version_normalized": "6.0.19.0",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/symfony/config.git",
+                "reference": "db4fc45c24e0c3e2198e68ada9d7f90daa1f97e3"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/symfony/config/zipball/db4fc45c24e0c3e2198e68ada9d7f90daa1f97e3",
+                "reference": "db4fc45c24e0c3e2198e68ada9d7f90daa1f97e3",
+                "shasum": "",
+                "mirrors": [
+                    {
+                        "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
+                        "preferred": true
+                    }
+                ]
+            },
+            "require": {
+                "php": ">=8.0.2",
+                "symfony/deprecation-contracts": "^2.1|^3",
+                "symfony/filesystem": "^5.4|^6.0",
+                "symfony/polyfill-ctype": "~1.8",
+                "symfony/polyfill-php81": "^1.22"
+            },
+            "conflict": {
+                "symfony/finder": "<4.4"
+            },
+            "require-dev": {
+                "symfony/event-dispatcher": "^5.4|^6.0",
+                "symfony/finder": "^5.4|^6.0",
+                "symfony/messenger": "^5.4|^6.0",
+                "symfony/service-contracts": "^1.1|^2|^3",
+                "symfony/yaml": "^5.4|^6.0"
+            },
+            "suggest": {
+                "symfony/yaml": "To use the yaml reference dumper"
+            },
+            "time": "2023-01-09T04:36:00+00:00",
+            "type": "library",
+            "installation-source": "dist",
+            "autoload": {
+                "psr-4": {
+                    "Symfony\\Component\\Config\\": ""
+                },
+                "exclude-from-classmap": [
+                    "/Tests/"
+                ]
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "Fabien Potencier",
+                    "email": "fabien@symfony.com"
+                },
+                {
+                    "name": "Symfony Community",
+                    "homepage": "https://symfony.com/contributors"
+                }
+            ],
+            "description": "Helps you find, load, combine, autofill and validate configuration values of any kind",
+            "homepage": "https://symfony.com",
+            "support": {
+                "source": "https://github.com/symfony/config/tree/v6.0.19"
+            },
+            "funding": [
+                {
+                    "url": "https://symfony.com/sponsor",
+                    "type": "custom"
+                },
+                {
+                    "url": "https://github.com/fabpot",
+                    "type": "github"
+                },
+                {
+                    "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
+                    "type": "tidelift"
+                }
+            ],
+            "install-path": "../symfony/config"
+        },
         {
             "name": "symfony/console",
             "version": "v6.0.19",
@@ -2593,6 +3195,78 @@
             ],
             "install-path": "../symfony/deprecation-contracts"
         },
+        {
+            "name": "symfony/filesystem",
+            "version": "v6.0.19",
+            "version_normalized": "6.0.19.0",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/symfony/filesystem.git",
+                "reference": "3d49eec03fda1f0fc19b7349fbbe55ebc1004214"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/symfony/filesystem/zipball/3d49eec03fda1f0fc19b7349fbbe55ebc1004214",
+                "reference": "3d49eec03fda1f0fc19b7349fbbe55ebc1004214",
+                "shasum": "",
+                "mirrors": [
+                    {
+                        "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
+                        "preferred": true
+                    }
+                ]
+            },
+            "require": {
+                "php": ">=8.0.2",
+                "symfony/polyfill-ctype": "~1.8",
+                "symfony/polyfill-mbstring": "~1.8"
+            },
+            "time": "2023-01-20T17:44:14+00:00",
+            "type": "library",
+            "installation-source": "dist",
+            "autoload": {
+                "psr-4": {
+                    "Symfony\\Component\\Filesystem\\": ""
+                },
+                "exclude-from-classmap": [
+                    "/Tests/"
+                ]
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "Fabien Potencier",
+                    "email": "fabien@symfony.com"
+                },
+                {
+                    "name": "Symfony Community",
+                    "homepage": "https://symfony.com/contributors"
+                }
+            ],
+            "description": "Provides basic utilities for the filesystem",
+            "homepage": "https://symfony.com",
+            "support": {
+                "source": "https://github.com/symfony/filesystem/tree/v6.0.19"
+            },
+            "funding": [
+                {
+                    "url": "https://symfony.com/sponsor",
+                    "type": "custom"
+                },
+                {
+                    "url": "https://github.com/fabpot",
+                    "type": "github"
+                },
+                {
+                    "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
+                    "type": "tidelift"
+                }
+            ],
+            "install-path": "../symfony/filesystem"
+        },
         {
             "name": "symfony/polyfill-ctype",
             "version": "v1.28.0",
@@ -3021,6 +3695,94 @@
             ],
             "install-path": "../symfony/polyfill-php80"
         },
+        {
+            "name": "symfony/polyfill-php81",
+            "version": "v1.28.0",
+            "version_normalized": "1.28.0.0",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/symfony/polyfill-php81.git",
+                "reference": "7581cd600fa9fd681b797d00b02f068e2f13263b"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/symfony/polyfill-php81/zipball/7581cd600fa9fd681b797d00b02f068e2f13263b",
+                "reference": "7581cd600fa9fd681b797d00b02f068e2f13263b",
+                "shasum": "",
+                "mirrors": [
+                    {
+                        "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
+                        "preferred": true
+                    }
+                ]
+            },
+            "require": {
+                "php": ">=7.1"
+            },
+            "time": "2023-01-26T09:26:14+00:00",
+            "type": "library",
+            "extra": {
+                "branch-alias": {
+                    "dev-main": "1.28-dev"
+                },
+                "thanks": {
+                    "name": "symfony/polyfill",
+                    "url": "https://github.com/symfony/polyfill"
+                }
+            },
+            "installation-source": "dist",
+            "autoload": {
+                "files": [
+                    "bootstrap.php"
+                ],
+                "psr-4": {
+                    "Symfony\\Polyfill\\Php81\\": ""
+                },
+                "classmap": [
+                    "Resources/stubs"
+                ]
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "Nicolas Grekas",
+                    "email": "p@tchwork.com"
+                },
+                {
+                    "name": "Symfony Community",
+                    "homepage": "https://symfony.com/contributors"
+                }
+            ],
+            "description": "Symfony polyfill backporting some PHP 8.1+ features to lower PHP versions",
+            "homepage": "https://symfony.com",
+            "keywords": [
+                "compatibility",
+                "polyfill",
+                "portable",
+                "shim"
+            ],
+            "support": {
+                "source": "https://github.com/symfony/polyfill-php81/tree/v1.28.0"
+            },
+            "funding": [
+                {
+                    "url": "https://symfony.com/sponsor",
+                    "type": "custom"
+                },
+                {
+                    "url": "https://github.com/fabpot",
+                    "type": "github"
+                },
+                {
+                    "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
+                    "type": "tidelift"
+                }
+            ],
+            "install-path": "../symfony/polyfill-php81"
+        },
         {
             "name": "symfony/service-contracts",
             "version": "v3.0.2",
@@ -3628,52 +4390,6 @@
             ],
             "install-path": "../voku/portable-ascii"
         },
-        {
-            "name": "webman-tech/debugbar",
-            "version": "v2.2.1",
-            "version_normalized": "2.2.1.0",
-            "source": {
-                "type": "git",
-                "url": "https://github.com/webman-tech/debugbar.git",
-                "reference": "f448183bb2a2fe3dce8c4de59f5668611e4e2e8b"
-            },
-            "dist": {
-                "type": "zip",
-                "url": "https://api.github.com/repos/webman-tech/debugbar/zipball/f448183bb2a2fe3dce8c4de59f5668611e4e2e8b",
-                "reference": "f448183bb2a2fe3dce8c4de59f5668611e4e2e8b",
-                "shasum": ""
-            },
-            "require": {
-                "maximebf/debugbar": "^1.18",
-                "php": ">=7.2"
-            },
-            "require-dev": {
-                "illuminate/database": "^8.83",
-                "illuminate/events": "^8.83",
-                "illuminate/redis": "^8.83",
-                "symfony/finder": "^5.4",
-                "topthink/think-orm": "^2.0",
-                "workerman/webman-framework": "^1.4"
-            },
-            "time": "2024-01-10T09:23:31+00:00",
-            "type": "library",
-            "installation-source": "dist",
-            "autoload": {
-                "psr-4": {
-                    "WebmanTech\\Debugbar\\": "src"
-                }
-            },
-            "notification-url": "https://packagist.org/downloads/",
-            "license": [
-                "MIT"
-            ],
-            "description": "Webman plugin webman-tech/debugbar",
-            "support": {
-                "issues": "https://github.com/webman-tech/debugbar/issues",
-                "source": "https://github.com/webman-tech/debugbar/tree/v2.2.1"
-            },
-            "install-path": "../webman-tech/debugbar"
-        },
         {
             "name": "webman/console",
             "version": "v1.3.4",
@@ -4038,9 +4754,5 @@
         }
     ],
     "dev": true,
-    "dev-package-names": [
-        "maximebf/debugbar",
-        "symfony/var-dumper",
-        "webman-tech/debugbar"
-    ]
+    "dev-package-names": []
 }
diff --git a/vendor/composer/installed.php b/vendor/composer/installed.php
index 1b6da19..ce83b12 100644
--- a/vendor/composer/installed.php
+++ b/vendor/composer/installed.php
@@ -3,13 +3,58 @@
         'name' => 'laysense/highspeaker',
         'pretty_version' => 'dev-master',
         'version' => 'dev-master',
-        'reference' => 'b5ff5e8b5f9960d37346ed85377268d733ae16e1',
+        'reference' => '20678a6a0cc68fded62619de04ae86cb7cb31017',
         'type' => 'project',
         'install_path' => __DIR__ . '/../../',
         'aliases' => array(),
         'dev' => true,
     ),
     'versions' => array(
+        'brick/math' => array(
+            'pretty_version' => '0.11.0',
+            'version' => '0.11.0.0',
+            'reference' => '0ad82ce168c82ba30d1c01ec86116ab52f589478',
+            'type' => 'library',
+            'install_path' => __DIR__ . '/../brick/math',
+            'aliases' => array(),
+            'dev_requirement' => false,
+        ),
+        'cakephp/core' => array(
+            'pretty_version' => '4.5.3',
+            'version' => '4.5.3.0',
+            'reference' => 'c2f4dff110d41e475d1041f2abe236f1c62d0cd0',
+            'type' => 'library',
+            'install_path' => __DIR__ . '/../cakephp/core',
+            'aliases' => array(),
+            'dev_requirement' => false,
+        ),
+        'cakephp/database' => array(
+            'pretty_version' => '4.5.3',
+            'version' => '4.5.3.0',
+            'reference' => '317739cc32060ef19b6c19c87ac6b64848d78e27',
+            'type' => 'library',
+            'install_path' => __DIR__ . '/../cakephp/database',
+            'aliases' => array(),
+            'dev_requirement' => false,
+        ),
+        'cakephp/datasource' => array(
+            'pretty_version' => '4.5.3',
+            'version' => '4.5.3.0',
+            'reference' => '5d11a35ffc09dee744faaab7f758aeb42c17cfec',
+            'type' => 'library',
+            'install_path' => __DIR__ . '/../cakephp/datasource',
+            'aliases' => array(),
+            'dev_requirement' => false,
+        ),
+        'cakephp/utility' => array(
+            'pretty_version' => '4.5.3',
+            'version' => '4.5.3.0',
+            'reference' => '9fb72974e91e81f1545a15a6d45f50c82cd77def',
+            'type' => 'library',
+            'install_path' => __DIR__ . '/../cakephp/utility',
+            'aliases' => array(),
+            'dev_requirement' => false,
+        ),
         'carbonphp/carbon-doctrine-types' => array(
             'pretty_version' => '2.1.0',
             'version' => '2.1.0.0',
@@ -29,9 +74,9 @@
             'dev_requirement' => false,
         ),
         'doctrine/inflector' => array(
-            'pretty_version' => '2.0.9',
-            'version' => '2.0.9.0',
-            'reference' => '2930cd5ef353871c821d5c43ed030d39ac8cfe65',
+            'pretty_version' => '2.0.8',
+            'version' => '2.0.8.0',
+            'reference' => 'f9301a5b2fb1216b2b08f02ba04dc45423db6bff',
             'type' => 'library',
             'install_path' => __DIR__ . '/../doctrine/inflector',
             'aliases' => array(),
@@ -118,6 +163,15 @@
             'aliases' => array(),
             'dev_requirement' => false,
         ),
+        'illuminate/database' => array(
+            'pretty_version' => 'v9.52.16',
+            'version' => '9.52.16.0',
+            'reference' => '93cfc8e1f9ac147e6a2851ecabe8d8f21ad85182',
+            'type' => 'library',
+            'install_path' => __DIR__ . '/../illuminate/database',
+            'aliases' => array(),
+            'dev_requirement' => false,
+        ),
         'illuminate/events' => array(
             'pretty_version' => 'v9.52.16',
             'version' => '9.52.16.0',
@@ -136,6 +190,15 @@
             'aliases' => array(),
             'dev_requirement' => false,
         ),
+        'illuminate/pagination' => array(
+            'pretty_version' => 'v9.52.16',
+            'version' => '9.52.16.0',
+            'reference' => '0c913d6af303ae0060d94d74d68d537637f7e6d4',
+            'type' => 'library',
+            'install_path' => __DIR__ . '/../illuminate/pagination',
+            'aliases' => array(),
+            'dev_requirement' => false,
+        ),
         'illuminate/pipeline' => array(
             'pretty_version' => 'v9.52.16',
             'version' => '9.52.16.0',
@@ -175,21 +238,12 @@
         'laysense/highspeaker' => array(
             'pretty_version' => 'dev-master',
             'version' => 'dev-master',
-            'reference' => 'b5ff5e8b5f9960d37346ed85377268d733ae16e1',
+            'reference' => '20678a6a0cc68fded62619de04ae86cb7cb31017',
             'type' => 'project',
             'install_path' => __DIR__ . '/../../',
             'aliases' => array(),
             'dev_requirement' => false,
         ),
-        'maximebf/debugbar' => array(
-            'pretty_version' => 'v1.19.1',
-            'version' => '1.19.1.0',
-            'reference' => '03dd40a1826f4d585ef93ef83afa2a9874a00523',
-            'type' => 'library',
-            'install_path' => __DIR__ . '/../maximebf/debugbar',
-            'aliases' => array(),
-            'dev_requirement' => true,
-        ),
         'maxmind-db/reader' => array(
             'pretty_version' => 'v1.11.1',
             'version' => '1.11.1.0',
@@ -218,9 +272,9 @@
             'dev_requirement' => false,
         ),
         'nesbot/carbon' => array(
-            'pretty_version' => '2.72.2',
-            'version' => '2.72.2.0',
-            'reference' => '3e7edc41b58d65509baeb0d4a14c8fa41d627130',
+            'pretty_version' => '2.72.3',
+            'version' => '2.72.3.0',
+            'reference' => '0c6fd108360c562f6e4fd1dedb8233b423e91c83',
             'type' => 'library',
             'install_path' => __DIR__ . '/../nesbot/carbon',
             'aliases' => array(),
@@ -277,7 +331,8 @@
         'psr/container-implementation' => array(
             'dev_requirement' => false,
             'provided' => array(
-                0 => '1.1|2.0',
+                0 => '^1.0 || ^2.0',
+                1 => '1.1|2.0',
             ),
         ),
         'psr/http-client' => array(
@@ -326,9 +381,9 @@
             ),
         ),
         'psr/log' => array(
-            'pretty_version' => '3.0.0',
-            'version' => '3.0.0.0',
-            'reference' => 'fe5ea303b0887d5caefd3d431c3e61ad47037001',
+            'pretty_version' => '2.0.0',
+            'version' => '2.0.0.0',
+            'reference' => 'ef29f6d262798707a9edd554e2b82517ef3a9376',
             'type' => 'library',
             'install_path' => __DIR__ . '/../psr/log',
             'aliases' => array(),
@@ -342,9 +397,9 @@
             ),
         ),
         'psr/simple-cache' => array(
-            'pretty_version' => '3.0.0',
-            'version' => '3.0.0.0',
-            'reference' => '764e0b3939f5ca87cb904f570ef9be2d78a07865',
+            'pretty_version' => '2.0.0',
+            'version' => '2.0.0.0',
+            'reference' => '8707bf3cea6f710bf6ef05491234e3ab06f6432a',
             'type' => 'library',
             'install_path' => __DIR__ . '/../psr/simple-cache',
             'aliases' => array(),
@@ -374,6 +429,15 @@
             'aliases' => array(),
             'dev_requirement' => false,
         ),
+        'robmorgan/phinx' => array(
+            'pretty_version' => '0.14.0',
+            'version' => '0.14.0.0',
+            'reference' => '7bc24bae664b2124f3d5b8d1e98fdb8abaf70e87',
+            'type' => 'library',
+            'install_path' => __DIR__ . '/../robmorgan/phinx',
+            'aliases' => array(),
+            'dev_requirement' => false,
+        ),
         'symfony/cache' => array(
             'pretty_version' => 'v6.0.19',
             'version' => '6.0.19.0',
@@ -398,6 +462,15 @@
                 0 => '1.1|2.0|3.0',
             ),
         ),
+        'symfony/config' => array(
+            'pretty_version' => 'v6.0.19',
+            'version' => '6.0.19.0',
+            'reference' => 'db4fc45c24e0c3e2198e68ada9d7f90daa1f97e3',
+            'type' => 'library',
+            'install_path' => __DIR__ . '/../symfony/config',
+            'aliases' => array(),
+            'dev_requirement' => false,
+        ),
         'symfony/console' => array(
             'pretty_version' => 'v6.0.19',
             'version' => '6.0.19.0',
@@ -416,6 +489,15 @@
             'aliases' => array(),
             'dev_requirement' => false,
         ),
+        'symfony/filesystem' => array(
+            'pretty_version' => 'v6.0.19',
+            'version' => '6.0.19.0',
+            'reference' => '3d49eec03fda1f0fc19b7349fbbe55ebc1004214',
+            'type' => 'library',
+            'install_path' => __DIR__ . '/../symfony/filesystem',
+            'aliases' => array(),
+            'dev_requirement' => false,
+        ),
         'symfony/polyfill-ctype' => array(
             'pretty_version' => 'v1.28.0',
             'version' => '1.28.0.0',
@@ -461,6 +543,15 @@
             'aliases' => array(),
             'dev_requirement' => false,
         ),
+        'symfony/polyfill-php81' => array(
+            'pretty_version' => 'v1.28.0',
+            'version' => '1.28.0.0',
+            'reference' => '7581cd600fa9fd681b797d00b02f068e2f13263b',
+            'type' => 'library',
+            'install_path' => __DIR__ . '/../symfony/polyfill-php81',
+            'aliases' => array(),
+            'dev_requirement' => false,
+        ),
         'symfony/service-contracts' => array(
             'pretty_version' => 'v3.0.2',
             'version' => '3.0.2.0',
@@ -510,7 +601,7 @@
             'type' => 'library',
             'install_path' => __DIR__ . '/../symfony/var-dumper',
             'aliases' => array(),
-            'dev_requirement' => true,
+            'dev_requirement' => false,
         ),
         'symfony/var-exporter' => array(
             'pretty_version' => 'v6.0.19',
@@ -530,15 +621,6 @@
             'aliases' => array(),
             'dev_requirement' => false,
         ),
-        'webman-tech/debugbar' => array(
-            'pretty_version' => 'v2.2.1',
-            'version' => '2.2.1.0',
-            'reference' => 'f448183bb2a2fe3dce8c4de59f5668611e4e2e8b',
-            'type' => 'library',
-            'install_path' => __DIR__ . '/../webman-tech/debugbar',
-            'aliases' => array(),
-            'dev_requirement' => true,
-        ),
         'webman/console' => array(
             'pretty_version' => 'v1.3.4',
             'version' => '1.3.4.0',
diff --git a/vendor/doctrine/inflector/lib/Doctrine/Inflector/Rules/English/Inflectible.php b/vendor/doctrine/inflector/lib/Doctrine/Inflector/Rules/English/Inflectible.php
index 04b6d00..806e175 100644
--- a/vendor/doctrine/inflector/lib/Doctrine/Inflector/Rules/English/Inflectible.php
+++ b/vendor/doctrine/inflector/lib/Doctrine/Inflector/Rules/English/Inflectible.php
@@ -93,7 +93,6 @@ class Inflectible
     public static function getIrregular(): iterable
     {
         yield new Substitution(new Word('atlas'), new Word('atlases'));
-        yield new Substitution(new Word('axis'), new Word('axes'));
         yield new Substitution(new Word('axe'), new Word('axes'));
         yield new Substitution(new Word('beef'), new Word('beefs'));
         yield new Substitution(new Word('blouse'), new Word('blouses'));
@@ -105,7 +104,6 @@ class Inflectible
         yield new Substitution(new Word('child'), new Word('children'));
         yield new Substitution(new Word('canvas'), new Word('canvases'));
         yield new Substitution(new Word('cookie'), new Word('cookies'));
-        yield new Substitution(new Word('brownie'), new Word('brownies'));
         yield new Substitution(new Word('corpus'), new Word('corpuses'));
         yield new Substitution(new Word('cow'), new Word('cows'));
         yield new Substitution(new Word('criterion'), new Word('criteria'));
@@ -113,7 +111,6 @@ class Inflectible
         yield new Substitution(new Word('demo'), new Word('demos'));
         yield new Substitution(new Word('domino'), new Word('dominoes'));
         yield new Substitution(new Word('echo'), new Word('echoes'));
-        yield new Substitution(new Word('epoch'), new Word('epochs'));
         yield new Substitution(new Word('foot'), new Word('feet'));
         yield new Substitution(new Word('fungus'), new Word('fungi'));
         yield new Substitution(new Word('ganglion'), new Word('ganglions'));
diff --git a/vendor/illuminate/database/Capsule/Manager.php b/vendor/illuminate/database/Capsule/Manager.php
new file mode 100755
index 0000000..b877e7c
--- /dev/null
+++ b/vendor/illuminate/database/Capsule/Manager.php
@@ -0,0 +1,202 @@
+setupContainer($container ?: new Container);
+
+        // Once we have the container setup, we will setup the default configuration
+        // options in the container "config" binding. This will make the database
+        // manager work correctly out of the box without extreme configuration.
+        $this->setupDefaultConfiguration();
+
+        $this->setupManager();
+    }
+
+    /**
+     * Setup the default database configuration options.
+     *
+     * @return void
+     */
+    protected function setupDefaultConfiguration()
+    {
+        $this->container['config']['database.fetch'] = PDO::FETCH_OBJ;
+
+        $this->container['config']['database.default'] = 'default';
+    }
+
+    /**
+     * Build the database manager instance.
+     *
+     * @return void
+     */
+    protected function setupManager()
+    {
+        $factory = new ConnectionFactory($this->container);
+
+        $this->manager = new DatabaseManager($this->container, $factory);
+    }
+
+    /**
+     * Get a connection instance from the global manager.
+     *
+     * @param  string|null  $connection
+     * @return \Illuminate\Database\Connection
+     */
+    public static function connection($connection = null)
+    {
+        return static::$instance->getConnection($connection);
+    }
+
+    /**
+     * Get a fluent query builder instance.
+     *
+     * @param  \Closure|\Illuminate\Database\Query\Builder|string  $table
+     * @param  string|null  $as
+     * @param  string|null  $connection
+     * @return \Illuminate\Database\Query\Builder
+     */
+    public static function table($table, $as = null, $connection = null)
+    {
+        return static::$instance->connection($connection)->table($table, $as);
+    }
+
+    /**
+     * Get a schema builder instance.
+     *
+     * @param  string|null  $connection
+     * @return \Illuminate\Database\Schema\Builder
+     */
+    public static function schema($connection = null)
+    {
+        return static::$instance->connection($connection)->getSchemaBuilder();
+    }
+
+    /**
+     * Get a registered connection instance.
+     *
+     * @param  string|null  $name
+     * @return \Illuminate\Database\Connection
+     */
+    public function getConnection($name = null)
+    {
+        return $this->manager->connection($name);
+    }
+
+    /**
+     * Register a connection with the manager.
+     *
+     * @param  array  $config
+     * @param  string  $name
+     * @return void
+     */
+    public function addConnection(array $config, $name = 'default')
+    {
+        $connections = $this->container['config']['database.connections'];
+
+        $connections[$name] = $config;
+
+        $this->container['config']['database.connections'] = $connections;
+    }
+
+    /**
+     * Bootstrap Eloquent so it is ready for usage.
+     *
+     * @return void
+     */
+    public function bootEloquent()
+    {
+        Eloquent::setConnectionResolver($this->manager);
+
+        // If we have an event dispatcher instance, we will go ahead and register it
+        // with the Eloquent ORM, allowing for model callbacks while creating and
+        // updating "model" instances; however, it is not necessary to operate.
+        if ($dispatcher = $this->getEventDispatcher()) {
+            Eloquent::setEventDispatcher($dispatcher);
+        }
+    }
+
+    /**
+     * Set the fetch mode for the database connections.
+     *
+     * @param  int  $fetchMode
+     * @return $this
+     */
+    public function setFetchMode($fetchMode)
+    {
+        $this->container['config']['database.fetch'] = $fetchMode;
+
+        return $this;
+    }
+
+    /**
+     * Get the database manager instance.
+     *
+     * @return \Illuminate\Database\DatabaseManager
+     */
+    public function getDatabaseManager()
+    {
+        return $this->manager;
+    }
+
+    /**
+     * Get the current event dispatcher instance.
+     *
+     * @return \Illuminate\Contracts\Events\Dispatcher|null
+     */
+    public function getEventDispatcher()
+    {
+        if ($this->container->bound('events')) {
+            return $this->container['events'];
+        }
+    }
+
+    /**
+     * Set the event dispatcher instance to be used by connections.
+     *
+     * @param  \Illuminate\Contracts\Events\Dispatcher  $dispatcher
+     * @return void
+     */
+    public function setEventDispatcher(Dispatcher $dispatcher)
+    {
+        $this->container->instance('events', $dispatcher);
+    }
+
+    /**
+     * Dynamically pass methods to the default connection.
+     *
+     * @param  string  $method
+     * @param  array  $parameters
+     * @return mixed
+     */
+    public static function __callStatic($method, $parameters)
+    {
+        return static::connection()->$method(...$parameters);
+    }
+}
diff --git a/vendor/illuminate/database/ClassMorphViolationException.php b/vendor/illuminate/database/ClassMorphViolationException.php
new file mode 100644
index 0000000..6594d2d
--- /dev/null
+++ b/vendor/illuminate/database/ClassMorphViolationException.php
@@ -0,0 +1,29 @@
+model = $class;
+    }
+}
diff --git a/vendor/illuminate/database/Concerns/BuildsQueries.php b/vendor/illuminate/database/Concerns/BuildsQueries.php
new file mode 100644
index 0000000..16dc024
--- /dev/null
+++ b/vendor/illuminate/database/Concerns/BuildsQueries.php
@@ -0,0 +1,506 @@
+enforceOrderBy();
+
+        $page = 1;
+
+        do {
+            // We'll execute the query for the given page and get the results. If there are
+            // no results we can just break and return from here. When there are results
+            // we will call the callback with the current chunk of these results here.
+            $results = $this->forPage($page, $count)->get();
+
+            $countResults = $results->count();
+
+            if ($countResults == 0) {
+                break;
+            }
+
+            // On each chunk result set, we will pass them to the callback and then let the
+            // developer take care of everything within the callback, which allows us to
+            // keep the memory low for spinning through large result sets for working.
+            if ($callback($results, $page) === false) {
+                return false;
+            }
+
+            unset($results);
+
+            $page++;
+        } while ($countResults == $count);
+
+        return true;
+    }
+
+    /**
+     * Run a map over each item while chunking.
+     *
+     * @param  callable  $callback
+     * @param  int  $count
+     * @return \Illuminate\Support\Collection
+     */
+    public function chunkMap(callable $callback, $count = 1000)
+    {
+        $collection = Collection::make();
+
+        $this->chunk($count, function ($items) use ($collection, $callback) {
+            $items->each(function ($item) use ($collection, $callback) {
+                $collection->push($callback($item));
+            });
+        });
+
+        return $collection;
+    }
+
+    /**
+     * Execute a callback over each item while chunking.
+     *
+     * @param  callable  $callback
+     * @param  int  $count
+     * @return bool
+     *
+     * @throws \RuntimeException
+     */
+    public function each(callable $callback, $count = 1000)
+    {
+        return $this->chunk($count, function ($results) use ($callback) {
+            foreach ($results as $key => $value) {
+                if ($callback($value, $key) === false) {
+                    return false;
+                }
+            }
+        });
+    }
+
+    /**
+     * Chunk the results of a query by comparing IDs.
+     *
+     * @param  int  $count
+     * @param  callable  $callback
+     * @param  string|null  $column
+     * @param  string|null  $alias
+     * @return bool
+     */
+    public function chunkById($count, callable $callback, $column = null, $alias = null)
+    {
+        $column ??= $this->defaultKeyName();
+
+        $alias ??= $column;
+
+        $lastId = null;
+
+        $page = 1;
+
+        do {
+            $clone = clone $this;
+
+            // We'll execute the query for the given page and get the results. If there are
+            // no results we can just break and return from here. When there are results
+            // we will call the callback with the current chunk of these results here.
+            $results = $clone->forPageAfterId($count, $lastId, $column)->get();
+
+            $countResults = $results->count();
+
+            if ($countResults == 0) {
+                break;
+            }
+
+            // On each chunk result set, we will pass them to the callback and then let the
+            // developer take care of everything within the callback, which allows us to
+            // keep the memory low for spinning through large result sets for working.
+            if ($callback($results, $page) === false) {
+                return false;
+            }
+
+            $lastId = data_get($results->last(), $alias);
+
+            if ($lastId === null) {
+                throw new RuntimeException("The chunkById operation was aborted because the [{$alias}] column is not present in the query result.");
+            }
+
+            unset($results);
+
+            $page++;
+        } while ($countResults == $count);
+
+        return true;
+    }
+
+    /**
+     * Execute a callback over each item while chunking by ID.
+     *
+     * @param  callable  $callback
+     * @param  int  $count
+     * @param  string|null  $column
+     * @param  string|null  $alias
+     * @return bool
+     */
+    public function eachById(callable $callback, $count = 1000, $column = null, $alias = null)
+    {
+        return $this->chunkById($count, function ($results, $page) use ($callback, $count) {
+            foreach ($results as $key => $value) {
+                if ($callback($value, (($page - 1) * $count) + $key) === false) {
+                    return false;
+                }
+            }
+        }, $column, $alias);
+    }
+
+    /**
+     * Query lazily, by chunks of the given size.
+     *
+     * @param  int  $chunkSize
+     * @return \Illuminate\Support\LazyCollection
+     *
+     * @throws \InvalidArgumentException
+     */
+    public function lazy($chunkSize = 1000)
+    {
+        if ($chunkSize < 1) {
+            throw new InvalidArgumentException('The chunk size should be at least 1');
+        }
+
+        $this->enforceOrderBy();
+
+        return LazyCollection::make(function () use ($chunkSize) {
+            $page = 1;
+
+            while (true) {
+                $results = $this->forPage($page++, $chunkSize)->get();
+
+                foreach ($results as $result) {
+                    yield $result;
+                }
+
+                if ($results->count() < $chunkSize) {
+                    return;
+                }
+            }
+        });
+    }
+
+    /**
+     * Query lazily, by chunking the results of a query by comparing IDs.
+     *
+     * @param  int  $chunkSize
+     * @param  string|null  $column
+     * @param  string|null  $alias
+     * @return \Illuminate\Support\LazyCollection
+     *
+     * @throws \InvalidArgumentException
+     */
+    public function lazyById($chunkSize = 1000, $column = null, $alias = null)
+    {
+        return $this->orderedLazyById($chunkSize, $column, $alias);
+    }
+
+    /**
+     * Query lazily, by chunking the results of a query by comparing IDs in descending order.
+     *
+     * @param  int  $chunkSize
+     * @param  string|null  $column
+     * @param  string|null  $alias
+     * @return \Illuminate\Support\LazyCollection
+     *
+     * @throws \InvalidArgumentException
+     */
+    public function lazyByIdDesc($chunkSize = 1000, $column = null, $alias = null)
+    {
+        return $this->orderedLazyById($chunkSize, $column, $alias, true);
+    }
+
+    /**
+     * Query lazily, by chunking the results of a query by comparing IDs in a given order.
+     *
+     * @param  int  $chunkSize
+     * @param  string|null  $column
+     * @param  string|null  $alias
+     * @param  bool  $descending
+     * @return \Illuminate\Support\LazyCollection
+     *
+     * @throws \InvalidArgumentException
+     */
+    protected function orderedLazyById($chunkSize = 1000, $column = null, $alias = null, $descending = false)
+    {
+        if ($chunkSize < 1) {
+            throw new InvalidArgumentException('The chunk size should be at least 1');
+        }
+
+        $column ??= $this->defaultKeyName();
+
+        $alias ??= $column;
+
+        return LazyCollection::make(function () use ($chunkSize, $column, $alias, $descending) {
+            $lastId = null;
+
+            while (true) {
+                $clone = clone $this;
+
+                if ($descending) {
+                    $results = $clone->forPageBeforeId($chunkSize, $lastId, $column)->get();
+                } else {
+                    $results = $clone->forPageAfterId($chunkSize, $lastId, $column)->get();
+                }
+
+                foreach ($results as $result) {
+                    yield $result;
+                }
+
+                if ($results->count() < $chunkSize) {
+                    return;
+                }
+
+                $lastId = $results->last()->{$alias};
+            }
+        });
+    }
+
+    /**
+     * Execute the query and get the first result.
+     *
+     * @param  array|string  $columns
+     * @return \Illuminate\Database\Eloquent\Model|object|static|null
+     */
+    public function first($columns = ['*'])
+    {
+        return $this->take(1)->get($columns)->first();
+    }
+
+    /**
+     * Execute the query and get the first result if it's the sole matching record.
+     *
+     * @param  array|string  $columns
+     * @return \Illuminate\Database\Eloquent\Model|object|static|null
+     *
+     * @throws \Illuminate\Database\RecordsNotFoundException
+     * @throws \Illuminate\Database\MultipleRecordsFoundException
+     */
+    public function sole($columns = ['*'])
+    {
+        $result = $this->take(2)->get($columns);
+
+        $count = $result->count();
+
+        if ($count === 0) {
+            throw new RecordsNotFoundException;
+        }
+
+        if ($count > 1) {
+            throw new MultipleRecordsFoundException($count);
+        }
+
+        return $result->first();
+    }
+
+    /**
+     * Paginate the given query using a cursor paginator.
+     *
+     * @param  int  $perPage
+     * @param  array|string  $columns
+     * @param  string  $cursorName
+     * @param  \Illuminate\Pagination\Cursor|string|null  $cursor
+     * @return \Illuminate\Contracts\Pagination\CursorPaginator
+     */
+    protected function paginateUsingCursor($perPage, $columns = ['*'], $cursorName = 'cursor', $cursor = null)
+    {
+        if (! $cursor instanceof Cursor) {
+            $cursor = is_string($cursor)
+                ? Cursor::fromEncoded($cursor)
+                : CursorPaginator::resolveCurrentCursor($cursorName, $cursor);
+        }
+
+        $orders = $this->ensureOrderForCursorPagination(! is_null($cursor) && $cursor->pointsToPreviousItems());
+
+        if (! is_null($cursor)) {
+            $addCursorConditions = function (self $builder, $previousColumn, $i) use (&$addCursorConditions, $cursor, $orders) {
+                $unionBuilders = isset($builder->unions) ? collect($builder->unions)->pluck('query') : collect();
+
+                if (! is_null($previousColumn)) {
+                    $originalColumn = $this->getOriginalColumnNameForCursorPagination($this, $previousColumn);
+
+                    $builder->where(
+                        Str::contains($originalColumn, ['(', ')']) ? new Expression($originalColumn) : $originalColumn,
+                        '=',
+                        $cursor->parameter($previousColumn)
+                    );
+
+                    $unionBuilders->each(function ($unionBuilder) use ($previousColumn, $cursor) {
+                        $unionBuilder->where(
+                            $this->getOriginalColumnNameForCursorPagination($this, $previousColumn),
+                            '=',
+                            $cursor->parameter($previousColumn)
+                        );
+
+                        $this->addBinding($unionBuilder->getRawBindings()['where'], 'union');
+                    });
+                }
+
+                $builder->where(function (self $builder) use ($addCursorConditions, $cursor, $orders, $i, $unionBuilders) {
+                    ['column' => $column, 'direction' => $direction] = $orders[$i];
+
+                    $originalColumn = $this->getOriginalColumnNameForCursorPagination($this, $column);
+
+                    $builder->where(
+                        Str::contains($originalColumn, ['(', ')']) ? new Expression($originalColumn) : $originalColumn,
+                        $direction === 'asc' ? '>' : '<',
+                        $cursor->parameter($column)
+                    );
+
+                    if ($i < $orders->count() - 1) {
+                        $builder->orWhere(function (self $builder) use ($addCursorConditions, $column, $i) {
+                            $addCursorConditions($builder, $column, $i + 1);
+                        });
+                    }
+
+                    $unionBuilders->each(function ($unionBuilder) use ($column, $direction, $cursor, $i, $orders, $addCursorConditions) {
+                        $unionBuilder->where(function ($unionBuilder) use ($column, $direction, $cursor, $i, $orders, $addCursorConditions) {
+                            $unionBuilder->where(
+                                $this->getOriginalColumnNameForCursorPagination($this, $column),
+                                $direction === 'asc' ? '>' : '<',
+                                $cursor->parameter($column)
+                            );
+
+                            if ($i < $orders->count() - 1) {
+                                $unionBuilder->orWhere(function (self $builder) use ($addCursorConditions, $column, $i) {
+                                    $addCursorConditions($builder, $column, $i + 1);
+                                });
+                            }
+
+                            $this->addBinding($unionBuilder->getRawBindings()['where'], 'union');
+                        });
+                    });
+                });
+            };
+
+            $addCursorConditions($this, null, 0);
+        }
+
+        $this->limit($perPage + 1);
+
+        return $this->cursorPaginator($this->get($columns), $perPage, $cursor, [
+            'path' => Paginator::resolveCurrentPath(),
+            'cursorName' => $cursorName,
+            'parameters' => $orders->pluck('column')->toArray(),
+        ]);
+    }
+
+    /**
+     * Get the original column name of the given column, without any aliasing.
+     *
+     * @param  \Illuminate\Database\Query\Builder|\Illuminate\Database\Eloquent\Builder  $builder
+     * @param  string  $parameter
+     * @return string
+     */
+    protected function getOriginalColumnNameForCursorPagination($builder, string $parameter)
+    {
+        $columns = $builder instanceof Builder ? $builder->getQuery()->columns : $builder->columns;
+
+        if (! is_null($columns)) {
+            foreach ($columns as $column) {
+                if (($position = strripos($column, ' as ')) !== false) {
+                    $original = substr($column, 0, $position);
+
+                    $alias = substr($column, $position + 4);
+
+                    if ($parameter === $alias || $builder->getGrammar()->wrap($parameter) === $alias) {
+                        return $original;
+                    }
+                }
+            }
+        }
+
+        return $parameter;
+    }
+
+    /**
+     * Create a new length-aware paginator instance.
+     *
+     * @param  \Illuminate\Support\Collection  $items
+     * @param  int  $total
+     * @param  int  $perPage
+     * @param  int  $currentPage
+     * @param  array  $options
+     * @return \Illuminate\Pagination\LengthAwarePaginator
+     */
+    protected function paginator($items, $total, $perPage, $currentPage, $options)
+    {
+        return Container::getInstance()->makeWith(LengthAwarePaginator::class, compact(
+            'items', 'total', 'perPage', 'currentPage', 'options'
+        ));
+    }
+
+    /**
+     * Create a new simple paginator instance.
+     *
+     * @param  \Illuminate\Support\Collection  $items
+     * @param  int  $perPage
+     * @param  int  $currentPage
+     * @param  array  $options
+     * @return \Illuminate\Pagination\Paginator
+     */
+    protected function simplePaginator($items, $perPage, $currentPage, $options)
+    {
+        return Container::getInstance()->makeWith(Paginator::class, compact(
+            'items', 'perPage', 'currentPage', 'options'
+        ));
+    }
+
+    /**
+     * Create a new cursor paginator instance.
+     *
+     * @param  \Illuminate\Support\Collection  $items
+     * @param  int  $perPage
+     * @param  \Illuminate\Pagination\Cursor  $cursor
+     * @param  array  $options
+     * @return \Illuminate\Pagination\CursorPaginator
+     */
+    protected function cursorPaginator($items, $perPage, $cursor, $options)
+    {
+        return Container::getInstance()->makeWith(CursorPaginator::class, compact(
+            'items', 'perPage', 'cursor', 'options'
+        ));
+    }
+
+    /**
+     * Pass the query to a given callback.
+     *
+     * @param  callable  $callback
+     * @return $this
+     */
+    public function tap($callback)
+    {
+        $callback($this);
+
+        return $this;
+    }
+}
diff --git a/vendor/illuminate/database/Concerns/CompilesJsonPaths.php b/vendor/illuminate/database/Concerns/CompilesJsonPaths.php
new file mode 100644
index 0000000..ade5461
--- /dev/null
+++ b/vendor/illuminate/database/Concerns/CompilesJsonPaths.php
@@ -0,0 +1,64 @@
+', $column, 2);
+
+        $field = $this->wrap($parts[0]);
+
+        $path = count($parts) > 1 ? ', '.$this->wrapJsonPath($parts[1], '->') : '';
+
+        return [$field, $path];
+    }
+
+    /**
+     * Wrap the given JSON path.
+     *
+     * @param  string  $value
+     * @param  string  $delimiter
+     * @return string
+     */
+    protected function wrapJsonPath($value, $delimiter = '->')
+    {
+        $value = preg_replace("/([\\\\]+)?\\'/", "''", $value);
+
+        $jsonPath = collect(explode($delimiter, $value))
+            ->map(fn ($segment) => $this->wrapJsonPathSegment($segment))
+            ->join('.');
+
+        return "'$".(str_starts_with($jsonPath, '[') ? '' : '.').$jsonPath."'";
+    }
+
+    /**
+     * Wrap the given JSON path segment.
+     *
+     * @param  string  $segment
+     * @return string
+     */
+    protected function wrapJsonPathSegment($segment)
+    {
+        if (preg_match('/(\[[^\]]+\])+$/', $segment, $parts)) {
+            $key = Str::beforeLast($segment, $parts[0]);
+
+            if (! empty($key)) {
+                return '"'.$key.'"'.$parts[0];
+            }
+
+            return $parts[0];
+        }
+
+        return '"'.$segment.'"';
+    }
+}
diff --git a/vendor/illuminate/database/Concerns/ExplainsQueries.php b/vendor/illuminate/database/Concerns/ExplainsQueries.php
new file mode 100644
index 0000000..7168de1
--- /dev/null
+++ b/vendor/illuminate/database/Concerns/ExplainsQueries.php
@@ -0,0 +1,24 @@
+toSql();
+
+        $bindings = $this->getBindings();
+
+        $explanation = $this->getConnection()->select('EXPLAIN '.$sql, $bindings);
+
+        return new Collection($explanation);
+    }
+}
diff --git a/vendor/illuminate/database/Concerns/ManagesTransactions.php b/vendor/illuminate/database/Concerns/ManagesTransactions.php
new file mode 100644
index 0000000..14661cc
--- /dev/null
+++ b/vendor/illuminate/database/Concerns/ManagesTransactions.php
@@ -0,0 +1,352 @@
+beginTransaction();
+
+            // We'll simply execute the given callback within a try / catch block and if we
+            // catch any exception we can rollback this transaction so that none of this
+            // gets actually persisted to a database or stored in a permanent fashion.
+            try {
+                $callbackResult = $callback($this);
+            }
+
+            // If we catch an exception we'll rollback this transaction and try again if we
+            // are not out of attempts. If we are out of attempts we will just throw the
+            // exception back out, and let the developer handle an uncaught exception.
+            catch (Throwable $e) {
+                $this->handleTransactionException(
+                    $e, $currentAttempt, $attempts
+                );
+
+                continue;
+            }
+
+            try {
+                if ($this->transactions == 1) {
+                    $this->fireConnectionEvent('committing');
+                    $this->getPdo()->commit();
+                }
+
+                $this->transactions = max(0, $this->transactions - 1);
+
+                if ($this->afterCommitCallbacksShouldBeExecuted()) {
+                    $this->transactionsManager?->commit($this->getName());
+                }
+            } catch (Throwable $e) {
+                $this->handleCommitTransactionException(
+                    $e, $currentAttempt, $attempts
+                );
+
+                continue;
+            }
+
+            $this->fireConnectionEvent('committed');
+
+            return $callbackResult;
+        }
+    }
+
+    /**
+     * Handle an exception encountered when running a transacted statement.
+     *
+     * @param  \Throwable  $e
+     * @param  int  $currentAttempt
+     * @param  int  $maxAttempts
+     * @return void
+     *
+     * @throws \Throwable
+     */
+    protected function handleTransactionException(Throwable $e, $currentAttempt, $maxAttempts)
+    {
+        // On a deadlock, MySQL rolls back the entire transaction so we can't just
+        // retry the query. We have to throw this exception all the way out and
+        // let the developer handle it in another way. We will decrement too.
+        if ($this->causedByConcurrencyError($e) &&
+            $this->transactions > 1) {
+            $this->transactions--;
+
+            $this->transactionsManager?->rollback(
+                $this->getName(), $this->transactions
+            );
+
+            throw new DeadlockException($e->getMessage(), is_int($e->getCode()) ? $e->getCode() : 0, $e);
+        }
+
+        // If there was an exception we will rollback this transaction and then we
+        // can check if we have exceeded the maximum attempt count for this and
+        // if we haven't we will return and try this query again in our loop.
+        $this->rollBack();
+
+        if ($this->causedByConcurrencyError($e) &&
+            $currentAttempt < $maxAttempts) {
+            return;
+        }
+
+        throw $e;
+    }
+
+    /**
+     * Start a new database transaction.
+     *
+     * @return void
+     *
+     * @throws \Throwable
+     */
+    public function beginTransaction()
+    {
+        $this->createTransaction();
+
+        $this->transactions++;
+
+        $this->transactionsManager?->begin(
+            $this->getName(), $this->transactions
+        );
+
+        $this->fireConnectionEvent('beganTransaction');
+    }
+
+    /**
+     * Create a transaction within the database.
+     *
+     * @return void
+     *
+     * @throws \Throwable
+     */
+    protected function createTransaction()
+    {
+        if ($this->transactions == 0) {
+            $this->reconnectIfMissingConnection();
+
+            try {
+                $this->getPdo()->beginTransaction();
+            } catch (Throwable $e) {
+                $this->handleBeginTransactionException($e);
+            }
+        } elseif ($this->transactions >= 1 && $this->queryGrammar->supportsSavepoints()) {
+            $this->createSavepoint();
+        }
+    }
+
+    /**
+     * Create a save point within the database.
+     *
+     * @return void
+     *
+     * @throws \Throwable
+     */
+    protected function createSavepoint()
+    {
+        $this->getPdo()->exec(
+            $this->queryGrammar->compileSavepoint('trans'.($this->transactions + 1))
+        );
+    }
+
+    /**
+     * Handle an exception from a transaction beginning.
+     *
+     * @param  \Throwable  $e
+     * @return void
+     *
+     * @throws \Throwable
+     */
+    protected function handleBeginTransactionException(Throwable $e)
+    {
+        if ($this->causedByLostConnection($e)) {
+            $this->reconnect();
+
+            $this->getPdo()->beginTransaction();
+        } else {
+            throw $e;
+        }
+    }
+
+    /**
+     * Commit the active database transaction.
+     *
+     * @return void
+     *
+     * @throws \Throwable
+     */
+    public function commit()
+    {
+        if ($this->transactionLevel() == 1) {
+            $this->fireConnectionEvent('committing');
+            $this->getPdo()->commit();
+        }
+
+        $this->transactions = max(0, $this->transactions - 1);
+
+        if ($this->afterCommitCallbacksShouldBeExecuted()) {
+            $this->transactionsManager?->commit($this->getName());
+        }
+
+        $this->fireConnectionEvent('committed');
+    }
+
+    /**
+     * Determine if after commit callbacks should be executed.
+     *
+     * @return bool
+     */
+    protected function afterCommitCallbacksShouldBeExecuted()
+    {
+        return $this->transactions == 0 ||
+            ($this->transactionsManager &&
+             $this->transactionsManager->callbackApplicableTransactions()->count() === 1);
+    }
+
+    /**
+     * Handle an exception encountered when committing a transaction.
+     *
+     * @param  \Throwable  $e
+     * @param  int  $currentAttempt
+     * @param  int  $maxAttempts
+     * @return void
+     *
+     * @throws \Throwable
+     */
+    protected function handleCommitTransactionException(Throwable $e, $currentAttempt, $maxAttempts)
+    {
+        $this->transactions = max(0, $this->transactions - 1);
+
+        if ($this->causedByConcurrencyError($e) && $currentAttempt < $maxAttempts) {
+            return;
+        }
+
+        if ($this->causedByLostConnection($e)) {
+            $this->transactions = 0;
+        }
+
+        throw $e;
+    }
+
+    /**
+     * Rollback the active database transaction.
+     *
+     * @param  int|null  $toLevel
+     * @return void
+     *
+     * @throws \Throwable
+     */
+    public function rollBack($toLevel = null)
+    {
+        // We allow developers to rollback to a certain transaction level. We will verify
+        // that this given transaction level is valid before attempting to rollback to
+        // that level. If it's not we will just return out and not attempt anything.
+        $toLevel = is_null($toLevel)
+                    ? $this->transactions - 1
+                    : $toLevel;
+
+        if ($toLevel < 0 || $toLevel >= $this->transactions) {
+            return;
+        }
+
+        // Next, we will actually perform this rollback within this database and fire the
+        // rollback event. We will also set the current transaction level to the given
+        // level that was passed into this method so it will be right from here out.
+        try {
+            $this->performRollBack($toLevel);
+        } catch (Throwable $e) {
+            $this->handleRollBackException($e);
+        }
+
+        $this->transactions = $toLevel;
+
+        $this->transactionsManager?->rollback(
+            $this->getName(), $this->transactions
+        );
+
+        $this->fireConnectionEvent('rollingBack');
+    }
+
+    /**
+     * Perform a rollback within the database.
+     *
+     * @param  int  $toLevel
+     * @return void
+     *
+     * @throws \Throwable
+     */
+    protected function performRollBack($toLevel)
+    {
+        if ($toLevel == 0) {
+            $pdo = $this->getPdo();
+
+            if ($pdo->inTransaction()) {
+                $pdo->rollBack();
+            }
+        } elseif ($this->queryGrammar->supportsSavepoints()) {
+            $this->getPdo()->exec(
+                $this->queryGrammar->compileSavepointRollBack('trans'.($toLevel + 1))
+            );
+        }
+    }
+
+    /**
+     * Handle an exception from a rollback.
+     *
+     * @param  \Throwable  $e
+     * @return void
+     *
+     * @throws \Throwable
+     */
+    protected function handleRollBackException(Throwable $e)
+    {
+        if ($this->causedByLostConnection($e)) {
+            $this->transactions = 0;
+
+            $this->transactionsManager?->rollback(
+                $this->getName(), $this->transactions
+            );
+        }
+
+        throw $e;
+    }
+
+    /**
+     * Get the number of active transactions.
+     *
+     * @return int
+     */
+    public function transactionLevel()
+    {
+        return $this->transactions;
+    }
+
+    /**
+     * Execute the callback after a transaction commits.
+     *
+     * @param  callable  $callback
+     * @return void
+     *
+     * @throws \RuntimeException
+     */
+    public function afterCommit($callback)
+    {
+        if ($this->transactionsManager) {
+            return $this->transactionsManager->addCallback($callback);
+        }
+
+        throw new RuntimeException('Transactions Manager has not been set.');
+    }
+}
diff --git a/vendor/illuminate/database/Concerns/ParsesSearchPath.php b/vendor/illuminate/database/Concerns/ParsesSearchPath.php
new file mode 100644
index 0000000..e822c72
--- /dev/null
+++ b/vendor/illuminate/database/Concerns/ParsesSearchPath.php
@@ -0,0 +1,25 @@
+
+     */
+    protected $doctrineTypeMappings = [];
+
+    /**
+     * The connection resolvers.
+     *
+     * @var \Closure[]
+     */
+    protected static $resolvers = [];
+
+    /**
+     * Create a new database connection instance.
+     *
+     * @param  \PDO|\Closure  $pdo
+     * @param  string  $database
+     * @param  string  $tablePrefix
+     * @param  array  $config
+     * @return void
+     */
+    public function __construct($pdo, $database = '', $tablePrefix = '', array $config = [])
+    {
+        $this->pdo = $pdo;
+
+        // First we will setup the default properties. We keep track of the DB
+        // name we are connected to since it is needed when some reflective
+        // type commands are run such as checking whether a table exists.
+        $this->database = $database;
+
+        $this->tablePrefix = $tablePrefix;
+
+        $this->config = $config;
+
+        // We need to initialize a query grammar and the query post processors
+        // which are both very important parts of the database abstractions
+        // so we initialize these to their default values while starting.
+        $this->useDefaultQueryGrammar();
+
+        $this->useDefaultPostProcessor();
+    }
+
+    /**
+     * Set the query grammar to the default implementation.
+     *
+     * @return void
+     */
+    public function useDefaultQueryGrammar()
+    {
+        $this->queryGrammar = $this->getDefaultQueryGrammar();
+    }
+
+    /**
+     * Get the default query grammar instance.
+     *
+     * @return \Illuminate\Database\Query\Grammars\Grammar
+     */
+    protected function getDefaultQueryGrammar()
+    {
+        return new QueryGrammar;
+    }
+
+    /**
+     * Set the schema grammar to the default implementation.
+     *
+     * @return void
+     */
+    public function useDefaultSchemaGrammar()
+    {
+        $this->schemaGrammar = $this->getDefaultSchemaGrammar();
+    }
+
+    /**
+     * Get the default schema grammar instance.
+     *
+     * @return \Illuminate\Database\Schema\Grammars\Grammar
+     */
+    protected function getDefaultSchemaGrammar()
+    {
+        //
+    }
+
+    /**
+     * Set the query post processor to the default implementation.
+     *
+     * @return void
+     */
+    public function useDefaultPostProcessor()
+    {
+        $this->postProcessor = $this->getDefaultPostProcessor();
+    }
+
+    /**
+     * Get the default post processor instance.
+     *
+     * @return \Illuminate\Database\Query\Processors\Processor
+     */
+    protected function getDefaultPostProcessor()
+    {
+        return new Processor;
+    }
+
+    /**
+     * Get a schema builder instance for the connection.
+     *
+     * @return \Illuminate\Database\Schema\Builder
+     */
+    public function getSchemaBuilder()
+    {
+        if (is_null($this->schemaGrammar)) {
+            $this->useDefaultSchemaGrammar();
+        }
+
+        return new SchemaBuilder($this);
+    }
+
+    /**
+     * Begin a fluent query against a database table.
+     *
+     * @param  \Closure|\Illuminate\Database\Query\Builder|string  $table
+     * @param  string|null  $as
+     * @return \Illuminate\Database\Query\Builder
+     */
+    public function table($table, $as = null)
+    {
+        return $this->query()->from($table, $as);
+    }
+
+    /**
+     * Get a new query builder instance.
+     *
+     * @return \Illuminate\Database\Query\Builder
+     */
+    public function query()
+    {
+        return new QueryBuilder(
+            $this, $this->getQueryGrammar(), $this->getPostProcessor()
+        );
+    }
+
+    /**
+     * Run a select statement and return a single result.
+     *
+     * @param  string  $query
+     * @param  array  $bindings
+     * @param  bool  $useReadPdo
+     * @return mixed
+     */
+    public function selectOne($query, $bindings = [], $useReadPdo = true)
+    {
+        $records = $this->select($query, $bindings, $useReadPdo);
+
+        return array_shift($records);
+    }
+
+    /**
+     * Run a select statement and return the first column of the first row.
+     *
+     * @param  string  $query
+     * @param  array  $bindings
+     * @param  bool  $useReadPdo
+     * @return mixed
+     *
+     * @throws \Illuminate\Database\MultipleColumnsSelectedException
+     */
+    public function scalar($query, $bindings = [], $useReadPdo = true)
+    {
+        $record = $this->selectOne($query, $bindings, $useReadPdo);
+
+        if (is_null($record)) {
+            return null;
+        }
+
+        $record = (array) $record;
+
+        if (count($record) > 1) {
+            throw new MultipleColumnsSelectedException;
+        }
+
+        return reset($record);
+    }
+
+    /**
+     * Run a select statement against the database.
+     *
+     * @param  string  $query
+     * @param  array  $bindings
+     * @return array
+     */
+    public function selectFromWriteConnection($query, $bindings = [])
+    {
+        return $this->select($query, $bindings, false);
+    }
+
+    /**
+     * Run a select statement against the database.
+     *
+     * @param  string  $query
+     * @param  array  $bindings
+     * @param  bool  $useReadPdo
+     * @return array
+     */
+    public function select($query, $bindings = [], $useReadPdo = true)
+    {
+        return $this->run($query, $bindings, function ($query, $bindings) use ($useReadPdo) {
+            if ($this->pretending()) {
+                return [];
+            }
+
+            // For select statements, we'll simply execute the query and return an array
+            // of the database result set. Each element in the array will be a single
+            // row from the database table, and will either be an array or objects.
+            $statement = $this->prepared(
+                $this->getPdoForSelect($useReadPdo)->prepare($query)
+            );
+
+            $this->bindValues($statement, $this->prepareBindings($bindings));
+
+            $statement->execute();
+
+            return $statement->fetchAll();
+        });
+    }
+
+    /**
+     * Run a select statement against the database and returns a generator.
+     *
+     * @param  string  $query
+     * @param  array  $bindings
+     * @param  bool  $useReadPdo
+     * @return \Generator
+     */
+    public function cursor($query, $bindings = [], $useReadPdo = true)
+    {
+        $statement = $this->run($query, $bindings, function ($query, $bindings) use ($useReadPdo) {
+            if ($this->pretending()) {
+                return [];
+            }
+
+            // First we will create a statement for the query. Then, we will set the fetch
+            // mode and prepare the bindings for the query. Once that's done we will be
+            // ready to execute the query against the database and return the cursor.
+            $statement = $this->prepared($this->getPdoForSelect($useReadPdo)
+                              ->prepare($query));
+
+            $this->bindValues(
+                $statement, $this->prepareBindings($bindings)
+            );
+
+            // Next, we'll execute the query against the database and return the statement
+            // so we can return the cursor. The cursor will use a PHP generator to give
+            // back one row at a time without using a bunch of memory to render them.
+            $statement->execute();
+
+            return $statement;
+        });
+
+        while ($record = $statement->fetch()) {
+            yield $record;
+        }
+    }
+
+    /**
+     * Configure the PDO prepared statement.
+     *
+     * @param  \PDOStatement  $statement
+     * @return \PDOStatement
+     */
+    protected function prepared(PDOStatement $statement)
+    {
+        $statement->setFetchMode($this->fetchMode);
+
+        $this->event(new StatementPrepared($this, $statement));
+
+        return $statement;
+    }
+
+    /**
+     * Get the PDO connection to use for a select query.
+     *
+     * @param  bool  $useReadPdo
+     * @return \PDO
+     */
+    protected function getPdoForSelect($useReadPdo = true)
+    {
+        return $useReadPdo ? $this->getReadPdo() : $this->getPdo();
+    }
+
+    /**
+     * Run an insert statement against the database.
+     *
+     * @param  string  $query
+     * @param  array  $bindings
+     * @return bool
+     */
+    public function insert($query, $bindings = [])
+    {
+        return $this->statement($query, $bindings);
+    }
+
+    /**
+     * Run an update statement against the database.
+     *
+     * @param  string  $query
+     * @param  array  $bindings
+     * @return int
+     */
+    public function update($query, $bindings = [])
+    {
+        return $this->affectingStatement($query, $bindings);
+    }
+
+    /**
+     * Run a delete statement against the database.
+     *
+     * @param  string  $query
+     * @param  array  $bindings
+     * @return int
+     */
+    public function delete($query, $bindings = [])
+    {
+        return $this->affectingStatement($query, $bindings);
+    }
+
+    /**
+     * Execute an SQL statement and return the boolean result.
+     *
+     * @param  string  $query
+     * @param  array  $bindings
+     * @return bool
+     */
+    public function statement($query, $bindings = [])
+    {
+        return $this->run($query, $bindings, function ($query, $bindings) {
+            if ($this->pretending()) {
+                return true;
+            }
+
+            $statement = $this->getPdo()->prepare($query);
+
+            $this->bindValues($statement, $this->prepareBindings($bindings));
+
+            $this->recordsHaveBeenModified();
+
+            return $statement->execute();
+        });
+    }
+
+    /**
+     * Run an SQL statement and get the number of rows affected.
+     *
+     * @param  string  $query
+     * @param  array  $bindings
+     * @return int
+     */
+    public function affectingStatement($query, $bindings = [])
+    {
+        return $this->run($query, $bindings, function ($query, $bindings) {
+            if ($this->pretending()) {
+                return 0;
+            }
+
+            // For update or delete statements, we want to get the number of rows affected
+            // by the statement and return that back to the developer. We'll first need
+            // to execute the statement and then we'll use PDO to fetch the affected.
+            $statement = $this->getPdo()->prepare($query);
+
+            $this->bindValues($statement, $this->prepareBindings($bindings));
+
+            $statement->execute();
+
+            $this->recordsHaveBeenModified(
+                ($count = $statement->rowCount()) > 0
+            );
+
+            return $count;
+        });
+    }
+
+    /**
+     * Run a raw, unprepared query against the PDO connection.
+     *
+     * @param  string  $query
+     * @return bool
+     */
+    public function unprepared($query)
+    {
+        return $this->run($query, [], function ($query) {
+            if ($this->pretending()) {
+                return true;
+            }
+
+            $this->recordsHaveBeenModified(
+                $change = $this->getPdo()->exec($query) !== false
+            );
+
+            return $change;
+        });
+    }
+
+    /**
+     * Execute the given callback in "dry run" mode.
+     *
+     * @param  \Closure  $callback
+     * @return array
+     */
+    public function pretend(Closure $callback)
+    {
+        return $this->withFreshQueryLog(function () use ($callback) {
+            $this->pretending = true;
+
+            // Basically to make the database connection "pretend", we will just return
+            // the default values for all the query methods, then we will return an
+            // array of queries that were "executed" within the Closure callback.
+            $callback($this);
+
+            $this->pretending = false;
+
+            return $this->queryLog;
+        });
+    }
+
+    /**
+     * Execute the given callback in "dry run" mode.
+     *
+     * @param  \Closure  $callback
+     * @return array
+     */
+    protected function withFreshQueryLog($callback)
+    {
+        $loggingQueries = $this->loggingQueries;
+
+        // First we will back up the value of the logging queries property and then
+        // we'll be ready to run callbacks. This query log will also get cleared
+        // so we will have a new log of all the queries that are executed now.
+        $this->enableQueryLog();
+
+        $this->queryLog = [];
+
+        // Now we'll execute this callback and capture the result. Once it has been
+        // executed we will restore the value of query logging and give back the
+        // value of the callback so the original callers can have the results.
+        $result = $callback();
+
+        $this->loggingQueries = $loggingQueries;
+
+        return $result;
+    }
+
+    /**
+     * Bind values to their parameters in the given statement.
+     *
+     * @param  \PDOStatement  $statement
+     * @param  array  $bindings
+     * @return void
+     */
+    public function bindValues($statement, $bindings)
+    {
+        foreach ($bindings as $key => $value) {
+            $statement->bindValue(
+                is_string($key) ? $key : $key + 1,
+                $value,
+                match (true) {
+                    is_int($value) => PDO::PARAM_INT,
+                    is_resource($value) => PDO::PARAM_LOB,
+                    default => PDO::PARAM_STR
+                },
+            );
+        }
+    }
+
+    /**
+     * Prepare the query bindings for execution.
+     *
+     * @param  array  $bindings
+     * @return array
+     */
+    public function prepareBindings(array $bindings)
+    {
+        $grammar = $this->getQueryGrammar();
+
+        foreach ($bindings as $key => $value) {
+            // We need to transform all instances of DateTimeInterface into the actual
+            // date string. Each query grammar maintains its own date string format
+            // so we'll just ask the grammar for the format to get from the date.
+            if ($value instanceof DateTimeInterface) {
+                $bindings[$key] = $value->format($grammar->getDateFormat());
+            } elseif (is_bool($value)) {
+                $bindings[$key] = (int) $value;
+            }
+        }
+
+        return $bindings;
+    }
+
+    /**
+     * Run a SQL statement and log its execution context.
+     *
+     * @param  string  $query
+     * @param  array  $bindings
+     * @param  \Closure  $callback
+     * @return mixed
+     *
+     * @throws \Illuminate\Database\QueryException
+     */
+    protected function run($query, $bindings, Closure $callback)
+    {
+        foreach ($this->beforeExecutingCallbacks as $beforeExecutingCallback) {
+            $beforeExecutingCallback($query, $bindings, $this);
+        }
+
+        $this->reconnectIfMissingConnection();
+
+        $start = microtime(true);
+
+        // Here we will run this query. If an exception occurs we'll determine if it was
+        // caused by a connection that has been lost. If that is the cause, we'll try
+        // to re-establish connection and re-run the query with a fresh connection.
+        try {
+            $result = $this->runQueryCallback($query, $bindings, $callback);
+        } catch (QueryException $e) {
+            $result = $this->handleQueryException(
+                $e, $query, $bindings, $callback
+            );
+        }
+
+        // Once we have run the query we will calculate the time that it took to run and
+        // then log the query, bindings, and execution time so we will report them on
+        // the event that the developer needs them. We'll log time in milliseconds.
+        $this->logQuery(
+            $query, $bindings, $this->getElapsedTime($start)
+        );
+
+        return $result;
+    }
+
+    /**
+     * Run a SQL statement.
+     *
+     * @param  string  $query
+     * @param  array  $bindings
+     * @param  \Closure  $callback
+     * @return mixed
+     *
+     * @throws \Illuminate\Database\QueryException
+     */
+    protected function runQueryCallback($query, $bindings, Closure $callback)
+    {
+        // To execute the statement, we'll simply call the callback, which will actually
+        // run the SQL against the PDO connection. Then we can calculate the time it
+        // took to execute and log the query SQL, bindings and time in our memory.
+        try {
+            return $callback($query, $bindings);
+        }
+
+        // If an exception occurs when attempting to run a query, we'll format the error
+        // message to include the bindings with SQL, which will make this exception a
+        // lot more helpful to the developer instead of just the database's errors.
+        catch (Exception $e) {
+            throw new QueryException(
+                $query, $this->prepareBindings($bindings), $e
+            );
+        }
+    }
+
+    /**
+     * Log a query in the connection's query log.
+     *
+     * @param  string  $query
+     * @param  array  $bindings
+     * @param  float|null  $time
+     * @return void
+     */
+    public function logQuery($query, $bindings, $time = null)
+    {
+        $this->totalQueryDuration += $time ?? 0.0;
+
+        $this->event(new QueryExecuted($query, $bindings, $time, $this));
+
+        if ($this->loggingQueries) {
+            $this->queryLog[] = compact('query', 'bindings', 'time');
+        }
+    }
+
+    /**
+     * Get the elapsed time since a given starting point.
+     *
+     * @param  int  $start
+     * @return float
+     */
+    protected function getElapsedTime($start)
+    {
+        return round((microtime(true) - $start) * 1000, 2);
+    }
+
+    /**
+     * Register a callback to be invoked when the connection queries for longer than a given amount of time.
+     *
+     * @param  \DateTimeInterface|\Carbon\CarbonInterval|float|int  $threshold
+     * @param  callable  $handler
+     * @return void
+     */
+    public function whenQueryingForLongerThan($threshold, $handler)
+    {
+        $threshold = $threshold instanceof DateTimeInterface
+            ? $this->secondsUntil($threshold) * 1000
+            : $threshold;
+
+        $threshold = $threshold instanceof CarbonInterval
+            ? $threshold->totalMilliseconds
+            : $threshold;
+
+        $this->queryDurationHandlers[] = [
+            'has_run' => false,
+            'handler' => $handler,
+        ];
+
+        $key = count($this->queryDurationHandlers) - 1;
+
+        $this->listen(function ($event) use ($threshold, $handler, $key) {
+            if (! $this->queryDurationHandlers[$key]['has_run'] && $this->totalQueryDuration() > $threshold) {
+                $handler($this, $event);
+
+                $this->queryDurationHandlers[$key]['has_run'] = true;
+            }
+        });
+    }
+
+    /**
+     * Allow all the query duration handlers to run again, even if they have already run.
+     *
+     * @return void
+     */
+    public function allowQueryDurationHandlersToRunAgain()
+    {
+        foreach ($this->queryDurationHandlers as $key => $queryDurationHandler) {
+            $this->queryDurationHandlers[$key]['has_run'] = false;
+        }
+    }
+
+    /**
+     * Get the duration of all run queries in milliseconds.
+     *
+     * @return float
+     */
+    public function totalQueryDuration()
+    {
+        return $this->totalQueryDuration;
+    }
+
+    /**
+     * Reset the duration of all run queries.
+     *
+     * @return void
+     */
+    public function resetTotalQueryDuration()
+    {
+        $this->totalQueryDuration = 0.0;
+    }
+
+    /**
+     * Handle a query exception.
+     *
+     * @param  \Illuminate\Database\QueryException  $e
+     * @param  string  $query
+     * @param  array  $bindings
+     * @param  \Closure  $callback
+     * @return mixed
+     *
+     * @throws \Illuminate\Database\QueryException
+     */
+    protected function handleQueryException(QueryException $e, $query, $bindings, Closure $callback)
+    {
+        if ($this->transactions >= 1) {
+            throw $e;
+        }
+
+        return $this->tryAgainIfCausedByLostConnection(
+            $e, $query, $bindings, $callback
+        );
+    }
+
+    /**
+     * Handle a query exception that occurred during query execution.
+     *
+     * @param  \Illuminate\Database\QueryException  $e
+     * @param  string  $query
+     * @param  array  $bindings
+     * @param  \Closure  $callback
+     * @return mixed
+     *
+     * @throws \Illuminate\Database\QueryException
+     */
+    protected function tryAgainIfCausedByLostConnection(QueryException $e, $query, $bindings, Closure $callback)
+    {
+        if ($this->causedByLostConnection($e->getPrevious())) {
+            $this->reconnect();
+
+            return $this->runQueryCallback($query, $bindings, $callback);
+        }
+
+        throw $e;
+    }
+
+    /**
+     * Reconnect to the database.
+     *
+     * @return mixed|false
+     *
+     * @throws \Illuminate\Database\LostConnectionException
+     */
+    public function reconnect()
+    {
+        if (is_callable($this->reconnector)) {
+            $this->doctrineConnection = null;
+
+            return call_user_func($this->reconnector, $this);
+        }
+
+        throw new LostConnectionException('Lost connection and no reconnector available.');
+    }
+
+    /**
+     * Reconnect to the database if a PDO connection is missing.
+     *
+     * @return void
+     */
+    protected function reconnectIfMissingConnection()
+    {
+        if (is_null($this->pdo)) {
+            $this->reconnect();
+        }
+    }
+
+    /**
+     * Disconnect from the underlying PDO connection.
+     *
+     * @return void
+     */
+    public function disconnect()
+    {
+        $this->setPdo(null)->setReadPdo(null);
+
+        $this->doctrineConnection = null;
+    }
+
+    /**
+     * Register a hook to be run just before a database query is executed.
+     *
+     * @param  \Closure  $callback
+     * @return $this
+     */
+    public function beforeExecuting(Closure $callback)
+    {
+        $this->beforeExecutingCallbacks[] = $callback;
+
+        return $this;
+    }
+
+    /**
+     * Register a database query listener with the connection.
+     *
+     * @param  \Closure  $callback
+     * @return void
+     */
+    public function listen(Closure $callback)
+    {
+        $this->events?->listen(Events\QueryExecuted::class, $callback);
+    }
+
+    /**
+     * Fire an event for this connection.
+     *
+     * @param  string  $event
+     * @return array|null
+     */
+    protected function fireConnectionEvent($event)
+    {
+        return $this->events?->dispatch(match ($event) {
+            'beganTransaction' => new TransactionBeginning($this),
+            'committed' => new TransactionCommitted($this),
+            'committing' => new TransactionCommitting($this),
+            'rollingBack' => new TransactionRolledBack($this),
+            default => null,
+        });
+    }
+
+    /**
+     * Fire the given event if possible.
+     *
+     * @param  mixed  $event
+     * @return void
+     */
+    protected function event($event)
+    {
+        $this->events?->dispatch($event);
+    }
+
+    /**
+     * Get a new raw query expression.
+     *
+     * @param  mixed  $value
+     * @return \Illuminate\Database\Query\Expression
+     */
+    public function raw($value)
+    {
+        return new Expression($value);
+    }
+
+    /**
+     * Determine if the database connection has modified any database records.
+     *
+     * @return bool
+     */
+    public function hasModifiedRecords()
+    {
+        return $this->recordsModified;
+    }
+
+    /**
+     * Indicate if any records have been modified.
+     *
+     * @param  bool  $value
+     * @return void
+     */
+    public function recordsHaveBeenModified($value = true)
+    {
+        if (! $this->recordsModified) {
+            $this->recordsModified = $value;
+        }
+    }
+
+    /**
+     * Set the record modification state.
+     *
+     * @param  bool  $value
+     * @return $this
+     */
+    public function setRecordModificationState(bool $value)
+    {
+        $this->recordsModified = $value;
+
+        return $this;
+    }
+
+    /**
+     * Reset the record modification state.
+     *
+     * @return void
+     */
+    public function forgetRecordModificationState()
+    {
+        $this->recordsModified = false;
+    }
+
+    /**
+     * Indicate that the connection should use the write PDO connection for reads.
+     *
+     * @param  bool  $value
+     * @return $this
+     */
+    public function useWriteConnectionWhenReading($value = true)
+    {
+        $this->readOnWriteConnection = $value;
+
+        return $this;
+    }
+
+    /**
+     * Is Doctrine available?
+     *
+     * @return bool
+     */
+    public function isDoctrineAvailable()
+    {
+        return class_exists('Doctrine\DBAL\Connection');
+    }
+
+    /**
+     * Indicates whether native alter operations will be used when dropping or renaming columns, even if Doctrine DBAL is installed.
+     *
+     * @return bool
+     */
+    public function usingNativeSchemaOperations()
+    {
+        return ! $this->isDoctrineAvailable() || SchemaBuilder::$alwaysUsesNativeSchemaOperationsIfPossible;
+    }
+
+    /**
+     * Get a Doctrine Schema Column instance.
+     *
+     * @param  string  $table
+     * @param  string  $column
+     * @return \Doctrine\DBAL\Schema\Column
+     */
+    public function getDoctrineColumn($table, $column)
+    {
+        $schema = $this->getDoctrineSchemaManager();
+
+        return $schema->listTableDetails($table)->getColumn($column);
+    }
+
+    /**
+     * Get the Doctrine DBAL schema manager for the connection.
+     *
+     * @return \Doctrine\DBAL\Schema\AbstractSchemaManager
+     */
+    public function getDoctrineSchemaManager()
+    {
+        $connection = $this->getDoctrineConnection();
+
+        // Doctrine v2 expects one parameter while v3 expects two. 2nd will be ignored on v2...
+        return $this->getDoctrineDriver()->getSchemaManager(
+            $connection,
+            $connection->getDatabasePlatform()
+        );
+    }
+
+    /**
+     * Get the Doctrine DBAL database connection instance.
+     *
+     * @return \Doctrine\DBAL\Connection
+     */
+    public function getDoctrineConnection()
+    {
+        if (is_null($this->doctrineConnection)) {
+            $driver = $this->getDoctrineDriver();
+
+            $this->doctrineConnection = new DoctrineConnection(array_filter([
+                'pdo' => $this->getPdo(),
+                'dbname' => $this->getDatabaseName(),
+                'driver' => $driver->getName(),
+                'serverVersion' => $this->getConfig('server_version'),
+            ]), $driver);
+
+            foreach ($this->doctrineTypeMappings as $name => $type) {
+                $this->doctrineConnection
+                    ->getDatabasePlatform()
+                    ->registerDoctrineTypeMapping($type, $name);
+            }
+        }
+
+        return $this->doctrineConnection;
+    }
+
+    /**
+     * Register a custom Doctrine mapping type.
+     *
+     * @param  Type|class-string  $class
+     * @param  string  $name
+     * @param  string  $type
+     * @return void
+     *
+     * @throws \Doctrine\DBAL\DBALException
+     * @throws \RuntimeException
+     */
+    public function registerDoctrineType(Type|string $class, string $name, string $type): void
+    {
+        if (! $this->isDoctrineAvailable()) {
+            throw new RuntimeException(
+                'Registering a custom Doctrine type requires Doctrine DBAL (doctrine/dbal).'
+            );
+        }
+
+        if (! Type::hasType($name)) {
+            Type::getTypeRegistry()
+                ->register($name, is_string($class) ? new $class() : $class);
+        }
+
+        $this->doctrineTypeMappings[$name] = $type;
+    }
+
+    /**
+     * Get the current PDO connection.
+     *
+     * @return \PDO
+     */
+    public function getPdo()
+    {
+        if ($this->pdo instanceof Closure) {
+            return $this->pdo = call_user_func($this->pdo);
+        }
+
+        return $this->pdo;
+    }
+
+    /**
+     * Get the current PDO connection parameter without executing any reconnect logic.
+     *
+     * @return \PDO|\Closure|null
+     */
+    public function getRawPdo()
+    {
+        return $this->pdo;
+    }
+
+    /**
+     * Get the current PDO connection used for reading.
+     *
+     * @return \PDO
+     */
+    public function getReadPdo()
+    {
+        if ($this->transactions > 0) {
+            return $this->getPdo();
+        }
+
+        if ($this->readOnWriteConnection ||
+            ($this->recordsModified && $this->getConfig('sticky'))) {
+            return $this->getPdo();
+        }
+
+        if ($this->readPdo instanceof Closure) {
+            return $this->readPdo = call_user_func($this->readPdo);
+        }
+
+        return $this->readPdo ?: $this->getPdo();
+    }
+
+    /**
+     * Get the current read PDO connection parameter without executing any reconnect logic.
+     *
+     * @return \PDO|\Closure|null
+     */
+    public function getRawReadPdo()
+    {
+        return $this->readPdo;
+    }
+
+    /**
+     * Set the PDO connection.
+     *
+     * @param  \PDO|\Closure|null  $pdo
+     * @return $this
+     */
+    public function setPdo($pdo)
+    {
+        $this->transactions = 0;
+
+        $this->pdo = $pdo;
+
+        return $this;
+    }
+
+    /**
+     * Set the PDO connection used for reading.
+     *
+     * @param  \PDO|\Closure|null  $pdo
+     * @return $this
+     */
+    public function setReadPdo($pdo)
+    {
+        $this->readPdo = $pdo;
+
+        return $this;
+    }
+
+    /**
+     * Set the reconnect instance on the connection.
+     *
+     * @param  callable  $reconnector
+     * @return $this
+     */
+    public function setReconnector(callable $reconnector)
+    {
+        $this->reconnector = $reconnector;
+
+        return $this;
+    }
+
+    /**
+     * Get the database connection name.
+     *
+     * @return string|null
+     */
+    public function getName()
+    {
+        return $this->getConfig('name');
+    }
+
+    /**
+     * Get the database connection full name.
+     *
+     * @return string|null
+     */
+    public function getNameWithReadWriteType()
+    {
+        return $this->getName().($this->readWriteType ? '::'.$this->readWriteType : '');
+    }
+
+    /**
+     * Get an option from the configuration options.
+     *
+     * @param  string|null  $option
+     * @return mixed
+     */
+    public function getConfig($option = null)
+    {
+        return Arr::get($this->config, $option);
+    }
+
+    /**
+     * Get the PDO driver name.
+     *
+     * @return string
+     */
+    public function getDriverName()
+    {
+        return $this->getConfig('driver');
+    }
+
+    /**
+     * Get the query grammar used by the connection.
+     *
+     * @return \Illuminate\Database\Query\Grammars\Grammar
+     */
+    public function getQueryGrammar()
+    {
+        return $this->queryGrammar;
+    }
+
+    /**
+     * Set the query grammar used by the connection.
+     *
+     * @param  \Illuminate\Database\Query\Grammars\Grammar  $grammar
+     * @return $this
+     */
+    public function setQueryGrammar(Query\Grammars\Grammar $grammar)
+    {
+        $this->queryGrammar = $grammar;
+
+        return $this;
+    }
+
+    /**
+     * Get the schema grammar used by the connection.
+     *
+     * @return \Illuminate\Database\Schema\Grammars\Grammar
+     */
+    public function getSchemaGrammar()
+    {
+        return $this->schemaGrammar;
+    }
+
+    /**
+     * Set the schema grammar used by the connection.
+     *
+     * @param  \Illuminate\Database\Schema\Grammars\Grammar  $grammar
+     * @return $this
+     */
+    public function setSchemaGrammar(Schema\Grammars\Grammar $grammar)
+    {
+        $this->schemaGrammar = $grammar;
+
+        return $this;
+    }
+
+    /**
+     * Get the query post processor used by the connection.
+     *
+     * @return \Illuminate\Database\Query\Processors\Processor
+     */
+    public function getPostProcessor()
+    {
+        return $this->postProcessor;
+    }
+
+    /**
+     * Set the query post processor used by the connection.
+     *
+     * @param  \Illuminate\Database\Query\Processors\Processor  $processor
+     * @return $this
+     */
+    public function setPostProcessor(Processor $processor)
+    {
+        $this->postProcessor = $processor;
+
+        return $this;
+    }
+
+    /**
+     * Get the event dispatcher used by the connection.
+     *
+     * @return \Illuminate\Contracts\Events\Dispatcher
+     */
+    public function getEventDispatcher()
+    {
+        return $this->events;
+    }
+
+    /**
+     * Set the event dispatcher instance on the connection.
+     *
+     * @param  \Illuminate\Contracts\Events\Dispatcher  $events
+     * @return $this
+     */
+    public function setEventDispatcher(Dispatcher $events)
+    {
+        $this->events = $events;
+
+        return $this;
+    }
+
+    /**
+     * Unset the event dispatcher for this connection.
+     *
+     * @return void
+     */
+    public function unsetEventDispatcher()
+    {
+        $this->events = null;
+    }
+
+    /**
+     * Set the transaction manager instance on the connection.
+     *
+     * @param  \Illuminate\Database\DatabaseTransactionsManager  $manager
+     * @return $this
+     */
+    public function setTransactionManager($manager)
+    {
+        $this->transactionsManager = $manager;
+
+        return $this;
+    }
+
+    /**
+     * Unset the transaction manager for this connection.
+     *
+     * @return void
+     */
+    public function unsetTransactionManager()
+    {
+        $this->transactionsManager = null;
+    }
+
+    /**
+     * Determine if the connection is in a "dry run".
+     *
+     * @return bool
+     */
+    public function pretending()
+    {
+        return $this->pretending === true;
+    }
+
+    /**
+     * Get the connection query log.
+     *
+     * @return array
+     */
+    public function getQueryLog()
+    {
+        return $this->queryLog;
+    }
+
+    /**
+     * Clear the query log.
+     *
+     * @return void
+     */
+    public function flushQueryLog()
+    {
+        $this->queryLog = [];
+    }
+
+    /**
+     * Enable the query log on the connection.
+     *
+     * @return void
+     */
+    public function enableQueryLog()
+    {
+        $this->loggingQueries = true;
+    }
+
+    /**
+     * Disable the query log on the connection.
+     *
+     * @return void
+     */
+    public function disableQueryLog()
+    {
+        $this->loggingQueries = false;
+    }
+
+    /**
+     * Determine whether we're logging queries.
+     *
+     * @return bool
+     */
+    public function logging()
+    {
+        return $this->loggingQueries;
+    }
+
+    /**
+     * Get the name of the connected database.
+     *
+     * @return string
+     */
+    public function getDatabaseName()
+    {
+        return $this->database;
+    }
+
+    /**
+     * Set the name of the connected database.
+     *
+     * @param  string  $database
+     * @return $this
+     */
+    public function setDatabaseName($database)
+    {
+        $this->database = $database;
+
+        return $this;
+    }
+
+    /**
+     * Set the read / write type of the connection.
+     *
+     * @param  string|null  $readWriteType
+     * @return $this
+     */
+    public function setReadWriteType($readWriteType)
+    {
+        $this->readWriteType = $readWriteType;
+
+        return $this;
+    }
+
+    /**
+     * Get the table prefix for the connection.
+     *
+     * @return string
+     */
+    public function getTablePrefix()
+    {
+        return $this->tablePrefix;
+    }
+
+    /**
+     * Set the table prefix in use by the connection.
+     *
+     * @param  string  $prefix
+     * @return $this
+     */
+    public function setTablePrefix($prefix)
+    {
+        $this->tablePrefix = $prefix;
+
+        $this->getQueryGrammar()->setTablePrefix($prefix);
+
+        return $this;
+    }
+
+    /**
+     * Set the table prefix and return the grammar.
+     *
+     * @param  \Illuminate\Database\Grammar  $grammar
+     * @return \Illuminate\Database\Grammar
+     */
+    public function withTablePrefix(Grammar $grammar)
+    {
+        $grammar->setTablePrefix($this->tablePrefix);
+
+        return $grammar;
+    }
+
+    /**
+     * Register a connection resolver.
+     *
+     * @param  string  $driver
+     * @param  \Closure  $callback
+     * @return void
+     */
+    public static function resolverFor($driver, Closure $callback)
+    {
+        static::$resolvers[$driver] = $callback;
+    }
+
+    /**
+     * Get the connection resolver for the given driver.
+     *
+     * @param  string  $driver
+     * @return mixed
+     */
+    public static function getResolver($driver)
+    {
+        return static::$resolvers[$driver] ?? null;
+    }
+}
diff --git a/vendor/illuminate/database/ConnectionInterface.php b/vendor/illuminate/database/ConnectionInterface.php
new file mode 100755
index 0000000..00b2395
--- /dev/null
+++ b/vendor/illuminate/database/ConnectionInterface.php
@@ -0,0 +1,170 @@
+  $connections
+     * @return void
+     */
+    public function __construct(array $connections = [])
+    {
+        foreach ($connections as $name => $connection) {
+            $this->addConnection($name, $connection);
+        }
+    }
+
+    /**
+     * Get a database connection instance.
+     *
+     * @param  string|null  $name
+     * @return \Illuminate\Database\ConnectionInterface
+     */
+    public function connection($name = null)
+    {
+        if (is_null($name)) {
+            $name = $this->getDefaultConnection();
+        }
+
+        return $this->connections[$name];
+    }
+
+    /**
+     * Add a connection to the resolver.
+     *
+     * @param  string  $name
+     * @param  \Illuminate\Database\ConnectionInterface  $connection
+     * @return void
+     */
+    public function addConnection($name, ConnectionInterface $connection)
+    {
+        $this->connections[$name] = $connection;
+    }
+
+    /**
+     * Check if a connection has been registered.
+     *
+     * @param  string  $name
+     * @return bool
+     */
+    public function hasConnection($name)
+    {
+        return isset($this->connections[$name]);
+    }
+
+    /**
+     * Get the default connection name.
+     *
+     * @return string
+     */
+    public function getDefaultConnection()
+    {
+        return $this->default;
+    }
+
+    /**
+     * Set the default connection name.
+     *
+     * @param  string  $name
+     * @return void
+     */
+    public function setDefaultConnection($name)
+    {
+        $this->default = $name;
+    }
+}
diff --git a/vendor/illuminate/database/ConnectionResolverInterface.php b/vendor/illuminate/database/ConnectionResolverInterface.php
new file mode 100755
index 0000000..b31e5a7
--- /dev/null
+++ b/vendor/illuminate/database/ConnectionResolverInterface.php
@@ -0,0 +1,29 @@
+container = $container;
+    }
+
+    /**
+     * Establish a PDO connection based on the configuration.
+     *
+     * @param  array  $config
+     * @param  string|null  $name
+     * @return \Illuminate\Database\Connection
+     */
+    public function make(array $config, $name = null)
+    {
+        $config = $this->parseConfig($config, $name);
+
+        if (isset($config['read'])) {
+            return $this->createReadWriteConnection($config);
+        }
+
+        return $this->createSingleConnection($config);
+    }
+
+    /**
+     * Parse and prepare the database configuration.
+     *
+     * @param  array  $config
+     * @param  string  $name
+     * @return array
+     */
+    protected function parseConfig(array $config, $name)
+    {
+        return Arr::add(Arr::add($config, 'prefix', ''), 'name', $name);
+    }
+
+    /**
+     * Create a single database connection instance.
+     *
+     * @param  array  $config
+     * @return \Illuminate\Database\Connection
+     */
+    protected function createSingleConnection(array $config)
+    {
+        $pdo = $this->createPdoResolver($config);
+
+        return $this->createConnection(
+            $config['driver'], $pdo, $config['database'], $config['prefix'], $config
+        );
+    }
+
+    /**
+     * Create a read / write database connection instance.
+     *
+     * @param  array  $config
+     * @return \Illuminate\Database\Connection
+     */
+    protected function createReadWriteConnection(array $config)
+    {
+        $connection = $this->createSingleConnection($this->getWriteConfig($config));
+
+        return $connection->setReadPdo($this->createReadPdo($config));
+    }
+
+    /**
+     * Create a new PDO instance for reading.
+     *
+     * @param  array  $config
+     * @return \Closure
+     */
+    protected function createReadPdo(array $config)
+    {
+        return $this->createPdoResolver($this->getReadConfig($config));
+    }
+
+    /**
+     * Get the read configuration for a read / write connection.
+     *
+     * @param  array  $config
+     * @return array
+     */
+    protected function getReadConfig(array $config)
+    {
+        return $this->mergeReadWriteConfig(
+            $config, $this->getReadWriteConfig($config, 'read')
+        );
+    }
+
+    /**
+     * Get the write configuration for a read / write connection.
+     *
+     * @param  array  $config
+     * @return array
+     */
+    protected function getWriteConfig(array $config)
+    {
+        return $this->mergeReadWriteConfig(
+            $config, $this->getReadWriteConfig($config, 'write')
+        );
+    }
+
+    /**
+     * Get a read / write level configuration.
+     *
+     * @param  array  $config
+     * @param  string  $type
+     * @return array
+     */
+    protected function getReadWriteConfig(array $config, $type)
+    {
+        return isset($config[$type][0])
+                        ? Arr::random($config[$type])
+                        : $config[$type];
+    }
+
+    /**
+     * Merge a configuration for a read / write connection.
+     *
+     * @param  array  $config
+     * @param  array  $merge
+     * @return array
+     */
+    protected function mergeReadWriteConfig(array $config, array $merge)
+    {
+        return Arr::except(array_merge($config, $merge), ['read', 'write']);
+    }
+
+    /**
+     * Create a new Closure that resolves to a PDO instance.
+     *
+     * @param  array  $config
+     * @return \Closure
+     */
+    protected function createPdoResolver(array $config)
+    {
+        return array_key_exists('host', $config)
+                            ? $this->createPdoResolverWithHosts($config)
+                            : $this->createPdoResolverWithoutHosts($config);
+    }
+
+    /**
+     * Create a new Closure that resolves to a PDO instance with a specific host or an array of hosts.
+     *
+     * @param  array  $config
+     * @return \Closure
+     *
+     * @throws \PDOException
+     */
+    protected function createPdoResolverWithHosts(array $config)
+    {
+        return function () use ($config) {
+            foreach (Arr::shuffle($this->parseHosts($config)) as $host) {
+                $config['host'] = $host;
+
+                try {
+                    return $this->createConnector($config)->connect($config);
+                } catch (PDOException $e) {
+                    continue;
+                }
+            }
+
+            throw $e;
+        };
+    }
+
+    /**
+     * Parse the hosts configuration item into an array.
+     *
+     * @param  array  $config
+     * @return array
+     *
+     * @throws \InvalidArgumentException
+     */
+    protected function parseHosts(array $config)
+    {
+        $hosts = Arr::wrap($config['host']);
+
+        if (empty($hosts)) {
+            throw new InvalidArgumentException('Database hosts array is empty.');
+        }
+
+        return $hosts;
+    }
+
+    /**
+     * Create a new Closure that resolves to a PDO instance where there is no configured host.
+     *
+     * @param  array  $config
+     * @return \Closure
+     */
+    protected function createPdoResolverWithoutHosts(array $config)
+    {
+        return fn () => $this->createConnector($config)->connect($config);
+    }
+
+    /**
+     * Create a connector instance based on the configuration.
+     *
+     * @param  array  $config
+     * @return \Illuminate\Database\Connectors\ConnectorInterface
+     *
+     * @throws \InvalidArgumentException
+     */
+    public function createConnector(array $config)
+    {
+        if (! isset($config['driver'])) {
+            throw new InvalidArgumentException('A driver must be specified.');
+        }
+
+        if ($this->container->bound($key = "db.connector.{$config['driver']}")) {
+            return $this->container->make($key);
+        }
+
+        return match ($config['driver']) {
+            'mysql' => new MySqlConnector,
+            'pgsql' => new PostgresConnector,
+            'sqlite' => new SQLiteConnector,
+            'sqlsrv' => new SqlServerConnector,
+            default => throw new InvalidArgumentException("Unsupported driver [{$config['driver']}]."),
+        };
+    }
+
+    /**
+     * Create a new connection instance.
+     *
+     * @param  string  $driver
+     * @param  \PDO|\Closure  $connection
+     * @param  string  $database
+     * @param  string  $prefix
+     * @param  array  $config
+     * @return \Illuminate\Database\Connection
+     *
+     * @throws \InvalidArgumentException
+     */
+    protected function createConnection($driver, $connection, $database, $prefix = '', array $config = [])
+    {
+        if ($resolver = Connection::getResolver($driver)) {
+            return $resolver($connection, $database, $prefix, $config);
+        }
+
+        return match ($driver) {
+            'mysql' => new MySqlConnection($connection, $database, $prefix, $config),
+            'pgsql' => new PostgresConnection($connection, $database, $prefix, $config),
+            'sqlite' => new SQLiteConnection($connection, $database, $prefix, $config),
+            'sqlsrv' => new SqlServerConnection($connection, $database, $prefix, $config),
+            default => throw new InvalidArgumentException("Unsupported driver [{$driver}]."),
+        };
+    }
+}
diff --git a/vendor/illuminate/database/Connectors/Connector.php b/vendor/illuminate/database/Connectors/Connector.php
new file mode 100755
index 0000000..0fecfb5
--- /dev/null
+++ b/vendor/illuminate/database/Connectors/Connector.php
@@ -0,0 +1,139 @@
+ PDO::CASE_NATURAL,
+        PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
+        PDO::ATTR_ORACLE_NULLS => PDO::NULL_NATURAL,
+        PDO::ATTR_STRINGIFY_FETCHES => false,
+        PDO::ATTR_EMULATE_PREPARES => false,
+    ];
+
+    /**
+     * Create a new PDO connection.
+     *
+     * @param  string  $dsn
+     * @param  array  $config
+     * @param  array  $options
+     * @return \PDO
+     *
+     * @throws \Exception
+     */
+    public function createConnection($dsn, array $config, array $options)
+    {
+        [$username, $password] = [
+            $config['username'] ?? null, $config['password'] ?? null,
+        ];
+
+        try {
+            return $this->createPdoConnection(
+                $dsn, $username, $password, $options
+            );
+        } catch (Exception $e) {
+            return $this->tryAgainIfCausedByLostConnection(
+                $e, $dsn, $username, $password, $options
+            );
+        }
+    }
+
+    /**
+     * Create a new PDO connection instance.
+     *
+     * @param  string  $dsn
+     * @param  string  $username
+     * @param  string  $password
+     * @param  array  $options
+     * @return \PDO
+     */
+    protected function createPdoConnection($dsn, $username, $password, $options)
+    {
+        if (class_exists(PDOConnection::class) && ! $this->isPersistentConnection($options)) {
+            return new PDOConnection($dsn, $username, $password, $options);
+        }
+
+        return new PDO($dsn, $username, $password, $options);
+    }
+
+    /**
+     * Determine if the connection is persistent.
+     *
+     * @param  array  $options
+     * @return bool
+     */
+    protected function isPersistentConnection($options)
+    {
+        return isset($options[PDO::ATTR_PERSISTENT]) &&
+               $options[PDO::ATTR_PERSISTENT];
+    }
+
+    /**
+     * Handle an exception that occurred during connect execution.
+     *
+     * @param  \Throwable  $e
+     * @param  string  $dsn
+     * @param  string  $username
+     * @param  string  $password
+     * @param  array  $options
+     * @return \PDO
+     *
+     * @throws \Exception
+     */
+    protected function tryAgainIfCausedByLostConnection(Throwable $e, $dsn, $username, $password, $options)
+    {
+        if ($this->causedByLostConnection($e)) {
+            return $this->createPdoConnection($dsn, $username, $password, $options);
+        }
+
+        throw $e;
+    }
+
+    /**
+     * Get the PDO options based on the configuration.
+     *
+     * @param  array  $config
+     * @return array
+     */
+    public function getOptions(array $config)
+    {
+        $options = $config['options'] ?? [];
+
+        return array_diff_key($this->options, $options) + $options;
+    }
+
+    /**
+     * Get the default PDO connection options.
+     *
+     * @return array
+     */
+    public function getDefaultOptions()
+    {
+        return $this->options;
+    }
+
+    /**
+     * Set the default PDO connection options.
+     *
+     * @param  array  $options
+     * @return void
+     */
+    public function setDefaultOptions(array $options)
+    {
+        $this->options = $options;
+    }
+}
diff --git a/vendor/illuminate/database/Connectors/ConnectorInterface.php b/vendor/illuminate/database/Connectors/ConnectorInterface.php
new file mode 100755
index 0000000..08597ac
--- /dev/null
+++ b/vendor/illuminate/database/Connectors/ConnectorInterface.php
@@ -0,0 +1,14 @@
+getDsn($config);
+
+        $options = $this->getOptions($config);
+
+        // We need to grab the PDO options that should be used while making the brand
+        // new connection instance. The PDO options control various aspects of the
+        // connection's behavior, and some might be specified by the developers.
+        $connection = $this->createConnection($dsn, $config, $options);
+
+        if (! empty($config['database'])) {
+            $connection->exec("use `{$config['database']}`;");
+        }
+
+        $this->configureIsolationLevel($connection, $config);
+
+        $this->configureEncoding($connection, $config);
+
+        // Next, we will check to see if a timezone has been specified in this config
+        // and if it has we will issue a statement to modify the timezone with the
+        // database. Setting this DB timezone is an optional configuration item.
+        $this->configureTimezone($connection, $config);
+
+        $this->setModes($connection, $config);
+
+        return $connection;
+    }
+
+    /**
+     * Set the connection transaction isolation level.
+     *
+     * @param  \PDO  $connection
+     * @param  array  $config
+     * @return void
+     */
+    protected function configureIsolationLevel($connection, array $config)
+    {
+        if (! isset($config['isolation_level'])) {
+            return;
+        }
+
+        $connection->prepare(
+            "SET SESSION TRANSACTION ISOLATION LEVEL {$config['isolation_level']}"
+        )->execute();
+    }
+
+    /**
+     * Set the connection character set and collation.
+     *
+     * @param  \PDO  $connection
+     * @param  array  $config
+     * @return void|\PDO
+     */
+    protected function configureEncoding($connection, array $config)
+    {
+        if (! isset($config['charset'])) {
+            return $connection;
+        }
+
+        $connection->prepare(
+            "set names '{$config['charset']}'".$this->getCollation($config)
+        )->execute();
+    }
+
+    /**
+     * Get the collation for the configuration.
+     *
+     * @param  array  $config
+     * @return string
+     */
+    protected function getCollation(array $config)
+    {
+        return isset($config['collation']) ? " collate '{$config['collation']}'" : '';
+    }
+
+    /**
+     * Set the timezone on the connection.
+     *
+     * @param  \PDO  $connection
+     * @param  array  $config
+     * @return void
+     */
+    protected function configureTimezone($connection, array $config)
+    {
+        if (isset($config['timezone'])) {
+            $connection->prepare('set time_zone="'.$config['timezone'].'"')->execute();
+        }
+    }
+
+    /**
+     * Create a DSN string from a configuration.
+     *
+     * Chooses socket or host/port based on the 'unix_socket' config value.
+     *
+     * @param  array  $config
+     * @return string
+     */
+    protected function getDsn(array $config)
+    {
+        return $this->hasSocket($config)
+                            ? $this->getSocketDsn($config)
+                            : $this->getHostDsn($config);
+    }
+
+    /**
+     * Determine if the given configuration array has a UNIX socket value.
+     *
+     * @param  array  $config
+     * @return bool
+     */
+    protected function hasSocket(array $config)
+    {
+        return isset($config['unix_socket']) && ! empty($config['unix_socket']);
+    }
+
+    /**
+     * Get the DSN string for a socket configuration.
+     *
+     * @param  array  $config
+     * @return string
+     */
+    protected function getSocketDsn(array $config)
+    {
+        return "mysql:unix_socket={$config['unix_socket']};dbname={$config['database']}";
+    }
+
+    /**
+     * Get the DSN string for a host / port configuration.
+     *
+     * @param  array  $config
+     * @return string
+     */
+    protected function getHostDsn(array $config)
+    {
+        extract($config, EXTR_SKIP);
+
+        return isset($port)
+                    ? "mysql:host={$host};port={$port};dbname={$database}"
+                    : "mysql:host={$host};dbname={$database}";
+    }
+
+    /**
+     * Set the modes for the connection.
+     *
+     * @param  \PDO  $connection
+     * @param  array  $config
+     * @return void
+     */
+    protected function setModes(PDO $connection, array $config)
+    {
+        if (isset($config['modes'])) {
+            $this->setCustomModes($connection, $config);
+        } elseif (isset($config['strict'])) {
+            if ($config['strict']) {
+                $connection->prepare($this->strictMode($connection, $config))->execute();
+            } else {
+                $connection->prepare("set session sql_mode='NO_ENGINE_SUBSTITUTION'")->execute();
+            }
+        }
+    }
+
+    /**
+     * Set the custom modes on the connection.
+     *
+     * @param  \PDO  $connection
+     * @param  array  $config
+     * @return void
+     */
+    protected function setCustomModes(PDO $connection, array $config)
+    {
+        $modes = implode(',', $config['modes']);
+
+        $connection->prepare("set session sql_mode='{$modes}'")->execute();
+    }
+
+    /**
+     * Get the query to enable strict mode.
+     *
+     * @param  \PDO  $connection
+     * @param  array  $config
+     * @return string
+     */
+    protected function strictMode(PDO $connection, $config)
+    {
+        $version = $config['version'] ?? $connection->getAttribute(PDO::ATTR_SERVER_VERSION);
+
+        if (version_compare($version, '8.0.11') >= 0) {
+            return "set session sql_mode='ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION'";
+        }
+
+        return "set session sql_mode='ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION'";
+    }
+}
diff --git a/vendor/illuminate/database/Connectors/PostgresConnector.php b/vendor/illuminate/database/Connectors/PostgresConnector.php
new file mode 100755
index 0000000..c54163f
--- /dev/null
+++ b/vendor/illuminate/database/Connectors/PostgresConnector.php
@@ -0,0 +1,216 @@
+ PDO::CASE_NATURAL,
+        PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
+        PDO::ATTR_ORACLE_NULLS => PDO::NULL_NATURAL,
+        PDO::ATTR_STRINGIFY_FETCHES => false,
+    ];
+
+    /**
+     * Establish a database connection.
+     *
+     * @param  array  $config
+     * @return \PDO
+     */
+    public function connect(array $config)
+    {
+        // First we'll create the basic DSN and connection instance connecting to the
+        // using the configuration option specified by the developer. We will also
+        // set the default character set on the connections to UTF-8 by default.
+        $connection = $this->createConnection(
+            $this->getDsn($config), $config, $this->getOptions($config)
+        );
+
+        $this->configureIsolationLevel($connection, $config);
+
+        $this->configureEncoding($connection, $config);
+
+        // Next, we will check to see if a timezone has been specified in this config
+        // and if it has we will issue a statement to modify the timezone with the
+        // database. Setting this DB timezone is an optional configuration item.
+        $this->configureTimezone($connection, $config);
+
+        $this->configureSearchPath($connection, $config);
+
+        // Postgres allows an application_name to be set by the user and this name is
+        // used to when monitoring the application with pg_stat_activity. So we'll
+        // determine if the option has been specified and run a statement if so.
+        $this->configureApplicationName($connection, $config);
+
+        $this->configureSynchronousCommit($connection, $config);
+
+        return $connection;
+    }
+
+    /**
+     * Set the connection transaction isolation level.
+     *
+     * @param  \PDO  $connection
+     * @param  array  $config
+     * @return void
+     */
+    protected function configureIsolationLevel($connection, array $config)
+    {
+        if (isset($config['isolation_level'])) {
+            $connection->prepare("set session characteristics as transaction isolation level {$config['isolation_level']}")->execute();
+        }
+    }
+
+    /**
+     * Set the connection character set and collation.
+     *
+     * @param  \PDO  $connection
+     * @param  array  $config
+     * @return void
+     */
+    protected function configureEncoding($connection, $config)
+    {
+        if (! isset($config['charset'])) {
+            return;
+        }
+
+        $connection->prepare("set names '{$config['charset']}'")->execute();
+    }
+
+    /**
+     * Set the timezone on the connection.
+     *
+     * @param  \PDO  $connection
+     * @param  array  $config
+     * @return void
+     */
+    protected function configureTimezone($connection, array $config)
+    {
+        if (isset($config['timezone'])) {
+            $timezone = $config['timezone'];
+
+            $connection->prepare("set time zone '{$timezone}'")->execute();
+        }
+    }
+
+    /**
+     * Set the "search_path" on the database connection.
+     *
+     * @param  \PDO  $connection
+     * @param  array  $config
+     * @return void
+     */
+    protected function configureSearchPath($connection, $config)
+    {
+        if (isset($config['search_path']) || isset($config['schema'])) {
+            $searchPath = $this->quoteSearchPath(
+                $this->parseSearchPath($config['search_path'] ?? $config['schema'])
+            );
+
+            $connection->prepare("set search_path to {$searchPath}")->execute();
+        }
+    }
+
+    /**
+     * Format the search path for the DSN.
+     *
+     * @param  array  $searchPath
+     * @return string
+     */
+    protected function quoteSearchPath($searchPath)
+    {
+        return count($searchPath) === 1 ? '"'.$searchPath[0].'"' : '"'.implode('", "', $searchPath).'"';
+    }
+
+    /**
+     * Set the application name on the connection.
+     *
+     * @param  \PDO  $connection
+     * @param  array  $config
+     * @return void
+     */
+    protected function configureApplicationName($connection, $config)
+    {
+        if (isset($config['application_name'])) {
+            $applicationName = $config['application_name'];
+
+            $connection->prepare("set application_name to '$applicationName'")->execute();
+        }
+    }
+
+    /**
+     * Create a DSN string from a configuration.
+     *
+     * @param  array  $config
+     * @return string
+     */
+    protected function getDsn(array $config)
+    {
+        // First we will create the basic DSN setup as well as the port if it is in
+        // in the configuration options. This will give us the basic DSN we will
+        // need to establish the PDO connections and return them back for use.
+        extract($config, EXTR_SKIP);
+
+        $host = isset($host) ? "host={$host};" : '';
+
+        // Sometimes - users may need to connect to a database that has a different
+        // name than the database used for "information_schema" queries. This is
+        // typically the case if using "pgbouncer" type software when pooling.
+        $database = $connect_via_database ?? $database;
+
+        $dsn = "pgsql:{$host}dbname='{$database}'";
+
+        // If a port was specified, we will add it to this Postgres DSN connections
+        // format. Once we have done that we are ready to return this connection
+        // string back out for usage, as this has been fully constructed here.
+        if (isset($config['port'])) {
+            $dsn .= ";port={$port}";
+        }
+
+        return $this->addSslOptions($dsn, $config);
+    }
+
+    /**
+     * Add the SSL options to the DSN.
+     *
+     * @param  string  $dsn
+     * @param  array  $config
+     * @return string
+     */
+    protected function addSslOptions($dsn, array $config)
+    {
+        foreach (['sslmode', 'sslcert', 'sslkey', 'sslrootcert'] as $option) {
+            if (isset($config[$option])) {
+                $dsn .= ";{$option}={$config[$option]}";
+            }
+        }
+
+        return $dsn;
+    }
+
+    /**
+     * Configure the synchronous_commit setting.
+     *
+     * @param  \PDO  $connection
+     * @param  array  $config
+     * @return void
+     */
+    protected function configureSynchronousCommit($connection, array $config)
+    {
+        if (! isset($config['synchronous_commit'])) {
+            return;
+        }
+
+        $connection->prepare("set synchronous_commit to '{$config['synchronous_commit']}'")->execute();
+    }
+}
diff --git a/vendor/illuminate/database/Connectors/SQLiteConnector.php b/vendor/illuminate/database/Connectors/SQLiteConnector.php
new file mode 100755
index 0000000..ddedfbf
--- /dev/null
+++ b/vendor/illuminate/database/Connectors/SQLiteConnector.php
@@ -0,0 +1,39 @@
+getOptions($config);
+
+        // SQLite supports "in-memory" databases that only last as long as the owning
+        // connection does. These are useful for tests or for short lifetime store
+        // querying. In-memory databases may only have a single open connection.
+        if ($config['database'] === ':memory:') {
+            return $this->createConnection('sqlite::memory:', $config, $options);
+        }
+
+        $path = realpath($config['database']);
+
+        // Here we'll verify that the SQLite database exists before going any further
+        // as the developer probably wants to know if the database exists and this
+        // SQLite driver will not throw any exception if it does not by default.
+        if ($path === false) {
+            throw new SQLiteDatabaseDoesNotExistException($config['database']);
+        }
+
+        return $this->createConnection("sqlite:{$path}", $config, $options);
+    }
+}
diff --git a/vendor/illuminate/database/Connectors/SqlServerConnector.php b/vendor/illuminate/database/Connectors/SqlServerConnector.php
new file mode 100755
index 0000000..b6ed47d
--- /dev/null
+++ b/vendor/illuminate/database/Connectors/SqlServerConnector.php
@@ -0,0 +1,233 @@
+ PDO::CASE_NATURAL,
+        PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
+        PDO::ATTR_ORACLE_NULLS => PDO::NULL_NATURAL,
+        PDO::ATTR_STRINGIFY_FETCHES => false,
+    ];
+
+    /**
+     * Establish a database connection.
+     *
+     * @param  array  $config
+     * @return \PDO
+     */
+    public function connect(array $config)
+    {
+        $options = $this->getOptions($config);
+
+        $connection = $this->createConnection($this->getDsn($config), $config, $options);
+
+        $this->configureIsolationLevel($connection, $config);
+
+        return $connection;
+    }
+
+    /**
+     * Set the connection transaction isolation level.
+     *
+     * https://learn.microsoft.com/en-us/sql/t-sql/statements/set-transaction-isolation-level-transact-sql
+     *
+     * @param  \PDO  $connection
+     * @param  array  $config
+     * @return void
+     */
+    protected function configureIsolationLevel($connection, array $config)
+    {
+        if (! isset($config['isolation_level'])) {
+            return;
+        }
+
+        $connection->prepare(
+            "SET TRANSACTION ISOLATION LEVEL {$config['isolation_level']}"
+        )->execute();
+    }
+
+    /**
+     * Create a DSN string from a configuration.
+     *
+     * @param  array  $config
+     * @return string
+     */
+    protected function getDsn(array $config)
+    {
+        // First we will create the basic DSN setup as well as the port if it is in
+        // in the configuration options. This will give us the basic DSN we will
+        // need to establish the PDO connections and return them back for use.
+        if ($this->prefersOdbc($config)) {
+            return $this->getOdbcDsn($config);
+        }
+
+        if (in_array('sqlsrv', $this->getAvailableDrivers())) {
+            return $this->getSqlSrvDsn($config);
+        } else {
+            return $this->getDblibDsn($config);
+        }
+    }
+
+    /**
+     * Determine if the database configuration prefers ODBC.
+     *
+     * @param  array  $config
+     * @return bool
+     */
+    protected function prefersOdbc(array $config)
+    {
+        return in_array('odbc', $this->getAvailableDrivers()) &&
+               ($config['odbc'] ?? null) === true;
+    }
+
+    /**
+     * Get the DSN string for a DbLib connection.
+     *
+     * @param  array  $config
+     * @return string
+     */
+    protected function getDblibDsn(array $config)
+    {
+        return $this->buildConnectString('dblib', array_merge([
+            'host' => $this->buildHostString($config, ':'),
+            'dbname' => $config['database'],
+        ], Arr::only($config, ['appname', 'charset', 'version'])));
+    }
+
+    /**
+     * Get the DSN string for an ODBC connection.
+     *
+     * @param  array  $config
+     * @return string
+     */
+    protected function getOdbcDsn(array $config)
+    {
+        return isset($config['odbc_datasource_name'])
+                    ? 'odbc:'.$config['odbc_datasource_name'] : '';
+    }
+
+    /**
+     * Get the DSN string for a SqlSrv connection.
+     *
+     * @param  array  $config
+     * @return string
+     */
+    protected function getSqlSrvDsn(array $config)
+    {
+        $arguments = [
+            'Server' => $this->buildHostString($config, ','),
+        ];
+
+        if (isset($config['database'])) {
+            $arguments['Database'] = $config['database'];
+        }
+
+        if (isset($config['readonly'])) {
+            $arguments['ApplicationIntent'] = 'ReadOnly';
+        }
+
+        if (isset($config['pooling']) && $config['pooling'] === false) {
+            $arguments['ConnectionPooling'] = '0';
+        }
+
+        if (isset($config['appname'])) {
+            $arguments['APP'] = $config['appname'];
+        }
+
+        if (isset($config['encrypt'])) {
+            $arguments['Encrypt'] = $config['encrypt'];
+        }
+
+        if (isset($config['trust_server_certificate'])) {
+            $arguments['TrustServerCertificate'] = $config['trust_server_certificate'];
+        }
+
+        if (isset($config['multiple_active_result_sets']) && $config['multiple_active_result_sets'] === false) {
+            $arguments['MultipleActiveResultSets'] = 'false';
+        }
+
+        if (isset($config['transaction_isolation'])) {
+            $arguments['TransactionIsolation'] = $config['transaction_isolation'];
+        }
+
+        if (isset($config['multi_subnet_failover'])) {
+            $arguments['MultiSubnetFailover'] = $config['multi_subnet_failover'];
+        }
+
+        if (isset($config['column_encryption'])) {
+            $arguments['ColumnEncryption'] = $config['column_encryption'];
+        }
+
+        if (isset($config['key_store_authentication'])) {
+            $arguments['KeyStoreAuthentication'] = $config['key_store_authentication'];
+        }
+
+        if (isset($config['key_store_principal_id'])) {
+            $arguments['KeyStorePrincipalId'] = $config['key_store_principal_id'];
+        }
+
+        if (isset($config['key_store_secret'])) {
+            $arguments['KeyStoreSecret'] = $config['key_store_secret'];
+        }
+
+        if (isset($config['login_timeout'])) {
+            $arguments['LoginTimeout'] = $config['login_timeout'];
+        }
+
+        if (isset($config['authentication'])) {
+            $arguments['Authentication'] = $config['authentication'];
+        }
+
+        return $this->buildConnectString('sqlsrv', $arguments);
+    }
+
+    /**
+     * Build a connection string from the given arguments.
+     *
+     * @param  string  $driver
+     * @param  array  $arguments
+     * @return string
+     */
+    protected function buildConnectString($driver, array $arguments)
+    {
+        return $driver.':'.implode(';', array_map(function ($key) use ($arguments) {
+            return sprintf('%s=%s', $key, $arguments[$key]);
+        }, array_keys($arguments)));
+    }
+
+    /**
+     * Build a host string from the given configuration.
+     *
+     * @param  array  $config
+     * @param  string  $separator
+     * @return string
+     */
+    protected function buildHostString(array $config, $separator)
+    {
+        if (empty($config['port'])) {
+            return $config['host'];
+        }
+
+        return $config['host'].$separator.$config['port'];
+    }
+
+    /**
+     * Get the available PDO drivers.
+     *
+     * @return array
+     */
+    protected function getAvailableDrivers()
+    {
+        return PDO::getAvailableDrivers();
+    }
+}
diff --git a/vendor/illuminate/database/Console/DatabaseInspectionCommand.php b/vendor/illuminate/database/Console/DatabaseInspectionCommand.php
new file mode 100644
index 0000000..e3391a0
--- /dev/null
+++ b/vendor/illuminate/database/Console/DatabaseInspectionCommand.php
@@ -0,0 +1,246 @@
+ 'string',
+        'citext' => 'string',
+        'enum' => 'string',
+        'geometry' => 'string',
+        'geomcollection' => 'string',
+        'linestring' => 'string',
+        'ltree' => 'string',
+        'multilinestring' => 'string',
+        'multipoint' => 'string',
+        'multipolygon' => 'string',
+        'point' => 'string',
+        'polygon' => 'string',
+        'sysname' => 'string',
+    ];
+
+    /**
+     * The Composer instance.
+     *
+     * @var \Illuminate\Support\Composer
+     */
+    protected $composer;
+
+    /**
+     * Create a new command instance.
+     *
+     * @param  \Illuminate\Support\Composer|null  $composer
+     * @return void
+     */
+    public function __construct(Composer $composer = null)
+    {
+        parent::__construct();
+
+        $this->composer = $composer ?? $this->laravel->make(Composer::class);
+    }
+
+    /**
+     * Register the custom Doctrine type mappings for inspection commands.
+     *
+     * @param  \Doctrine\DBAL\Platforms\AbstractPlatform  $platform
+     * @return void
+     */
+    protected function registerTypeMappings(AbstractPlatform $platform)
+    {
+        foreach ($this->typeMappings as $type => $value) {
+            $platform->registerDoctrineTypeMapping($type, $value);
+        }
+    }
+
+    /**
+     * Get a human-readable platform name for the given platform.
+     *
+     * @param  \Doctrine\DBAL\Platforms\AbstractPlatform  $platform
+     * @param  string  $database
+     * @return string
+     */
+    protected function getPlatformName(AbstractPlatform $platform, $database)
+    {
+        return match (class_basename($platform)) {
+            'MySQLPlatform' => 'MySQL <= 5',
+            'MySQL57Platform' => 'MySQL 5.7',
+            'MySQL80Platform' => 'MySQL 8',
+            'PostgreSQL100Platform', 'PostgreSQLPlatform' => 'Postgres',
+            'SqlitePlatform' => 'SQLite',
+            'SQLServerPlatform' => 'SQL Server',
+            'SQLServer2012Platform' => 'SQL Server 2012',
+            default => $database,
+        };
+    }
+
+    /**
+     * Get the size of a table in bytes.
+     *
+     * @param  \Illuminate\Database\ConnectionInterface  $connection
+     * @param  string  $table
+     * @return int|null
+     */
+    protected function getTableSize(ConnectionInterface $connection, string $table)
+    {
+        return match (true) {
+            $connection instanceof MySqlConnection => $this->getMySQLTableSize($connection, $table),
+            $connection instanceof PostgresConnection => $this->getPostgresTableSize($connection, $table),
+            $connection instanceof SQLiteConnection => $this->getSqliteTableSize($connection, $table),
+            default => null,
+        };
+    }
+
+    /**
+     * Get the size of a MySQL table in bytes.
+     *
+     * @param  \Illuminate\Database\ConnectionInterface  $connection
+     * @param  string  $table
+     * @return mixed
+     */
+    protected function getMySQLTableSize(ConnectionInterface $connection, string $table)
+    {
+        $result = $connection->selectOne('SELECT (data_length + index_length) AS size FROM information_schema.TABLES WHERE table_schema = ? AND table_name = ?', [
+            $connection->getDatabaseName(),
+            $table,
+        ]);
+
+        return Arr::wrap((array) $result)['size'];
+    }
+
+    /**
+     * Get the size of a Postgres table in bytes.
+     *
+     * @param  \Illuminate\Database\ConnectionInterface  $connection
+     * @param  string  $table
+     * @return mixed
+     */
+    protected function getPostgresTableSize(ConnectionInterface $connection, string $table)
+    {
+        $result = $connection->selectOne('SELECT pg_total_relation_size(?) AS size;', [
+            $table,
+        ]);
+
+        return Arr::wrap((array) $result)['size'];
+    }
+
+    /**
+     * Get the size of a SQLite table in bytes.
+     *
+     * @param  \Illuminate\Database\ConnectionInterface  $connection
+     * @param  string  $table
+     * @return mixed
+     */
+    protected function getSqliteTableSize(ConnectionInterface $connection, string $table)
+    {
+        try {
+            $result = $connection->selectOne('SELECT SUM(pgsize) AS size FROM dbstat WHERE name=?', [
+                $table,
+            ]);
+
+            return Arr::wrap((array) $result)['size'];
+        } catch (QueryException $e) {
+            return null;
+        }
+    }
+
+    /**
+     * Get the number of open connections for a database.
+     *
+     * @param  \Illuminate\Database\ConnectionInterface  $connection
+     * @return int|null
+     */
+    protected function getConnectionCount(ConnectionInterface $connection)
+    {
+        $result = match (true) {
+            $connection instanceof MySqlConnection => $connection->selectOne('show status where variable_name = "threads_connected"'),
+            $connection instanceof PostgresConnection => $connection->selectOne('select count(*) AS "Value" from pg_stat_activity'),
+            $connection instanceof SqlServerConnection => $connection->selectOne('SELECT COUNT(*) Value FROM sys.dm_exec_sessions WHERE status = ?', ['running']),
+            default => null,
+        };
+
+        if (! $result) {
+            return null;
+        }
+
+        return Arr::wrap((array) $result)['Value'];
+    }
+
+    /**
+     * Get the connection configuration details for the given connection.
+     *
+     * @param  string  $database
+     * @return array
+     */
+    protected function getConfigFromDatabase($database)
+    {
+        $database ??= config('database.default');
+
+        return Arr::except(config('database.connections.'.$database), ['password']);
+    }
+
+    /**
+     * Ensure the dependencies for the database commands are available.
+     *
+     * @return bool
+     */
+    protected function ensureDependenciesExist()
+    {
+        return tap(interface_exists('Doctrine\DBAL\Driver'), function ($dependenciesExist) {
+            if (! $dependenciesExist && $this->components->confirm('Inspecting database information requires the Doctrine DBAL (doctrine/dbal) package. Would you like to install it?')) {
+                $this->installDependencies();
+            }
+        });
+    }
+
+    /**
+     * Install the command's dependencies.
+     *
+     * @return void
+     *
+     * @throws \Symfony\Component\Process\Exception\ProcessSignaledException
+     */
+    protected function installDependencies()
+    {
+        $command = collect($this->composer->findComposer())
+            ->push('require doctrine/dbal')
+            ->implode(' ');
+
+        $process = Process::fromShellCommandline($command, null, null, null, null);
+
+        if ('\\' !== DIRECTORY_SEPARATOR && file_exists('/dev/tty') && is_readable('/dev/tty')) {
+            try {
+                $process->setTty(true);
+            } catch (RuntimeException $e) {
+                $this->components->warn($e->getMessage());
+            }
+        }
+
+        try {
+            $process->run(fn ($type, $line) => $this->output->write($line));
+        } catch (ProcessSignaledException $e) {
+            if (extension_loaded('pcntl') && $e->getSignal() !== SIGINT) {
+                throw $e;
+            }
+        }
+    }
+}
diff --git a/vendor/illuminate/database/Console/DbCommand.php b/vendor/illuminate/database/Console/DbCommand.php
new file mode 100644
index 0000000..caecafe
--- /dev/null
+++ b/vendor/illuminate/database/Console/DbCommand.php
@@ -0,0 +1,227 @@
+getConnection();
+
+        if (! isset($connection['host']) && $connection['driver'] !== 'sqlite') {
+            $this->components->error('No host specified for this database connection.');
+            $this->line('  Use the [--read] and [--write] options to specify a read or write connection.');
+            $this->newLine();
+
+            return Command::FAILURE;
+        }
+
+        (new Process(
+            array_merge([$this->getCommand($connection)], $this->commandArguments($connection)),
+            null,
+            $this->commandEnvironment($connection)
+        ))->setTimeout(null)->setTty(true)->mustRun(function ($type, $buffer) {
+            $this->output->write($buffer);
+        });
+
+        return 0;
+    }
+
+    /**
+     * Get the database connection configuration.
+     *
+     * @return array
+     *
+     * @throws \UnexpectedValueException
+     */
+    public function getConnection()
+    {
+        $connection = $this->laravel['config']['database.connections.'.
+            (($db = $this->argument('connection')) ?? $this->laravel['config']['database.default'])
+        ];
+
+        if (empty($connection)) {
+            throw new UnexpectedValueException("Invalid database connection [{$db}].");
+        }
+
+        if (! empty($connection['url'])) {
+            $connection = (new ConfigurationUrlParser)->parseConfiguration($connection);
+        }
+
+        if ($this->option('read')) {
+            if (is_array($connection['read']['host'])) {
+                $connection['read']['host'] = $connection['read']['host'][0];
+            }
+
+            $connection = array_merge($connection, $connection['read']);
+        } elseif ($this->option('write')) {
+            if (is_array($connection['write']['host'])) {
+                $connection['write']['host'] = $connection['write']['host'][0];
+            }
+
+            $connection = array_merge($connection, $connection['write']);
+        }
+
+        return $connection;
+    }
+
+    /**
+     * Get the arguments for the database client command.
+     *
+     * @param  array  $connection
+     * @return array
+     */
+    public function commandArguments(array $connection)
+    {
+        $driver = ucfirst($connection['driver']);
+
+        return $this->{"get{$driver}Arguments"}($connection);
+    }
+
+    /**
+     * Get the environment variables for the database client command.
+     *
+     * @param  array  $connection
+     * @return array|null
+     */
+    public function commandEnvironment(array $connection)
+    {
+        $driver = ucfirst($connection['driver']);
+
+        if (method_exists($this, "get{$driver}Environment")) {
+            return $this->{"get{$driver}Environment"}($connection);
+        }
+
+        return null;
+    }
+
+    /**
+     * Get the database client command to run.
+     *
+     * @param  array  $connection
+     * @return string
+     */
+    public function getCommand(array $connection)
+    {
+        return [
+            'mysql' => 'mysql',
+            'pgsql' => 'psql',
+            'sqlite' => 'sqlite3',
+            'sqlsrv' => 'sqlcmd',
+        ][$connection['driver']];
+    }
+
+    /**
+     * Get the arguments for the MySQL CLI.
+     *
+     * @param  array  $connection
+     * @return array
+     */
+    protected function getMysqlArguments(array $connection)
+    {
+        return array_merge([
+            '--host='.$connection['host'],
+            '--port='.$connection['port'],
+            '--user='.$connection['username'],
+        ], $this->getOptionalArguments([
+            'password' => '--password='.$connection['password'],
+            'unix_socket' => '--socket='.($connection['unix_socket'] ?? ''),
+            'charset' => '--default-character-set='.($connection['charset'] ?? ''),
+        ], $connection), [$connection['database']]);
+    }
+
+    /**
+     * Get the arguments for the Postgres CLI.
+     *
+     * @param  array  $connection
+     * @return array
+     */
+    protected function getPgsqlArguments(array $connection)
+    {
+        return [$connection['database']];
+    }
+
+    /**
+     * Get the arguments for the SQLite CLI.
+     *
+     * @param  array  $connection
+     * @return array
+     */
+    protected function getSqliteArguments(array $connection)
+    {
+        return [$connection['database']];
+    }
+
+    /**
+     * Get the arguments for the SQL Server CLI.
+     *
+     * @param  array  $connection
+     * @return array
+     */
+    protected function getSqlsrvArguments(array $connection)
+    {
+        return array_merge(...$this->getOptionalArguments([
+            'database' => ['-d', $connection['database']],
+            'username' => ['-U', $connection['username']],
+            'password' => ['-P', $connection['password']],
+            'host' => ['-S', 'tcp:'.$connection['host']
+                        .($connection['port'] ? ','.$connection['port'] : ''), ],
+        ], $connection));
+    }
+
+    /**
+     * Get the environment variables for the Postgres CLI.
+     *
+     * @param  array  $connection
+     * @return array|null
+     */
+    protected function getPgsqlEnvironment(array $connection)
+    {
+        return array_merge(...$this->getOptionalArguments([
+            'username' => ['PGUSER' => $connection['username']],
+            'host' => ['PGHOST' => $connection['host']],
+            'port' => ['PGPORT' => $connection['port']],
+            'password' => ['PGPASSWORD' => $connection['password']],
+        ], $connection));
+    }
+
+    /**
+     * Get the optional arguments based on the connection configuration.
+     *
+     * @param  array  $args
+     * @param  array  $connection
+     * @return array
+     */
+    protected function getOptionalArguments(array $args, array $connection)
+    {
+        return array_values(array_filter($args, function ($key) use ($connection) {
+            return ! empty($connection[$key]);
+        }, ARRAY_FILTER_USE_KEY));
+    }
+}
diff --git a/vendor/illuminate/database/Console/DumpCommand.php b/vendor/illuminate/database/Console/DumpCommand.php
new file mode 100644
index 0000000..3f21aaf
--- /dev/null
+++ b/vendor/illuminate/database/Console/DumpCommand.php
@@ -0,0 +1,101 @@
+connection($database = $this->input->getOption('database'));
+
+        $this->schemaState($connection)->dump(
+            $connection, $path = $this->path($connection)
+        );
+
+        $dispatcher->dispatch(new SchemaDumped($connection, $path));
+
+        $info = 'Database schema dumped';
+
+        if ($this->option('prune')) {
+            (new Filesystem)->deleteDirectory(
+                database_path('migrations'), $preserve = false
+            );
+
+            $info .= ' and pruned';
+        }
+
+        $this->components->info($info.' successfully.');
+    }
+
+    /**
+     * Create a schema state instance for the given connection.
+     *
+     * @param  \Illuminate\Database\Connection  $connection
+     * @return mixed
+     */
+    protected function schemaState(Connection $connection)
+    {
+        return $connection->getSchemaState()
+                ->withMigrationTable($connection->getTablePrefix().Config::get('database.migrations', 'migrations'))
+                ->handleOutputUsing(function ($type, $buffer) {
+                    $this->output->write($buffer);
+                });
+    }
+
+    /**
+     * Get the path that the dump should be written to.
+     *
+     * @param  \Illuminate\Database\Connection  $connection
+     */
+    protected function path(Connection $connection)
+    {
+        return tap($this->option('path') ?: database_path('schema/'.$connection->getName().'-schema.sql'), function ($path) {
+            (new Filesystem)->ensureDirectoryExists(dirname($path));
+        });
+    }
+}
diff --git a/vendor/illuminate/database/Console/Factories/FactoryMakeCommand.php b/vendor/illuminate/database/Console/Factories/FactoryMakeCommand.php
new file mode 100644
index 0000000..48c4375
--- /dev/null
+++ b/vendor/illuminate/database/Console/Factories/FactoryMakeCommand.php
@@ -0,0 +1,154 @@
+resolveStubPath('/stubs/factory.stub');
+    }
+
+    /**
+     * Resolve the fully-qualified path to the stub.
+     *
+     * @param  string  $stub
+     * @return string
+     */
+    protected function resolveStubPath($stub)
+    {
+        return file_exists($customPath = $this->laravel->basePath(trim($stub, '/')))
+            ? $customPath
+            : __DIR__.$stub;
+    }
+
+    /**
+     * Build the class with the given name.
+     *
+     * @param  string  $name
+     * @return string
+     */
+    protected function buildClass($name)
+    {
+        $factory = class_basename(Str::ucfirst(str_replace('Factory', '', $name)));
+
+        $namespaceModel = $this->option('model')
+                        ? $this->qualifyModel($this->option('model'))
+                        : $this->qualifyModel($this->guessModelName($name));
+
+        $model = class_basename($namespaceModel);
+
+        $namespace = $this->getNamespace(
+            Str::replaceFirst($this->rootNamespace(), 'Database\\Factories\\', $this->qualifyClass($this->getNameInput()))
+        );
+
+        $replace = [
+            '{{ factoryNamespace }}' => $namespace,
+            'NamespacedDummyModel' => $namespaceModel,
+            '{{ namespacedModel }}' => $namespaceModel,
+            '{{namespacedModel}}' => $namespaceModel,
+            'DummyModel' => $model,
+            '{{ model }}' => $model,
+            '{{model}}' => $model,
+            '{{ factory }}' => $factory,
+            '{{factory}}' => $factory,
+        ];
+
+        return str_replace(
+            array_keys($replace), array_values($replace), parent::buildClass($name)
+        );
+    }
+
+    /**
+     * Get the destination class path.
+     *
+     * @param  string  $name
+     * @return string
+     */
+    protected function getPath($name)
+    {
+        $name = (string) Str::of($name)->replaceFirst($this->rootNamespace(), '')->finish('Factory');
+
+        return $this->laravel->databasePath().'/factories/'.str_replace('\\', '/', $name).'.php';
+    }
+
+    /**
+     * Guess the model name from the Factory name or return a default model name.
+     *
+     * @param  string  $name
+     * @return string
+     */
+    protected function guessModelName($name)
+    {
+        if (str_ends_with($name, 'Factory')) {
+            $name = substr($name, 0, -7);
+        }
+
+        $modelName = $this->qualifyModel(Str::after($name, $this->rootNamespace()));
+
+        if (class_exists($modelName)) {
+            return $modelName;
+        }
+
+        if (is_dir(app_path('Models/'))) {
+            return $this->rootNamespace().'Models\Model';
+        }
+
+        return $this->rootNamespace().'Model';
+    }
+
+    /**
+     * Get the console command options.
+     *
+     * @return array
+     */
+    protected function getOptions()
+    {
+        return [
+            ['model', 'm', InputOption::VALUE_OPTIONAL, 'The name of the model'],
+        ];
+    }
+}
diff --git a/vendor/illuminate/database/Console/Factories/stubs/factory.stub b/vendor/illuminate/database/Console/Factories/stubs/factory.stub
new file mode 100644
index 0000000..0759b5d
--- /dev/null
+++ b/vendor/illuminate/database/Console/Factories/stubs/factory.stub
@@ -0,0 +1,23 @@
+
+ */
+class {{ factory }}Factory extends Factory
+{
+    /**
+     * Define the model's default state.
+     *
+     * @return array
+     */
+    public function definition()
+    {
+        return [
+            //
+        ];
+    }
+}
diff --git a/vendor/illuminate/database/Console/Migrations/BaseCommand.php b/vendor/illuminate/database/Console/Migrations/BaseCommand.php
new file mode 100755
index 0000000..6c4f255
--- /dev/null
+++ b/vendor/illuminate/database/Console/Migrations/BaseCommand.php
@@ -0,0 +1,51 @@
+input->hasOption('path') && $this->option('path')) {
+            return collect($this->option('path'))->map(function ($path) {
+                return ! $this->usingRealPath()
+                                ? $this->laravel->basePath().'/'.$path
+                                : $path;
+            })->all();
+        }
+
+        return array_merge(
+            $this->migrator->paths(), [$this->getMigrationPath()]
+        );
+    }
+
+    /**
+     * Determine if the given path(s) are pre-resolved "real" paths.
+     *
+     * @return bool
+     */
+    protected function usingRealPath()
+    {
+        return $this->input->hasOption('realpath') && $this->option('realpath');
+    }
+
+    /**
+     * Get the path to the migration directory.
+     *
+     * @return string
+     */
+    protected function getMigrationPath()
+    {
+        return $this->laravel->databasePath().DIRECTORY_SEPARATOR.'migrations';
+    }
+}
diff --git a/vendor/illuminate/database/Console/Migrations/FreshCommand.php b/vendor/illuminate/database/Console/Migrations/FreshCommand.php
new file mode 100644
index 0000000..e319e74
--- /dev/null
+++ b/vendor/illuminate/database/Console/Migrations/FreshCommand.php
@@ -0,0 +1,120 @@
+confirmToProceed()) {
+            return 1;
+        }
+
+        $database = $this->input->getOption('database');
+
+        $this->newLine();
+
+        $this->components->task('Dropping all tables', fn () => $this->callSilent('db:wipe', array_filter([
+            '--database' => $database,
+            '--drop-views' => $this->option('drop-views'),
+            '--drop-types' => $this->option('drop-types'),
+            '--force' => true,
+        ])) == 0);
+
+        $this->newLine();
+
+        $this->call('migrate', array_filter([
+            '--database' => $database,
+            '--path' => $this->input->getOption('path'),
+            '--realpath' => $this->input->getOption('realpath'),
+            '--schema-path' => $this->input->getOption('schema-path'),
+            '--force' => true,
+            '--step' => $this->option('step'),
+        ]));
+
+        if ($this->laravel->bound(Dispatcher::class)) {
+            $this->laravel[Dispatcher::class]->dispatch(
+                new DatabaseRefreshed
+            );
+        }
+
+        if ($this->needsSeeding()) {
+            $this->runSeeder($database);
+        }
+
+        return 0;
+    }
+
+    /**
+     * Determine if the developer has requested database seeding.
+     *
+     * @return bool
+     */
+    protected function needsSeeding()
+    {
+        return $this->option('seed') || $this->option('seeder');
+    }
+
+    /**
+     * Run the database seeder command.
+     *
+     * @param  string  $database
+     * @return void
+     */
+    protected function runSeeder($database)
+    {
+        $this->call('db:seed', array_filter([
+            '--database' => $database,
+            '--class' => $this->option('seeder') ?: 'Database\\Seeders\\DatabaseSeeder',
+            '--force' => true,
+        ]));
+    }
+
+    /**
+     * Get the console command options.
+     *
+     * @return array
+     */
+    protected function getOptions()
+    {
+        return [
+            ['database', null, InputOption::VALUE_OPTIONAL, 'The database connection to use'],
+            ['drop-views', null, InputOption::VALUE_NONE, 'Drop all tables and views'],
+            ['drop-types', null, InputOption::VALUE_NONE, 'Drop all tables and types (Postgres only)'],
+            ['force', null, InputOption::VALUE_NONE, 'Force the operation to run when in production'],
+            ['path', null, InputOption::VALUE_OPTIONAL | InputOption::VALUE_IS_ARRAY, 'The path(s) to the migrations files to be executed'],
+            ['realpath', null, InputOption::VALUE_NONE, 'Indicate any provided migration file paths are pre-resolved absolute paths'],
+            ['schema-path', null, InputOption::VALUE_OPTIONAL, 'The path to a schema dump file'],
+            ['seed', null, InputOption::VALUE_NONE, 'Indicates if the seed task should be re-run'],
+            ['seeder', null, InputOption::VALUE_OPTIONAL, 'The class name of the root seeder'],
+            ['step', null, InputOption::VALUE_NONE, 'Force the migrations to be run so they can be rolled back individually'],
+        ];
+    }
+}
diff --git a/vendor/illuminate/database/Console/Migrations/InstallCommand.php b/vendor/illuminate/database/Console/Migrations/InstallCommand.php
new file mode 100755
index 0000000..901a83b
--- /dev/null
+++ b/vendor/illuminate/database/Console/Migrations/InstallCommand.php
@@ -0,0 +1,70 @@
+repository = $repository;
+    }
+
+    /**
+     * Execute the console command.
+     *
+     * @return void
+     */
+    public function handle()
+    {
+        $this->repository->setSource($this->input->getOption('database'));
+
+        $this->repository->createRepository();
+
+        $this->components->info('Migration table created successfully.');
+    }
+
+    /**
+     * Get the console command options.
+     *
+     * @return array
+     */
+    protected function getOptions()
+    {
+        return [
+            ['database', null, InputOption::VALUE_OPTIONAL, 'The database connection to use'],
+        ];
+    }
+}
diff --git a/vendor/illuminate/database/Console/Migrations/MigrateCommand.php b/vendor/illuminate/database/Console/Migrations/MigrateCommand.php
new file mode 100755
index 0000000..fc43bf5
--- /dev/null
+++ b/vendor/illuminate/database/Console/Migrations/MigrateCommand.php
@@ -0,0 +1,281 @@
+migrator = $migrator;
+        $this->dispatcher = $dispatcher;
+    }
+
+    /**
+     * Execute the console command.
+     *
+     * @return int
+     */
+    public function handle()
+    {
+        if (! $this->confirmToProceed()) {
+            return 1;
+        }
+
+        $this->migrator->usingConnection($this->option('database'), function () {
+            $this->prepareDatabase();
+
+            // Next, we will check to see if a path option has been defined. If it has
+            // we will use the path relative to the root of this installation folder
+            // so that migrations may be run for any path within the applications.
+            $migrations = $this->migrator->setOutput($this->output)
+                    ->run($this->getMigrationPaths(), [
+                        'pretend' => $this->option('pretend'),
+                        'step' => $this->option('step'),
+                    ]);
+
+            // Finally, if the "seed" option has been given, we will re-run the database
+            // seed task to re-populate the database, which is convenient when adding
+            // a migration and a seed at the same time, as it is only this command.
+            if ($this->option('seed') && ! $this->option('pretend')) {
+                $this->call('db:seed', [
+                    '--class' => $this->option('seeder') ?: 'Database\\Seeders\\DatabaseSeeder',
+                    '--force' => true,
+                ]);
+            }
+        });
+
+        return 0;
+    }
+
+    /**
+     * Prepare the migration database for running.
+     *
+     * @return void
+     */
+    protected function prepareDatabase()
+    {
+        if (! $this->repositoryExists()) {
+            $this->components->info('Preparing database.');
+
+            $this->components->task('Creating migration table', function () {
+                return $this->callSilent('migrate:install', array_filter([
+                    '--database' => $this->option('database'),
+                ])) == 0;
+            });
+
+            $this->newLine();
+        }
+
+        if (! $this->migrator->hasRunAnyMigrations() && ! $this->option('pretend')) {
+            $this->loadSchemaState();
+        }
+    }
+
+    /**
+     * Determine if the migrator repository exists.
+     *
+     * @return bool
+     */
+    protected function repositoryExists()
+    {
+        return retry(2, fn () => $this->migrator->repositoryExists(), 0, function ($e) {
+            try {
+                if ($e->getPrevious() instanceof SQLiteDatabaseDoesNotExistException) {
+                    return $this->createMissingSqliteDatbase($e->getPrevious()->path);
+                }
+
+                $connection = $this->migrator->resolveConnection($this->option('database'));
+
+                if (
+                    $e->getPrevious() instanceof PDOException &&
+                    $e->getPrevious()->getCode() === 1049 &&
+                    $connection->getDriverName() === 'mysql') {
+                    return $this->createMissingMysqlDatabase($connection);
+                }
+
+                return false;
+            } catch (Throwable) {
+                return false;
+            }
+        });
+    }
+
+    /**
+     * Create a missing SQLite database.
+     *
+     * @param  string  $path
+     * @return bool
+     */
+    protected function createMissingSqliteDatbase($path)
+    {
+        if ($this->option('force')) {
+            return touch($path);
+        }
+
+        if ($this->option('no-interaction')) {
+            return false;
+        }
+
+        $this->components->warn('The SQLite database does not exist: '.$path);
+
+        if (! $this->components->confirm('Would you like to create it?')) {
+            return false;
+        }
+
+        return touch($path);
+    }
+
+    /**
+     * Create a missing MySQL database.
+     *
+     * @return bool
+     */
+    protected function createMissingMysqlDatabase($connection)
+    {
+        if ($this->laravel['config']->get("database.connections.{$connection->getName()}.database") !== $connection->getDatabaseName()) {
+            return false;
+        }
+
+        if (! $this->option('force') && $this->option('no-interaction')) {
+            return false;
+        }
+
+        if (! $this->option('force') && ! $this->option('no-interaction')) {
+            $this->components->warn("The database '{$connection->getDatabaseName()}' does not exist on the '{$connection->getName()}' connection.");
+
+            if (! $this->components->confirm('Would you like to create it?')) {
+                return false;
+            }
+        }
+
+        try {
+            $this->laravel['config']->set("database.connections.{$connection->getName()}.database", null);
+
+            $this->laravel['db']->purge();
+
+            $freshConnection = $this->migrator->resolveConnection($this->option('database'));
+
+            return tap($freshConnection->unprepared("CREATE DATABASE IF NOT EXISTS `{$connection->getDatabaseName()}`"), function () {
+                $this->laravel['db']->purge();
+            });
+        } finally {
+            $this->laravel['config']->set("database.connections.{$connection->getName()}.database", $connection->getDatabaseName());
+        }
+    }
+
+    /**
+     * Load the schema state to seed the initial database schema structure.
+     *
+     * @return void
+     */
+    protected function loadSchemaState()
+    {
+        $connection = $this->migrator->resolveConnection($this->option('database'));
+
+        // First, we will make sure that the connection supports schema loading and that
+        // the schema file exists before we proceed any further. If not, we will just
+        // continue with the standard migration operation as normal without errors.
+        if ($connection instanceof SqlServerConnection ||
+            ! is_file($path = $this->schemaPath($connection))) {
+            return;
+        }
+
+        $this->components->info('Loading stored database schemas.');
+
+        $this->components->task($path, function () use ($connection, $path) {
+            // Since the schema file will create the "migrations" table and reload it to its
+            // proper state, we need to delete it here so we don't get an error that this
+            // table already exists when the stored database schema file gets executed.
+            $this->migrator->deleteRepository();
+
+            $connection->getSchemaState()->handleOutputUsing(function ($type, $buffer) {
+                $this->output->write($buffer);
+            })->load($path);
+        });
+
+        $this->newLine();
+
+        // Finally, we will fire an event that this schema has been loaded so developers
+        // can perform any post schema load tasks that are necessary in listeners for
+        // this event, which may seed the database tables with some necessary data.
+        $this->dispatcher->dispatch(
+            new SchemaLoaded($connection, $path)
+        );
+    }
+
+    /**
+     * Get the path to the stored schema for the given connection.
+     *
+     * @param  \Illuminate\Database\Connection  $connection
+     * @return string
+     */
+    protected function schemaPath($connection)
+    {
+        if ($this->option('schema-path')) {
+            return $this->option('schema-path');
+        }
+
+        if (file_exists($path = database_path('schema/'.$connection->getName().'-schema.dump'))) {
+            return $path;
+        }
+
+        return database_path('schema/'.$connection->getName().'-schema.sql');
+    }
+}
diff --git a/vendor/illuminate/database/Console/Migrations/MigrateMakeCommand.php b/vendor/illuminate/database/Console/Migrations/MigrateMakeCommand.php
new file mode 100644
index 0000000..75c0634
--- /dev/null
+++ b/vendor/illuminate/database/Console/Migrations/MigrateMakeCommand.php
@@ -0,0 +1,144 @@
+creator = $creator;
+        $this->composer = $composer;
+    }
+
+    /**
+     * Execute the console command.
+     *
+     * @return void
+     */
+    public function handle()
+    {
+        // It's possible for the developer to specify the tables to modify in this
+        // schema operation. The developer may also specify if this table needs
+        // to be freshly created so we can create the appropriate migrations.
+        $name = Str::snake(trim($this->input->getArgument('name')));
+
+        $table = $this->input->getOption('table');
+
+        $create = $this->input->getOption('create') ?: false;
+
+        // If no table was given as an option but a create option is given then we
+        // will use the "create" option as the table name. This allows the devs
+        // to pass a table name into this option as a short-cut for creating.
+        if (! $table && is_string($create)) {
+            $table = $create;
+
+            $create = true;
+        }
+
+        // Next, we will attempt to guess the table name if this the migration has
+        // "create" in the name. This will allow us to provide a convenient way
+        // of creating migrations that create new tables for the application.
+        if (! $table) {
+            [$table, $create] = TableGuesser::guess($name);
+        }
+
+        // Now we are ready to write the migration out to disk. Once we've written
+        // the migration out, we will dump-autoload for the entire framework to
+        // make sure that the migrations are registered by the class loaders.
+        $this->writeMigration($name, $table, $create);
+
+        $this->composer->dumpAutoloads();
+    }
+
+    /**
+     * Write the migration file to disk.
+     *
+     * @param  string  $name
+     * @param  string  $table
+     * @param  bool  $create
+     * @return string
+     */
+    protected function writeMigration($name, $table, $create)
+    {
+        $file = $this->creator->create(
+            $name, $this->getMigrationPath(), $table, $create
+        );
+
+        $this->components->info(sprintf('Migration [%s] created successfully.', $file));
+    }
+
+    /**
+     * Get migration path (either specified by '--path' option or default location).
+     *
+     * @return string
+     */
+    protected function getMigrationPath()
+    {
+        if (! is_null($targetPath = $this->input->getOption('path'))) {
+            return ! $this->usingRealPath()
+                            ? $this->laravel->basePath().'/'.$targetPath
+                            : $targetPath;
+        }
+
+        return parent::getMigrationPath();
+    }
+
+    /**
+     * Prompt for missing input arguments using the returned questions.
+     *
+     * @return array
+     */
+    protected function promptForMissingArgumentsUsing()
+    {
+        return [
+            'name' => 'What should the migration be named?',
+        ];
+    }
+}
diff --git a/vendor/illuminate/database/Console/Migrations/RefreshCommand.php b/vendor/illuminate/database/Console/Migrations/RefreshCommand.php
new file mode 100755
index 0000000..2073cd9
--- /dev/null
+++ b/vendor/illuminate/database/Console/Migrations/RefreshCommand.php
@@ -0,0 +1,159 @@
+confirmToProceed()) {
+            return 1;
+        }
+
+        // Next we'll gather some of the options so that we can have the right options
+        // to pass to the commands. This includes options such as which database to
+        // use and the path to use for the migration. Then we'll run the command.
+        $database = $this->input->getOption('database');
+
+        $path = $this->input->getOption('path');
+
+        // If the "step" option is specified it means we only want to rollback a small
+        // number of migrations before migrating again. For example, the user might
+        // only rollback and remigrate the latest four migrations instead of all.
+        $step = $this->input->getOption('step') ?: 0;
+
+        if ($step > 0) {
+            $this->runRollback($database, $path, $step);
+        } else {
+            $this->runReset($database, $path);
+        }
+
+        // The refresh command is essentially just a brief aggregate of a few other of
+        // the migration commands and just provides a convenient wrapper to execute
+        // them in succession. We'll also see if we need to re-seed the database.
+        $this->call('migrate', array_filter([
+            '--database' => $database,
+            '--path' => $path,
+            '--realpath' => $this->input->getOption('realpath'),
+            '--force' => true,
+        ]));
+
+        if ($this->laravel->bound(Dispatcher::class)) {
+            $this->laravel[Dispatcher::class]->dispatch(
+                new DatabaseRefreshed
+            );
+        }
+
+        if ($this->needsSeeding()) {
+            $this->runSeeder($database);
+        }
+
+        return 0;
+    }
+
+    /**
+     * Run the rollback command.
+     *
+     * @param  string  $database
+     * @param  string  $path
+     * @param  int  $step
+     * @return void
+     */
+    protected function runRollback($database, $path, $step)
+    {
+        $this->call('migrate:rollback', array_filter([
+            '--database' => $database,
+            '--path' => $path,
+            '--realpath' => $this->input->getOption('realpath'),
+            '--step' => $step,
+            '--force' => true,
+        ]));
+    }
+
+    /**
+     * Run the reset command.
+     *
+     * @param  string  $database
+     * @param  string  $path
+     * @return void
+     */
+    protected function runReset($database, $path)
+    {
+        $this->call('migrate:reset', array_filter([
+            '--database' => $database,
+            '--path' => $path,
+            '--realpath' => $this->input->getOption('realpath'),
+            '--force' => true,
+        ]));
+    }
+
+    /**
+     * Determine if the developer has requested database seeding.
+     *
+     * @return bool
+     */
+    protected function needsSeeding()
+    {
+        return $this->option('seed') || $this->option('seeder');
+    }
+
+    /**
+     * Run the database seeder command.
+     *
+     * @param  string  $database
+     * @return void
+     */
+    protected function runSeeder($database)
+    {
+        $this->call('db:seed', array_filter([
+            '--database' => $database,
+            '--class' => $this->option('seeder') ?: 'Database\\Seeders\\DatabaseSeeder',
+            '--force' => true,
+        ]));
+    }
+
+    /**
+     * Get the console command options.
+     *
+     * @return array
+     */
+    protected function getOptions()
+    {
+        return [
+            ['database', null, InputOption::VALUE_OPTIONAL, 'The database connection to use'],
+            ['force', null, InputOption::VALUE_NONE, 'Force the operation to run when in production'],
+            ['path', null, InputOption::VALUE_OPTIONAL | InputOption::VALUE_IS_ARRAY, 'The path(s) to the migrations files to be executed'],
+            ['realpath', null, InputOption::VALUE_NONE, 'Indicate any provided migration file paths are pre-resolved absolute paths'],
+            ['seed', null, InputOption::VALUE_NONE, 'Indicates if the seed task should be re-run'],
+            ['seeder', null, InputOption::VALUE_OPTIONAL, 'The class name of the root seeder'],
+            ['step', null, InputOption::VALUE_OPTIONAL, 'The number of migrations to be reverted & re-run'],
+        ];
+    }
+}
diff --git a/vendor/illuminate/database/Console/Migrations/ResetCommand.php b/vendor/illuminate/database/Console/Migrations/ResetCommand.php
new file mode 100755
index 0000000..c5952fa
--- /dev/null
+++ b/vendor/illuminate/database/Console/Migrations/ResetCommand.php
@@ -0,0 +1,91 @@
+migrator = $migrator;
+    }
+
+    /**
+     * Execute the console command.
+     *
+     * @return int
+     */
+    public function handle()
+    {
+        if (! $this->confirmToProceed()) {
+            return 1;
+        }
+
+        return $this->migrator->usingConnection($this->option('database'), function () {
+            // First, we'll make sure that the migration table actually exists before we
+            // start trying to rollback and re-run all of the migrations. If it's not
+            // present we'll just bail out with an info message for the developers.
+            if (! $this->migrator->repositoryExists()) {
+                return $this->components->warn('Migration table not found.');
+            }
+
+            $this->migrator->setOutput($this->output)->reset(
+                $this->getMigrationPaths(), $this->option('pretend')
+            );
+        });
+    }
+
+    /**
+     * Get the console command options.
+     *
+     * @return array
+     */
+    protected function getOptions()
+    {
+        return [
+            ['database', null, InputOption::VALUE_OPTIONAL, 'The database connection to use'],
+
+            ['force', null, InputOption::VALUE_NONE, 'Force the operation to run when in production'],
+
+            ['path', null, InputOption::VALUE_OPTIONAL | InputOption::VALUE_IS_ARRAY, 'The path(s) to the migrations files to be executed'],
+
+            ['realpath', null, InputOption::VALUE_NONE, 'Indicate any provided migration file paths are pre-resolved absolute paths'],
+
+            ['pretend', null, InputOption::VALUE_NONE, 'Dump the SQL queries that would be run'],
+        ];
+    }
+}
diff --git a/vendor/illuminate/database/Console/Migrations/RollbackCommand.php b/vendor/illuminate/database/Console/Migrations/RollbackCommand.php
new file mode 100755
index 0000000..c851360
--- /dev/null
+++ b/vendor/illuminate/database/Console/Migrations/RollbackCommand.php
@@ -0,0 +1,91 @@
+migrator = $migrator;
+    }
+
+    /**
+     * Execute the console command.
+     *
+     * @return int
+     */
+    public function handle()
+    {
+        if (! $this->confirmToProceed()) {
+            return 1;
+        }
+
+        $this->migrator->usingConnection($this->option('database'), function () {
+            $this->migrator->setOutput($this->output)->rollback(
+                $this->getMigrationPaths(), [
+                    'pretend' => $this->option('pretend'),
+                    'step' => (int) $this->option('step'),
+                ]
+            );
+        });
+
+        return 0;
+    }
+
+    /**
+     * Get the console command options.
+     *
+     * @return array
+     */
+    protected function getOptions()
+    {
+        return [
+            ['database', null, InputOption::VALUE_OPTIONAL, 'The database connection to use'],
+
+            ['force', null, InputOption::VALUE_NONE, 'Force the operation to run when in production'],
+
+            ['path', null, InputOption::VALUE_OPTIONAL | InputOption::VALUE_IS_ARRAY, 'The path(s) to the migrations files to be executed'],
+
+            ['realpath', null, InputOption::VALUE_NONE, 'Indicate any provided migration file paths are pre-resolved absolute paths'],
+
+            ['pretend', null, InputOption::VALUE_NONE, 'Dump the SQL queries that would be run'],
+
+            ['step', null, InputOption::VALUE_OPTIONAL, 'The number of migrations to be reverted'],
+        ];
+    }
+}
diff --git a/vendor/illuminate/database/Console/Migrations/StatusCommand.php b/vendor/illuminate/database/Console/Migrations/StatusCommand.php
new file mode 100644
index 0000000..aa01f07
--- /dev/null
+++ b/vendor/illuminate/database/Console/Migrations/StatusCommand.php
@@ -0,0 +1,132 @@
+migrator = $migrator;
+    }
+
+    /**
+     * Execute the console command.
+     *
+     * @return int|null
+     */
+    public function handle()
+    {
+        return $this->migrator->usingConnection($this->option('database'), function () {
+            if (! $this->migrator->repositoryExists()) {
+                $this->components->error('Migration table not found.');
+
+                return 1;
+            }
+
+            $ran = $this->migrator->getRepository()->getRan();
+
+            $batches = $this->migrator->getRepository()->getMigrationBatches();
+
+            if (count($migrations = $this->getStatusFor($ran, $batches)) > 0) {
+                $this->newLine();
+
+                $this->components->twoColumnDetail('Migration name', 'Batch / Status');
+
+                $migrations
+                    ->when($this->option('pending'), fn ($collection) => $collection->filter(function ($migration) {
+                        return str($migration[1])->contains('Pending');
+                    }))
+                    ->each(
+                        fn ($migration) => $this->components->twoColumnDetail($migration[0], $migration[1])
+                    );
+
+                $this->newLine();
+            } else {
+                $this->components->info('No migrations found');
+            }
+        });
+    }
+
+    /**
+     * Get the status for the given run migrations.
+     *
+     * @param  array  $ran
+     * @param  array  $batches
+     * @return \Illuminate\Support\Collection
+     */
+    protected function getStatusFor(array $ran, array $batches)
+    {
+        return Collection::make($this->getAllMigrationFiles())
+                    ->map(function ($migration) use ($ran, $batches) {
+                        $migrationName = $this->migrator->getMigrationName($migration);
+
+                        $status = in_array($migrationName, $ran)
+                            ? 'Ran'
+                            : 'Pending';
+
+                        if (in_array($migrationName, $ran)) {
+                            $status = '['.$batches[$migrationName].'] '.$status;
+                        }
+
+                        return [$migrationName, $status];
+                    });
+    }
+
+    /**
+     * Get an array of all of the migration files.
+     *
+     * @return array
+     */
+    protected function getAllMigrationFiles()
+    {
+        return $this->migrator->getMigrationFiles($this->getMigrationPaths());
+    }
+
+    /**
+     * Get the console command options.
+     *
+     * @return array
+     */
+    protected function getOptions()
+    {
+        return [
+            ['database', null, InputOption::VALUE_OPTIONAL, 'The database connection to use'],
+            ['pending', null, InputOption::VALUE_NONE, 'Only list pending migrations'],
+            ['path', null, InputOption::VALUE_OPTIONAL | InputOption::VALUE_IS_ARRAY, 'The path(s) to the migrations files to use'],
+            ['realpath', null, InputOption::VALUE_NONE, 'Indicate any provided migration file paths are pre-resolved absolute paths'],
+        ];
+    }
+}
diff --git a/vendor/illuminate/database/Console/Migrations/TableGuesser.php b/vendor/illuminate/database/Console/Migrations/TableGuesser.php
new file mode 100644
index 0000000..82dfbdd
--- /dev/null
+++ b/vendor/illuminate/database/Console/Migrations/TableGuesser.php
@@ -0,0 +1,37 @@
+connection = $connection;
+        $this->events = $events;
+    }
+
+    /**
+     * Execute the console command.
+     *
+     * @return void
+     */
+    public function handle()
+    {
+        $databases = $this->parseDatabases($this->option('databases'));
+
+        $this->displayConnections($databases);
+
+        if ($this->option('max')) {
+            $this->dispatchEvents($databases);
+        }
+    }
+
+    /**
+     * Parse the database into an array of the connections.
+     *
+     * @param  string  $databases
+     * @return \Illuminate\Support\Collection
+     */
+    protected function parseDatabases($databases)
+    {
+        return collect(explode(',', $databases))->map(function ($database) {
+            if (! $database) {
+                $database = $this->laravel['config']['database.default'];
+            }
+
+            $maxConnections = $this->option('max');
+
+            return [
+                'database' => $database,
+                'connections' => $connections = $this->getConnectionCount($this->connection->connection($database)),
+                'status' => $maxConnections && $connections >= $maxConnections ? 'ALERT' : 'OK',
+            ];
+        });
+    }
+
+    /**
+     * Display the databases and their connection counts in the console.
+     *
+     * @param  \Illuminate\Support\Collection  $databases
+     * @return void
+     */
+    protected function displayConnections($databases)
+    {
+        $this->newLine();
+
+        $this->components->twoColumnDetail('Database name', 'Connections');
+
+        $databases->each(function ($database) {
+            $status = '['.$database['connections'].'] '.$database['status'];
+
+            $this->components->twoColumnDetail($database['database'], $status);
+        });
+
+        $this->newLine();
+    }
+
+    /**
+     * Dispatch the database monitoring events.
+     *
+     * @param  \Illuminate\Support\Collection  $databases
+     * @return void
+     */
+    protected function dispatchEvents($databases)
+    {
+        $databases->each(function ($database) {
+            if ($database['status'] === 'OK') {
+                return;
+            }
+
+            $this->events->dispatch(
+                new DatabaseBusy(
+                    $database['database'],
+                    $database['connections']
+                )
+            );
+        });
+    }
+}
diff --git a/vendor/illuminate/database/Console/PruneCommand.php b/vendor/illuminate/database/Console/PruneCommand.php
new file mode 100644
index 0000000..7ea6cec
--- /dev/null
+++ b/vendor/illuminate/database/Console/PruneCommand.php
@@ -0,0 +1,186 @@
+models();
+
+        if ($models->isEmpty()) {
+            $this->components->info('No prunable models found.');
+
+            return;
+        }
+
+        if ($this->option('pretend')) {
+            $models->each(function ($model) {
+                $this->pretendToPrune($model);
+            });
+
+            return;
+        }
+
+        $pruning = [];
+
+        $events->listen(ModelsPruned::class, function ($event) use (&$pruning) {
+            if (! in_array($event->model, $pruning)) {
+                $pruning[] = $event->model;
+
+                $this->newLine();
+
+                $this->components->info(sprintf('Pruning [%s] records.', $event->model));
+            }
+
+            $this->components->twoColumnDetail($event->model, "{$event->count} records");
+        });
+
+        $models->each(function ($model) {
+            $this->pruneModel($model);
+        });
+
+        $events->forget(ModelsPruned::class);
+    }
+
+    /**
+     * Prune the given model.
+     *
+     * @param  string  $model
+     * @return void
+     */
+    protected function pruneModel(string $model)
+    {
+        $instance = new $model;
+
+        $chunkSize = property_exists($instance, 'prunableChunkSize')
+            ? $instance->prunableChunkSize
+            : $this->option('chunk');
+
+        $total = $this->isPrunable($model)
+            ? $instance->pruneAll($chunkSize)
+            : 0;
+
+        if ($total == 0) {
+            $this->components->info("No prunable [$model] records found.");
+        }
+    }
+
+    /**
+     * Determine the models that should be pruned.
+     *
+     * @return \Illuminate\Support\Collection
+     */
+    protected function models()
+    {
+        if (! empty($models = $this->option('model'))) {
+            return collect($models)->filter(function ($model) {
+                return class_exists($model);
+            })->values();
+        }
+
+        $except = $this->option('except');
+
+        if (! empty($models) && ! empty($except)) {
+            throw new InvalidArgumentException('The --models and --except options cannot be combined.');
+        }
+
+        return collect((new Finder)->in($this->getDefaultPath())->files()->name('*.php'))
+            ->map(function ($model) {
+                $namespace = $this->laravel->getNamespace();
+
+                return $namespace.str_replace(
+                    ['/', '.php'],
+                    ['\\', ''],
+                    Str::after($model->getRealPath(), realpath(app_path()).DIRECTORY_SEPARATOR)
+                );
+            })->when(! empty($except), function ($models) use ($except) {
+                return $models->reject(function ($model) use ($except) {
+                    return in_array($model, $except);
+                });
+            })->filter(function ($model) {
+                return $this->isPrunable($model);
+            })->filter(function ($model) {
+                return class_exists($model);
+            })->values();
+    }
+
+    /**
+     * Get the default path where models are located.
+     *
+     * @return string|string[]
+     */
+    protected function getDefaultPath()
+    {
+        return app_path('Models');
+    }
+
+    /**
+     * Determine if the given model class is prunable.
+     *
+     * @param  string  $model
+     * @return bool
+     */
+    protected function isPrunable($model)
+    {
+        $uses = class_uses_recursive($model);
+
+        return in_array(Prunable::class, $uses) || in_array(MassPrunable::class, $uses);
+    }
+
+    /**
+     * Display how many models will be pruned.
+     *
+     * @param  string  $model
+     * @return void
+     */
+    protected function pretendToPrune($model)
+    {
+        $instance = new $model;
+
+        $count = $instance->prunable()
+            ->when(in_array(SoftDeletes::class, class_uses_recursive(get_class($instance))), function ($query) {
+                $query->withTrashed();
+            })->count();
+
+        if ($count === 0) {
+            $this->components->info("No prunable [$model] records found.");
+        } else {
+            $this->components->info("{$count} [{$model}] records will be pruned.");
+        }
+    }
+}
diff --git a/vendor/illuminate/database/Console/Seeds/SeedCommand.php b/vendor/illuminate/database/Console/Seeds/SeedCommand.php
new file mode 100644
index 0000000..2359586
--- /dev/null
+++ b/vendor/illuminate/database/Console/Seeds/SeedCommand.php
@@ -0,0 +1,151 @@
+resolver = $resolver;
+    }
+
+    /**
+     * Execute the console command.
+     *
+     * @return int
+     */
+    public function handle()
+    {
+        if (! $this->confirmToProceed()) {
+            return 1;
+        }
+
+        $this->components->info('Seeding database.');
+
+        $previousConnection = $this->resolver->getDefaultConnection();
+
+        $this->resolver->setDefaultConnection($this->getDatabase());
+
+        Model::unguarded(function () {
+            $this->getSeeder()->__invoke();
+        });
+
+        if ($previousConnection) {
+            $this->resolver->setDefaultConnection($previousConnection);
+        }
+
+        return 0;
+    }
+
+    /**
+     * Get a seeder instance from the container.
+     *
+     * @return \Illuminate\Database\Seeder
+     */
+    protected function getSeeder()
+    {
+        $class = $this->input->getArgument('class') ?? $this->input->getOption('class');
+
+        if (! str_contains($class, '\\')) {
+            $class = 'Database\\Seeders\\'.$class;
+        }
+
+        if ($class === 'Database\\Seeders\\DatabaseSeeder' &&
+            ! class_exists($class)) {
+            $class = 'DatabaseSeeder';
+        }
+
+        return $this->laravel->make($class)
+                        ->setContainer($this->laravel)
+                        ->setCommand($this);
+    }
+
+    /**
+     * Get the name of the database connection to use.
+     *
+     * @return string
+     */
+    protected function getDatabase()
+    {
+        $database = $this->input->getOption('database');
+
+        return $database ?: $this->laravel['config']['database.default'];
+    }
+
+    /**
+     * Get the console command arguments.
+     *
+     * @return array
+     */
+    protected function getArguments()
+    {
+        return [
+            ['class', InputArgument::OPTIONAL, 'The class name of the root seeder', null],
+        ];
+    }
+
+    /**
+     * Get the console command options.
+     *
+     * @return array
+     */
+    protected function getOptions()
+    {
+        return [
+            ['class', null, InputOption::VALUE_OPTIONAL, 'The class name of the root seeder', 'Database\\Seeders\\DatabaseSeeder'],
+            ['database', null, InputOption::VALUE_OPTIONAL, 'The database connection to seed'],
+            ['force', null, InputOption::VALUE_NONE, 'Force the operation to run when in production'],
+        ];
+    }
+}
diff --git a/vendor/illuminate/database/Console/Seeds/SeederMakeCommand.php b/vendor/illuminate/database/Console/Seeds/SeederMakeCommand.php
new file mode 100644
index 0000000..8ba01cb
--- /dev/null
+++ b/vendor/illuminate/database/Console/Seeds/SeederMakeCommand.php
@@ -0,0 +1,103 @@
+resolveStubPath('/stubs/seeder.stub');
+    }
+
+    /**
+     * Resolve the fully-qualified path to the stub.
+     *
+     * @param  string  $stub
+     * @return string
+     */
+    protected function resolveStubPath($stub)
+    {
+        return is_file($customPath = $this->laravel->basePath(trim($stub, '/')))
+            ? $customPath
+            : __DIR__.$stub;
+    }
+
+    /**
+     * Get the destination class path.
+     *
+     * @param  string  $name
+     * @return string
+     */
+    protected function getPath($name)
+    {
+        $name = str_replace('\\', '/', Str::replaceFirst($this->rootNamespace(), '', $name));
+
+        if (is_dir($this->laravel->databasePath().'/seeds')) {
+            return $this->laravel->databasePath().'/seeds/'.$name.'.php';
+        }
+
+        return $this->laravel->databasePath().'/seeders/'.$name.'.php';
+    }
+
+    /**
+     * Get the root namespace for the class.
+     *
+     * @return string
+     */
+    protected function rootNamespace()
+    {
+        return 'Database\Seeders\\';
+    }
+}
diff --git a/vendor/illuminate/database/Console/Seeds/WithoutModelEvents.php b/vendor/illuminate/database/Console/Seeds/WithoutModelEvents.php
new file mode 100644
index 0000000..acd9ec3
--- /dev/null
+++ b/vendor/illuminate/database/Console/Seeds/WithoutModelEvents.php
@@ -0,0 +1,19 @@
+ Model::withoutEvents($callback);
+    }
+}
diff --git a/vendor/illuminate/database/Console/Seeds/stubs/seeder.stub b/vendor/illuminate/database/Console/Seeds/stubs/seeder.stub
new file mode 100644
index 0000000..19ae5f5
--- /dev/null
+++ b/vendor/illuminate/database/Console/Seeds/stubs/seeder.stub
@@ -0,0 +1,19 @@
+ Note: This can be slow on large databases };
+                {--views : Show the database views  Note: This can be slow on large databases }';
+
+    /**
+     * The console command description.
+     *
+     * @var string
+     */
+    protected $description = 'Display information about the given database';
+
+    /**
+     * Execute the console command.
+     *
+     * @param  \Illuminate\Database\ConnectionResolverInterface  $connections
+     * @return int
+     */
+    public function handle(ConnectionResolverInterface $connections)
+    {
+        if (! $this->ensureDependenciesExist()) {
+            return 1;
+        }
+
+        $connection = $connections->connection($database = $this->input->getOption('database'));
+
+        $schema = $connection->getDoctrineSchemaManager();
+
+        $this->registerTypeMappings($schema->getDatabasePlatform());
+
+        $data = [
+            'platform' => [
+                'config' => $this->getConfigFromDatabase($database),
+                'name' => $this->getPlatformName($schema->getDatabasePlatform(), $database),
+                'open_connections' => $this->getConnectionCount($connection),
+            ],
+            'tables' => $this->tables($connection, $schema),
+        ];
+
+        if ($this->option('views')) {
+            $data['views'] = $this->collectViews($connection, $schema);
+        }
+
+        $this->display($data);
+
+        return 0;
+    }
+
+    /**
+     * Get information regarding the tables within the database.
+     *
+     * @param  \Illuminate\Database\ConnectionInterface  $connection
+     * @param  \Doctrine\DBAL\Schema\AbstractSchemaManager  $schema
+     * @return \Illuminate\Support\Collection
+     */
+    protected function tables(ConnectionInterface $connection, AbstractSchemaManager $schema)
+    {
+        return collect($schema->listTables())->map(fn (Table $table, $index) => [
+            'table' => $table->getName(),
+            'size' => $this->getTableSize($connection, $table->getName()),
+            'rows' => $this->option('counts') ? $connection->table($table->getName())->count() : null,
+            'engine' => rescue(fn () => $table->getOption('engine'), null, false),
+            'comment' => $table->getComment(),
+        ]);
+    }
+
+    /**
+     * Get information regarding the views within the database.
+     *
+     * @param  \Illuminate\Database\ConnectionInterface  $connection
+     * @param  \Doctrine\DBAL\Schema\AbstractSchemaManager  $schema
+     * @return \Illuminate\Support\Collection
+     */
+    protected function collectViews(ConnectionInterface $connection, AbstractSchemaManager $schema)
+    {
+        return collect($schema->listViews())
+            ->reject(fn (View $view) => str($view->getName())
+                ->startsWith(['pg_catalog', 'information_schema', 'spt_']))
+            ->map(fn (View $view) => [
+                'view' => $view->getName(),
+                'rows' => $connection->table($view->getName())->count(),
+            ]);
+    }
+
+    /**
+     * Render the database information.
+     *
+     * @param  array  $data
+     * @return void
+     */
+    protected function display(array $data)
+    {
+        $this->option('json') ? $this->displayJson($data) : $this->displayForCli($data);
+    }
+
+    /**
+     * Render the database information as JSON.
+     *
+     * @param  array  $data
+     * @return void
+     */
+    protected function displayJson(array $data)
+    {
+        $this->output->writeln(json_encode($data));
+    }
+
+    /**
+     * Render the database information formatted for the CLI.
+     *
+     * @param  array  $data
+     * @return void
+     */
+    protected function displayForCli(array $data)
+    {
+        $platform = $data['platform'];
+        $tables = $data['tables'];
+        $views = $data['views'] ?? null;
+
+        $this->newLine();
+
+        $this->components->twoColumnDetail(''.$platform['name'].'');
+        $this->components->twoColumnDetail('Database', Arr::get($platform['config'], 'database'));
+        $this->components->twoColumnDetail('Host', Arr::get($platform['config'], 'host'));
+        $this->components->twoColumnDetail('Port', Arr::get($platform['config'], 'port'));
+        $this->components->twoColumnDetail('Username', Arr::get($platform['config'], 'username'));
+        $this->components->twoColumnDetail('URL', Arr::get($platform['config'], 'url'));
+        $this->components->twoColumnDetail('Open Connections', $platform['open_connections']);
+        $this->components->twoColumnDetail('Tables', $tables->count());
+
+        if ($tableSizeSum = $tables->sum('size')) {
+            $this->components->twoColumnDetail('Total Size', number_format($tableSizeSum / 1024 / 1024, 2).'MiB');
+        }
+
+        $this->newLine();
+
+        if ($tables->isNotEmpty()) {
+            $this->components->twoColumnDetail('Table', 'Size (MiB)'.($this->option('counts') ? ' / Rows' : ''));
+
+            $tables->each(function ($table) {
+                if ($tableSize = $table['size']) {
+                    $tableSize = number_format($tableSize / 1024 / 1024, 2);
+                }
+
+                $this->components->twoColumnDetail(
+                    $table['table'].($this->output->isVerbose() ? ' '.$table['engine'].'' : null),
+                    ($tableSize ? $tableSize : '—').($this->option('counts') ? ' / '.number_format($table['rows']).'' : '')
+                );
+
+                if ($this->output->isVerbose()) {
+                    if ($table['comment']) {
+                        $this->components->bulletList([
+                            $table['comment'],
+                        ]);
+                    }
+                }
+            });
+
+            $this->newLine();
+        }
+
+        if ($views && $views->isNotEmpty()) {
+            $this->components->twoColumnDetail('View', 'Rows');
+
+            $views->each(fn ($view) => $this->components->twoColumnDetail($view['view'], number_format($view['rows'])));
+
+            $this->newLine();
+        }
+    }
+}
diff --git a/vendor/illuminate/database/Console/TableCommand.php b/vendor/illuminate/database/Console/TableCommand.php
new file mode 100644
index 0000000..3b08bde
--- /dev/null
+++ b/vendor/illuminate/database/Console/TableCommand.php
@@ -0,0 +1,246 @@
+ensureDependenciesExist()) {
+            return 1;
+        }
+
+        $connection = $connections->connection($this->input->getOption('database'));
+
+        $schema = $connection->getDoctrineSchemaManager();
+
+        $this->registerTypeMappings($schema->getDatabasePlatform());
+
+        $table = $this->argument('table') ?: $this->components->choice(
+            'Which table would you like to inspect?',
+            collect($schema->listTables())->flatMap(fn (Table $table) => [$table->getName()])->toArray()
+        );
+
+        if (! $schema->tablesExist([$table])) {
+            return $this->components->warn("Table [{$table}] doesn't exist.");
+        }
+
+        $table = $schema->listTableDetails($table);
+
+        $columns = $this->columns($table);
+        $indexes = $this->indexes($table);
+        $foreignKeys = $this->foreignKeys($table);
+
+        $data = [
+            'table' => [
+                'name' => $table->getName(),
+                'columns' => $columns->count(),
+                'size' => $this->getTableSize($connection, $table->getName()),
+            ],
+            'columns' => $columns,
+            'indexes' => $indexes,
+            'foreign_keys' => $foreignKeys,
+        ];
+
+        $this->display($data);
+
+        return 0;
+    }
+
+    /**
+     * Get the information regarding the table's columns.
+     *
+     * @param  \Doctrine\DBAL\Schema\Table  $table
+     * @return \Illuminate\Support\Collection
+     */
+    protected function columns(Table $table)
+    {
+        return collect($table->getColumns())->map(fn (Column $column) => [
+            'column' => $column->getName(),
+            'attributes' => $this->getAttributesForColumn($column),
+            'default' => $column->getDefault(),
+            'type' => $column->getType()->getName(),
+        ]);
+    }
+
+    /**
+     * Get the attributes for a table column.
+     *
+     * @param  \Doctrine\DBAL\Schema\Column  $column
+     * @return \Illuminate\Support\Collection
+     */
+    protected function getAttributesForColumn(Column $column)
+    {
+        return collect([
+            $column->getAutoincrement() ? 'autoincrement' : null,
+            'type' => $column->getType()->getName(),
+            $column->getUnsigned() ? 'unsigned' : null,
+            ! $column->getNotNull() ? 'nullable' : null,
+        ])->filter();
+    }
+
+    /**
+     * Get the information regarding the table's indexes.
+     *
+     * @param  \Doctrine\DBAL\Schema\Table  $table
+     * @return \Illuminate\Support\Collection
+     */
+    protected function indexes(Table $table)
+    {
+        return collect($table->getIndexes())->map(fn (Index $index) => [
+            'name' => $index->getName(),
+            'columns' => collect($index->getColumns()),
+            'attributes' => $this->getAttributesForIndex($index),
+        ]);
+    }
+
+    /**
+     * Get the attributes for a table index.
+     *
+     * @param  \Doctrine\DBAL\Schema\Index  $index
+     * @return \Illuminate\Support\Collection
+     */
+    protected function getAttributesForIndex(Index $index)
+    {
+        return collect([
+            'compound' => count($index->getColumns()) > 1,
+            'unique' => $index->isUnique(),
+            'primary' => $index->isPrimary(),
+        ])->filter()->keys()->map(fn ($attribute) => Str::lower($attribute));
+    }
+
+    /**
+     * Get the information regarding the table's foreign keys.
+     *
+     * @param  \Doctrine\DBAL\Schema\Table  $table
+     * @return \Illuminate\Support\Collection
+     */
+    protected function foreignKeys(Table $table)
+    {
+        return collect($table->getForeignKeys())->map(fn (ForeignKeyConstraint $foreignKey) => [
+            'name' => $foreignKey->getName(),
+            'local_table' => $table->getName(),
+            'local_columns' => collect($foreignKey->getLocalColumns()),
+            'foreign_table' => $foreignKey->getForeignTableName(),
+            'foreign_columns' => collect($foreignKey->getForeignColumns()),
+            'on_update' => Str::lower(rescue(fn () => $foreignKey->getOption('onUpdate'), 'N/A')),
+            'on_delete' => Str::lower(rescue(fn () => $foreignKey->getOption('onDelete'), 'N/A')),
+        ]);
+    }
+
+    /**
+     * Render the table information.
+     *
+     * @param  array  $data
+     * @return void
+     */
+    protected function display(array $data)
+    {
+        $this->option('json') ? $this->displayJson($data) : $this->displayForCli($data);
+    }
+
+    /**
+     * Render the table information as JSON.
+     *
+     * @param  array  $data
+     * @return void
+     */
+    protected function displayJson(array $data)
+    {
+        $this->output->writeln(json_encode($data));
+    }
+
+    /**
+     * Render the table information formatted for the CLI.
+     *
+     * @param  array  $data
+     * @return void
+     */
+    protected function displayForCli(array $data)
+    {
+        [$table, $columns, $indexes, $foreignKeys] = [
+            $data['table'], $data['columns'], $data['indexes'], $data['foreign_keys'],
+        ];
+
+        $this->newLine();
+
+        $this->components->twoColumnDetail(''.$table['name'].'');
+        $this->components->twoColumnDetail('Columns', $table['columns']);
+
+        if ($size = $table['size']) {
+            $this->components->twoColumnDetail('Size', number_format($size / 1024 / 1024, 2).'MiB');
+        }
+
+        $this->newLine();
+
+        if ($columns->isNotEmpty()) {
+            $this->components->twoColumnDetail('Column', 'Type');
+
+            $columns->each(function ($column) {
+                $this->components->twoColumnDetail(
+                    $column['column'].' '.$column['attributes']->implode(', ').'',
+                    ($column['default'] ? ''.$column['default'].' ' : '').''.$column['type'].''
+                );
+            });
+
+            $this->newLine();
+        }
+
+        if ($indexes->isNotEmpty()) {
+            $this->components->twoColumnDetail('Index');
+
+            $indexes->each(function ($index) {
+                $this->components->twoColumnDetail(
+                    $index['name'].' '.$index['columns']->implode(', ').'',
+                    $index['attributes']->implode(', ')
+                );
+            });
+
+            $this->newLine();
+        }
+
+        if ($foreignKeys->isNotEmpty()) {
+            $this->components->twoColumnDetail('Foreign Key', 'On Update / On Delete');
+
+            $foreignKeys->each(function ($foreignKey) {
+                $this->components->twoColumnDetail(
+                    $foreignKey['name'].' '.$foreignKey['local_columns']->implode(', ').' references '.$foreignKey['foreign_columns']->implode(', ').' on '.$foreignKey['foreign_table'].'',
+                    $foreignKey['on_update'].' / '.$foreignKey['on_delete'],
+                );
+            });
+
+            $this->newLine();
+        }
+    }
+}
diff --git a/vendor/illuminate/database/Console/WipeCommand.php b/vendor/illuminate/database/Console/WipeCommand.php
new file mode 100644
index 0000000..cb26922
--- /dev/null
+++ b/vendor/illuminate/database/Console/WipeCommand.php
@@ -0,0 +1,125 @@
+confirmToProceed()) {
+            return 1;
+        }
+
+        $database = $this->input->getOption('database');
+
+        if ($this->option('drop-views')) {
+            $this->dropAllViews($database);
+
+            $this->components->info('Dropped all views successfully.');
+        }
+
+        $this->dropAllTables($database);
+
+        $this->components->info('Dropped all tables successfully.');
+
+        if ($this->option('drop-types')) {
+            $this->dropAllTypes($database);
+
+            $this->components->info('Dropped all types successfully.');
+        }
+
+        return 0;
+    }
+
+    /**
+     * Drop all of the database tables.
+     *
+     * @param  string  $database
+     * @return void
+     */
+    protected function dropAllTables($database)
+    {
+        $this->laravel['db']->connection($database)
+                    ->getSchemaBuilder()
+                    ->dropAllTables();
+    }
+
+    /**
+     * Drop all of the database views.
+     *
+     * @param  string  $database
+     * @return void
+     */
+    protected function dropAllViews($database)
+    {
+        $this->laravel['db']->connection($database)
+                    ->getSchemaBuilder()
+                    ->dropAllViews();
+    }
+
+    /**
+     * Drop all of the database types.
+     *
+     * @param  string  $database
+     * @return void
+     */
+    protected function dropAllTypes($database)
+    {
+        $this->laravel['db']->connection($database)
+                    ->getSchemaBuilder()
+                    ->dropAllTypes();
+    }
+
+    /**
+     * Get the console command options.
+     *
+     * @return array
+     */
+    protected function getOptions()
+    {
+        return [
+            ['database', null, InputOption::VALUE_OPTIONAL, 'The database connection to use'],
+            ['drop-views', null, InputOption::VALUE_NONE, 'Drop all tables and views'],
+            ['drop-types', null, InputOption::VALUE_NONE, 'Drop all tables and types (Postgres only)'],
+            ['force', null, InputOption::VALUE_NONE, 'Force the operation to run when in production'],
+        ];
+    }
+}
diff --git a/vendor/illuminate/database/DBAL/TimestampType.php b/vendor/illuminate/database/DBAL/TimestampType.php
new file mode 100644
index 0000000..4a863bc
--- /dev/null
+++ b/vendor/illuminate/database/DBAL/TimestampType.php
@@ -0,0 +1,99 @@
+getName()) {
+            'mysql',
+            'mysql2' => $this->getMySqlPlatformSQLDeclaration($fieldDeclaration),
+            'postgresql',
+            'pgsql',
+            'postgres' => $this->getPostgresPlatformSQLDeclaration($fieldDeclaration),
+            'mssql' => $this->getSqlServerPlatformSQLDeclaration($fieldDeclaration),
+            'sqlite',
+            'sqlite3' => $this->getSQLitePlatformSQLDeclaration($fieldDeclaration),
+            default => throw new DBALException('Invalid platform: '.$name),
+        };
+    }
+
+    /**
+     * Get the SQL declaration for MySQL.
+     *
+     * @param  array  $fieldDeclaration
+     * @return string
+     */
+    protected function getMySqlPlatformSQLDeclaration(array $fieldDeclaration)
+    {
+        $columnType = 'TIMESTAMP';
+
+        if ($fieldDeclaration['precision']) {
+            $columnType = 'TIMESTAMP('.$fieldDeclaration['precision'].')';
+        }
+
+        $notNull = $fieldDeclaration['notnull'] ?? false;
+
+        if (! $notNull) {
+            return $columnType.' NULL';
+        }
+
+        return $columnType;
+    }
+
+    /**
+     * Get the SQL declaration for PostgreSQL.
+     *
+     * @param  array  $fieldDeclaration
+     * @return string
+     */
+    protected function getPostgresPlatformSQLDeclaration(array $fieldDeclaration)
+    {
+        return 'TIMESTAMP('.(int) $fieldDeclaration['precision'].')';
+    }
+
+    /**
+     * Get the SQL declaration for SQL Server.
+     *
+     * @param  array  $fieldDeclaration
+     * @return string
+     */
+    protected function getSqlServerPlatformSQLDeclaration(array $fieldDeclaration)
+    {
+        return $fieldDeclaration['precision'] ?? false
+                    ? 'DATETIME2('.$fieldDeclaration['precision'].')'
+                    : 'DATETIME';
+    }
+
+    /**
+     * Get the SQL declaration for SQLite.
+     *
+     * @param  array  $fieldDeclaration
+     * @return string
+     */
+    protected function getSQLitePlatformSQLDeclaration(array $fieldDeclaration)
+    {
+        return 'DATETIME';
+    }
+
+    /**
+     * {@inheritdoc}
+     *
+     * @return string
+     */
+    public function getName()
+    {
+        return 'timestamp';
+    }
+}
diff --git a/vendor/illuminate/database/DatabaseManager.php b/vendor/illuminate/database/DatabaseManager.php
new file mode 100755
index 0000000..fc81353
--- /dev/null
+++ b/vendor/illuminate/database/DatabaseManager.php
@@ -0,0 +1,471 @@
+
+     */
+    protected $connections = [];
+
+    /**
+     * The custom connection resolvers.
+     *
+     * @var array
+     */
+    protected $extensions = [];
+
+    /**
+     * The callback to be executed to reconnect to a database.
+     *
+     * @var callable
+     */
+    protected $reconnector;
+
+    /**
+     * The custom Doctrine column types.
+     *
+     * @var array
+     */
+    protected $doctrineTypes = [];
+
+    /**
+     * Create a new database manager instance.
+     *
+     * @param  \Illuminate\Contracts\Foundation\Application  $app
+     * @param  \Illuminate\Database\Connectors\ConnectionFactory  $factory
+     * @return void
+     */
+    public function __construct($app, ConnectionFactory $factory)
+    {
+        $this->app = $app;
+        $this->factory = $factory;
+
+        $this->reconnector = function ($connection) {
+            $this->reconnect($connection->getNameWithReadWriteType());
+        };
+    }
+
+    /**
+     * Get a database connection instance.
+     *
+     * @param  string|null  $name
+     * @return \Illuminate\Database\Connection
+     */
+    public function connection($name = null)
+    {
+        [$database, $type] = $this->parseConnectionName($name);
+
+        $name = $name ?: $database;
+
+        // If we haven't created this connection, we'll create it based on the config
+        // provided in the application. Once we've created the connections we will
+        // set the "fetch mode" for PDO which determines the query return types.
+        if (! isset($this->connections[$name])) {
+            $this->connections[$name] = $this->configure(
+                $this->makeConnection($database), $type
+            );
+
+            if ($this->app->bound('events')) {
+                $this->app['events']->dispatch(
+                    new ConnectionEstablished($this->connections[$name])
+                );
+            }
+        }
+
+        return $this->connections[$name];
+    }
+
+    /**
+     * Parse the connection into an array of the name and read / write type.
+     *
+     * @param  string  $name
+     * @return array
+     */
+    protected function parseConnectionName($name)
+    {
+        $name = $name ?: $this->getDefaultConnection();
+
+        return Str::endsWith($name, ['::read', '::write'])
+                            ? explode('::', $name, 2) : [$name, null];
+    }
+
+    /**
+     * Make the database connection instance.
+     *
+     * @param  string  $name
+     * @return \Illuminate\Database\Connection
+     */
+    protected function makeConnection($name)
+    {
+        $config = $this->configuration($name);
+
+        // First we will check by the connection name to see if an extension has been
+        // registered specifically for that connection. If it has we will call the
+        // Closure and pass it the config allowing it to resolve the connection.
+        if (isset($this->extensions[$name])) {
+            return call_user_func($this->extensions[$name], $config, $name);
+        }
+
+        // Next we will check to see if an extension has been registered for a driver
+        // and will call the Closure if so, which allows us to have a more generic
+        // resolver for the drivers themselves which applies to all connections.
+        if (isset($this->extensions[$driver = $config['driver']])) {
+            return call_user_func($this->extensions[$driver], $config, $name);
+        }
+
+        return $this->factory->make($config, $name);
+    }
+
+    /**
+     * Get the configuration for a connection.
+     *
+     * @param  string  $name
+     * @return array
+     *
+     * @throws \InvalidArgumentException
+     */
+    protected function configuration($name)
+    {
+        $name = $name ?: $this->getDefaultConnection();
+
+        // To get the database connection configuration, we will just pull each of the
+        // connection configurations and get the configurations for the given name.
+        // If the configuration doesn't exist, we'll throw an exception and bail.
+        $connections = $this->app['config']['database.connections'];
+
+        if (is_null($config = Arr::get($connections, $name))) {
+            throw new InvalidArgumentException("Database connection [{$name}] not configured.");
+        }
+
+        return (new ConfigurationUrlParser)
+                    ->parseConfiguration($config);
+    }
+
+    /**
+     * Prepare the database connection instance.
+     *
+     * @param  \Illuminate\Database\Connection  $connection
+     * @param  string  $type
+     * @return \Illuminate\Database\Connection
+     */
+    protected function configure(Connection $connection, $type)
+    {
+        $connection = $this->setPdoForType($connection, $type)->setReadWriteType($type);
+
+        // First we'll set the fetch mode and a few other dependencies of the database
+        // connection. This method basically just configures and prepares it to get
+        // used by the application. Once we're finished we'll return it back out.
+        if ($this->app->bound('events')) {
+            $connection->setEventDispatcher($this->app['events']);
+        }
+
+        if ($this->app->bound('db.transactions')) {
+            $connection->setTransactionManager($this->app['db.transactions']);
+        }
+
+        // Here we'll set a reconnector callback. This reconnector can be any callable
+        // so we will set a Closure to reconnect from this manager with the name of
+        // the connection, which will allow us to reconnect from the connections.
+        $connection->setReconnector($this->reconnector);
+
+        $this->registerConfiguredDoctrineTypes($connection);
+
+        return $connection;
+    }
+
+    /**
+     * Prepare the read / write mode for database connection instance.
+     *
+     * @param  \Illuminate\Database\Connection  $connection
+     * @param  string|null  $type
+     * @return \Illuminate\Database\Connection
+     */
+    protected function setPdoForType(Connection $connection, $type = null)
+    {
+        if ($type === 'read') {
+            $connection->setPdo($connection->getReadPdo());
+        } elseif ($type === 'write') {
+            $connection->setReadPdo($connection->getPdo());
+        }
+
+        return $connection;
+    }
+
+    /**
+     * Register custom Doctrine types with the connection.
+     *
+     * @param  \Illuminate\Database\Connection  $connection
+     * @return void
+     */
+    protected function registerConfiguredDoctrineTypes(Connection $connection): void
+    {
+        foreach ($this->app['config']->get('database.dbal.types', []) as $name => $class) {
+            $this->registerDoctrineType($class, $name, $name);
+        }
+
+        foreach ($this->doctrineTypes as $name => [$type, $class]) {
+            $connection->registerDoctrineType($class, $name, $type);
+        }
+    }
+
+    /**
+     * Register a custom Doctrine type.
+     *
+     * @param  string  $class
+     * @param  string  $name
+     * @param  string  $type
+     * @return void
+     *
+     * @throws \Doctrine\DBAL\DBALException
+     * @throws \RuntimeException
+     */
+    public function registerDoctrineType(string $class, string $name, string $type): void
+    {
+        if (! class_exists('Doctrine\DBAL\Connection')) {
+            throw new RuntimeException(
+                'Registering a custom Doctrine type requires Doctrine DBAL (doctrine/dbal).'
+            );
+        }
+
+        if (! Type::hasType($name)) {
+            Type::addType($name, $class);
+        }
+
+        $this->doctrineTypes[$name] = [$type, $class];
+    }
+
+    /**
+     * Disconnect from the given database and remove from local cache.
+     *
+     * @param  string|null  $name
+     * @return void
+     */
+    public function purge($name = null)
+    {
+        $name = $name ?: $this->getDefaultConnection();
+
+        $this->disconnect($name);
+
+        unset($this->connections[$name]);
+    }
+
+    /**
+     * Disconnect from the given database.
+     *
+     * @param  string|null  $name
+     * @return void
+     */
+    public function disconnect($name = null)
+    {
+        if (isset($this->connections[$name = $name ?: $this->getDefaultConnection()])) {
+            $this->connections[$name]->disconnect();
+        }
+    }
+
+    /**
+     * Reconnect to the given database.
+     *
+     * @param  string|null  $name
+     * @return \Illuminate\Database\Connection
+     */
+    public function reconnect($name = null)
+    {
+        $this->disconnect($name = $name ?: $this->getDefaultConnection());
+
+        if (! isset($this->connections[$name])) {
+            return $this->connection($name);
+        }
+
+        return $this->refreshPdoConnections($name);
+    }
+
+    /**
+     * Set the default database connection for the callback execution.
+     *
+     * @param  string  $name
+     * @param  callable  $callback
+     * @return mixed
+     */
+    public function usingConnection($name, callable $callback)
+    {
+        $previousName = $this->getDefaultConnection();
+
+        $this->setDefaultConnection($name);
+
+        return tap($callback(), function () use ($previousName) {
+            $this->setDefaultConnection($previousName);
+        });
+    }
+
+    /**
+     * Refresh the PDO connections on a given connection.
+     *
+     * @param  string  $name
+     * @return \Illuminate\Database\Connection
+     */
+    protected function refreshPdoConnections($name)
+    {
+        [$database, $type] = $this->parseConnectionName($name);
+
+        $fresh = $this->configure(
+            $this->makeConnection($database), $type
+        );
+
+        return $this->connections[$name]
+                    ->setPdo($fresh->getRawPdo())
+                    ->setReadPdo($fresh->getRawReadPdo());
+    }
+
+    /**
+     * Get the default connection name.
+     *
+     * @return string
+     */
+    public function getDefaultConnection()
+    {
+        return $this->app['config']['database.default'];
+    }
+
+    /**
+     * Set the default connection name.
+     *
+     * @param  string  $name
+     * @return void
+     */
+    public function setDefaultConnection($name)
+    {
+        $this->app['config']['database.default'] = $name;
+    }
+
+    /**
+     * Get all of the support drivers.
+     *
+     * @return string[]
+     */
+    public function supportedDrivers()
+    {
+        return ['mysql', 'pgsql', 'sqlite', 'sqlsrv'];
+    }
+
+    /**
+     * Get all of the drivers that are actually available.
+     *
+     * @return string[]
+     */
+    public function availableDrivers()
+    {
+        return array_intersect(
+            $this->supportedDrivers(),
+            str_replace('dblib', 'sqlsrv', PDO::getAvailableDrivers())
+        );
+    }
+
+    /**
+     * Register an extension connection resolver.
+     *
+     * @param  string  $name
+     * @param  callable  $resolver
+     * @return void
+     */
+    public function extend($name, callable $resolver)
+    {
+        $this->extensions[$name] = $resolver;
+    }
+
+    /**
+     * Remove an extension connection resolver.
+     *
+     * @param  string  $name
+     * @return void
+     */
+    public function forgetExtension($name)
+    {
+        unset($this->extensions[$name]);
+    }
+
+    /**
+     * Return all of the created connections.
+     *
+     * @return array
+     */
+    public function getConnections()
+    {
+        return $this->connections;
+    }
+
+    /**
+     * Set the database reconnector callback.
+     *
+     * @param  callable  $reconnector
+     * @return void
+     */
+    public function setReconnector(callable $reconnector)
+    {
+        $this->reconnector = $reconnector;
+    }
+
+    /**
+     * Set the application instance used by the manager.
+     *
+     * @param  \Illuminate\Contracts\Foundation\Application  $app
+     * @return $this
+     */
+    public function setApplication($app)
+    {
+        $this->app = $app;
+
+        return $this;
+    }
+
+    /**
+     * Dynamically pass methods to the default connection.
+     *
+     * @param  string  $method
+     * @param  array  $parameters
+     * @return mixed
+     */
+    public function __call($method, $parameters)
+    {
+        if (static::hasMacro($method)) {
+            return $this->macroCall($method, $parameters);
+        }
+
+        return $this->connection()->$method(...$parameters);
+    }
+}
diff --git a/vendor/illuminate/database/DatabaseServiceProvider.php b/vendor/illuminate/database/DatabaseServiceProvider.php
new file mode 100755
index 0000000..9a2f47d
--- /dev/null
+++ b/vendor/illuminate/database/DatabaseServiceProvider.php
@@ -0,0 +1,113 @@
+app['db']);
+
+        Model::setEventDispatcher($this->app['events']);
+    }
+
+    /**
+     * Register the service provider.
+     *
+     * @return void
+     */
+    public function register()
+    {
+        Model::clearBootedModels();
+
+        $this->registerConnectionServices();
+        $this->registerEloquentFactory();
+        $this->registerQueueableEntityResolver();
+    }
+
+    /**
+     * Register the primary database bindings.
+     *
+     * @return void
+     */
+    protected function registerConnectionServices()
+    {
+        // The connection factory is used to create the actual connection instances on
+        // the database. We will inject the factory into the manager so that it may
+        // make the connections while they are actually needed and not of before.
+        $this->app->singleton('db.factory', function ($app) {
+            return new ConnectionFactory($app);
+        });
+
+        // The database manager is used to resolve various connections, since multiple
+        // connections might be managed. It also implements the connection resolver
+        // interface which may be used by other components requiring connections.
+        $this->app->singleton('db', function ($app) {
+            return new DatabaseManager($app, $app['db.factory']);
+        });
+
+        $this->app->bind('db.connection', function ($app) {
+            return $app['db']->connection();
+        });
+
+        $this->app->bind('db.schema', function ($app) {
+            return $app['db']->connection()->getSchemaBuilder();
+        });
+
+        $this->app->singleton('db.transactions', function ($app) {
+            return new DatabaseTransactionsManager;
+        });
+    }
+
+    /**
+     * Register the Eloquent factory instance in the container.
+     *
+     * @return void
+     */
+    protected function registerEloquentFactory()
+    {
+        $this->app->singleton(FakerGenerator::class, function ($app, $parameters) {
+            $locale = $parameters['locale'] ?? $app['config']->get('app.faker_locale', 'en_US');
+
+            if (! isset(static::$fakers[$locale])) {
+                static::$fakers[$locale] = FakerFactory::create($locale);
+            }
+
+            static::$fakers[$locale]->unique(true);
+
+            return static::$fakers[$locale];
+        });
+    }
+
+    /**
+     * Register the queueable entity resolver implementation.
+     *
+     * @return void
+     */
+    protected function registerQueueableEntityResolver()
+    {
+        $this->app->singleton(EntityResolver::class, function () {
+            return new QueueEntityResolver;
+        });
+    }
+}
diff --git a/vendor/illuminate/database/DatabaseTransactionRecord.php b/vendor/illuminate/database/DatabaseTransactionRecord.php
new file mode 100755
index 0000000..4736ee9
--- /dev/null
+++ b/vendor/illuminate/database/DatabaseTransactionRecord.php
@@ -0,0 +1,73 @@
+connection = $connection;
+        $this->level = $level;
+    }
+
+    /**
+     * Register a callback to be executed after committing.
+     *
+     * @param  callable  $callback
+     * @return void
+     */
+    public function addCallback($callback)
+    {
+        $this->callbacks[] = $callback;
+    }
+
+    /**
+     * Execute all of the callbacks.
+     *
+     * @return void
+     */
+    public function executeCallbacks()
+    {
+        foreach ($this->callbacks as $callback) {
+            $callback();
+        }
+    }
+
+    /**
+     * Get all of the callbacks.
+     *
+     * @return array
+     */
+    public function getCallbacks()
+    {
+        return $this->callbacks;
+    }
+}
diff --git a/vendor/illuminate/database/DatabaseTransactionsManager.php b/vendor/illuminate/database/DatabaseTransactionsManager.php
new file mode 100755
index 0000000..8d14518
--- /dev/null
+++ b/vendor/illuminate/database/DatabaseTransactionsManager.php
@@ -0,0 +1,133 @@
+transactions = collect();
+    }
+
+    /**
+     * Start a new database transaction.
+     *
+     * @param  string  $connection
+     * @param  int  $level
+     * @return void
+     */
+    public function begin($connection, $level)
+    {
+        $this->transactions->push(
+            new DatabaseTransactionRecord($connection, $level)
+        );
+    }
+
+    /**
+     * Rollback the active database transaction.
+     *
+     * @param  string  $connection
+     * @param  int  $level
+     * @return void
+     */
+    public function rollback($connection, $level)
+    {
+        $this->transactions = $this->transactions->reject(
+            fn ($transaction) => $transaction->connection == $connection && $transaction->level > $level
+        )->values();
+
+        if ($this->transactions->isEmpty()) {
+            $this->callbacksShouldIgnore = null;
+        }
+    }
+
+    /**
+     * Commit the active database transaction.
+     *
+     * @param  string  $connection
+     * @return void
+     */
+    public function commit($connection)
+    {
+        [$forThisConnection, $forOtherConnections] = $this->transactions->partition(
+            fn ($transaction) => $transaction->connection == $connection
+        );
+
+        $this->transactions = $forOtherConnections->values();
+
+        $forThisConnection->map->executeCallbacks();
+
+        if ($this->transactions->isEmpty()) {
+            $this->callbacksShouldIgnore = null;
+        }
+    }
+
+    /**
+     * Register a transaction callback.
+     *
+     * @param  callable  $callback
+     * @return void
+     */
+    public function addCallback($callback)
+    {
+        if ($current = $this->callbackApplicableTransactions()->last()) {
+            return $current->addCallback($callback);
+        }
+
+        $callback();
+    }
+
+    /**
+     * Specify that callbacks should ignore the given transaction when determining if they should be executed.
+     *
+     * @param  \Illuminate\Database\DatabaseTransactionRecord  $transaction
+     * @return $this
+     */
+    public function callbacksShouldIgnore(DatabaseTransactionRecord $transaction)
+    {
+        $this->callbacksShouldIgnore = $transaction;
+
+        return $this;
+    }
+
+    /**
+     * Get the transactions that are applicable to callbacks.
+     *
+     * @return \Illuminate\Support\Collection
+     */
+    public function callbackApplicableTransactions()
+    {
+        return $this->transactions->reject(function ($transaction) {
+            return $transaction === $this->callbacksShouldIgnore;
+        })->values();
+    }
+
+    /**
+     * Get all the transactions.
+     *
+     * @return \Illuminate\Support\Collection
+     */
+    public function getTransactions()
+    {
+        return $this->transactions;
+    }
+}
diff --git a/vendor/illuminate/database/DeadlockException.php b/vendor/illuminate/database/DeadlockException.php
new file mode 100644
index 0000000..375a39b
--- /dev/null
+++ b/vendor/illuminate/database/DeadlockException.php
@@ -0,0 +1,10 @@
+getCode() === 40001 || $e->getCode() === '40001')) {
+            return true;
+        }
+
+        $message = $e->getMessage();
+
+        return Str::contains($message, [
+            'Deadlock found when trying to get lock',
+            'deadlock detected',
+            'The database file is locked',
+            'database is locked',
+            'database table is locked',
+            'A table in the database is locked',
+            'has been chosen as the deadlock victim',
+            'Lock wait timeout exceeded; try restarting transaction',
+            'WSREP detected deadlock/conflict and aborted the transaction. Try restarting the transaction',
+        ]);
+    }
+}
diff --git a/vendor/illuminate/database/DetectsLostConnections.php b/vendor/illuminate/database/DetectsLostConnections.php
new file mode 100644
index 0000000..f0c216f
--- /dev/null
+++ b/vendor/illuminate/database/DetectsLostConnections.php
@@ -0,0 +1,66 @@
+getMessage();
+
+        return Str::contains($message, [
+            'server has gone away',
+            'no connection to the server',
+            'Lost connection',
+            'is dead or not enabled',
+            'Error while sending',
+            'decryption failed or bad record mac',
+            'server closed the connection unexpectedly',
+            'SSL connection has been closed unexpectedly',
+            'Error writing data to the connection',
+            'Resource deadlock avoided',
+            'Transaction() on null',
+            'child connection forced to terminate due to client_idle_limit',
+            'query_wait_timeout',
+            'reset by peer',
+            'Physical connection is not usable',
+            'TCP Provider: Error code 0x68',
+            'ORA-03114',
+            'Packets out of order. Expected',
+            'Adaptive Server connection failed',
+            'Communication link failure',
+            'connection is no longer usable',
+            'Login timeout expired',
+            'SQLSTATE[HY000] [2002] Connection refused',
+            'running with the --read-only option so it cannot execute this statement',
+            'The connection is broken and recovery is not possible. The connection is marked by the client driver as unrecoverable. No attempt was made to restore the connection.',
+            'SQLSTATE[HY000] [2002] php_network_getaddresses: getaddrinfo failed: Try again',
+            'SQLSTATE[HY000] [2002] php_network_getaddresses: getaddrinfo failed: Name or service not known',
+            'SQLSTATE[HY000] [2002] php_network_getaddresses: getaddrinfo for',
+            'SQLSTATE[HY000]: General error: 7 SSL SYSCALL error: EOF detected',
+            'SQLSTATE[HY000] [2002] Connection timed out',
+            'SSL: Connection timed out',
+            'SQLSTATE[HY000]: General error: 1105 The last transaction was aborted due to Seamless Scaling. Please retry.',
+            'Temporary failure in name resolution',
+            'SSL: Broken pipe',
+            'SQLSTATE[08S01]: Communication link failure',
+            'SQLSTATE[08006] [7] could not connect to server: Connection refused Is the server running on host',
+            'SQLSTATE[HY000]: General error: 7 SSL SYSCALL error: No route to host',
+            'The client was disconnected by the server because of inactivity. See wait_timeout and interactive_timeout for configuring this behavior.',
+            'SQLSTATE[08006] [7] could not translate host name',
+            'TCP Provider: Error code 0x274C',
+            'SQLSTATE[HY000] [2002] No such file or directory',
+            'SSL: Operation timed out',
+            'Reason: Server is in script upgrade mode. Only administrator can connect at this time.',
+        ]);
+    }
+}
diff --git a/vendor/illuminate/database/Eloquent/BroadcastableModelEventOccurred.php b/vendor/illuminate/database/Eloquent/BroadcastableModelEventOccurred.php
new file mode 100644
index 0000000..249b183
--- /dev/null
+++ b/vendor/illuminate/database/Eloquent/BroadcastableModelEventOccurred.php
@@ -0,0 +1,144 @@
+model = $model;
+        $this->event = $event;
+    }
+
+    /**
+     * The channels the event should broadcast on.
+     *
+     * @return array
+     */
+    public function broadcastOn()
+    {
+        $channels = empty($this->channels)
+                ? ($this->model->broadcastOn($this->event) ?: [])
+                : $this->channels;
+
+        return collect($channels)->map(function ($channel) {
+            return $channel instanceof Model ? new PrivateChannel($channel) : $channel;
+        })->all();
+    }
+
+    /**
+     * The name the event should broadcast as.
+     *
+     * @return string
+     */
+    public function broadcastAs()
+    {
+        $default = class_basename($this->model).ucfirst($this->event);
+
+        return method_exists($this->model, 'broadcastAs')
+                ? ($this->model->broadcastAs($this->event) ?: $default)
+                : $default;
+    }
+
+    /**
+     * Get the data that should be sent with the broadcasted event.
+     *
+     * @return array|null
+     */
+    public function broadcastWith()
+    {
+        return method_exists($this->model, 'broadcastWith')
+            ? $this->model->broadcastWith($this->event)
+            : null;
+    }
+
+    /**
+     * Manually specify the channels the event should broadcast on.
+     *
+     * @param  array  $channels
+     * @return $this
+     */
+    public function onChannels(array $channels)
+    {
+        $this->channels = $channels;
+
+        return $this;
+    }
+
+    /**
+     * Determine if the event should be broadcast synchronously.
+     *
+     * @return bool
+     */
+    public function shouldBroadcastNow()
+    {
+        return $this->event === 'deleted' &&
+               ! method_exists($this->model, 'bootSoftDeletes');
+    }
+
+    /**
+     * Get the event name.
+     *
+     * @return string
+     */
+    public function event()
+    {
+        return $this->event;
+    }
+}
diff --git a/vendor/illuminate/database/Eloquent/BroadcastsEvents.php b/vendor/illuminate/database/Eloquent/BroadcastsEvents.php
new file mode 100644
index 0000000..79dc02d
--- /dev/null
+++ b/vendor/illuminate/database/Eloquent/BroadcastsEvents.php
@@ -0,0 +1,197 @@
+broadcastCreated();
+        });
+
+        static::updated(function ($model) {
+            $model->broadcastUpdated();
+        });
+
+        if (method_exists(static::class, 'bootSoftDeletes')) {
+            static::softDeleted(function ($model) {
+                $model->broadcastTrashed();
+            });
+
+            static::restored(function ($model) {
+                $model->broadcastRestored();
+            });
+        }
+
+        static::deleted(function ($model) {
+            $model->broadcastDeleted();
+        });
+    }
+
+    /**
+     * Broadcast that the model was created.
+     *
+     * @param  \Illuminate\Broadcasting\Channel|\Illuminate\Contracts\Broadcasting\HasBroadcastChannel|array|null  $channels
+     * @return \Illuminate\Broadcasting\PendingBroadcast
+     */
+    public function broadcastCreated($channels = null)
+    {
+        return $this->broadcastIfBroadcastChannelsExistForEvent(
+            $this->newBroadcastableModelEvent('created'), 'created', $channels
+        );
+    }
+
+    /**
+     * Broadcast that the model was updated.
+     *
+     * @param  \Illuminate\Broadcasting\Channel|\Illuminate\Contracts\Broadcasting\HasBroadcastChannel|array|null  $channels
+     * @return \Illuminate\Broadcasting\PendingBroadcast
+     */
+    public function broadcastUpdated($channels = null)
+    {
+        return $this->broadcastIfBroadcastChannelsExistForEvent(
+            $this->newBroadcastableModelEvent('updated'), 'updated', $channels
+        );
+    }
+
+    /**
+     * Broadcast that the model was trashed.
+     *
+     * @param  \Illuminate\Broadcasting\Channel|\Illuminate\Contracts\Broadcasting\HasBroadcastChannel|array|null  $channels
+     * @return \Illuminate\Broadcasting\PendingBroadcast
+     */
+    public function broadcastTrashed($channels = null)
+    {
+        return $this->broadcastIfBroadcastChannelsExistForEvent(
+            $this->newBroadcastableModelEvent('trashed'), 'trashed', $channels
+        );
+    }
+
+    /**
+     * Broadcast that the model was restored.
+     *
+     * @param  \Illuminate\Broadcasting\Channel|\Illuminate\Contracts\Broadcasting\HasBroadcastChannel|array|null  $channels
+     * @return \Illuminate\Broadcasting\PendingBroadcast
+     */
+    public function broadcastRestored($channels = null)
+    {
+        return $this->broadcastIfBroadcastChannelsExistForEvent(
+            $this->newBroadcastableModelEvent('restored'), 'restored', $channels
+        );
+    }
+
+    /**
+     * Broadcast that the model was deleted.
+     *
+     * @param  \Illuminate\Broadcasting\Channel|\Illuminate\Contracts\Broadcasting\HasBroadcastChannel|array|null  $channels
+     * @return \Illuminate\Broadcasting\PendingBroadcast
+     */
+    public function broadcastDeleted($channels = null)
+    {
+        return $this->broadcastIfBroadcastChannelsExistForEvent(
+            $this->newBroadcastableModelEvent('deleted'), 'deleted', $channels
+        );
+    }
+
+    /**
+     * Broadcast the given event instance if channels are configured for the model event.
+     *
+     * @param  mixed  $instance
+     * @param  string  $event
+     * @param  mixed  $channels
+     * @return \Illuminate\Broadcasting\PendingBroadcast|null
+     */
+    protected function broadcastIfBroadcastChannelsExistForEvent($instance, $event, $channels = null)
+    {
+        if (! static::$isBroadcasting) {
+            return;
+        }
+
+        if (! empty($this->broadcastOn($event)) || ! empty($channels)) {
+            return broadcast($instance->onChannels(Arr::wrap($channels)));
+        }
+    }
+
+    /**
+     * Create a new broadcastable model event event.
+     *
+     * @param  string  $event
+     * @return mixed
+     */
+    public function newBroadcastableModelEvent($event)
+    {
+        return tap($this->newBroadcastableEvent($event), function ($event) {
+            $event->connection = property_exists($this, 'broadcastConnection')
+                            ? $this->broadcastConnection
+                            : $this->broadcastConnection();
+
+            $event->queue = property_exists($this, 'broadcastQueue')
+                            ? $this->broadcastQueue
+                            : $this->broadcastQueue();
+
+            $event->afterCommit = property_exists($this, 'broadcastAfterCommit')
+                            ? $this->broadcastAfterCommit
+                            : $this->broadcastAfterCommit();
+        });
+    }
+
+    /**
+     * Create a new broadcastable model event for the model.
+     *
+     * @param  string  $event
+     * @return \Illuminate\Database\Eloquent\BroadcastableModelEventOccurred
+     */
+    protected function newBroadcastableEvent($event)
+    {
+        return new BroadcastableModelEventOccurred($this, $event);
+    }
+
+    /**
+     * Get the channels that model events should broadcast on.
+     *
+     * @param  string  $event
+     * @return \Illuminate\Broadcasting\Channel|array
+     */
+    public function broadcastOn($event)
+    {
+        return [$this];
+    }
+
+    /**
+     * Get the queue connection that should be used to broadcast model events.
+     *
+     * @return string|null
+     */
+    public function broadcastConnection()
+    {
+        //
+    }
+
+    /**
+     * Get the queue that should be used to broadcast model events.
+     *
+     * @return string|null
+     */
+    public function broadcastQueue()
+    {
+        //
+    }
+
+    /**
+     * Determine if the model event broadcast queued job should be dispatched after all transactions are committed.
+     *
+     * @return bool
+     */
+    public function broadcastAfterCommit()
+    {
+        return false;
+    }
+}
diff --git a/vendor/illuminate/database/Eloquent/Builder.php b/vendor/illuminate/database/Eloquent/Builder.php
new file mode 100755
index 0000000..4387bc8
--- /dev/null
+++ b/vendor/illuminate/database/Eloquent/Builder.php
@@ -0,0 +1,1952 @@
+query = $query;
+    }
+
+    /**
+     * Create and return an un-saved model instance.
+     *
+     * @param  array  $attributes
+     * @return \Illuminate\Database\Eloquent\Model|static
+     */
+    public function make(array $attributes = [])
+    {
+        return $this->newModelInstance($attributes);
+    }
+
+    /**
+     * Register a new global scope.
+     *
+     * @param  string  $identifier
+     * @param  \Illuminate\Database\Eloquent\Scope|\Closure  $scope
+     * @return $this
+     */
+    public function withGlobalScope($identifier, $scope)
+    {
+        $this->scopes[$identifier] = $scope;
+
+        if (method_exists($scope, 'extend')) {
+            $scope->extend($this);
+        }
+
+        return $this;
+    }
+
+    /**
+     * Remove a registered global scope.
+     *
+     * @param  \Illuminate\Database\Eloquent\Scope|string  $scope
+     * @return $this
+     */
+    public function withoutGlobalScope($scope)
+    {
+        if (! is_string($scope)) {
+            $scope = get_class($scope);
+        }
+
+        unset($this->scopes[$scope]);
+
+        $this->removedScopes[] = $scope;
+
+        return $this;
+    }
+
+    /**
+     * Remove all or passed registered global scopes.
+     *
+     * @param  array|null  $scopes
+     * @return $this
+     */
+    public function withoutGlobalScopes(array $scopes = null)
+    {
+        if (! is_array($scopes)) {
+            $scopes = array_keys($this->scopes);
+        }
+
+        foreach ($scopes as $scope) {
+            $this->withoutGlobalScope($scope);
+        }
+
+        return $this;
+    }
+
+    /**
+     * Get an array of global scopes that were removed from the query.
+     *
+     * @return array
+     */
+    public function removedScopes()
+    {
+        return $this->removedScopes;
+    }
+
+    /**
+     * Add a where clause on the primary key to the query.
+     *
+     * @param  mixed  $id
+     * @return $this
+     */
+    public function whereKey($id)
+    {
+        if ($id instanceof Model) {
+            $id = $id->getKey();
+        }
+
+        if (is_array($id) || $id instanceof Arrayable) {
+            if (in_array($this->model->getKeyType(), ['int', 'integer'])) {
+                $this->query->whereIntegerInRaw($this->model->getQualifiedKeyName(), $id);
+            } else {
+                $this->query->whereIn($this->model->getQualifiedKeyName(), $id);
+            }
+
+            return $this;
+        }
+
+        if ($id !== null && $this->model->getKeyType() === 'string') {
+            $id = (string) $id;
+        }
+
+        return $this->where($this->model->getQualifiedKeyName(), '=', $id);
+    }
+
+    /**
+     * Add a where clause on the primary key to the query.
+     *
+     * @param  mixed  $id
+     * @return $this
+     */
+    public function whereKeyNot($id)
+    {
+        if ($id instanceof Model) {
+            $id = $id->getKey();
+        }
+
+        if (is_array($id) || $id instanceof Arrayable) {
+            if (in_array($this->model->getKeyType(), ['int', 'integer'])) {
+                $this->query->whereIntegerNotInRaw($this->model->getQualifiedKeyName(), $id);
+            } else {
+                $this->query->whereNotIn($this->model->getQualifiedKeyName(), $id);
+            }
+
+            return $this;
+        }
+
+        if ($id !== null && $this->model->getKeyType() === 'string') {
+            $id = (string) $id;
+        }
+
+        return $this->where($this->model->getQualifiedKeyName(), '!=', $id);
+    }
+
+    /**
+     * Add a basic where clause to the query.
+     *
+     * @param  \Closure|string|array|\Illuminate\Database\Query\Expression  $column
+     * @param  mixed  $operator
+     * @param  mixed  $value
+     * @param  string  $boolean
+     * @return $this
+     */
+    public function where($column, $operator = null, $value = null, $boolean = 'and')
+    {
+        if ($column instanceof Closure && is_null($operator)) {
+            $column($query = $this->model->newQueryWithoutRelationships());
+
+            $this->query->addNestedWhereQuery($query->getQuery(), $boolean);
+        } else {
+            $this->query->where(...func_get_args());
+        }
+
+        return $this;
+    }
+
+    /**
+     * Add a basic where clause to the query, and return the first result.
+     *
+     * @param  \Closure|string|array|\Illuminate\Database\Query\Expression  $column
+     * @param  mixed  $operator
+     * @param  mixed  $value
+     * @param  string  $boolean
+     * @return \Illuminate\Database\Eloquent\Model|static|null
+     */
+    public function firstWhere($column, $operator = null, $value = null, $boolean = 'and')
+    {
+        return $this->where(...func_get_args())->first();
+    }
+
+    /**
+     * Add an "or where" clause to the query.
+     *
+     * @param  \Closure|array|string|\Illuminate\Database\Query\Expression  $column
+     * @param  mixed  $operator
+     * @param  mixed  $value
+     * @return $this
+     */
+    public function orWhere($column, $operator = null, $value = null)
+    {
+        [$value, $operator] = $this->query->prepareValueAndOperator(
+            $value, $operator, func_num_args() === 2
+        );
+
+        return $this->where($column, $operator, $value, 'or');
+    }
+
+    /**
+     * Add a basic "where not" clause to the query.
+     *
+     * @param  \Closure|string|array|\Illuminate\Database\Query\Expression  $column
+     * @param  mixed  $operator
+     * @param  mixed  $value
+     * @param  string  $boolean
+     * @return $this
+     */
+    public function whereNot($column, $operator = null, $value = null, $boolean = 'and')
+    {
+        return $this->where($column, $operator, $value, $boolean.' not');
+    }
+
+    /**
+     * Add an "or where not" clause to the query.
+     *
+     * @param  \Closure|array|string|\Illuminate\Database\Query\Expression  $column
+     * @param  mixed  $operator
+     * @param  mixed  $value
+     * @return $this
+     */
+    public function orWhereNot($column, $operator = null, $value = null)
+    {
+        return $this->whereNot($column, $operator, $value, 'or');
+    }
+
+    /**
+     * Add an "order by" clause for a timestamp to the query.
+     *
+     * @param  string|\Illuminate\Database\Query\Expression  $column
+     * @return $this
+     */
+    public function latest($column = null)
+    {
+        if (is_null($column)) {
+            $column = $this->model->getCreatedAtColumn() ?? 'created_at';
+        }
+
+        $this->query->latest($column);
+
+        return $this;
+    }
+
+    /**
+     * Add an "order by" clause for a timestamp to the query.
+     *
+     * @param  string|\Illuminate\Database\Query\Expression  $column
+     * @return $this
+     */
+    public function oldest($column = null)
+    {
+        if (is_null($column)) {
+            $column = $this->model->getCreatedAtColumn() ?? 'created_at';
+        }
+
+        $this->query->oldest($column);
+
+        return $this;
+    }
+
+    /**
+     * Create a collection of models from plain arrays.
+     *
+     * @param  array  $items
+     * @return \Illuminate\Database\Eloquent\Collection
+     */
+    public function hydrate(array $items)
+    {
+        $instance = $this->newModelInstance();
+
+        return $instance->newCollection(array_map(function ($item) use ($items, $instance) {
+            $model = $instance->newFromBuilder($item);
+
+            if (count($items) > 1) {
+                $model->preventsLazyLoading = Model::preventsLazyLoading();
+            }
+
+            return $model;
+        }, $items));
+    }
+
+    /**
+     * Create a collection of models from a raw query.
+     *
+     * @param  string  $query
+     * @param  array  $bindings
+     * @return \Illuminate\Database\Eloquent\Collection
+     */
+    public function fromQuery($query, $bindings = [])
+    {
+        return $this->hydrate(
+            $this->query->getConnection()->select($query, $bindings)
+        );
+    }
+
+    /**
+     * Find a model by its primary key.
+     *
+     * @param  mixed  $id
+     * @param  array|string  $columns
+     * @return \Illuminate\Database\Eloquent\Model|\Illuminate\Database\Eloquent\Collection|static[]|static|null
+     */
+    public function find($id, $columns = ['*'])
+    {
+        if (is_array($id) || $id instanceof Arrayable) {
+            return $this->findMany($id, $columns);
+        }
+
+        return $this->whereKey($id)->first($columns);
+    }
+
+    /**
+     * Find multiple models by their primary keys.
+     *
+     * @param  \Illuminate\Contracts\Support\Arrayable|array  $ids
+     * @param  array|string  $columns
+     * @return \Illuminate\Database\Eloquent\Collection
+     */
+    public function findMany($ids, $columns = ['*'])
+    {
+        $ids = $ids instanceof Arrayable ? $ids->toArray() : $ids;
+
+        if (empty($ids)) {
+            return $this->model->newCollection();
+        }
+
+        return $this->whereKey($ids)->get($columns);
+    }
+
+    /**
+     * Find a model by its primary key or throw an exception.
+     *
+     * @param  mixed  $id
+     * @param  array|string  $columns
+     * @return \Illuminate\Database\Eloquent\Model|\Illuminate\Database\Eloquent\Collection|static|static[]
+     *
+     * @throws \Illuminate\Database\Eloquent\ModelNotFoundException<\Illuminate\Database\Eloquent\Model>
+     */
+    public function findOrFail($id, $columns = ['*'])
+    {
+        $result = $this->find($id, $columns);
+
+        $id = $id instanceof Arrayable ? $id->toArray() : $id;
+
+        if (is_array($id)) {
+            if (count($result) !== count(array_unique($id))) {
+                throw (new ModelNotFoundException)->setModel(
+                    get_class($this->model), array_diff($id, $result->modelKeys())
+                );
+            }
+
+            return $result;
+        }
+
+        if (is_null($result)) {
+            throw (new ModelNotFoundException)->setModel(
+                get_class($this->model), $id
+            );
+        }
+
+        return $result;
+    }
+
+    /**
+     * Find a model by its primary key or return fresh model instance.
+     *
+     * @param  mixed  $id
+     * @param  array|string  $columns
+     * @return \Illuminate\Database\Eloquent\Model|static
+     */
+    public function findOrNew($id, $columns = ['*'])
+    {
+        if (! is_null($model = $this->find($id, $columns))) {
+            return $model;
+        }
+
+        return $this->newModelInstance();
+    }
+
+    /**
+     * Find a model by its primary key or call a callback.
+     *
+     * @param  mixed  $id
+     * @param  \Closure|array|string  $columns
+     * @param  \Closure|null  $callback
+     * @return \Illuminate\Database\Eloquent\Model|\Illuminate\Database\Eloquent\Collection|static[]|static|mixed
+     */
+    public function findOr($id, $columns = ['*'], Closure $callback = null)
+    {
+        if ($columns instanceof Closure) {
+            $callback = $columns;
+
+            $columns = ['*'];
+        }
+
+        if (! is_null($model = $this->find($id, $columns))) {
+            return $model;
+        }
+
+        return $callback();
+    }
+
+    /**
+     * Get the first record matching the attributes or instantiate it.
+     *
+     * @param  array  $attributes
+     * @param  array  $values
+     * @return \Illuminate\Database\Eloquent\Model|static
+     */
+    public function firstOrNew(array $attributes = [], array $values = [])
+    {
+        if (! is_null($instance = $this->where($attributes)->first())) {
+            return $instance;
+        }
+
+        return $this->newModelInstance(array_merge($attributes, $values));
+    }
+
+    /**
+     * Get the first record matching the attributes or create it.
+     *
+     * @param  array  $attributes
+     * @param  array  $values
+     * @return \Illuminate\Database\Eloquent\Model|static
+     */
+    public function firstOrCreate(array $attributes = [], array $values = [])
+    {
+        if (! is_null($instance = $this->where($attributes)->first())) {
+            return $instance;
+        }
+
+        return tap($this->newModelInstance(array_merge($attributes, $values)), function ($instance) {
+            $instance->save();
+        });
+    }
+
+    /**
+     * Create or update a record matching the attributes, and fill it with values.
+     *
+     * @param  array  $attributes
+     * @param  array  $values
+     * @return \Illuminate\Database\Eloquent\Model|static
+     */
+    public function updateOrCreate(array $attributes, array $values = [])
+    {
+        return tap($this->firstOrNew($attributes), function ($instance) use ($values) {
+            $instance->fill($values)->save();
+        });
+    }
+
+    /**
+     * Execute the query and get the first result or throw an exception.
+     *
+     * @param  array|string  $columns
+     * @return \Illuminate\Database\Eloquent\Model|static
+     *
+     * @throws \Illuminate\Database\Eloquent\ModelNotFoundException<\Illuminate\Database\Eloquent\Model>
+     */
+    public function firstOrFail($columns = ['*'])
+    {
+        if (! is_null($model = $this->first($columns))) {
+            return $model;
+        }
+
+        throw (new ModelNotFoundException)->setModel(get_class($this->model));
+    }
+
+    /**
+     * Execute the query and get the first result or call a callback.
+     *
+     * @param  \Closure|array|string  $columns
+     * @param  \Closure|null  $callback
+     * @return \Illuminate\Database\Eloquent\Model|static|mixed
+     */
+    public function firstOr($columns = ['*'], Closure $callback = null)
+    {
+        if ($columns instanceof Closure) {
+            $callback = $columns;
+
+            $columns = ['*'];
+        }
+
+        if (! is_null($model = $this->first($columns))) {
+            return $model;
+        }
+
+        return $callback();
+    }
+
+    /**
+     * Execute the query and get the first result if it's the sole matching record.
+     *
+     * @param  array|string  $columns
+     * @return \Illuminate\Database\Eloquent\Model
+     *
+     * @throws \Illuminate\Database\Eloquent\ModelNotFoundException<\Illuminate\Database\Eloquent\Model>
+     * @throws \Illuminate\Database\MultipleRecordsFoundException
+     */
+    public function sole($columns = ['*'])
+    {
+        try {
+            return $this->baseSole($columns);
+        } catch (RecordsNotFoundException $exception) {
+            throw (new ModelNotFoundException)->setModel(get_class($this->model));
+        }
+    }
+
+    /**
+     * Get a single column's value from the first result of a query.
+     *
+     * @param  string|\Illuminate\Database\Query\Expression  $column
+     * @return mixed
+     */
+    public function value($column)
+    {
+        if ($result = $this->first([$column])) {
+            return $result->{Str::afterLast($column, '.')};
+        }
+    }
+
+    /**
+     * Get a single column's value from the first result of a query if it's the sole matching record.
+     *
+     * @param  string|\Illuminate\Database\Query\Expression  $column
+     * @return mixed
+     *
+     * @throws \Illuminate\Database\Eloquent\ModelNotFoundException<\Illuminate\Database\Eloquent\Model>
+     * @throws \Illuminate\Database\MultipleRecordsFoundException
+     */
+    public function soleValue($column)
+    {
+        return $this->sole([$column])->{Str::afterLast($column, '.')};
+    }
+
+    /**
+     * Get a single column's value from the first result of the query or throw an exception.
+     *
+     * @param  string|\Illuminate\Database\Query\Expression  $column
+     * @return mixed
+     *
+     * @throws \Illuminate\Database\Eloquent\ModelNotFoundException<\Illuminate\Database\Eloquent\Model>
+     */
+    public function valueOrFail($column)
+    {
+        return $this->firstOrFail([$column])->{Str::afterLast($column, '.')};
+    }
+
+    /**
+     * Execute the query as a "select" statement.
+     *
+     * @param  array|string  $columns
+     * @return \Illuminate\Database\Eloquent\Collection|static[]
+     */
+    public function get($columns = ['*'])
+    {
+        $builder = $this->applyScopes();
+
+        // If we actually found models we will also eager load any relationships that
+        // have been specified as needing to be eager loaded, which will solve the
+        // n+1 query issue for the developers to avoid running a lot of queries.
+        if (count($models = $builder->getModels($columns)) > 0) {
+            $models = $builder->eagerLoadRelations($models);
+        }
+
+        return $builder->getModel()->newCollection($models);
+    }
+
+    /**
+     * Get the hydrated models without eager loading.
+     *
+     * @param  array|string  $columns
+     * @return \Illuminate\Database\Eloquent\Model[]|static[]
+     */
+    public function getModels($columns = ['*'])
+    {
+        return $this->model->hydrate(
+            $this->query->get($columns)->all()
+        )->all();
+    }
+
+    /**
+     * Eager load the relationships for the models.
+     *
+     * @param  array  $models
+     * @return array
+     */
+    public function eagerLoadRelations(array $models)
+    {
+        foreach ($this->eagerLoad as $name => $constraints) {
+            // For nested eager loads we'll skip loading them here and they will be set as an
+            // eager load on the query to retrieve the relation so that they will be eager
+            // loaded on that query, because that is where they get hydrated as models.
+            if (! str_contains($name, '.')) {
+                $models = $this->eagerLoadRelation($models, $name, $constraints);
+            }
+        }
+
+        return $models;
+    }
+
+    /**
+     * Eagerly load the relationship on a set of models.
+     *
+     * @param  array  $models
+     * @param  string  $name
+     * @param  \Closure  $constraints
+     * @return array
+     */
+    protected function eagerLoadRelation(array $models, $name, Closure $constraints)
+    {
+        // First we will "back up" the existing where conditions on the query so we can
+        // add our eager constraints. Then we will merge the wheres that were on the
+        // query back to it in order that any where conditions might be specified.
+        $relation = $this->getRelation($name);
+
+        $relation->addEagerConstraints($models);
+
+        $constraints($relation);
+
+        // Once we have the results, we just match those back up to their parent models
+        // using the relationship instance. Then we just return the finished arrays
+        // of models which have been eagerly hydrated and are readied for return.
+        return $relation->match(
+            $relation->initRelation($models, $name),
+            $relation->getEager(), $name
+        );
+    }
+
+    /**
+     * Get the relation instance for the given relation name.
+     *
+     * @param  string  $name
+     * @return \Illuminate\Database\Eloquent\Relations\Relation
+     */
+    public function getRelation($name)
+    {
+        // We want to run a relationship query without any constrains so that we will
+        // not have to remove these where clauses manually which gets really hacky
+        // and error prone. We don't want constraints because we add eager ones.
+        $relation = Relation::noConstraints(function () use ($name) {
+            try {
+                return $this->getModel()->newInstance()->$name();
+            } catch (BadMethodCallException $e) {
+                throw RelationNotFoundException::make($this->getModel(), $name);
+            }
+        });
+
+        $nested = $this->relationsNestedUnder($name);
+
+        // If there are nested relationships set on the query, we will put those onto
+        // the query instances so that they can be handled after this relationship
+        // is loaded. In this way they will all trickle down as they are loaded.
+        if (count($nested) > 0) {
+            $relation->getQuery()->with($nested);
+        }
+
+        return $relation;
+    }
+
+    /**
+     * Get the deeply nested relations for a given top-level relation.
+     *
+     * @param  string  $relation
+     * @return array
+     */
+    protected function relationsNestedUnder($relation)
+    {
+        $nested = [];
+
+        // We are basically looking for any relationships that are nested deeper than
+        // the given top-level relationship. We will just check for any relations
+        // that start with the given top relations and adds them to our arrays.
+        foreach ($this->eagerLoad as $name => $constraints) {
+            if ($this->isNestedUnder($relation, $name)) {
+                $nested[substr($name, strlen($relation.'.'))] = $constraints;
+            }
+        }
+
+        return $nested;
+    }
+
+    /**
+     * Determine if the relationship is nested.
+     *
+     * @param  string  $relation
+     * @param  string  $name
+     * @return bool
+     */
+    protected function isNestedUnder($relation, $name)
+    {
+        return str_contains($name, '.') && str_starts_with($name, $relation.'.');
+    }
+
+    /**
+     * Get a lazy collection for the given query.
+     *
+     * @return \Illuminate\Support\LazyCollection
+     */
+    public function cursor()
+    {
+        return $this->applyScopes()->query->cursor()->map(function ($record) {
+            return $this->newModelInstance()->newFromBuilder($record);
+        });
+    }
+
+    /**
+     * Add a generic "order by" clause if the query doesn't already have one.
+     *
+     * @return void
+     */
+    protected function enforceOrderBy()
+    {
+        if (empty($this->query->orders) && empty($this->query->unionOrders)) {
+            $this->orderBy($this->model->getQualifiedKeyName(), 'asc');
+        }
+    }
+
+    /**
+     * Get a collection with the values of a given column.
+     *
+     * @param  string|\Illuminate\Database\Query\Expression  $column
+     * @param  string|null  $key
+     * @return \Illuminate\Support\Collection
+     */
+    public function pluck($column, $key = null)
+    {
+        $results = $this->toBase()->pluck($column, $key);
+
+        // If the model has a mutator for the requested column, we will spin through
+        // the results and mutate the values so that the mutated version of these
+        // columns are returned as you would expect from these Eloquent models.
+        if (! $this->model->hasGetMutator($column) &&
+            ! $this->model->hasCast($column) &&
+            ! in_array($column, $this->model->getDates())) {
+            return $results;
+        }
+
+        return $results->map(function ($value) use ($column) {
+            return $this->model->newFromBuilder([$column => $value])->{$column};
+        });
+    }
+
+    /**
+     * Paginate the given query.
+     *
+     * @param  int|null|\Closure  $perPage
+     * @param  array|string  $columns
+     * @param  string  $pageName
+     * @param  int|null  $page
+     * @return \Illuminate\Contracts\Pagination\LengthAwarePaginator
+     *
+     * @throws \InvalidArgumentException
+     */
+    public function paginate($perPage = null, $columns = ['*'], $pageName = 'page', $page = null)
+    {
+        $page = $page ?: Paginator::resolveCurrentPage($pageName);
+
+        $total = $this->toBase()->getCountForPagination();
+
+        $perPage = ($perPage instanceof Closure
+            ? $perPage($total)
+            : $perPage
+        ) ?: $this->model->getPerPage();
+
+        $results = $total
+            ? $this->forPage($page, $perPage)->get($columns)
+            : $this->model->newCollection();
+
+        return $this->paginator($results, $total, $perPage, $page, [
+            'path' => Paginator::resolveCurrentPath(),
+            'pageName' => $pageName,
+        ]);
+    }
+
+    /**
+     * Paginate the given query into a simple paginator.
+     *
+     * @param  int|null  $perPage
+     * @param  array|string  $columns
+     * @param  string  $pageName
+     * @param  int|null  $page
+     * @return \Illuminate\Contracts\Pagination\Paginator
+     */
+    public function simplePaginate($perPage = null, $columns = ['*'], $pageName = 'page', $page = null)
+    {
+        $page = $page ?: Paginator::resolveCurrentPage($pageName);
+
+        $perPage = $perPage ?: $this->model->getPerPage();
+
+        // Next we will set the limit and offset for this query so that when we get the
+        // results we get the proper section of results. Then, we'll create the full
+        // paginator instances for these results with the given page and per page.
+        $this->skip(($page - 1) * $perPage)->take($perPage + 1);
+
+        return $this->simplePaginator($this->get($columns), $perPage, $page, [
+            'path' => Paginator::resolveCurrentPath(),
+            'pageName' => $pageName,
+        ]);
+    }
+
+    /**
+     * Paginate the given query into a cursor paginator.
+     *
+     * @param  int|null  $perPage
+     * @param  array|string  $columns
+     * @param  string  $cursorName
+     * @param  \Illuminate\Pagination\Cursor|string|null  $cursor
+     * @return \Illuminate\Contracts\Pagination\CursorPaginator
+     */
+    public function cursorPaginate($perPage = null, $columns = ['*'], $cursorName = 'cursor', $cursor = null)
+    {
+        $perPage = $perPage ?: $this->model->getPerPage();
+
+        return $this->paginateUsingCursor($perPage, $columns, $cursorName, $cursor);
+    }
+
+    /**
+     * Ensure the proper order by required for cursor pagination.
+     *
+     * @param  bool  $shouldReverse
+     * @return \Illuminate\Support\Collection
+     */
+    protected function ensureOrderForCursorPagination($shouldReverse = false)
+    {
+        if (empty($this->query->orders) && empty($this->query->unionOrders)) {
+            $this->enforceOrderBy();
+        }
+
+        if ($shouldReverse) {
+            $this->query->orders = collect($this->query->orders)->map(function ($order) {
+                $order['direction'] = $order['direction'] === 'asc' ? 'desc' : 'asc';
+
+                return $order;
+            })->toArray();
+        }
+
+        if ($this->query->unionOrders) {
+            return collect($this->query->unionOrders);
+        }
+
+        return collect($this->query->orders);
+    }
+
+    /**
+     * Save a new model and return the instance.
+     *
+     * @param  array  $attributes
+     * @return \Illuminate\Database\Eloquent\Model|$this
+     */
+    public function create(array $attributes = [])
+    {
+        return tap($this->newModelInstance($attributes), function ($instance) {
+            $instance->save();
+        });
+    }
+
+    /**
+     * Save a new model and return the instance. Allow mass-assignment.
+     *
+     * @param  array  $attributes
+     * @return \Illuminate\Database\Eloquent\Model|$this
+     */
+    public function forceCreate(array $attributes)
+    {
+        return $this->model->unguarded(function () use ($attributes) {
+            return $this->newModelInstance()->create($attributes);
+        });
+    }
+
+    /**
+     * Update records in the database.
+     *
+     * @param  array  $values
+     * @return int
+     */
+    public function update(array $values)
+    {
+        return $this->toBase()->update($this->addUpdatedAtColumn($values));
+    }
+
+    /**
+     * Insert new records or update the existing ones.
+     *
+     * @param  array  $values
+     * @param  array|string  $uniqueBy
+     * @param  array|null  $update
+     * @return int
+     */
+    public function upsert(array $values, $uniqueBy, $update = null)
+    {
+        if (empty($values)) {
+            return 0;
+        }
+
+        if (! is_array(reset($values))) {
+            $values = [$values];
+        }
+
+        if (is_null($update)) {
+            $update = array_keys(reset($values));
+        }
+
+        return $this->toBase()->upsert(
+            $this->addTimestampsToUpsertValues($values),
+            $uniqueBy,
+            $this->addUpdatedAtToUpsertColumns($update)
+        );
+    }
+
+    /**
+     * Update the column's update timestamp.
+     *
+     * @param  string|null  $column
+     * @return int|false
+     */
+    public function touch($column = null)
+    {
+        $time = $this->model->freshTimestamp();
+
+        if ($column) {
+            return $this->toBase()->update([$column => $time]);
+        }
+
+        $column = $this->model->getUpdatedAtColumn();
+
+        if (! $this->model->usesTimestamps() || is_null($column)) {
+            return false;
+        }
+
+        return $this->toBase()->update([$column => $time]);
+    }
+
+    /**
+     * Increment a column's value by a given amount.
+     *
+     * @param  string|\Illuminate\Database\Query\Expression  $column
+     * @param  float|int  $amount
+     * @param  array  $extra
+     * @return int
+     */
+    public function increment($column, $amount = 1, array $extra = [])
+    {
+        return $this->toBase()->increment(
+            $column, $amount, $this->addUpdatedAtColumn($extra)
+        );
+    }
+
+    /**
+     * Decrement a column's value by a given amount.
+     *
+     * @param  string|\Illuminate\Database\Query\Expression  $column
+     * @param  float|int  $amount
+     * @param  array  $extra
+     * @return int
+     */
+    public function decrement($column, $amount = 1, array $extra = [])
+    {
+        return $this->toBase()->decrement(
+            $column, $amount, $this->addUpdatedAtColumn($extra)
+        );
+    }
+
+    /**
+     * Add the "updated at" column to an array of values.
+     *
+     * @param  array  $values
+     * @return array
+     */
+    protected function addUpdatedAtColumn(array $values)
+    {
+        if (! $this->model->usesTimestamps() ||
+            is_null($this->model->getUpdatedAtColumn())) {
+            return $values;
+        }
+
+        $column = $this->model->getUpdatedAtColumn();
+
+        $values = array_merge(
+            [$column => $this->model->freshTimestampString()],
+            $values
+        );
+
+        $segments = preg_split('/\s+as\s+/i', $this->query->from);
+
+        $qualifiedColumn = end($segments).'.'.$column;
+
+        $values[$qualifiedColumn] = Arr::get($values, $qualifiedColumn, $values[$column]);
+
+        unset($values[$column]);
+
+        return $values;
+    }
+
+    /**
+     * Add timestamps to the inserted values.
+     *
+     * @param  array  $values
+     * @return array
+     */
+    protected function addTimestampsToUpsertValues(array $values)
+    {
+        if (! $this->model->usesTimestamps()) {
+            return $values;
+        }
+
+        $timestamp = $this->model->freshTimestampString();
+
+        $columns = array_filter([
+            $this->model->getCreatedAtColumn(),
+            $this->model->getUpdatedAtColumn(),
+        ]);
+
+        foreach ($columns as $column) {
+            foreach ($values as &$row) {
+                $row = array_merge([$column => $timestamp], $row);
+            }
+        }
+
+        return $values;
+    }
+
+    /**
+     * Add the "updated at" column to the updated columns.
+     *
+     * @param  array  $update
+     * @return array
+     */
+    protected function addUpdatedAtToUpsertColumns(array $update)
+    {
+        if (! $this->model->usesTimestamps()) {
+            return $update;
+        }
+
+        $column = $this->model->getUpdatedAtColumn();
+
+        if (! is_null($column) &&
+            ! array_key_exists($column, $update) &&
+            ! in_array($column, $update)) {
+            $update[] = $column;
+        }
+
+        return $update;
+    }
+
+    /**
+     * Delete records from the database.
+     *
+     * @return mixed
+     */
+    public function delete()
+    {
+        if (isset($this->onDelete)) {
+            return call_user_func($this->onDelete, $this);
+        }
+
+        return $this->toBase()->delete();
+    }
+
+    /**
+     * Run the default delete function on the builder.
+     *
+     * Since we do not apply scopes here, the row will actually be deleted.
+     *
+     * @return mixed
+     */
+    public function forceDelete()
+    {
+        return $this->query->delete();
+    }
+
+    /**
+     * Register a replacement for the default delete function.
+     *
+     * @param  \Closure  $callback
+     * @return void
+     */
+    public function onDelete(Closure $callback)
+    {
+        $this->onDelete = $callback;
+    }
+
+    /**
+     * Determine if the given model has a scope.
+     *
+     * @param  string  $scope
+     * @return bool
+     */
+    public function hasNamedScope($scope)
+    {
+        return $this->model && $this->model->hasNamedScope($scope);
+    }
+
+    /**
+     * Call the given local model scopes.
+     *
+     * @param  array|string  $scopes
+     * @return static|mixed
+     */
+    public function scopes($scopes)
+    {
+        $builder = $this;
+
+        foreach (Arr::wrap($scopes) as $scope => $parameters) {
+            // If the scope key is an integer, then the scope was passed as the value and
+            // the parameter list is empty, so we will format the scope name and these
+            // parameters here. Then, we'll be ready to call the scope on the model.
+            if (is_int($scope)) {
+                [$scope, $parameters] = [$parameters, []];
+            }
+
+            // Next we'll pass the scope callback to the callScope method which will take
+            // care of grouping the "wheres" properly so the logical order doesn't get
+            // messed up when adding scopes. Then we'll return back out the builder.
+            $builder = $builder->callNamedScope(
+                $scope, Arr::wrap($parameters)
+            );
+        }
+
+        return $builder;
+    }
+
+    /**
+     * Apply the scopes to the Eloquent builder instance and return it.
+     *
+     * @return static
+     */
+    public function applyScopes()
+    {
+        if (! $this->scopes) {
+            return $this;
+        }
+
+        $builder = clone $this;
+
+        foreach ($this->scopes as $identifier => $scope) {
+            if (! isset($builder->scopes[$identifier])) {
+                continue;
+            }
+
+            $builder->callScope(function (self $builder) use ($scope) {
+                // If the scope is a Closure we will just go ahead and call the scope with the
+                // builder instance. The "callScope" method will properly group the clauses
+                // that are added to this query so "where" clauses maintain proper logic.
+                if ($scope instanceof Closure) {
+                    $scope($builder);
+                }
+
+                // If the scope is a scope object, we will call the apply method on this scope
+                // passing in the builder and the model instance. After we run all of these
+                // scopes we will return back the builder instance to the outside caller.
+                if ($scope instanceof Scope) {
+                    $scope->apply($builder, $this->getModel());
+                }
+            });
+        }
+
+        return $builder;
+    }
+
+    /**
+     * Apply the given scope on the current builder instance.
+     *
+     * @param  callable  $scope
+     * @param  array  $parameters
+     * @return mixed
+     */
+    protected function callScope(callable $scope, array $parameters = [])
+    {
+        array_unshift($parameters, $this);
+
+        $query = $this->getQuery();
+
+        // We will keep track of how many wheres are on the query before running the
+        // scope so that we can properly group the added scope constraints in the
+        // query as their own isolated nested where statement and avoid issues.
+        $originalWhereCount = is_null($query->wheres)
+                    ? 0 : count($query->wheres);
+
+        $result = $scope(...$parameters) ?? $this;
+
+        if (count((array) $query->wheres) > $originalWhereCount) {
+            $this->addNewWheresWithinGroup($query, $originalWhereCount);
+        }
+
+        return $result;
+    }
+
+    /**
+     * Apply the given named scope on the current builder instance.
+     *
+     * @param  string  $scope
+     * @param  array  $parameters
+     * @return mixed
+     */
+    protected function callNamedScope($scope, array $parameters = [])
+    {
+        return $this->callScope(function (...$parameters) use ($scope) {
+            return $this->model->callNamedScope($scope, $parameters);
+        }, $parameters);
+    }
+
+    /**
+     * Nest where conditions by slicing them at the given where count.
+     *
+     * @param  \Illuminate\Database\Query\Builder  $query
+     * @param  int  $originalWhereCount
+     * @return void
+     */
+    protected function addNewWheresWithinGroup(QueryBuilder $query, $originalWhereCount)
+    {
+        // Here, we totally remove all of the where clauses since we are going to
+        // rebuild them as nested queries by slicing the groups of wheres into
+        // their own sections. This is to prevent any confusing logic order.
+        $allWheres = $query->wheres;
+
+        $query->wheres = [];
+
+        $this->groupWhereSliceForScope(
+            $query, array_slice($allWheres, 0, $originalWhereCount)
+        );
+
+        $this->groupWhereSliceForScope(
+            $query, array_slice($allWheres, $originalWhereCount)
+        );
+    }
+
+    /**
+     * Slice where conditions at the given offset and add them to the query as a nested condition.
+     *
+     * @param  \Illuminate\Database\Query\Builder  $query
+     * @param  array  $whereSlice
+     * @return void
+     */
+    protected function groupWhereSliceForScope(QueryBuilder $query, $whereSlice)
+    {
+        $whereBooleans = collect($whereSlice)->pluck('boolean');
+
+        // Here we'll check if the given subset of where clauses contains any "or"
+        // booleans and in this case create a nested where expression. That way
+        // we don't add any unnecessary nesting thus keeping the query clean.
+        if ($whereBooleans->contains('or')) {
+            $query->wheres[] = $this->createNestedWhere(
+                $whereSlice, $whereBooleans->first()
+            );
+        } else {
+            $query->wheres = array_merge($query->wheres, $whereSlice);
+        }
+    }
+
+    /**
+     * Create a where array with nested where conditions.
+     *
+     * @param  array  $whereSlice
+     * @param  string  $boolean
+     * @return array
+     */
+    protected function createNestedWhere($whereSlice, $boolean = 'and')
+    {
+        $whereGroup = $this->getQuery()->forNestedWhere();
+
+        $whereGroup->wheres = $whereSlice;
+
+        return ['type' => 'Nested', 'query' => $whereGroup, 'boolean' => $boolean];
+    }
+
+    /**
+     * Set the relationships that should be eager loaded.
+     *
+     * @param  string|array  $relations
+     * @param  string|\Closure|null  $callback
+     * @return $this
+     */
+    public function with($relations, $callback = null)
+    {
+        if ($callback instanceof Closure) {
+            $eagerLoad = $this->parseWithRelations([$relations => $callback]);
+        } else {
+            $eagerLoad = $this->parseWithRelations(is_string($relations) ? func_get_args() : $relations);
+        }
+
+        $this->eagerLoad = array_merge($this->eagerLoad, $eagerLoad);
+
+        return $this;
+    }
+
+    /**
+     * Prevent the specified relations from being eager loaded.
+     *
+     * @param  mixed  $relations
+     * @return $this
+     */
+    public function without($relations)
+    {
+        $this->eagerLoad = array_diff_key($this->eagerLoad, array_flip(
+            is_string($relations) ? func_get_args() : $relations
+        ));
+
+        return $this;
+    }
+
+    /**
+     * Set the relationships that should be eager loaded while removing any previously added eager loading specifications.
+     *
+     * @param  mixed  $relations
+     * @return $this
+     */
+    public function withOnly($relations)
+    {
+        $this->eagerLoad = [];
+
+        return $this->with($relations);
+    }
+
+    /**
+     * Create a new instance of the model being queried.
+     *
+     * @param  array  $attributes
+     * @return \Illuminate\Database\Eloquent\Model|static
+     */
+    public function newModelInstance($attributes = [])
+    {
+        return $this->model->newInstance($attributes)->setConnection(
+            $this->query->getConnection()->getName()
+        );
+    }
+
+    /**
+     * Parse a list of relations into individuals.
+     *
+     * @param  array  $relations
+     * @return array
+     */
+    protected function parseWithRelations(array $relations)
+    {
+        if ($relations === []) {
+            return [];
+        }
+
+        $results = [];
+
+        foreach ($this->prepareNestedWithRelationships($relations) as $name => $constraints) {
+            // We need to separate out any nested includes, which allows the developers
+            // to load deep relationships using "dots" without stating each level of
+            // the relationship with its own key in the array of eager-load names.
+            $results = $this->addNestedWiths($name, $results);
+
+            $results[$name] = $constraints;
+        }
+
+        return $results;
+    }
+
+    /**
+     * Prepare nested with relationships.
+     *
+     * @param  array  $relations
+     * @param  string  $prefix
+     * @return array
+     */
+    protected function prepareNestedWithRelationships($relations, $prefix = '')
+    {
+        $preparedRelationships = [];
+
+        if ($prefix !== '') {
+            $prefix .= '.';
+        }
+
+        // If any of the relationships are formatted with the [$attribute => array()]
+        // syntax, we shall loop over the nested relations and prepend each key of
+        // this array while flattening into the traditional dot notation format.
+        foreach ($relations as $key => $value) {
+            if (! is_string($key) || ! is_array($value)) {
+                continue;
+            }
+
+            [$attribute, $attributeSelectConstraint] = $this->parseNameAndAttributeSelectionConstraint($key);
+
+            $preparedRelationships = array_merge(
+                $preparedRelationships,
+                ["{$prefix}{$attribute}" => $attributeSelectConstraint],
+                $this->prepareNestedWithRelationships($value, "{$prefix}{$attribute}"),
+            );
+
+            unset($relations[$key]);
+        }
+
+        // We now know that the remaining relationships are in a dot notation format
+        // and may be a string or Closure. We'll loop over them and ensure all of
+        // the present Closures are merged + strings are made into constraints.
+        foreach ($relations as $key => $value) {
+            if (is_numeric($key) && is_string($value)) {
+                [$key, $value] = $this->parseNameAndAttributeSelectionConstraint($value);
+            }
+
+            $preparedRelationships[$prefix.$key] = $this->combineConstraints([
+                $value,
+                $preparedRelationships[$prefix.$key] ?? static function () {
+                    //
+                },
+            ]);
+        }
+
+        return $preparedRelationships;
+    }
+
+    /**
+     * Combine an array of constraints into a single constraint.
+     *
+     * @param  array  $constraints
+     * @return \Closure
+     */
+    protected function combineConstraints(array $constraints)
+    {
+        return function ($builder) use ($constraints) {
+            foreach ($constraints as $constraint) {
+                $builder = $constraint($builder) ?? $builder;
+            }
+
+            return $builder;
+        };
+    }
+
+    /**
+     * Parse the attribute select constraints from the name.
+     *
+     * @param  string  $name
+     * @return array
+     */
+    protected function parseNameAndAttributeSelectionConstraint($name)
+    {
+        return str_contains($name, ':')
+            ? $this->createSelectWithConstraint($name)
+            : [$name, static function () {
+                //
+            }];
+    }
+
+    /**
+     * Create a constraint to select the given columns for the relation.
+     *
+     * @param  string  $name
+     * @return array
+     */
+    protected function createSelectWithConstraint($name)
+    {
+        return [explode(':', $name)[0], static function ($query) use ($name) {
+            $query->select(array_map(static function ($column) use ($query) {
+                if (str_contains($column, '.')) {
+                    return $column;
+                }
+
+                return $query instanceof BelongsToMany
+                        ? $query->getRelated()->getTable().'.'.$column
+                        : $column;
+            }, explode(',', explode(':', $name)[1])));
+        }];
+    }
+
+    /**
+     * Parse the nested relationships in a relation.
+     *
+     * @param  string  $name
+     * @param  array  $results
+     * @return array
+     */
+    protected function addNestedWiths($name, $results)
+    {
+        $progress = [];
+
+        // If the relation has already been set on the result array, we will not set it
+        // again, since that would override any constraints that were already placed
+        // on the relationships. We will only set the ones that are not specified.
+        foreach (explode('.', $name) as $segment) {
+            $progress[] = $segment;
+
+            if (! isset($results[$last = implode('.', $progress)])) {
+                $results[$last] = static function () {
+                    //
+                };
+            }
+        }
+
+        return $results;
+    }
+
+    /**
+     * Apply query-time casts to the model instance.
+     *
+     * @param  array  $casts
+     * @return $this
+     */
+    public function withCasts($casts)
+    {
+        $this->model->mergeCasts($casts);
+
+        return $this;
+    }
+
+    /**
+     * Get the underlying query builder instance.
+     *
+     * @return \Illuminate\Database\Query\Builder
+     */
+    public function getQuery()
+    {
+        return $this->query;
+    }
+
+    /**
+     * Set the underlying query builder instance.
+     *
+     * @param  \Illuminate\Database\Query\Builder  $query
+     * @return $this
+     */
+    public function setQuery($query)
+    {
+        $this->query = $query;
+
+        return $this;
+    }
+
+    /**
+     * Get a base query builder instance.
+     *
+     * @return \Illuminate\Database\Query\Builder
+     */
+    public function toBase()
+    {
+        return $this->applyScopes()->getQuery();
+    }
+
+    /**
+     * Get the relationships being eagerly loaded.
+     *
+     * @return array
+     */
+    public function getEagerLoads()
+    {
+        return $this->eagerLoad;
+    }
+
+    /**
+     * Set the relationships being eagerly loaded.
+     *
+     * @param  array  $eagerLoad
+     * @return $this
+     */
+    public function setEagerLoads(array $eagerLoad)
+    {
+        $this->eagerLoad = $eagerLoad;
+
+        return $this;
+    }
+
+    /**
+     * Indicate that the given relationships should not be eagerly loaded.
+     *
+     * @param  array  $relations
+     * @return $this
+     */
+    public function withoutEagerLoad(array $relations)
+    {
+        $relations = array_diff(array_keys($this->model->getRelations()), $relations);
+
+        return $this->with($relations);
+    }
+
+    /**
+     * Flush the relationships being eagerly loaded.
+     *
+     * @return $this
+     */
+    public function withoutEagerLoads()
+    {
+        return $this->setEagerLoads([]);
+    }
+
+    /**
+     * Get the default key name of the table.
+     *
+     * @return string
+     */
+    protected function defaultKeyName()
+    {
+        return $this->getModel()->getKeyName();
+    }
+
+    /**
+     * Get the model instance being queried.
+     *
+     * @return \Illuminate\Database\Eloquent\Model|static
+     */
+    public function getModel()
+    {
+        return $this->model;
+    }
+
+    /**
+     * Set a model instance for the model being queried.
+     *
+     * @param  \Illuminate\Database\Eloquent\Model  $model
+     * @return $this
+     */
+    public function setModel(Model $model)
+    {
+        $this->model = $model;
+
+        $this->query->from($model->getTable());
+
+        return $this;
+    }
+
+    /**
+     * Qualify the given column name by the model's table.
+     *
+     * @param  string|\Illuminate\Database\Query\Expression  $column
+     * @return string
+     */
+    public function qualifyColumn($column)
+    {
+        return $this->model->qualifyColumn($column);
+    }
+
+    /**
+     * Qualify the given columns with the model's table.
+     *
+     * @param  array|\Illuminate\Database\Query\Expression  $columns
+     * @return array
+     */
+    public function qualifyColumns($columns)
+    {
+        return $this->model->qualifyColumns($columns);
+    }
+
+    /**
+     * Get the given macro by name.
+     *
+     * @param  string  $name
+     * @return \Closure
+     */
+    public function getMacro($name)
+    {
+        return Arr::get($this->localMacros, $name);
+    }
+
+    /**
+     * Checks if a macro is registered.
+     *
+     * @param  string  $name
+     * @return bool
+     */
+    public function hasMacro($name)
+    {
+        return isset($this->localMacros[$name]);
+    }
+
+    /**
+     * Get the given global macro by name.
+     *
+     * @param  string  $name
+     * @return \Closure
+     */
+    public static function getGlobalMacro($name)
+    {
+        return Arr::get(static::$macros, $name);
+    }
+
+    /**
+     * Checks if a global macro is registered.
+     *
+     * @param  string  $name
+     * @return bool
+     */
+    public static function hasGlobalMacro($name)
+    {
+        return isset(static::$macros[$name]);
+    }
+
+    /**
+     * Dynamically access builder proxies.
+     *
+     * @param  string  $key
+     * @return mixed
+     *
+     * @throws \Exception
+     */
+    public function __get($key)
+    {
+        if (in_array($key, ['orWhere', 'whereNot', 'orWhereNot'])) {
+            return new HigherOrderBuilderProxy($this, $key);
+        }
+
+        if (in_array($key, $this->propertyPassthru)) {
+            return $this->toBase()->{$key};
+        }
+
+        throw new Exception("Property [{$key}] does not exist on the Eloquent builder instance.");
+    }
+
+    /**
+     * Dynamically handle calls into the query instance.
+     *
+     * @param  string  $method
+     * @param  array  $parameters
+     * @return mixed
+     */
+    public function __call($method, $parameters)
+    {
+        if ($method === 'macro') {
+            $this->localMacros[$parameters[0]] = $parameters[1];
+
+            return;
+        }
+
+        if ($this->hasMacro($method)) {
+            array_unshift($parameters, $this);
+
+            return $this->localMacros[$method](...$parameters);
+        }
+
+        if (static::hasGlobalMacro($method)) {
+            $callable = static::$macros[$method];
+
+            if ($callable instanceof Closure) {
+                $callable = $callable->bindTo($this, static::class);
+            }
+
+            return $callable(...$parameters);
+        }
+
+        if ($this->hasNamedScope($method)) {
+            return $this->callNamedScope($method, $parameters);
+        }
+
+        if (in_array($method, $this->passthru)) {
+            return $this->toBase()->{$method}(...$parameters);
+        }
+
+        $this->forwardCallTo($this->query, $method, $parameters);
+
+        return $this;
+    }
+
+    /**
+     * Dynamically handle calls into the query instance.
+     *
+     * @param  string  $method
+     * @param  array  $parameters
+     * @return mixed
+     *
+     * @throws \BadMethodCallException
+     */
+    public static function __callStatic($method, $parameters)
+    {
+        if ($method === 'macro') {
+            static::$macros[$parameters[0]] = $parameters[1];
+
+            return;
+        }
+
+        if ($method === 'mixin') {
+            return static::registerMixin($parameters[0], $parameters[1] ?? true);
+        }
+
+        if (! static::hasGlobalMacro($method)) {
+            static::throwBadMethodCallException($method);
+        }
+
+        $callable = static::$macros[$method];
+
+        if ($callable instanceof Closure) {
+            $callable = $callable->bindTo(null, static::class);
+        }
+
+        return $callable(...$parameters);
+    }
+
+    /**
+     * Register the given mixin with the builder.
+     *
+     * @param  string  $mixin
+     * @param  bool  $replace
+     * @return void
+     */
+    protected static function registerMixin($mixin, $replace)
+    {
+        $methods = (new ReflectionClass($mixin))->getMethods(
+            ReflectionMethod::IS_PUBLIC | ReflectionMethod::IS_PROTECTED
+        );
+
+        foreach ($methods as $method) {
+            if ($replace || ! static::hasGlobalMacro($method->name)) {
+                $method->setAccessible(true);
+
+                static::macro($method->name, $method->invoke($mixin));
+            }
+        }
+    }
+
+    /**
+     * Clone the Eloquent query builder.
+     *
+     * @return static
+     */
+    public function clone()
+    {
+        return clone $this;
+    }
+
+    /**
+     * Force a clone of the underlying query builder when cloning.
+     *
+     * @return void
+     */
+    public function __clone()
+    {
+        $this->query = clone $this->query;
+    }
+}
diff --git a/vendor/illuminate/database/Eloquent/Casts/ArrayObject.php b/vendor/illuminate/database/Eloquent/Casts/ArrayObject.php
new file mode 100644
index 0000000..176b733
--- /dev/null
+++ b/vendor/illuminate/database/Eloquent/Casts/ArrayObject.php
@@ -0,0 +1,46 @@
+
+ */
+class ArrayObject extends BaseArrayObject implements Arrayable, JsonSerializable
+{
+    /**
+     * Get a collection containing the underlying array.
+     *
+     * @return \Illuminate\Support\Collection
+     */
+    public function collect()
+    {
+        return collect($this->getArrayCopy());
+    }
+
+    /**
+     * Get the instance as an array.
+     *
+     * @return array
+     */
+    public function toArray()
+    {
+        return $this->getArrayCopy();
+    }
+
+    /**
+     * Get the array that should be JSON serialized.
+     *
+     * @return array
+     */
+    public function jsonSerialize(): array
+    {
+        return $this->getArrayCopy();
+    }
+}
diff --git a/vendor/illuminate/database/Eloquent/Casts/AsArrayObject.php b/vendor/illuminate/database/Eloquent/Casts/AsArrayObject.php
new file mode 100644
index 0000000..23543ba
--- /dev/null
+++ b/vendor/illuminate/database/Eloquent/Casts/AsArrayObject.php
@@ -0,0 +1,42 @@
+, iterable>
+     */
+    public static function castUsing(array $arguments)
+    {
+        return new class implements CastsAttributes
+        {
+            public function get($model, $key, $value, $attributes)
+            {
+                if (! isset($attributes[$key])) {
+                    return;
+                }
+
+                $data = json_decode($attributes[$key], true);
+
+                return is_array($data) ? new ArrayObject($data) : null;
+            }
+
+            public function set($model, $key, $value, $attributes)
+            {
+                return [$key => json_encode($value)];
+            }
+
+            public function serialize($model, string $key, $value, array $attributes)
+            {
+                return $value->getArrayCopy();
+            }
+        };
+    }
+}
diff --git a/vendor/illuminate/database/Eloquent/Casts/AsCollection.php b/vendor/illuminate/database/Eloquent/Casts/AsCollection.php
new file mode 100644
index 0000000..1a0dd83
--- /dev/null
+++ b/vendor/illuminate/database/Eloquent/Casts/AsCollection.php
@@ -0,0 +1,38 @@
+, iterable>
+     */
+    public static function castUsing(array $arguments)
+    {
+        return new class implements CastsAttributes
+        {
+            public function get($model, $key, $value, $attributes)
+            {
+                if (! isset($attributes[$key])) {
+                    return;
+                }
+
+                $data = json_decode($attributes[$key], true);
+
+                return is_array($data) ? new Collection($data) : null;
+            }
+
+            public function set($model, $key, $value, $attributes)
+            {
+                return [$key => json_encode($value)];
+            }
+        };
+    }
+}
diff --git a/vendor/illuminate/database/Eloquent/Casts/AsEncryptedArrayObject.php b/vendor/illuminate/database/Eloquent/Casts/AsEncryptedArrayObject.php
new file mode 100644
index 0000000..ce2b663
--- /dev/null
+++ b/vendor/illuminate/database/Eloquent/Casts/AsEncryptedArrayObject.php
@@ -0,0 +1,45 @@
+, iterable>
+     */
+    public static function castUsing(array $arguments)
+    {
+        return new class implements CastsAttributes
+        {
+            public function get($model, $key, $value, $attributes)
+            {
+                if (isset($attributes[$key])) {
+                    return new ArrayObject(json_decode(Crypt::decryptString($attributes[$key]), true));
+                }
+
+                return null;
+            }
+
+            public function set($model, $key, $value, $attributes)
+            {
+                if (! is_null($value)) {
+                    return [$key => Crypt::encryptString(json_encode($value))];
+                }
+
+                return null;
+            }
+
+            public function serialize($model, string $key, $value, array $attributes)
+            {
+                return ! is_null($value) ? $value->getArrayCopy() : null;
+            }
+        };
+    }
+}
diff --git a/vendor/illuminate/database/Eloquent/Casts/AsEncryptedCollection.php b/vendor/illuminate/database/Eloquent/Casts/AsEncryptedCollection.php
new file mode 100644
index 0000000..64cdf00
--- /dev/null
+++ b/vendor/illuminate/database/Eloquent/Casts/AsEncryptedCollection.php
@@ -0,0 +1,41 @@
+, iterable>
+     */
+    public static function castUsing(array $arguments)
+    {
+        return new class implements CastsAttributes
+        {
+            public function get($model, $key, $value, $attributes)
+            {
+                if (isset($attributes[$key])) {
+                    return new Collection(json_decode(Crypt::decryptString($attributes[$key]), true));
+                }
+
+                return null;
+            }
+
+            public function set($model, $key, $value, $attributes)
+            {
+                if (! is_null($value)) {
+                    return [$key => Crypt::encryptString(json_encode($value))];
+                }
+
+                return null;
+            }
+        };
+    }
+}
diff --git a/vendor/illuminate/database/Eloquent/Casts/AsEnumArrayObject.php b/vendor/illuminate/database/Eloquent/Casts/AsEnumArrayObject.php
new file mode 100644
index 0000000..5b47785
--- /dev/null
+++ b/vendor/illuminate/database/Eloquent/Casts/AsEnumArrayObject.php
@@ -0,0 +1,84 @@
+}  $arguments
+     * @return CastsAttributes, iterable>
+     */
+    public static function castUsing(array $arguments)
+    {
+        return new class($arguments) implements CastsAttributes
+        {
+            protected $arguments;
+
+            public function __construct(array $arguments)
+            {
+                $this->arguments = $arguments;
+            }
+
+            public function get($model, $key, $value, $attributes)
+            {
+                if (! isset($attributes[$key]) || is_null($attributes[$key])) {
+                    return;
+                }
+
+                $data = json_decode($attributes[$key], true);
+
+                if (! is_array($data)) {
+                    return;
+                }
+
+                $enumClass = $this->arguments[0];
+
+                return new ArrayObject((new Collection($data))->map(function ($value) use ($enumClass) {
+                    return is_subclass_of($enumClass, BackedEnum::class)
+                        ? $enumClass::from($value)
+                        : constant($enumClass.'::'.$value);
+                })->toArray());
+            }
+
+            public function set($model, $key, $value, $attributes)
+            {
+                if ($value === null) {
+                    return [$key => null];
+                }
+
+                $storable = [];
+
+                foreach ($value as $enum) {
+                    $storable[] = $this->getStorableEnumValue($enum);
+                }
+
+                return [$key => json_encode($storable)];
+            }
+
+            public function serialize($model, string $key, $value, array $attributes)
+            {
+                return (new Collection($value->getArrayCopy()))->map(function ($enum) {
+                    return $this->getStorableEnumValue($enum);
+                })->toArray();
+            }
+
+            protected function getStorableEnumValue($enum)
+            {
+                if (is_string($enum) || is_int($enum)) {
+                    return $enum;
+                }
+
+                return $enum instanceof BackedEnum ? $enum->value : $enum->name;
+            }
+        };
+    }
+}
diff --git a/vendor/illuminate/database/Eloquent/Casts/AsEnumCollection.php b/vendor/illuminate/database/Eloquent/Casts/AsEnumCollection.php
new file mode 100644
index 0000000..ca1feb5
--- /dev/null
+++ b/vendor/illuminate/database/Eloquent/Casts/AsEnumCollection.php
@@ -0,0 +1,80 @@
+}  $arguments
+     * @return CastsAttributes, iterable>
+     */
+    public static function castUsing(array $arguments)
+    {
+        return new class($arguments) implements CastsAttributes
+        {
+            protected $arguments;
+
+            public function __construct(array $arguments)
+            {
+                $this->arguments = $arguments;
+            }
+
+            public function get($model, $key, $value, $attributes)
+            {
+                if (! isset($attributes[$key]) || is_null($attributes[$key])) {
+                    return;
+                }
+
+                $data = json_decode($attributes[$key], true);
+
+                if (! is_array($data)) {
+                    return;
+                }
+
+                $enumClass = $this->arguments[0];
+
+                return (new Collection($data))->map(function ($value) use ($enumClass) {
+                    return is_subclass_of($enumClass, BackedEnum::class)
+                        ? $enumClass::from($value)
+                        : constant($enumClass.'::'.$value);
+                });
+            }
+
+            public function set($model, $key, $value, $attributes)
+            {
+                $value = $value !== null
+                    ? (new Collection($value))->map(function ($enum) {
+                        return $this->getStorableEnumValue($enum);
+                    })->toJson()
+                    : null;
+
+                return [$key => $value];
+            }
+
+            public function serialize($model, string $key, $value, array $attributes)
+            {
+                return (new Collection($value))->map(function ($enum) {
+                    return $this->getStorableEnumValue($enum);
+                })->toArray();
+            }
+
+            protected function getStorableEnumValue($enum)
+            {
+                if (is_string($enum) || is_int($enum)) {
+                    return $enum;
+                }
+
+                return $enum instanceof BackedEnum ? $enum->value : $enum->name;
+            }
+        };
+    }
+}
diff --git a/vendor/illuminate/database/Eloquent/Casts/AsStringable.php b/vendor/illuminate/database/Eloquent/Casts/AsStringable.php
new file mode 100644
index 0000000..c2927d2
--- /dev/null
+++ b/vendor/illuminate/database/Eloquent/Casts/AsStringable.php
@@ -0,0 +1,32 @@
+
+     */
+    public static function castUsing(array $arguments)
+    {
+        return new class implements CastsAttributes
+        {
+            public function get($model, $key, $value, $attributes)
+            {
+                return isset($value) ? Str::of($value) : null;
+            }
+
+            public function set($model, $key, $value, $attributes)
+            {
+                return isset($value) ? (string) $value : null;
+            }
+        };
+    }
+}
diff --git a/vendor/illuminate/database/Eloquent/Casts/Attribute.php b/vendor/illuminate/database/Eloquent/Casts/Attribute.php
new file mode 100644
index 0000000..3f9fd19
--- /dev/null
+++ b/vendor/illuminate/database/Eloquent/Casts/Attribute.php
@@ -0,0 +1,105 @@
+get = $get;
+        $this->set = $set;
+    }
+
+    /**
+     * Create a new attribute accessor / mutator.
+     *
+     * @param  callable|null  $get
+     * @param  callable|null  $set
+     * @return static
+     */
+    public static function make(callable $get = null, callable $set = null): static
+    {
+        return new static($get, $set);
+    }
+
+    /**
+     * Create a new attribute accessor.
+     *
+     * @param  callable  $get
+     * @return static
+     */
+    public static function get(callable $get)
+    {
+        return new static($get);
+    }
+
+    /**
+     * Create a new attribute mutator.
+     *
+     * @param  callable  $set
+     * @return static
+     */
+    public static function set(callable $set)
+    {
+        return new static(null, $set);
+    }
+
+    /**
+     * Disable object caching for the attribute.
+     *
+     * @return static
+     */
+    public function withoutObjectCaching()
+    {
+        $this->withObjectCaching = false;
+
+        return $this;
+    }
+
+    /**
+     * Enable caching for the attribute.
+     *
+     * @return static
+     */
+    public function shouldCache()
+    {
+        $this->withCaching = true;
+
+        return $this;
+    }
+}
diff --git a/vendor/illuminate/database/Eloquent/Collection.php b/vendor/illuminate/database/Eloquent/Collection.php
new file mode 100755
index 0000000..0904b8e
--- /dev/null
+++ b/vendor/illuminate/database/Eloquent/Collection.php
@@ -0,0 +1,782 @@
+
+ */
+class Collection extends BaseCollection implements QueueableCollection
+{
+    /**
+     * Find a model in the collection by key.
+     *
+     * @template TFindDefault
+     *
+     * @param  mixed  $key
+     * @param  TFindDefault  $default
+     * @return static|TModel|TFindDefault
+     */
+    public function find($key, $default = null)
+    {
+        if ($key instanceof Model) {
+            $key = $key->getKey();
+        }
+
+        if ($key instanceof Arrayable) {
+            $key = $key->toArray();
+        }
+
+        if (is_array($key)) {
+            if ($this->isEmpty()) {
+                return new static;
+            }
+
+            return $this->whereIn($this->first()->getKeyName(), $key);
+        }
+
+        return Arr::first($this->items, fn ($model) => $model->getKey() == $key, $default);
+    }
+
+    /**
+     * Load a set of relationships onto the collection.
+     *
+     * @param  array|string  $relations
+     * @return $this
+     */
+    public function load($relations)
+    {
+        if ($this->isNotEmpty()) {
+            if (is_string($relations)) {
+                $relations = func_get_args();
+            }
+
+            $query = $this->first()->newQueryWithoutRelationships()->with($relations);
+
+            $this->items = $query->eagerLoadRelations($this->items);
+        }
+
+        return $this;
+    }
+
+    /**
+     * Load a set of aggregations over relationship's column onto the collection.
+     *
+     * @param  array|string  $relations
+     * @param  string  $column
+     * @param  string|null  $function
+     * @return $this
+     */
+    public function loadAggregate($relations, $column, $function = null)
+    {
+        if ($this->isEmpty()) {
+            return $this;
+        }
+
+        $models = $this->first()->newModelQuery()
+            ->whereKey($this->modelKeys())
+            ->select($this->first()->getKeyName())
+            ->withAggregate($relations, $column, $function)
+            ->get()
+            ->keyBy($this->first()->getKeyName());
+
+        $attributes = Arr::except(
+            array_keys($models->first()->getAttributes()),
+            $models->first()->getKeyName()
+        );
+
+        $this->each(function ($model) use ($models, $attributes) {
+            $extraAttributes = Arr::only($models->get($model->getKey())->getAttributes(), $attributes);
+
+            $model->forceFill($extraAttributes)
+                ->syncOriginalAttributes($attributes)
+                ->mergeCasts($models->get($model->getKey())->getCasts());
+        });
+
+        return $this;
+    }
+
+    /**
+     * Load a set of relationship counts onto the collection.
+     *
+     * @param  array|string  $relations
+     * @return $this
+     */
+    public function loadCount($relations)
+    {
+        return $this->loadAggregate($relations, '*', 'count');
+    }
+
+    /**
+     * Load a set of relationship's max column values onto the collection.
+     *
+     * @param  array|string  $relations
+     * @param  string  $column
+     * @return $this
+     */
+    public function loadMax($relations, $column)
+    {
+        return $this->loadAggregate($relations, $column, 'max');
+    }
+
+    /**
+     * Load a set of relationship's min column values onto the collection.
+     *
+     * @param  array|string  $relations
+     * @param  string  $column
+     * @return $this
+     */
+    public function loadMin($relations, $column)
+    {
+        return $this->loadAggregate($relations, $column, 'min');
+    }
+
+    /**
+     * Load a set of relationship's column summations onto the collection.
+     *
+     * @param  array|string  $relations
+     * @param  string  $column
+     * @return $this
+     */
+    public function loadSum($relations, $column)
+    {
+        return $this->loadAggregate($relations, $column, 'sum');
+    }
+
+    /**
+     * Load a set of relationship's average column values onto the collection.
+     *
+     * @param  array|string  $relations
+     * @param  string  $column
+     * @return $this
+     */
+    public function loadAvg($relations, $column)
+    {
+        return $this->loadAggregate($relations, $column, 'avg');
+    }
+
+    /**
+     * Load a set of related existences onto the collection.
+     *
+     * @param  array|string  $relations
+     * @return $this
+     */
+    public function loadExists($relations)
+    {
+        return $this->loadAggregate($relations, '*', 'exists');
+    }
+
+    /**
+     * Load a set of relationships onto the collection if they are not already eager loaded.
+     *
+     * @param  array|string  $relations
+     * @return $this
+     */
+    public function loadMissing($relations)
+    {
+        if (is_string($relations)) {
+            $relations = func_get_args();
+        }
+
+        foreach ($relations as $key => $value) {
+            if (is_numeric($key)) {
+                $key = $value;
+            }
+
+            $segments = explode('.', explode(':', $key)[0]);
+
+            if (str_contains($key, ':')) {
+                $segments[count($segments) - 1] .= ':'.explode(':', $key)[1];
+            }
+
+            $path = [];
+
+            foreach ($segments as $segment) {
+                $path[] = [$segment => $segment];
+            }
+
+            if (is_callable($value)) {
+                $path[count($segments) - 1][end($segments)] = $value;
+            }
+
+            $this->loadMissingRelation($this, $path);
+        }
+
+        return $this;
+    }
+
+    /**
+     * Load a relationship path if it is not already eager loaded.
+     *
+     * @param  \Illuminate\Database\Eloquent\Collection  $models
+     * @param  array  $path
+     * @return void
+     */
+    protected function loadMissingRelation(self $models, array $path)
+    {
+        $relation = array_shift($path);
+
+        $name = explode(':', key($relation))[0];
+
+        if (is_string(reset($relation))) {
+            $relation = reset($relation);
+        }
+
+        $models->filter(fn ($model) => ! is_null($model) && ! $model->relationLoaded($name))->load($relation);
+
+        if (empty($path)) {
+            return;
+        }
+
+        $models = $models->pluck($name)->whereNotNull();
+
+        if ($models->first() instanceof BaseCollection) {
+            $models = $models->collapse();
+        }
+
+        $this->loadMissingRelation(new static($models), $path);
+    }
+
+    /**
+     * Load a set of relationships onto the mixed relationship collection.
+     *
+     * @param  string  $relation
+     * @param  array  $relations
+     * @return $this
+     */
+    public function loadMorph($relation, $relations)
+    {
+        $this->pluck($relation)
+            ->filter()
+            ->groupBy(fn ($model) => get_class($model))
+            ->each(fn ($models, $className) => static::make($models)->load($relations[$className] ?? []));
+
+        return $this;
+    }
+
+    /**
+     * Load a set of relationship counts onto the mixed relationship collection.
+     *
+     * @param  string  $relation
+     * @param  array  $relations
+     * @return $this
+     */
+    public function loadMorphCount($relation, $relations)
+    {
+        $this->pluck($relation)
+            ->filter()
+            ->groupBy(fn ($model) => get_class($model))
+            ->each(fn ($models, $className) => static::make($models)->loadCount($relations[$className] ?? []));
+
+        return $this;
+    }
+
+    /**
+     * Determine if a key exists in the collection.
+     *
+     * @param  (callable(TModel, TKey): bool)|TModel|string|int  $key
+     * @param  mixed  $operator
+     * @param  mixed  $value
+     * @return bool
+     */
+    public function contains($key, $operator = null, $value = null)
+    {
+        if (func_num_args() > 1 || $this->useAsCallable($key)) {
+            return parent::contains(...func_get_args());
+        }
+
+        if ($key instanceof Model) {
+            return parent::contains(fn ($model) => $model->is($key));
+        }
+
+        return parent::contains(fn ($model) => $model->getKey() == $key);
+    }
+
+    /**
+     * Get the array of primary keys.
+     *
+     * @return array
+     */
+    public function modelKeys()
+    {
+        return array_map(fn ($model) => $model->getKey(), $this->items);
+    }
+
+    /**
+     * Merge the collection with the given items.
+     *
+     * @param  iterable  $items
+     * @return static
+     */
+    public function merge($items)
+    {
+        $dictionary = $this->getDictionary();
+
+        foreach ($items as $item) {
+            $dictionary[$item->getKey()] = $item;
+        }
+
+        return new static(array_values($dictionary));
+    }
+
+    /**
+     * Run a map over each of the items.
+     *
+     * @template TMapValue
+     *
+     * @param  callable(TModel, TKey): TMapValue  $callback
+     * @return \Illuminate\Support\Collection|static
+     */
+    public function map(callable $callback)
+    {
+        $result = parent::map($callback);
+
+        return $result->contains(fn ($item) => ! $item instanceof Model) ? $result->toBase() : $result;
+    }
+
+    /**
+     * Run an associative map over each of the items.
+     *
+     * The callback should return an associative array with a single key / value pair.
+     *
+     * @template TMapWithKeysKey of array-key
+     * @template TMapWithKeysValue
+     *
+     * @param  callable(TModel, TKey): array  $callback
+     * @return \Illuminate\Support\Collection|static
+     */
+    public function mapWithKeys(callable $callback)
+    {
+        $result = parent::mapWithKeys($callback);
+
+        return $result->contains(fn ($item) => ! $item instanceof Model) ? $result->toBase() : $result;
+    }
+
+    /**
+     * Reload a fresh model instance from the database for all the entities.
+     *
+     * @param  array|string  $with
+     * @return static
+     */
+    public function fresh($with = [])
+    {
+        if ($this->isEmpty()) {
+            return new static;
+        }
+
+        $model = $this->first();
+
+        $freshModels = $model->newQueryWithoutScopes()
+            ->with(is_string($with) ? func_get_args() : $with)
+            ->whereIn($model->getKeyName(), $this->modelKeys())
+            ->get()
+            ->getDictionary();
+
+        return $this->filter(fn ($model) => $model->exists && isset($freshModels[$model->getKey()]))
+            ->map(fn ($model) => $freshModels[$model->getKey()]);
+    }
+
+    /**
+     * Diff the collection with the given items.
+     *
+     * @param  iterable  $items
+     * @return static
+     */
+    public function diff($items)
+    {
+        $diff = new static;
+
+        $dictionary = $this->getDictionary($items);
+
+        foreach ($this->items as $item) {
+            if (! isset($dictionary[$item->getKey()])) {
+                $diff->add($item);
+            }
+        }
+
+        return $diff;
+    }
+
+    /**
+     * Intersect the collection with the given items.
+     *
+     * @param  iterable  $items
+     * @return static
+     */
+    public function intersect($items)
+    {
+        $intersect = new static;
+
+        if (empty($items)) {
+            return $intersect;
+        }
+
+        $dictionary = $this->getDictionary($items);
+
+        foreach ($this->items as $item) {
+            if (isset($dictionary[$item->getKey()])) {
+                $intersect->add($item);
+            }
+        }
+
+        return $intersect;
+    }
+
+    /**
+     * Return only unique items from the collection.
+     *
+     * @param  (callable(TModel, TKey): mixed)|string|null  $key
+     * @param  bool  $strict
+     * @return static
+     */
+    public function unique($key = null, $strict = false)
+    {
+        if (! is_null($key)) {
+            return parent::unique($key, $strict);
+        }
+
+        return new static(array_values($this->getDictionary()));
+    }
+
+    /**
+     * Returns only the models from the collection with the specified keys.
+     *
+     * @param  array|null  $keys
+     * @return static
+     */
+    public function only($keys)
+    {
+        if (is_null($keys)) {
+            return new static($this->items);
+        }
+
+        $dictionary = Arr::only($this->getDictionary(), $keys);
+
+        return new static(array_values($dictionary));
+    }
+
+    /**
+     * Returns all models in the collection except the models with specified keys.
+     *
+     * @param  array|null  $keys
+     * @return static
+     */
+    public function except($keys)
+    {
+        $dictionary = Arr::except($this->getDictionary(), $keys);
+
+        return new static(array_values($dictionary));
+    }
+
+    /**
+     * Make the given, typically visible, attributes hidden across the entire collection.
+     *
+     * @param  array|string  $attributes
+     * @return $this
+     */
+    public function makeHidden($attributes)
+    {
+        return $this->each->makeHidden($attributes);
+    }
+
+    /**
+     * Make the given, typically hidden, attributes visible across the entire collection.
+     *
+     * @param  array|string  $attributes
+     * @return $this
+     */
+    public function makeVisible($attributes)
+    {
+        return $this->each->makeVisible($attributes);
+    }
+
+    /**
+     * Set the visible attributes across the entire collection.
+     *
+     * @param  array  $visible
+     * @return $this
+     */
+    public function setVisible($visible)
+    {
+        return $this->each->setVisible($visible);
+    }
+
+    /**
+     * Set the hidden attributes across the entire collection.
+     *
+     * @param  array  $hidden
+     * @return $this
+     */
+    public function setHidden($hidden)
+    {
+        return $this->each->setHidden($hidden);
+    }
+
+    /**
+     * Append an attribute across the entire collection.
+     *
+     * @param  array|string  $attributes
+     * @return $this
+     */
+    public function append($attributes)
+    {
+        return $this->each->append($attributes);
+    }
+
+    /**
+     * Get a dictionary keyed by primary keys.
+     *
+     * @param  iterable|null  $items
+     * @return array
+     */
+    public function getDictionary($items = null)
+    {
+        $items = is_null($items) ? $this->items : $items;
+
+        $dictionary = [];
+
+        foreach ($items as $value) {
+            $dictionary[$value->getKey()] = $value;
+        }
+
+        return $dictionary;
+    }
+
+    /**
+     * The following methods are intercepted to always return base collections.
+     */
+
+    /**
+     * Count the number of items in the collection by a field or using a callback.
+     *
+     * @param  (callable(TModel, TKey): array-key)|string|null  $countBy
+     * @return \Illuminate\Support\Collection
+     */
+    public function countBy($countBy = null)
+    {
+        return $this->toBase()->countBy($countBy);
+    }
+
+    /**
+     * Collapse the collection of items into a single array.
+     *
+     * @return \Illuminate\Support\Collection
+     */
+    public function collapse()
+    {
+        return $this->toBase()->collapse();
+    }
+
+    /**
+     * Get a flattened array of the items in the collection.
+     *
+     * @param  int  $depth
+     * @return \Illuminate\Support\Collection
+     */
+    public function flatten($depth = INF)
+    {
+        return $this->toBase()->flatten($depth);
+    }
+
+    /**
+     * Flip the items in the collection.
+     *
+     * @return \Illuminate\Support\Collection
+     */
+    public function flip()
+    {
+        return $this->toBase()->flip();
+    }
+
+    /**
+     * Get the keys of the collection items.
+     *
+     * @return \Illuminate\Support\Collection
+     */
+    public function keys()
+    {
+        return $this->toBase()->keys();
+    }
+
+    /**
+     * Pad collection to the specified length with a value.
+     *
+     * @template TPadValue
+     *
+     * @param  int  $size
+     * @param  TPadValue  $value
+     * @return \Illuminate\Support\Collection
+     */
+    public function pad($size, $value)
+    {
+        return $this->toBase()->pad($size, $value);
+    }
+
+    /**
+     * Get an array with the values of a given key.
+     *
+     * @param  string|array  $value
+     * @param  string|null  $key
+     * @return \Illuminate\Support\Collection
+     */
+    public function pluck($value, $key = null)
+    {
+        return $this->toBase()->pluck($value, $key);
+    }
+
+    /**
+     * Zip the collection together with one or more arrays.
+     *
+     * @template TZipValue
+     *
+     * @param  \Illuminate\Contracts\Support\Arrayable|iterable  ...$items
+     * @return \Illuminate\Support\Collection>
+     */
+    public function zip($items)
+    {
+        return $this->toBase()->zip(...func_get_args());
+    }
+
+    /**
+     * Get the comparison function to detect duplicates.
+     *
+     * @param  bool  $strict
+     * @return callable(TModel, TModel): bool
+     */
+    protected function duplicateComparator($strict)
+    {
+        return fn ($a, $b) => $a->is($b);
+    }
+
+    /**
+     * Get the type of the entities being queued.
+     *
+     * @return string|null
+     *
+     * @throws \LogicException
+     */
+    public function getQueueableClass()
+    {
+        if ($this->isEmpty()) {
+            return;
+        }
+
+        $class = $this->getQueueableModelClass($this->first());
+
+        $this->each(function ($model) use ($class) {
+            if ($this->getQueueableModelClass($model) !== $class) {
+                throw new LogicException('Queueing collections with multiple model types is not supported.');
+            }
+        });
+
+        return $class;
+    }
+
+    /**
+     * Get the queueable class name for the given model.
+     *
+     * @param  \Illuminate\Database\Eloquent\Model  $model
+     * @return string
+     */
+    protected function getQueueableModelClass($model)
+    {
+        return method_exists($model, 'getQueueableClassName')
+                ? $model->getQueueableClassName()
+                : get_class($model);
+    }
+
+    /**
+     * Get the identifiers for all of the entities.
+     *
+     * @return array
+     */
+    public function getQueueableIds()
+    {
+        if ($this->isEmpty()) {
+            return [];
+        }
+
+        return $this->first() instanceof QueueableEntity
+                    ? $this->map->getQueueableId()->all()
+                    : $this->modelKeys();
+    }
+
+    /**
+     * Get the relationships of the entities being queued.
+     *
+     * @return array
+     */
+    public function getQueueableRelations()
+    {
+        if ($this->isEmpty()) {
+            return [];
+        }
+
+        $relations = $this->map->getQueueableRelations()->all();
+
+        if (count($relations) === 0 || $relations === [[]]) {
+            return [];
+        } elseif (count($relations) === 1) {
+            return reset($relations);
+        } else {
+            return array_intersect(...array_values($relations));
+        }
+    }
+
+    /**
+     * Get the connection of the entities being queued.
+     *
+     * @return string|null
+     *
+     * @throws \LogicException
+     */
+    public function getQueueableConnection()
+    {
+        if ($this->isEmpty()) {
+            return;
+        }
+
+        $connection = $this->first()->getConnectionName();
+
+        $this->each(function ($model) use ($connection) {
+            if ($model->getConnectionName() !== $connection) {
+                throw new LogicException('Queueing collections with multiple model connections is not supported.');
+            }
+        });
+
+        return $connection;
+    }
+
+    /**
+     * Get the Eloquent query builder from the collection.
+     *
+     * @return \Illuminate\Database\Eloquent\Builder
+     *
+     * @throws \LogicException
+     */
+    public function toQuery()
+    {
+        $model = $this->first();
+
+        if (! $model) {
+            throw new LogicException('Unable to create query for empty collection.');
+        }
+
+        $class = get_class($model);
+
+        if ($this->filter(fn ($model) => ! $model instanceof $class)->isNotEmpty()) {
+            throw new LogicException('Unable to create query for collection with mixed types.');
+        }
+
+        return $model->newModelQuery()->whereKey($this->modelKeys());
+    }
+}
diff --git a/vendor/illuminate/database/Eloquent/Concerns/GuardsAttributes.php b/vendor/illuminate/database/Eloquent/Concerns/GuardsAttributes.php
new file mode 100644
index 0000000..bfb6775
--- /dev/null
+++ b/vendor/illuminate/database/Eloquent/Concerns/GuardsAttributes.php
@@ -0,0 +1,255 @@
+
+     */
+    protected $fillable = [];
+
+    /**
+     * The attributes that aren't mass assignable.
+     *
+     * @var array|bool
+     */
+    protected $guarded = ['*'];
+
+    /**
+     * Indicates if all mass assignment is enabled.
+     *
+     * @var bool
+     */
+    protected static $unguarded = false;
+
+    /**
+     * The actual columns that exist on the database and can be guarded.
+     *
+     * @var array
+     */
+    protected static $guardableColumns = [];
+
+    /**
+     * Get the fillable attributes for the model.
+     *
+     * @return array
+     */
+    public function getFillable()
+    {
+        return $this->fillable;
+    }
+
+    /**
+     * Set the fillable attributes for the model.
+     *
+     * @param  array  $fillable
+     * @return $this
+     */
+    public function fillable(array $fillable)
+    {
+        $this->fillable = $fillable;
+
+        return $this;
+    }
+
+    /**
+     * Merge new fillable attributes with existing fillable attributes on the model.
+     *
+     * @param  array  $fillable
+     * @return $this
+     */
+    public function mergeFillable(array $fillable)
+    {
+        $this->fillable = array_merge($this->fillable, $fillable);
+
+        return $this;
+    }
+
+    /**
+     * Get the guarded attributes for the model.
+     *
+     * @return array
+     */
+    public function getGuarded()
+    {
+        return $this->guarded === false
+                    ? []
+                    : $this->guarded;
+    }
+
+    /**
+     * Set the guarded attributes for the model.
+     *
+     * @param  array  $guarded
+     * @return $this
+     */
+    public function guard(array $guarded)
+    {
+        $this->guarded = $guarded;
+
+        return $this;
+    }
+
+    /**
+     * Merge new guarded attributes with existing guarded attributes on the model.
+     *
+     * @param  array  $guarded
+     * @return $this
+     */
+    public function mergeGuarded(array $guarded)
+    {
+        $this->guarded = array_merge($this->guarded, $guarded);
+
+        return $this;
+    }
+
+    /**
+     * Disable all mass assignable restrictions.
+     *
+     * @param  bool  $state
+     * @return void
+     */
+    public static function unguard($state = true)
+    {
+        static::$unguarded = $state;
+    }
+
+    /**
+     * Enable the mass assignment restrictions.
+     *
+     * @return void
+     */
+    public static function reguard()
+    {
+        static::$unguarded = false;
+    }
+
+    /**
+     * Determine if the current state is "unguarded".
+     *
+     * @return bool
+     */
+    public static function isUnguarded()
+    {
+        return static::$unguarded;
+    }
+
+    /**
+     * Run the given callable while being unguarded.
+     *
+     * @param  callable  $callback
+     * @return mixed
+     */
+    public static function unguarded(callable $callback)
+    {
+        if (static::$unguarded) {
+            return $callback();
+        }
+
+        static::unguard();
+
+        try {
+            return $callback();
+        } finally {
+            static::reguard();
+        }
+    }
+
+    /**
+     * Determine if the given attribute may be mass assigned.
+     *
+     * @param  string  $key
+     * @return bool
+     */
+    public function isFillable($key)
+    {
+        if (static::$unguarded) {
+            return true;
+        }
+
+        // If the key is in the "fillable" array, we can of course assume that it's
+        // a fillable attribute. Otherwise, we will check the guarded array when
+        // we need to determine if the attribute is black-listed on the model.
+        if (in_array($key, $this->getFillable())) {
+            return true;
+        }
+
+        // If the attribute is explicitly listed in the "guarded" array then we can
+        // return false immediately. This means this attribute is definitely not
+        // fillable and there is no point in going any further in this method.
+        if ($this->isGuarded($key)) {
+            return false;
+        }
+
+        return empty($this->getFillable()) &&
+            ! str_contains($key, '.') &&
+            ! str_starts_with($key, '_');
+    }
+
+    /**
+     * Determine if the given key is guarded.
+     *
+     * @param  string  $key
+     * @return bool
+     */
+    public function isGuarded($key)
+    {
+        if (empty($this->getGuarded())) {
+            return false;
+        }
+
+        return $this->getGuarded() == ['*'] ||
+               ! empty(preg_grep('/^'.preg_quote($key, '/').'$/i', $this->getGuarded())) ||
+               ! $this->isGuardableColumn($key);
+    }
+
+    /**
+     * Determine if the given column is a valid, guardable column.
+     *
+     * @param  string  $key
+     * @return bool
+     */
+    protected function isGuardableColumn($key)
+    {
+        if (! isset(static::$guardableColumns[get_class($this)])) {
+            $columns = $this->getConnection()
+                        ->getSchemaBuilder()
+                        ->getColumnListing($this->getTable());
+
+            if (empty($columns)) {
+                return true;
+            }
+            static::$guardableColumns[get_class($this)] = $columns;
+        }
+
+        return in_array($key, static::$guardableColumns[get_class($this)]);
+    }
+
+    /**
+     * Determine if the model is totally guarded.
+     *
+     * @return bool
+     */
+    public function totallyGuarded()
+    {
+        return count($this->getFillable()) === 0 && $this->getGuarded() == ['*'];
+    }
+
+    /**
+     * Get the fillable attributes of a given array.
+     *
+     * @param  array  $attributes
+     * @return array
+     */
+    protected function fillableFromArray(array $attributes)
+    {
+        if (count($this->getFillable()) > 0 && ! static::$unguarded) {
+            return array_intersect_key($attributes, array_flip($this->getFillable()));
+        }
+
+        return $attributes;
+    }
+}
diff --git a/vendor/illuminate/database/Eloquent/Concerns/HasAttributes.php b/vendor/illuminate/database/Eloquent/Concerns/HasAttributes.php
new file mode 100644
index 0000000..2b1b7ca
--- /dev/null
+++ b/vendor/illuminate/database/Eloquent/Concerns/HasAttributes.php
@@ -0,0 +1,2232 @@
+addDateAttributesToArray(
+            $attributes = $this->getArrayableAttributes()
+        );
+
+        $attributes = $this->addMutatedAttributesToArray(
+            $attributes, $mutatedAttributes = $this->getMutatedAttributes()
+        );
+
+        // Next we will handle any casts that have been setup for this model and cast
+        // the values to their appropriate type. If the attribute has a mutator we
+        // will not perform the cast on those attributes to avoid any confusion.
+        $attributes = $this->addCastAttributesToArray(
+            $attributes, $mutatedAttributes
+        );
+
+        // Here we will grab all of the appended, calculated attributes to this model
+        // as these attributes are not really in the attributes array, but are run
+        // when we need to array or JSON the model for convenience to the coder.
+        foreach ($this->getArrayableAppends() as $key) {
+            $attributes[$key] = $this->mutateAttributeForArray($key, null);
+        }
+
+        return $attributes;
+    }
+
+    /**
+     * Add the date attributes to the attributes array.
+     *
+     * @param  array  $attributes
+     * @return array
+     */
+    protected function addDateAttributesToArray(array $attributes)
+    {
+        foreach ($this->getDates() as $key) {
+            if (! isset($attributes[$key])) {
+                continue;
+            }
+
+            $attributes[$key] = $this->serializeDate(
+                $this->asDateTime($attributes[$key])
+            );
+        }
+
+        return $attributes;
+    }
+
+    /**
+     * Add the mutated attributes to the attributes array.
+     *
+     * @param  array  $attributes
+     * @param  array  $mutatedAttributes
+     * @return array
+     */
+    protected function addMutatedAttributesToArray(array $attributes, array $mutatedAttributes)
+    {
+        foreach ($mutatedAttributes as $key) {
+            // We want to spin through all the mutated attributes for this model and call
+            // the mutator for the attribute. We cache off every mutated attributes so
+            // we don't have to constantly check on attributes that actually change.
+            if (! array_key_exists($key, $attributes)) {
+                continue;
+            }
+
+            // Next, we will call the mutator for this attribute so that we can get these
+            // mutated attribute's actual values. After we finish mutating each of the
+            // attributes we will return this final array of the mutated attributes.
+            $attributes[$key] = $this->mutateAttributeForArray(
+                $key, $attributes[$key]
+            );
+        }
+
+        return $attributes;
+    }
+
+    /**
+     * Add the casted attributes to the attributes array.
+     *
+     * @param  array  $attributes
+     * @param  array  $mutatedAttributes
+     * @return array
+     */
+    protected function addCastAttributesToArray(array $attributes, array $mutatedAttributes)
+    {
+        foreach ($this->getCasts() as $key => $value) {
+            if (! array_key_exists($key, $attributes) ||
+                in_array($key, $mutatedAttributes)) {
+                continue;
+            }
+
+            // Here we will cast the attribute. Then, if the cast is a date or datetime cast
+            // then we will serialize the date for the array. This will convert the dates
+            // to strings based on the date format specified for these Eloquent models.
+            $attributes[$key] = $this->castAttribute(
+                $key, $attributes[$key]
+            );
+
+            // If the attribute cast was a date or a datetime, we will serialize the date as
+            // a string. This allows the developers to customize how dates are serialized
+            // into an array without affecting how they are persisted into the storage.
+            if (isset($attributes[$key]) && in_array($value, ['date', 'datetime', 'immutable_date', 'immutable_datetime'])) {
+                $attributes[$key] = $this->serializeDate($attributes[$key]);
+            }
+
+            if (isset($attributes[$key]) && ($this->isCustomDateTimeCast($value) ||
+                $this->isImmutableCustomDateTimeCast($value))) {
+                $attributes[$key] = $attributes[$key]->format(explode(':', $value, 2)[1]);
+            }
+
+            if ($attributes[$key] instanceof DateTimeInterface &&
+                $this->isClassCastable($key)) {
+                $attributes[$key] = $this->serializeDate($attributes[$key]);
+            }
+
+            if (isset($attributes[$key]) && $this->isClassSerializable($key)) {
+                $attributes[$key] = $this->serializeClassCastableAttribute($key, $attributes[$key]);
+            }
+
+            if ($this->isEnumCastable($key) && (! ($attributes[$key] ?? null) instanceof Arrayable)) {
+                $attributes[$key] = isset($attributes[$key]) ? $this->getStorableEnumValue($attributes[$key]) : null;
+            }
+
+            if ($attributes[$key] instanceof Arrayable) {
+                $attributes[$key] = $attributes[$key]->toArray();
+            }
+        }
+
+        return $attributes;
+    }
+
+    /**
+     * Get an attribute array of all arrayable attributes.
+     *
+     * @return array
+     */
+    protected function getArrayableAttributes()
+    {
+        return $this->getArrayableItems($this->getAttributes());
+    }
+
+    /**
+     * Get all of the appendable values that are arrayable.
+     *
+     * @return array
+     */
+    protected function getArrayableAppends()
+    {
+        if (! count($this->appends)) {
+            return [];
+        }
+
+        return $this->getArrayableItems(
+            array_combine($this->appends, $this->appends)
+        );
+    }
+
+    /**
+     * Get the model's relationships in array form.
+     *
+     * @return array
+     */
+    public function relationsToArray()
+    {
+        $attributes = [];
+
+        foreach ($this->getArrayableRelations() as $key => $value) {
+            // If the values implement the Arrayable interface we can just call this
+            // toArray method on the instances which will convert both models and
+            // collections to their proper array form and we'll set the values.
+            if ($value instanceof Arrayable) {
+                $relation = $value->toArray();
+            }
+
+            // If the value is null, we'll still go ahead and set it in this list of
+            // attributes, since null is used to represent empty relationships if
+            // it has a has one or belongs to type relationships on the models.
+            elseif (is_null($value)) {
+                $relation = $value;
+            }
+
+            // If the relationships snake-casing is enabled, we will snake case this
+            // key so that the relation attribute is snake cased in this returned
+            // array to the developers, making this consistent with attributes.
+            if (static::$snakeAttributes) {
+                $key = Str::snake($key);
+            }
+
+            // If the relation value has been set, we will set it on this attributes
+            // list for returning. If it was not arrayable or null, we'll not set
+            // the value on the array because it is some type of invalid value.
+            if (isset($relation) || is_null($value)) {
+                $attributes[$key] = $relation;
+            }
+
+            unset($relation);
+        }
+
+        return $attributes;
+    }
+
+    /**
+     * Get an attribute array of all arrayable relations.
+     *
+     * @return array
+     */
+    protected function getArrayableRelations()
+    {
+        return $this->getArrayableItems($this->relations);
+    }
+
+    /**
+     * Get an attribute array of all arrayable values.
+     *
+     * @param  array  $values
+     * @return array
+     */
+    protected function getArrayableItems(array $values)
+    {
+        if (count($this->getVisible()) > 0) {
+            $values = array_intersect_key($values, array_flip($this->getVisible()));
+        }
+
+        if (count($this->getHidden()) > 0) {
+            $values = array_diff_key($values, array_flip($this->getHidden()));
+        }
+
+        return $values;
+    }
+
+    /**
+     * Get an attribute from the model.
+     *
+     * @param  string  $key
+     * @return mixed
+     */
+    public function getAttribute($key)
+    {
+        if (! $key) {
+            return;
+        }
+
+        // If the attribute exists in the attribute array or has a "get" mutator we will
+        // get the attribute's value. Otherwise, we will proceed as if the developers
+        // are asking for a relationship's value. This covers both types of values.
+        if (array_key_exists($key, $this->attributes) ||
+            array_key_exists($key, $this->casts) ||
+            $this->hasGetMutator($key) ||
+            $this->hasAttributeMutator($key) ||
+            $this->isClassCastable($key)) {
+            return $this->getAttributeValue($key);
+        }
+
+        // Here we will determine if the model base class itself contains this given key
+        // since we don't want to treat any of those methods as relationships because
+        // they are all intended as helper methods and none of these are relations.
+        if (method_exists(self::class, $key)) {
+            return $this->throwMissingAttributeExceptionIfApplicable($key);
+        }
+
+        return $this->isRelation($key) || $this->relationLoaded($key)
+                    ? $this->getRelationValue($key)
+                    : $this->throwMissingAttributeExceptionIfApplicable($key);
+    }
+
+    /**
+     * Either throw a missing attribute exception or return null depending on Eloquent's configuration.
+     *
+     * @param  string  $key
+     * @return null
+     *
+     * @throws \Illuminate\Database\Eloquent\MissingAttributeException
+     */
+    protected function throwMissingAttributeExceptionIfApplicable($key)
+    {
+        if ($this->exists &&
+            ! $this->wasRecentlyCreated &&
+            static::preventsAccessingMissingAttributes()) {
+            if (isset(static::$missingAttributeViolationCallback)) {
+                return call_user_func(static::$missingAttributeViolationCallback, $this, $key);
+            }
+
+            throw new MissingAttributeException($this, $key);
+        }
+
+        return null;
+    }
+
+    /**
+     * Get a plain attribute (not a relationship).
+     *
+     * @param  string  $key
+     * @return mixed
+     */
+    public function getAttributeValue($key)
+    {
+        return $this->transformModelValue($key, $this->getAttributeFromArray($key));
+    }
+
+    /**
+     * Get an attribute from the $attributes array.
+     *
+     * @param  string  $key
+     * @return mixed
+     */
+    protected function getAttributeFromArray($key)
+    {
+        return $this->getAttributes()[$key] ?? null;
+    }
+
+    /**
+     * Get a relationship.
+     *
+     * @param  string  $key
+     * @return mixed
+     */
+    public function getRelationValue($key)
+    {
+        // If the key already exists in the relationships array, it just means the
+        // relationship has already been loaded, so we'll just return it out of
+        // here because there is no need to query within the relations twice.
+        if ($this->relationLoaded($key)) {
+            return $this->relations[$key];
+        }
+
+        if (! $this->isRelation($key)) {
+            return;
+        }
+
+        if ($this->preventsLazyLoading) {
+            $this->handleLazyLoadingViolation($key);
+        }
+
+        // If the "attribute" exists as a method on the model, we will just assume
+        // it is a relationship and will load and return results from the query
+        // and hydrate the relationship's value on the "relationships" array.
+        return $this->getRelationshipFromMethod($key);
+    }
+
+    /**
+     * Determine if the given key is a relationship method on the model.
+     *
+     * @param  string  $key
+     * @return bool
+     */
+    public function isRelation($key)
+    {
+        if ($this->hasAttributeMutator($key)) {
+            return false;
+        }
+
+        return method_exists($this, $key) ||
+               $this->relationResolver(static::class, $key);
+    }
+
+    /**
+     * Handle a lazy loading violation.
+     *
+     * @param  string  $key
+     * @return mixed
+     */
+    protected function handleLazyLoadingViolation($key)
+    {
+        if (isset(static::$lazyLoadingViolationCallback)) {
+            return call_user_func(static::$lazyLoadingViolationCallback, $this, $key);
+        }
+
+        if (! $this->exists || $this->wasRecentlyCreated) {
+            return;
+        }
+
+        throw new LazyLoadingViolationException($this, $key);
+    }
+
+    /**
+     * Get a relationship value from a method.
+     *
+     * @param  string  $method
+     * @return mixed
+     *
+     * @throws \LogicException
+     */
+    protected function getRelationshipFromMethod($method)
+    {
+        $relation = $this->$method();
+
+        if (! $relation instanceof Relation) {
+            if (is_null($relation)) {
+                throw new LogicException(sprintf(
+                    '%s::%s must return a relationship instance, but "null" was returned. Was the "return" keyword used?', static::class, $method
+                ));
+            }
+
+            throw new LogicException(sprintf(
+                '%s::%s must return a relationship instance.', static::class, $method
+            ));
+        }
+
+        return tap($relation->getResults(), function ($results) use ($method) {
+            $this->setRelation($method, $results);
+        });
+    }
+
+    /**
+     * Determine if a get mutator exists for an attribute.
+     *
+     * @param  string  $key
+     * @return bool
+     */
+    public function hasGetMutator($key)
+    {
+        return method_exists($this, 'get'.Str::studly($key).'Attribute');
+    }
+
+    /**
+     * Determine if a "Attribute" return type marked mutator exists for an attribute.
+     *
+     * @param  string  $key
+     * @return bool
+     */
+    public function hasAttributeMutator($key)
+    {
+        if (isset(static::$attributeMutatorCache[get_class($this)][$key])) {
+            return static::$attributeMutatorCache[get_class($this)][$key];
+        }
+
+        if (! method_exists($this, $method = Str::camel($key))) {
+            return static::$attributeMutatorCache[get_class($this)][$key] = false;
+        }
+
+        $returnType = (new ReflectionMethod($this, $method))->getReturnType();
+
+        return static::$attributeMutatorCache[get_class($this)][$key] =
+                    $returnType instanceof ReflectionNamedType &&
+                    $returnType->getName() === Attribute::class;
+    }
+
+    /**
+     * Determine if a "Attribute" return type marked get mutator exists for an attribute.
+     *
+     * @param  string  $key
+     * @return bool
+     */
+    public function hasAttributeGetMutator($key)
+    {
+        if (isset(static::$getAttributeMutatorCache[get_class($this)][$key])) {
+            return static::$getAttributeMutatorCache[get_class($this)][$key];
+        }
+
+        if (! $this->hasAttributeMutator($key)) {
+            return static::$getAttributeMutatorCache[get_class($this)][$key] = false;
+        }
+
+        return static::$getAttributeMutatorCache[get_class($this)][$key] = is_callable($this->{Str::camel($key)}()->get);
+    }
+
+    /**
+     * Get the value of an attribute using its mutator.
+     *
+     * @param  string  $key
+     * @param  mixed  $value
+     * @return mixed
+     */
+    protected function mutateAttribute($key, $value)
+    {
+        return $this->{'get'.Str::studly($key).'Attribute'}($value);
+    }
+
+    /**
+     * Get the value of an "Attribute" return type marked attribute using its mutator.
+     *
+     * @param  string  $key
+     * @param  mixed  $value
+     * @return mixed
+     */
+    protected function mutateAttributeMarkedAttribute($key, $value)
+    {
+        if (array_key_exists($key, $this->attributeCastCache)) {
+            return $this->attributeCastCache[$key];
+        }
+
+        $attribute = $this->{Str::camel($key)}();
+
+        $value = call_user_func($attribute->get ?: function ($value) {
+            return $value;
+        }, $value, $this->attributes);
+
+        if ($attribute->withCaching || (is_object($value) && $attribute->withObjectCaching)) {
+            $this->attributeCastCache[$key] = $value;
+        } else {
+            unset($this->attributeCastCache[$key]);
+        }
+
+        return $value;
+    }
+
+    /**
+     * Get the value of an attribute using its mutator for array conversion.
+     *
+     * @param  string  $key
+     * @param  mixed  $value
+     * @return mixed
+     */
+    protected function mutateAttributeForArray($key, $value)
+    {
+        if ($this->isClassCastable($key)) {
+            $value = $this->getClassCastableAttributeValue($key, $value);
+        } elseif (isset(static::$getAttributeMutatorCache[get_class($this)][$key]) &&
+                  static::$getAttributeMutatorCache[get_class($this)][$key] === true) {
+            $value = $this->mutateAttributeMarkedAttribute($key, $value);
+
+            $value = $value instanceof DateTimeInterface
+                        ? $this->serializeDate($value)
+                        : $value;
+        } else {
+            $value = $this->mutateAttribute($key, $value);
+        }
+
+        return $value instanceof Arrayable ? $value->toArray() : $value;
+    }
+
+    /**
+     * Merge new casts with existing casts on the model.
+     *
+     * @param  array  $casts
+     * @return $this
+     */
+    public function mergeCasts($casts)
+    {
+        $this->casts = array_merge($this->casts, $casts);
+
+        return $this;
+    }
+
+    /**
+     * Cast an attribute to a native PHP type.
+     *
+     * @param  string  $key
+     * @param  mixed  $value
+     * @return mixed
+     */
+    protected function castAttribute($key, $value)
+    {
+        $castType = $this->getCastType($key);
+
+        if (is_null($value) && in_array($castType, static::$primitiveCastTypes)) {
+            return $value;
+        }
+
+        // If the key is one of the encrypted castable types, we'll first decrypt
+        // the value and update the cast type so we may leverage the following
+        // logic for casting this value to any additionally specified types.
+        if ($this->isEncryptedCastable($key)) {
+            $value = $this->fromEncryptedString($value);
+
+            $castType = Str::after($castType, 'encrypted:');
+        }
+
+        switch ($castType) {
+            case 'int':
+            case 'integer':
+                return (int) $value;
+            case 'real':
+            case 'float':
+            case 'double':
+                return $this->fromFloat($value);
+            case 'decimal':
+                return $this->asDecimal($value, explode(':', $this->getCasts()[$key], 2)[1]);
+            case 'string':
+                return (string) $value;
+            case 'bool':
+            case 'boolean':
+                return (bool) $value;
+            case 'object':
+                return $this->fromJson($value, true);
+            case 'array':
+            case 'json':
+                return $this->fromJson($value);
+            case 'collection':
+                return new BaseCollection($this->fromJson($value));
+            case 'date':
+                return $this->asDate($value);
+            case 'datetime':
+            case 'custom_datetime':
+                return $this->asDateTime($value);
+            case 'immutable_date':
+                return $this->asDate($value)->toImmutable();
+            case 'immutable_custom_datetime':
+            case 'immutable_datetime':
+                return $this->asDateTime($value)->toImmutable();
+            case 'timestamp':
+                return $this->asTimestamp($value);
+        }
+
+        if ($this->isEnumCastable($key)) {
+            return $this->getEnumCastableAttributeValue($key, $value);
+        }
+
+        if ($this->isClassCastable($key)) {
+            return $this->getClassCastableAttributeValue($key, $value);
+        }
+
+        return $value;
+    }
+
+    /**
+     * Cast the given attribute using a custom cast class.
+     *
+     * @param  string  $key
+     * @param  mixed  $value
+     * @return mixed
+     */
+    protected function getClassCastableAttributeValue($key, $value)
+    {
+        if (isset($this->classCastCache[$key])) {
+            return $this->classCastCache[$key];
+        } else {
+            $caster = $this->resolveCasterClass($key);
+
+            $value = $caster instanceof CastsInboundAttributes
+                ? $value
+                : $caster->get($this, $key, $value, $this->attributes);
+
+            if ($caster instanceof CastsInboundAttributes || ! is_object($value)) {
+                unset($this->classCastCache[$key]);
+            } else {
+                $this->classCastCache[$key] = $value;
+            }
+
+            return $value;
+        }
+    }
+
+    /**
+     * Cast the given attribute to an enum.
+     *
+     * @param  string  $key
+     * @param  mixed  $value
+     * @return mixed
+     */
+    protected function getEnumCastableAttributeValue($key, $value)
+    {
+        if (is_null($value)) {
+            return;
+        }
+
+        $castType = $this->getCasts()[$key];
+
+        if ($value instanceof $castType) {
+            return $value;
+        }
+
+        return $this->getEnumCaseFromValue($castType, $value);
+    }
+
+    /**
+     * Get the type of cast for a model attribute.
+     *
+     * @param  string  $key
+     * @return string
+     */
+    protected function getCastType($key)
+    {
+        $castType = $this->getCasts()[$key];
+
+        if (isset(static::$castTypeCache[$castType])) {
+            return static::$castTypeCache[$castType];
+        }
+
+        if ($this->isCustomDateTimeCast($castType)) {
+            $convertedCastType = 'custom_datetime';
+        } elseif ($this->isImmutableCustomDateTimeCast($castType)) {
+            $convertedCastType = 'immutable_custom_datetime';
+        } elseif ($this->isDecimalCast($castType)) {
+            $convertedCastType = 'decimal';
+        } else {
+            $convertedCastType = trim(strtolower($castType));
+        }
+
+        return static::$castTypeCache[$castType] = $convertedCastType;
+    }
+
+    /**
+     * Increment or decrement the given attribute using the custom cast class.
+     *
+     * @param  string  $method
+     * @param  string  $key
+     * @param  mixed  $value
+     * @return mixed
+     */
+    protected function deviateClassCastableAttribute($method, $key, $value)
+    {
+        return $this->resolveCasterClass($key)->{$method}(
+            $this, $key, $value, $this->attributes
+        );
+    }
+
+    /**
+     * Serialize the given attribute using the custom cast class.
+     *
+     * @param  string  $key
+     * @param  mixed  $value
+     * @return mixed
+     */
+    protected function serializeClassCastableAttribute($key, $value)
+    {
+        return $this->resolveCasterClass($key)->serialize(
+            $this, $key, $value, $this->attributes
+        );
+    }
+
+    /**
+     * Determine if the cast type is a custom date time cast.
+     *
+     * @param  string  $cast
+     * @return bool
+     */
+    protected function isCustomDateTimeCast($cast)
+    {
+        return str_starts_with($cast, 'date:') ||
+                str_starts_with($cast, 'datetime:');
+    }
+
+    /**
+     * Determine if the cast type is an immutable custom date time cast.
+     *
+     * @param  string  $cast
+     * @return bool
+     */
+    protected function isImmutableCustomDateTimeCast($cast)
+    {
+        return str_starts_with($cast, 'immutable_date:') ||
+                str_starts_with($cast, 'immutable_datetime:');
+    }
+
+    /**
+     * Determine if the cast type is a decimal cast.
+     *
+     * @param  string  $cast
+     * @return bool
+     */
+    protected function isDecimalCast($cast)
+    {
+        return str_starts_with($cast, 'decimal:');
+    }
+
+    /**
+     * Set a given attribute on the model.
+     *
+     * @param  string  $key
+     * @param  mixed  $value
+     * @return mixed
+     */
+    public function setAttribute($key, $value)
+    {
+        // First we will check for the presence of a mutator for the set operation
+        // which simply lets the developers tweak the attribute as it is set on
+        // this model, such as "json_encoding" a listing of data for storage.
+        if ($this->hasSetMutator($key)) {
+            return $this->setMutatedAttributeValue($key, $value);
+        } elseif ($this->hasAttributeSetMutator($key)) {
+            return $this->setAttributeMarkedMutatedAttributeValue($key, $value);
+        }
+
+        // If an attribute is listed as a "date", we'll convert it from a DateTime
+        // instance into a form proper for storage on the database tables using
+        // the connection grammar's date format. We will auto set the values.
+        elseif (! is_null($value) && $this->isDateAttribute($key)) {
+            $value = $this->fromDateTime($value);
+        }
+
+        if ($this->isEnumCastable($key)) {
+            $this->setEnumCastableAttribute($key, $value);
+
+            return $this;
+        }
+
+        if ($this->isClassCastable($key)) {
+            $this->setClassCastableAttribute($key, $value);
+
+            return $this;
+        }
+
+        if (! is_null($value) && $this->isJsonCastable($key)) {
+            $value = $this->castAttributeAsJson($key, $value);
+        }
+
+        // If this attribute contains a JSON ->, we'll set the proper value in the
+        // attribute's underlying array. This takes care of properly nesting an
+        // attribute in the array's value in the case of deeply nested items.
+        if (str_contains($key, '->')) {
+            return $this->fillJsonAttribute($key, $value);
+        }
+
+        if (! is_null($value) && $this->isEncryptedCastable($key)) {
+            $value = $this->castAttributeAsEncryptedString($key, $value);
+        }
+
+        $this->attributes[$key] = $value;
+
+        return $this;
+    }
+
+    /**
+     * Determine if a set mutator exists for an attribute.
+     *
+     * @param  string  $key
+     * @return bool
+     */
+    public function hasSetMutator($key)
+    {
+        return method_exists($this, 'set'.Str::studly($key).'Attribute');
+    }
+
+    /**
+     * Determine if an "Attribute" return type marked set mutator exists for an attribute.
+     *
+     * @param  string  $key
+     * @return bool
+     */
+    public function hasAttributeSetMutator($key)
+    {
+        $class = get_class($this);
+
+        if (isset(static::$setAttributeMutatorCache[$class][$key])) {
+            return static::$setAttributeMutatorCache[$class][$key];
+        }
+
+        if (! method_exists($this, $method = Str::camel($key))) {
+            return static::$setAttributeMutatorCache[$class][$key] = false;
+        }
+
+        $returnType = (new ReflectionMethod($this, $method))->getReturnType();
+
+        return static::$setAttributeMutatorCache[$class][$key] =
+                    $returnType instanceof ReflectionNamedType &&
+                    $returnType->getName() === Attribute::class &&
+                    is_callable($this->{$method}()->set);
+    }
+
+    /**
+     * Set the value of an attribute using its mutator.
+     *
+     * @param  string  $key
+     * @param  mixed  $value
+     * @return mixed
+     */
+    protected function setMutatedAttributeValue($key, $value)
+    {
+        return $this->{'set'.Str::studly($key).'Attribute'}($value);
+    }
+
+    /**
+     * Set the value of a "Attribute" return type marked attribute using its mutator.
+     *
+     * @param  string  $key
+     * @param  mixed  $value
+     * @return mixed
+     */
+    protected function setAttributeMarkedMutatedAttributeValue($key, $value)
+    {
+        $attribute = $this->{Str::camel($key)}();
+
+        $callback = $attribute->set ?: function ($value) use ($key) {
+            $this->attributes[$key] = $value;
+        };
+
+        $this->attributes = array_merge(
+            $this->attributes,
+            $this->normalizeCastClassResponse(
+                $key, $callback($value, $this->attributes)
+            )
+        );
+
+        if ($attribute->withCaching || (is_object($value) && $attribute->withObjectCaching)) {
+            $this->attributeCastCache[$key] = $value;
+        } else {
+            unset($this->attributeCastCache[$key]);
+        }
+
+        return $this;
+    }
+
+    /**
+     * Determine if the given attribute is a date or date castable.
+     *
+     * @param  string  $key
+     * @return bool
+     */
+    protected function isDateAttribute($key)
+    {
+        return in_array($key, $this->getDates(), true) ||
+            $this->isDateCastable($key);
+    }
+
+    /**
+     * Set a given JSON attribute on the model.
+     *
+     * @param  string  $key
+     * @param  mixed  $value
+     * @return $this
+     */
+    public function fillJsonAttribute($key, $value)
+    {
+        [$key, $path] = explode('->', $key, 2);
+
+        $value = $this->asJson($this->getArrayAttributeWithValue(
+            $path, $key, $value
+        ));
+
+        $this->attributes[$key] = $this->isEncryptedCastable($key)
+            ? $this->castAttributeAsEncryptedString($key, $value)
+            : $value;
+
+        if ($this->isClassCastable($key)) {
+            unset($this->classCastCache[$key]);
+        }
+
+        return $this;
+    }
+
+    /**
+     * Set the value of a class castable attribute.
+     *
+     * @param  string  $key
+     * @param  mixed  $value
+     * @return void
+     */
+    protected function setClassCastableAttribute($key, $value)
+    {
+        $caster = $this->resolveCasterClass($key);
+
+        $this->attributes = array_replace(
+            $this->attributes,
+            $this->normalizeCastClassResponse($key, $caster->set(
+                $this, $key, $value, $this->attributes
+            ))
+        );
+
+        if ($caster instanceof CastsInboundAttributes || ! is_object($value)) {
+            unset($this->classCastCache[$key]);
+        } else {
+            $this->classCastCache[$key] = $value;
+        }
+    }
+
+    /**
+     * Set the value of an enum castable attribute.
+     *
+     * @param  string  $key
+     * @param  \UnitEnum|string|int  $value
+     * @return void
+     */
+    protected function setEnumCastableAttribute($key, $value)
+    {
+        $enumClass = $this->getCasts()[$key];
+
+        if (! isset($value)) {
+            $this->attributes[$key] = null;
+        } elseif (is_object($value)) {
+            $this->attributes[$key] = $this->getStorableEnumValue($value);
+        } else {
+            $this->attributes[$key] = $this->getStorableEnumValue(
+                $this->getEnumCaseFromValue($enumClass, $value)
+            );
+        }
+    }
+
+    /**
+     * Get an enum case instance from a given class and value.
+     *
+     * @param  string  $enumClass
+     * @param  string|int  $value
+     * @return \UnitEnum|\BackedEnum
+     */
+    protected function getEnumCaseFromValue($enumClass, $value)
+    {
+        return is_subclass_of($enumClass, BackedEnum::class)
+                ? $enumClass::from($value)
+                : constant($enumClass.'::'.$value);
+    }
+
+    /**
+     * Get the storable value from the given enum.
+     *
+     * @param  \UnitEnum|\BackedEnum  $value
+     * @return string|int
+     */
+    protected function getStorableEnumValue($value)
+    {
+        return $value instanceof BackedEnum
+                ? $value->value
+                : $value->name;
+    }
+
+    /**
+     * Get an array attribute with the given key and value set.
+     *
+     * @param  string  $path
+     * @param  string  $key
+     * @param  mixed  $value
+     * @return $this
+     */
+    protected function getArrayAttributeWithValue($path, $key, $value)
+    {
+        return tap($this->getArrayAttributeByKey($key), function (&$array) use ($path, $value) {
+            Arr::set($array, str_replace('->', '.', $path), $value);
+        });
+    }
+
+    /**
+     * Get an array attribute or return an empty array if it is not set.
+     *
+     * @param  string  $key
+     * @return array
+     */
+    protected function getArrayAttributeByKey($key)
+    {
+        if (! isset($this->attributes[$key])) {
+            return [];
+        }
+
+        return $this->fromJson(
+            $this->isEncryptedCastable($key)
+                ? $this->fromEncryptedString($this->attributes[$key])
+                : $this->attributes[$key]
+        );
+    }
+
+    /**
+     * Cast the given attribute to JSON.
+     *
+     * @param  string  $key
+     * @param  mixed  $value
+     * @return string
+     */
+    protected function castAttributeAsJson($key, $value)
+    {
+        $value = $this->asJson($value);
+
+        if ($value === false) {
+            throw JsonEncodingException::forAttribute(
+                $this, $key, json_last_error_msg()
+            );
+        }
+
+        return $value;
+    }
+
+    /**
+     * Encode the given value as JSON.
+     *
+     * @param  mixed  $value
+     * @return string
+     */
+    protected function asJson($value)
+    {
+        return json_encode($value);
+    }
+
+    /**
+     * Decode the given JSON back into an array or object.
+     *
+     * @param  string  $value
+     * @param  bool  $asObject
+     * @return mixed
+     */
+    public function fromJson($value, $asObject = false)
+    {
+        return json_decode($value ?? '', ! $asObject);
+    }
+
+    /**
+     * Decrypt the given encrypted string.
+     *
+     * @param  string  $value
+     * @return mixed
+     */
+    public function fromEncryptedString($value)
+    {
+        return (static::$encrypter ?? Crypt::getFacadeRoot())->decrypt($value, false);
+    }
+
+    /**
+     * Cast the given attribute to an encrypted string.
+     *
+     * @param  string  $key
+     * @param  mixed  $value
+     * @return string
+     */
+    protected function castAttributeAsEncryptedString($key, $value)
+    {
+        return (static::$encrypter ?? Crypt::getFacadeRoot())->encrypt($value, false);
+    }
+
+    /**
+     * Set the encrypter instance that will be used to encrypt attributes.
+     *
+     * @param  \Illuminate\Contracts\Encryption\Encrypter|null  $encrypter
+     * @return void
+     */
+    public static function encryptUsing($encrypter)
+    {
+        static::$encrypter = $encrypter;
+    }
+
+    /**
+     * Decode the given float.
+     *
+     * @param  mixed  $value
+     * @return mixed
+     */
+    public function fromFloat($value)
+    {
+        return match ((string) $value) {
+            'Infinity' => INF,
+            '-Infinity' => -INF,
+            'NaN' => NAN,
+            default => (float) $value,
+        };
+    }
+
+    /**
+     * Return a decimal as string.
+     *
+     * @param  float|string  $value
+     * @param  int  $decimals
+     * @return string
+     */
+    protected function asDecimal($value, $decimals)
+    {
+        try {
+            return (string) BigDecimal::of($value)->toScale($decimals, RoundingMode::HALF_UP);
+        } catch (BrickMathException $e) {
+            throw new MathException('Unable to cast value to a decimal.', previous: $e);
+        }
+    }
+
+    /**
+     * Return a timestamp as DateTime object with time set to 00:00:00.
+     *
+     * @param  mixed  $value
+     * @return \Illuminate\Support\Carbon
+     */
+    protected function asDate($value)
+    {
+        return $this->asDateTime($value)->startOfDay();
+    }
+
+    /**
+     * Return a timestamp as DateTime object.
+     *
+     * @param  mixed  $value
+     * @return \Illuminate\Support\Carbon
+     */
+    protected function asDateTime($value)
+    {
+        // If this value is already a Carbon instance, we shall just return it as is.
+        // This prevents us having to re-instantiate a Carbon instance when we know
+        // it already is one, which wouldn't be fulfilled by the DateTime check.
+        if ($value instanceof CarbonInterface) {
+            return Date::instance($value);
+        }
+
+        // If the value is already a DateTime instance, we will just skip the rest of
+        // these checks since they will be a waste of time, and hinder performance
+        // when checking the field. We will just return the DateTime right away.
+        if ($value instanceof DateTimeInterface) {
+            return Date::parse(
+                $value->format('Y-m-d H:i:s.u'), $value->getTimezone()
+            );
+        }
+
+        // If this value is an integer, we will assume it is a UNIX timestamp's value
+        // and format a Carbon object from this timestamp. This allows flexibility
+        // when defining your date fields as they might be UNIX timestamps here.
+        if (is_numeric($value)) {
+            return Date::createFromTimestamp($value);
+        }
+
+        // If the value is in simply year, month, day format, we will instantiate the
+        // Carbon instances from that format. Again, this provides for simple date
+        // fields on the database, while still supporting Carbonized conversion.
+        if ($this->isStandardDateFormat($value)) {
+            return Date::instance(Carbon::createFromFormat('Y-m-d', $value)->startOfDay());
+        }
+
+        $format = $this->getDateFormat();
+
+        // Finally, we will just assume this date is in the format used by default on
+        // the database connection and use that format to create the Carbon object
+        // that is returned back out to the developers after we convert it here.
+        try {
+            $date = Date::createFromFormat($format, $value);
+        } catch (InvalidArgumentException $e) {
+            $date = false;
+        }
+
+        return $date ?: Date::parse($value);
+    }
+
+    /**
+     * Determine if the given value is a standard date format.
+     *
+     * @param  string  $value
+     * @return bool
+     */
+    protected function isStandardDateFormat($value)
+    {
+        return preg_match('/^(\d{4})-(\d{1,2})-(\d{1,2})$/', $value);
+    }
+
+    /**
+     * Convert a DateTime to a storable string.
+     *
+     * @param  mixed  $value
+     * @return string|null
+     */
+    public function fromDateTime($value)
+    {
+        return empty($value) ? $value : $this->asDateTime($value)->format(
+            $this->getDateFormat()
+        );
+    }
+
+    /**
+     * Return a timestamp as unix timestamp.
+     *
+     * @param  mixed  $value
+     * @return int
+     */
+    protected function asTimestamp($value)
+    {
+        return $this->asDateTime($value)->getTimestamp();
+    }
+
+    /**
+     * Prepare a date for array / JSON serialization.
+     *
+     * @param  \DateTimeInterface  $date
+     * @return string
+     */
+    protected function serializeDate(DateTimeInterface $date)
+    {
+        return $date instanceof DateTimeImmutable ?
+            CarbonImmutable::instance($date)->toJSON() :
+            Carbon::instance($date)->toJSON();
+    }
+
+    /**
+     * Get the attributes that should be converted to dates.
+     *
+     * @return array
+     */
+    public function getDates()
+    {
+        if (! $this->usesTimestamps()) {
+            return $this->dates;
+        }
+
+        $defaults = [
+            $this->getCreatedAtColumn(),
+            $this->getUpdatedAtColumn(),
+        ];
+
+        return array_unique(array_merge($this->dates, $defaults));
+    }
+
+    /**
+     * Get the format for database stored dates.
+     *
+     * @return string
+     */
+    public function getDateFormat()
+    {
+        return $this->dateFormat ?: $this->getConnection()->getQueryGrammar()->getDateFormat();
+    }
+
+    /**
+     * Set the date format used by the model.
+     *
+     * @param  string  $format
+     * @return $this
+     */
+    public function setDateFormat($format)
+    {
+        $this->dateFormat = $format;
+
+        return $this;
+    }
+
+    /**
+     * Determine whether an attribute should be cast to a native type.
+     *
+     * @param  string  $key
+     * @param  array|string|null  $types
+     * @return bool
+     */
+    public function hasCast($key, $types = null)
+    {
+        if (array_key_exists($key, $this->getCasts())) {
+            return $types ? in_array($this->getCastType($key), (array) $types, true) : true;
+        }
+
+        return false;
+    }
+
+    /**
+     * Get the casts array.
+     *
+     * @return array
+     */
+    public function getCasts()
+    {
+        if ($this->getIncrementing()) {
+            return array_merge([$this->getKeyName() => $this->getKeyType()], $this->casts);
+        }
+
+        return $this->casts;
+    }
+
+    /**
+     * Determine whether a value is Date / DateTime castable for inbound manipulation.
+     *
+     * @param  string  $key
+     * @return bool
+     */
+    protected function isDateCastable($key)
+    {
+        return $this->hasCast($key, ['date', 'datetime', 'immutable_date', 'immutable_datetime']);
+    }
+
+    /**
+     * Determine whether a value is Date / DateTime custom-castable for inbound manipulation.
+     *
+     * @param  string  $key
+     * @return bool
+     */
+    protected function isDateCastableWithCustomFormat($key)
+    {
+        return $this->hasCast($key, ['custom_datetime', 'immutable_custom_datetime']);
+    }
+
+    /**
+     * Determine whether a value is JSON castable for inbound manipulation.
+     *
+     * @param  string  $key
+     * @return bool
+     */
+    protected function isJsonCastable($key)
+    {
+        return $this->hasCast($key, ['array', 'json', 'object', 'collection', 'encrypted:array', 'encrypted:collection', 'encrypted:json', 'encrypted:object']);
+    }
+
+    /**
+     * Determine whether a value is an encrypted castable for inbound manipulation.
+     *
+     * @param  string  $key
+     * @return bool
+     */
+    protected function isEncryptedCastable($key)
+    {
+        return $this->hasCast($key, ['encrypted', 'encrypted:array', 'encrypted:collection', 'encrypted:json', 'encrypted:object']);
+    }
+
+    /**
+     * Determine if the given key is cast using a custom class.
+     *
+     * @param  string  $key
+     * @return bool
+     *
+     * @throws \Illuminate\Database\Eloquent\InvalidCastException
+     */
+    protected function isClassCastable($key)
+    {
+        $casts = $this->getCasts();
+
+        if (! array_key_exists($key, $casts)) {
+            return false;
+        }
+
+        $castType = $this->parseCasterClass($casts[$key]);
+
+        if (in_array($castType, static::$primitiveCastTypes)) {
+            return false;
+        }
+
+        if (class_exists($castType)) {
+            return true;
+        }
+
+        throw new InvalidCastException($this->getModel(), $key, $castType);
+    }
+
+    /**
+     * Determine if the given key is cast using an enum.
+     *
+     * @param  string  $key
+     * @return bool
+     */
+    protected function isEnumCastable($key)
+    {
+        $casts = $this->getCasts();
+
+        if (! array_key_exists($key, $casts)) {
+            return false;
+        }
+
+        $castType = $casts[$key];
+
+        if (in_array($castType, static::$primitiveCastTypes)) {
+            return false;
+        }
+
+        if (function_exists('enum_exists') && enum_exists($castType)) {
+            return true;
+        }
+    }
+
+    /**
+     * Determine if the key is deviable using a custom class.
+     *
+     * @param  string  $key
+     * @return bool
+     *
+     * @throws \Illuminate\Database\Eloquent\InvalidCastException
+     */
+    protected function isClassDeviable($key)
+    {
+        if (! $this->isClassCastable($key)) {
+            return false;
+        }
+
+        $castType = $this->resolveCasterClass($key);
+
+        return method_exists($castType::class, 'increment') && method_exists($castType::class, 'decrement');
+    }
+
+    /**
+     * Determine if the key is serializable using a custom class.
+     *
+     * @param  string  $key
+     * @return bool
+     *
+     * @throws \Illuminate\Database\Eloquent\InvalidCastException
+     */
+    protected function isClassSerializable($key)
+    {
+        return ! $this->isEnumCastable($key) &&
+            $this->isClassCastable($key) &&
+            method_exists($this->resolveCasterClass($key), 'serialize');
+    }
+
+    /**
+     * Resolve the custom caster class for a given key.
+     *
+     * @param  string  $key
+     * @return mixed
+     */
+    protected function resolveCasterClass($key)
+    {
+        $castType = $this->getCasts()[$key];
+
+        $arguments = [];
+
+        if (is_string($castType) && str_contains($castType, ':')) {
+            $segments = explode(':', $castType, 2);
+
+            $castType = $segments[0];
+            $arguments = explode(',', $segments[1]);
+        }
+
+        if (is_subclass_of($castType, Castable::class)) {
+            $castType = $castType::castUsing($arguments);
+        }
+
+        if (is_object($castType)) {
+            return $castType;
+        }
+
+        return new $castType(...$arguments);
+    }
+
+    /**
+     * Parse the given caster class, removing any arguments.
+     *
+     * @param  string  $class
+     * @return string
+     */
+    protected function parseCasterClass($class)
+    {
+        return ! str_contains($class, ':')
+            ? $class
+            : explode(':', $class, 2)[0];
+    }
+
+    /**
+     * Merge the cast class and attribute cast attributes back into the model.
+     *
+     * @return void
+     */
+    protected function mergeAttributesFromCachedCasts()
+    {
+        $this->mergeAttributesFromClassCasts();
+        $this->mergeAttributesFromAttributeCasts();
+    }
+
+    /**
+     * Merge the cast class attributes back into the model.
+     *
+     * @return void
+     */
+    protected function mergeAttributesFromClassCasts()
+    {
+        foreach ($this->classCastCache as $key => $value) {
+            $caster = $this->resolveCasterClass($key);
+
+            $this->attributes = array_merge(
+                $this->attributes,
+                $caster instanceof CastsInboundAttributes
+                    ? [$key => $value]
+                    : $this->normalizeCastClassResponse($key, $caster->set($this, $key, $value, $this->attributes))
+            );
+        }
+    }
+
+    /**
+     * Merge the cast class attributes back into the model.
+     *
+     * @return void
+     */
+    protected function mergeAttributesFromAttributeCasts()
+    {
+        foreach ($this->attributeCastCache as $key => $value) {
+            $attribute = $this->{Str::camel($key)}();
+
+            if ($attribute->get && ! $attribute->set) {
+                continue;
+            }
+
+            $callback = $attribute->set ?: function ($value) use ($key) {
+                $this->attributes[$key] = $value;
+            };
+
+            $this->attributes = array_merge(
+                $this->attributes,
+                $this->normalizeCastClassResponse(
+                    $key, $callback($value, $this->attributes)
+                )
+            );
+        }
+    }
+
+    /**
+     * Normalize the response from a custom class caster.
+     *
+     * @param  string  $key
+     * @param  mixed  $value
+     * @return array
+     */
+    protected function normalizeCastClassResponse($key, $value)
+    {
+        return is_array($value) ? $value : [$key => $value];
+    }
+
+    /**
+     * Get all of the current attributes on the model.
+     *
+     * @return array
+     */
+    public function getAttributes()
+    {
+        $this->mergeAttributesFromCachedCasts();
+
+        return $this->attributes;
+    }
+
+    /**
+     * Get all of the current attributes on the model for an insert operation.
+     *
+     * @return array
+     */
+    protected function getAttributesForInsert()
+    {
+        return $this->getAttributes();
+    }
+
+    /**
+     * Set the array of model attributes. No checking is done.
+     *
+     * @param  array  $attributes
+     * @param  bool  $sync
+     * @return $this
+     */
+    public function setRawAttributes(array $attributes, $sync = false)
+    {
+        $this->attributes = $attributes;
+
+        if ($sync) {
+            $this->syncOriginal();
+        }
+
+        $this->classCastCache = [];
+        $this->attributeCastCache = [];
+
+        return $this;
+    }
+
+    /**
+     * Get the model's original attribute values.
+     *
+     * @param  string|null  $key
+     * @param  mixed  $default
+     * @return mixed|array
+     */
+    public function getOriginal($key = null, $default = null)
+    {
+        return (new static)->setRawAttributes(
+            $this->original, $sync = true
+        )->getOriginalWithoutRewindingModel($key, $default);
+    }
+
+    /**
+     * Get the model's original attribute values.
+     *
+     * @param  string|null  $key
+     * @param  mixed  $default
+     * @return mixed|array
+     */
+    protected function getOriginalWithoutRewindingModel($key = null, $default = null)
+    {
+        if ($key) {
+            return $this->transformModelValue(
+                $key, Arr::get($this->original, $key, $default)
+            );
+        }
+
+        return collect($this->original)->mapWithKeys(function ($value, $key) {
+            return [$key => $this->transformModelValue($key, $value)];
+        })->all();
+    }
+
+    /**
+     * Get the model's raw original attribute values.
+     *
+     * @param  string|null  $key
+     * @param  mixed  $default
+     * @return mixed|array
+     */
+    public function getRawOriginal($key = null, $default = null)
+    {
+        return Arr::get($this->original, $key, $default);
+    }
+
+    /**
+     * Get a subset of the model's attributes.
+     *
+     * @param  array|mixed  $attributes
+     * @return array
+     */
+    public function only($attributes)
+    {
+        $results = [];
+
+        foreach (is_array($attributes) ? $attributes : func_get_args() as $attribute) {
+            $results[$attribute] = $this->getAttribute($attribute);
+        }
+
+        return $results;
+    }
+
+    /**
+     * Sync the original attributes with the current.
+     *
+     * @return $this
+     */
+    public function syncOriginal()
+    {
+        $this->original = $this->getAttributes();
+
+        return $this;
+    }
+
+    /**
+     * Sync a single original attribute with its current value.
+     *
+     * @param  string  $attribute
+     * @return $this
+     */
+    public function syncOriginalAttribute($attribute)
+    {
+        return $this->syncOriginalAttributes($attribute);
+    }
+
+    /**
+     * Sync multiple original attribute with their current values.
+     *
+     * @param  array|string  $attributes
+     * @return $this
+     */
+    public function syncOriginalAttributes($attributes)
+    {
+        $attributes = is_array($attributes) ? $attributes : func_get_args();
+
+        $modelAttributes = $this->getAttributes();
+
+        foreach ($attributes as $attribute) {
+            $this->original[$attribute] = $modelAttributes[$attribute];
+        }
+
+        return $this;
+    }
+
+    /**
+     * Sync the changed attributes.
+     *
+     * @return $this
+     */
+    public function syncChanges()
+    {
+        $this->changes = $this->getDirty();
+
+        return $this;
+    }
+
+    /**
+     * Determine if the model or any of the given attribute(s) have been modified.
+     *
+     * @param  array|string|null  $attributes
+     * @return bool
+     */
+    public function isDirty($attributes = null)
+    {
+        return $this->hasChanges(
+            $this->getDirty(), is_array($attributes) ? $attributes : func_get_args()
+        );
+    }
+
+    /**
+     * Determine if the model or all the given attribute(s) have remained the same.
+     *
+     * @param  array|string|null  $attributes
+     * @return bool
+     */
+    public function isClean($attributes = null)
+    {
+        return ! $this->isDirty(...func_get_args());
+    }
+
+    /**
+     * Discard attribute changes and reset the attributes to their original state.
+     *
+     * @return $this
+     */
+    public function discardChanges()
+    {
+        [$this->attributes, $this->changes] = [$this->original, []];
+
+        return $this;
+    }
+
+    /**
+     * Determine if the model or any of the given attribute(s) were changed when the model was last saved.
+     *
+     * @param  array|string|null  $attributes
+     * @return bool
+     */
+    public function wasChanged($attributes = null)
+    {
+        return $this->hasChanges(
+            $this->getChanges(), is_array($attributes) ? $attributes : func_get_args()
+        );
+    }
+
+    /**
+     * Determine if any of the given attributes were changed when the model was last saved.
+     *
+     * @param  array  $changes
+     * @param  array|string|null  $attributes
+     * @return bool
+     */
+    protected function hasChanges($changes, $attributes = null)
+    {
+        // If no specific attributes were provided, we will just see if the dirty array
+        // already contains any attributes. If it does we will just return that this
+        // count is greater than zero. Else, we need to check specific attributes.
+        if (empty($attributes)) {
+            return count($changes) > 0;
+        }
+
+        // Here we will spin through every attribute and see if this is in the array of
+        // dirty attributes. If it is, we will return true and if we make it through
+        // all of the attributes for the entire array we will return false at end.
+        foreach (Arr::wrap($attributes) as $attribute) {
+            if (array_key_exists($attribute, $changes)) {
+                return true;
+            }
+        }
+
+        return false;
+    }
+
+    /**
+     * Get the attributes that have been changed since the last sync.
+     *
+     * @return array
+     */
+    public function getDirty()
+    {
+        $dirty = [];
+
+        foreach ($this->getAttributes() as $key => $value) {
+            if (! $this->originalIsEquivalent($key)) {
+                $dirty[$key] = $value;
+            }
+        }
+
+        return $dirty;
+    }
+
+    /**
+     * Get the attributes that were changed when the model was last saved.
+     *
+     * @return array
+     */
+    public function getChanges()
+    {
+        return $this->changes;
+    }
+
+    /**
+     * Determine if the new and old values for a given key are equivalent.
+     *
+     * @param  string  $key
+     * @return bool
+     */
+    public function originalIsEquivalent($key)
+    {
+        if (! array_key_exists($key, $this->original)) {
+            return false;
+        }
+
+        $attribute = Arr::get($this->attributes, $key);
+        $original = Arr::get($this->original, $key);
+
+        if ($attribute === $original) {
+            return true;
+        } elseif (is_null($attribute)) {
+            return false;
+        } elseif ($this->isDateAttribute($key) || $this->isDateCastableWithCustomFormat($key)) {
+            return $this->fromDateTime($attribute) ===
+                $this->fromDateTime($original);
+        } elseif ($this->hasCast($key, ['object', 'collection'])) {
+            return $this->fromJson($attribute) ===
+                $this->fromJson($original);
+        } elseif ($this->hasCast($key, ['real', 'float', 'double'])) {
+            if ($original === null) {
+                return false;
+            }
+
+            return abs($this->castAttribute($key, $attribute) - $this->castAttribute($key, $original)) < PHP_FLOAT_EPSILON * 4;
+        } elseif ($this->hasCast($key, static::$primitiveCastTypes)) {
+            return $this->castAttribute($key, $attribute) ===
+                $this->castAttribute($key, $original);
+        } elseif ($this->isClassCastable($key) && in_array($this->getCasts()[$key], [AsArrayObject::class, AsCollection::class])) {
+            return $this->fromJson($attribute) === $this->fromJson($original);
+        } elseif ($this->isClassCastable($key) && $original !== null && in_array($this->getCasts()[$key], [AsEncryptedArrayObject::class, AsEncryptedCollection::class])) {
+            return $this->fromEncryptedString($attribute) === $this->fromEncryptedString($original);
+        }
+
+        return is_numeric($attribute) && is_numeric($original)
+            && strcmp((string) $attribute, (string) $original) === 0;
+    }
+
+    /**
+     * Transform a raw model value using mutators, casts, etc.
+     *
+     * @param  string  $key
+     * @param  mixed  $value
+     * @return mixed
+     */
+    protected function transformModelValue($key, $value)
+    {
+        // If the attribute has a get mutator, we will call that then return what
+        // it returns as the value, which is useful for transforming values on
+        // retrieval from the model to a form that is more useful for usage.
+        if ($this->hasGetMutator($key)) {
+            return $this->mutateAttribute($key, $value);
+        } elseif ($this->hasAttributeGetMutator($key)) {
+            return $this->mutateAttributeMarkedAttribute($key, $value);
+        }
+
+        // If the attribute exists within the cast array, we will convert it to
+        // an appropriate native PHP type dependent upon the associated value
+        // given with the key in the pair. Dayle made this comment line up.
+        if ($this->hasCast($key)) {
+            return $this->castAttribute($key, $value);
+        }
+
+        // If the attribute is listed as a date, we will convert it to a DateTime
+        // instance on retrieval, which makes it quite convenient to work with
+        // date fields without having to create a mutator for each property.
+        if ($value !== null
+            && \in_array($key, $this->getDates(), false)) {
+            return $this->asDateTime($value);
+        }
+
+        return $value;
+    }
+
+    /**
+     * Append attributes to query when building a query.
+     *
+     * @param  array|string  $attributes
+     * @return $this
+     */
+    public function append($attributes)
+    {
+        $this->appends = array_unique(
+            array_merge($this->appends, is_string($attributes) ? func_get_args() : $attributes)
+        );
+
+        return $this;
+    }
+
+    /**
+     * Get the accessors that are being appended to model arrays.
+     *
+     * @return array
+     */
+    public function getAppends()
+    {
+        return $this->appends;
+    }
+
+    /**
+     * Set the accessors to append to model arrays.
+     *
+     * @param  array  $appends
+     * @return $this
+     */
+    public function setAppends(array $appends)
+    {
+        $this->appends = $appends;
+
+        return $this;
+    }
+
+    /**
+     * Return whether the accessor attribute has been appended.
+     *
+     * @param  string  $attribute
+     * @return bool
+     */
+    public function hasAppended($attribute)
+    {
+        return in_array($attribute, $this->appends);
+    }
+
+    /**
+     * Get the mutated attributes for a given instance.
+     *
+     * @return array
+     */
+    public function getMutatedAttributes()
+    {
+        if (! isset(static::$mutatorCache[static::class])) {
+            static::cacheMutatedAttributes($this);
+        }
+
+        return static::$mutatorCache[static::class];
+    }
+
+    /**
+     * Extract and cache all the mutated attributes of a class.
+     *
+     * @param  object|string  $classOrInstance
+     * @return void
+     */
+    public static function cacheMutatedAttributes($classOrInstance)
+    {
+        $reflection = new ReflectionClass($classOrInstance);
+
+        $class = $reflection->getName();
+
+        static::$getAttributeMutatorCache[$class] =
+            collect($attributeMutatorMethods = static::getAttributeMarkedMutatorMethods($classOrInstance))
+                    ->mapWithKeys(function ($match) {
+                        return [lcfirst(static::$snakeAttributes ? Str::snake($match) : $match) => true];
+                    })->all();
+
+        static::$mutatorCache[$class] = collect(static::getMutatorMethods($class))
+                ->merge($attributeMutatorMethods)
+                ->map(function ($match) {
+                    return lcfirst(static::$snakeAttributes ? Str::snake($match) : $match);
+                })->all();
+    }
+
+    /**
+     * Get all of the attribute mutator methods.
+     *
+     * @param  mixed  $class
+     * @return array
+     */
+    protected static function getMutatorMethods($class)
+    {
+        preg_match_all('/(?<=^|;)get([^;]+?)Attribute(;|$)/', implode(';', get_class_methods($class)), $matches);
+
+        return $matches[1];
+    }
+
+    /**
+     * Get all of the "Attribute" return typed attribute mutator methods.
+     *
+     * @param  mixed  $class
+     * @return array
+     */
+    protected static function getAttributeMarkedMutatorMethods($class)
+    {
+        $instance = is_object($class) ? $class : new $class;
+
+        return collect((new ReflectionClass($instance))->getMethods())->filter(function ($method) use ($instance) {
+            $returnType = $method->getReturnType();
+
+            if ($returnType instanceof ReflectionNamedType &&
+                $returnType->getName() === Attribute::class) {
+                $method->setAccessible(true);
+
+                if (is_callable($method->invoke($instance)->get)) {
+                    return true;
+                }
+            }
+
+            return false;
+        })->map->name->values()->all();
+    }
+}
diff --git a/vendor/illuminate/database/Eloquent/Concerns/HasEvents.php b/vendor/illuminate/database/Eloquent/Concerns/HasEvents.php
new file mode 100644
index 0000000..37bc063
--- /dev/null
+++ b/vendor/illuminate/database/Eloquent/Concerns/HasEvents.php
@@ -0,0 +1,415 @@
+registerObserver($class);
+        }
+    }
+
+    /**
+     * Register a single observer with the model.
+     *
+     * @param  object|string  $class
+     * @return void
+     *
+     * @throws \RuntimeException
+     */
+    protected function registerObserver($class)
+    {
+        $className = $this->resolveObserverClassName($class);
+
+        // When registering a model observer, we will spin through the possible events
+        // and determine if this observer has that method. If it does, we will hook
+        // it into the model's event system, making it convenient to watch these.
+        foreach ($this->getObservableEvents() as $event) {
+            if (method_exists($class, $event)) {
+                static::registerModelEvent($event, $className.'@'.$event);
+            }
+        }
+    }
+
+    /**
+     * Resolve the observer's class name from an object or string.
+     *
+     * @param  object|string  $class
+     * @return string
+     *
+     * @throws \InvalidArgumentException
+     */
+    private function resolveObserverClassName($class)
+    {
+        if (is_object($class)) {
+            return get_class($class);
+        }
+
+        if (class_exists($class)) {
+            return $class;
+        }
+
+        throw new InvalidArgumentException('Unable to find observer: '.$class);
+    }
+
+    /**
+     * Get the observable event names.
+     *
+     * @return array
+     */
+    public function getObservableEvents()
+    {
+        return array_merge(
+            [
+                'retrieved', 'creating', 'created', 'updating', 'updated',
+                'saving', 'saved', 'restoring', 'restored', 'replicating',
+                'deleting', 'deleted', 'forceDeleting', 'forceDeleted',
+            ],
+            $this->observables
+        );
+    }
+
+    /**
+     * Set the observable event names.
+     *
+     * @param  array  $observables
+     * @return $this
+     */
+    public function setObservableEvents(array $observables)
+    {
+        $this->observables = $observables;
+
+        return $this;
+    }
+
+    /**
+     * Add an observable event name.
+     *
+     * @param  array|mixed  $observables
+     * @return void
+     */
+    public function addObservableEvents($observables)
+    {
+        $this->observables = array_unique(array_merge(
+            $this->observables, is_array($observables) ? $observables : func_get_args()
+        ));
+    }
+
+    /**
+     * Remove an observable event name.
+     *
+     * @param  array|mixed  $observables
+     * @return void
+     */
+    public function removeObservableEvents($observables)
+    {
+        $this->observables = array_diff(
+            $this->observables, is_array($observables) ? $observables : func_get_args()
+        );
+    }
+
+    /**
+     * Register a model event with the dispatcher.
+     *
+     * @param  string  $event
+     * @param  \Illuminate\Events\QueuedClosure|\Closure|string|array  $callback
+     * @return void
+     */
+    protected static function registerModelEvent($event, $callback)
+    {
+        if (isset(static::$dispatcher)) {
+            $name = static::class;
+
+            static::$dispatcher->listen("eloquent.{$event}: {$name}", $callback);
+        }
+    }
+
+    /**
+     * Fire the given event for the model.
+     *
+     * @param  string  $event
+     * @param  bool  $halt
+     * @return mixed
+     */
+    protected function fireModelEvent($event, $halt = true)
+    {
+        if (! isset(static::$dispatcher)) {
+            return true;
+        }
+
+        // First, we will get the proper method to call on the event dispatcher, and then we
+        // will attempt to fire a custom, object based event for the given event. If that
+        // returns a result we can return that result, or we'll call the string events.
+        $method = $halt ? 'until' : 'dispatch';
+
+        $result = $this->filterModelEventResults(
+            $this->fireCustomModelEvent($event, $method)
+        );
+
+        if ($result === false) {
+            return false;
+        }
+
+        return ! empty($result) ? $result : static::$dispatcher->{$method}(
+            "eloquent.{$event}: ".static::class, $this
+        );
+    }
+
+    /**
+     * Fire a custom model event for the given event.
+     *
+     * @param  string  $event
+     * @param  string  $method
+     * @return mixed|null
+     */
+    protected function fireCustomModelEvent($event, $method)
+    {
+        if (! isset($this->dispatchesEvents[$event])) {
+            return;
+        }
+
+        $result = static::$dispatcher->$method(new $this->dispatchesEvents[$event]($this));
+
+        if (! is_null($result)) {
+            return $result;
+        }
+    }
+
+    /**
+     * Filter the model event results.
+     *
+     * @param  mixed  $result
+     * @return mixed
+     */
+    protected function filterModelEventResults($result)
+    {
+        if (is_array($result)) {
+            $result = array_filter($result, function ($response) {
+                return ! is_null($response);
+            });
+        }
+
+        return $result;
+    }
+
+    /**
+     * Register a retrieved model event with the dispatcher.
+     *
+     * @param  \Illuminate\Events\QueuedClosure|\Closure|string|array  $callback
+     * @return void
+     */
+    public static function retrieved($callback)
+    {
+        static::registerModelEvent('retrieved', $callback);
+    }
+
+    /**
+     * Register a saving model event with the dispatcher.
+     *
+     * @param  \Illuminate\Events\QueuedClosure|\Closure|string|array  $callback
+     * @return void
+     */
+    public static function saving($callback)
+    {
+        static::registerModelEvent('saving', $callback);
+    }
+
+    /**
+     * Register a saved model event with the dispatcher.
+     *
+     * @param  \Illuminate\Events\QueuedClosure|\Closure|string|array  $callback
+     * @return void
+     */
+    public static function saved($callback)
+    {
+        static::registerModelEvent('saved', $callback);
+    }
+
+    /**
+     * Register an updating model event with the dispatcher.
+     *
+     * @param  \Illuminate\Events\QueuedClosure|\Closure|string|array  $callback
+     * @return void
+     */
+    public static function updating($callback)
+    {
+        static::registerModelEvent('updating', $callback);
+    }
+
+    /**
+     * Register an updated model event with the dispatcher.
+     *
+     * @param  \Illuminate\Events\QueuedClosure|\Closure|string|array  $callback
+     * @return void
+     */
+    public static function updated($callback)
+    {
+        static::registerModelEvent('updated', $callback);
+    }
+
+    /**
+     * Register a creating model event with the dispatcher.
+     *
+     * @param  \Illuminate\Events\QueuedClosure|\Closure|string|array  $callback
+     * @return void
+     */
+    public static function creating($callback)
+    {
+        static::registerModelEvent('creating', $callback);
+    }
+
+    /**
+     * Register a created model event with the dispatcher.
+     *
+     * @param  \Illuminate\Events\QueuedClosure|\Closure|string|array  $callback
+     * @return void
+     */
+    public static function created($callback)
+    {
+        static::registerModelEvent('created', $callback);
+    }
+
+    /**
+     * Register a replicating model event with the dispatcher.
+     *
+     * @param  \Illuminate\Events\QueuedClosure|\Closure|string|array  $callback
+     * @return void
+     */
+    public static function replicating($callback)
+    {
+        static::registerModelEvent('replicating', $callback);
+    }
+
+    /**
+     * Register a deleting model event with the dispatcher.
+     *
+     * @param  \Illuminate\Events\QueuedClosure|\Closure|string|array  $callback
+     * @return void
+     */
+    public static function deleting($callback)
+    {
+        static::registerModelEvent('deleting', $callback);
+    }
+
+    /**
+     * Register a deleted model event with the dispatcher.
+     *
+     * @param  \Illuminate\Events\QueuedClosure|\Closure|string|array  $callback
+     * @return void
+     */
+    public static function deleted($callback)
+    {
+        static::registerModelEvent('deleted', $callback);
+    }
+
+    /**
+     * Remove all the event listeners for the model.
+     *
+     * @return void
+     */
+    public static function flushEventListeners()
+    {
+        if (! isset(static::$dispatcher)) {
+            return;
+        }
+
+        $instance = new static;
+
+        foreach ($instance->getObservableEvents() as $event) {
+            static::$dispatcher->forget("eloquent.{$event}: ".static::class);
+        }
+
+        foreach (array_values($instance->dispatchesEvents) as $event) {
+            static::$dispatcher->forget($event);
+        }
+    }
+
+    /**
+     * Get the event dispatcher instance.
+     *
+     * @return \Illuminate\Contracts\Events\Dispatcher
+     */
+    public static function getEventDispatcher()
+    {
+        return static::$dispatcher;
+    }
+
+    /**
+     * Set the event dispatcher instance.
+     *
+     * @param  \Illuminate\Contracts\Events\Dispatcher  $dispatcher
+     * @return void
+     */
+    public static function setEventDispatcher(Dispatcher $dispatcher)
+    {
+        static::$dispatcher = $dispatcher;
+    }
+
+    /**
+     * Unset the event dispatcher for models.
+     *
+     * @return void
+     */
+    public static function unsetEventDispatcher()
+    {
+        static::$dispatcher = null;
+    }
+
+    /**
+     * Execute a callback without firing any model events for any model type.
+     *
+     * @param  callable  $callback
+     * @return mixed
+     */
+    public static function withoutEvents(callable $callback)
+    {
+        $dispatcher = static::getEventDispatcher();
+
+        if ($dispatcher) {
+            static::setEventDispatcher(new NullDispatcher($dispatcher));
+        }
+
+        try {
+            return $callback();
+        } finally {
+            if ($dispatcher) {
+                static::setEventDispatcher($dispatcher);
+            }
+        }
+    }
+}
diff --git a/vendor/illuminate/database/Eloquent/Concerns/HasGlobalScopes.php b/vendor/illuminate/database/Eloquent/Concerns/HasGlobalScopes.php
new file mode 100644
index 0000000..72afb17
--- /dev/null
+++ b/vendor/illuminate/database/Eloquent/Concerns/HasGlobalScopes.php
@@ -0,0 +1,71 @@
+relationResolver($parent, $key);
+        }
+
+        return null;
+    }
+
+    /**
+     * Define a dynamic relation resolver.
+     *
+     * @param  string  $name
+     * @param  \Closure  $callback
+     * @return void
+     */
+    public static function resolveRelationUsing($name, Closure $callback)
+    {
+        static::$relationResolvers = array_replace_recursive(
+            static::$relationResolvers,
+            [static::class => [$name => $callback]]
+        );
+    }
+
+    /**
+     * Define a one-to-one relationship.
+     *
+     * @param  string  $related
+     * @param  string|null  $foreignKey
+     * @param  string|null  $localKey
+     * @return \Illuminate\Database\Eloquent\Relations\HasOne
+     */
+    public function hasOne($related, $foreignKey = null, $localKey = null)
+    {
+        $instance = $this->newRelatedInstance($related);
+
+        $foreignKey = $foreignKey ?: $this->getForeignKey();
+
+        $localKey = $localKey ?: $this->getKeyName();
+
+        return $this->newHasOne($instance->newQuery(), $this, $instance->getTable().'.'.$foreignKey, $localKey);
+    }
+
+    /**
+     * Instantiate a new HasOne relationship.
+     *
+     * @param  \Illuminate\Database\Eloquent\Builder  $query
+     * @param  \Illuminate\Database\Eloquent\Model  $parent
+     * @param  string  $foreignKey
+     * @param  string  $localKey
+     * @return \Illuminate\Database\Eloquent\Relations\HasOne
+     */
+    protected function newHasOne(Builder $query, Model $parent, $foreignKey, $localKey)
+    {
+        return new HasOne($query, $parent, $foreignKey, $localKey);
+    }
+
+    /**
+     * Define a has-one-through relationship.
+     *
+     * @param  string  $related
+     * @param  string  $through
+     * @param  string|null  $firstKey
+     * @param  string|null  $secondKey
+     * @param  string|null  $localKey
+     * @param  string|null  $secondLocalKey
+     * @return \Illuminate\Database\Eloquent\Relations\HasOneThrough
+     */
+    public function hasOneThrough($related, $through, $firstKey = null, $secondKey = null, $localKey = null, $secondLocalKey = null)
+    {
+        $through = $this->newRelatedThroughInstance($through);
+
+        $firstKey = $firstKey ?: $this->getForeignKey();
+
+        $secondKey = $secondKey ?: $through->getForeignKey();
+
+        return $this->newHasOneThrough(
+            $this->newRelatedInstance($related)->newQuery(), $this, $through,
+            $firstKey, $secondKey, $localKey ?: $this->getKeyName(),
+            $secondLocalKey ?: $through->getKeyName()
+        );
+    }
+
+    /**
+     * Instantiate a new HasOneThrough relationship.
+     *
+     * @param  \Illuminate\Database\Eloquent\Builder  $query
+     * @param  \Illuminate\Database\Eloquent\Model  $farParent
+     * @param  \Illuminate\Database\Eloquent\Model  $throughParent
+     * @param  string  $firstKey
+     * @param  string  $secondKey
+     * @param  string  $localKey
+     * @param  string  $secondLocalKey
+     * @return \Illuminate\Database\Eloquent\Relations\HasOneThrough
+     */
+    protected function newHasOneThrough(Builder $query, Model $farParent, Model $throughParent, $firstKey, $secondKey, $localKey, $secondLocalKey)
+    {
+        return new HasOneThrough($query, $farParent, $throughParent, $firstKey, $secondKey, $localKey, $secondLocalKey);
+    }
+
+    /**
+     * Define a polymorphic one-to-one relationship.
+     *
+     * @param  string  $related
+     * @param  string  $name
+     * @param  string|null  $type
+     * @param  string|null  $id
+     * @param  string|null  $localKey
+     * @return \Illuminate\Database\Eloquent\Relations\MorphOne
+     */
+    public function morphOne($related, $name, $type = null, $id = null, $localKey = null)
+    {
+        $instance = $this->newRelatedInstance($related);
+
+        [$type, $id] = $this->getMorphs($name, $type, $id);
+
+        $table = $instance->getTable();
+
+        $localKey = $localKey ?: $this->getKeyName();
+
+        return $this->newMorphOne($instance->newQuery(), $this, $table.'.'.$type, $table.'.'.$id, $localKey);
+    }
+
+    /**
+     * Instantiate a new MorphOne relationship.
+     *
+     * @param  \Illuminate\Database\Eloquent\Builder  $query
+     * @param  \Illuminate\Database\Eloquent\Model  $parent
+     * @param  string  $type
+     * @param  string  $id
+     * @param  string  $localKey
+     * @return \Illuminate\Database\Eloquent\Relations\MorphOne
+     */
+    protected function newMorphOne(Builder $query, Model $parent, $type, $id, $localKey)
+    {
+        return new MorphOne($query, $parent, $type, $id, $localKey);
+    }
+
+    /**
+     * Define an inverse one-to-one or many relationship.
+     *
+     * @param  string  $related
+     * @param  string|null  $foreignKey
+     * @param  string|null  $ownerKey
+     * @param  string|null  $relation
+     * @return \Illuminate\Database\Eloquent\Relations\BelongsTo
+     */
+    public function belongsTo($related, $foreignKey = null, $ownerKey = null, $relation = null)
+    {
+        // If no relation name was given, we will use this debug backtrace to extract
+        // the calling method's name and use that as the relationship name as most
+        // of the time this will be what we desire to use for the relationships.
+        if (is_null($relation)) {
+            $relation = $this->guessBelongsToRelation();
+        }
+
+        $instance = $this->newRelatedInstance($related);
+
+        // If no foreign key was supplied, we can use a backtrace to guess the proper
+        // foreign key name by using the name of the relationship function, which
+        // when combined with an "_id" should conventionally match the columns.
+        if (is_null($foreignKey)) {
+            $foreignKey = Str::snake($relation).'_'.$instance->getKeyName();
+        }
+
+        // Once we have the foreign key names we'll just create a new Eloquent query
+        // for the related models and return the relationship instance which will
+        // actually be responsible for retrieving and hydrating every relation.
+        $ownerKey = $ownerKey ?: $instance->getKeyName();
+
+        return $this->newBelongsTo(
+            $instance->newQuery(), $this, $foreignKey, $ownerKey, $relation
+        );
+    }
+
+    /**
+     * Instantiate a new BelongsTo relationship.
+     *
+     * @param  \Illuminate\Database\Eloquent\Builder  $query
+     * @param  \Illuminate\Database\Eloquent\Model  $child
+     * @param  string  $foreignKey
+     * @param  string  $ownerKey
+     * @param  string  $relation
+     * @return \Illuminate\Database\Eloquent\Relations\BelongsTo
+     */
+    protected function newBelongsTo(Builder $query, Model $child, $foreignKey, $ownerKey, $relation)
+    {
+        return new BelongsTo($query, $child, $foreignKey, $ownerKey, $relation);
+    }
+
+    /**
+     * Define a polymorphic, inverse one-to-one or many relationship.
+     *
+     * @param  string|null  $name
+     * @param  string|null  $type
+     * @param  string|null  $id
+     * @param  string|null  $ownerKey
+     * @return \Illuminate\Database\Eloquent\Relations\MorphTo
+     */
+    public function morphTo($name = null, $type = null, $id = null, $ownerKey = null)
+    {
+        // If no name is provided, we will use the backtrace to get the function name
+        // since that is most likely the name of the polymorphic interface. We can
+        // use that to get both the class and foreign key that will be utilized.
+        $name = $name ?: $this->guessBelongsToRelation();
+
+        [$type, $id] = $this->getMorphs(
+            Str::snake($name), $type, $id
+        );
+
+        // If the type value is null it is probably safe to assume we're eager loading
+        // the relationship. In this case we'll just pass in a dummy query where we
+        // need to remove any eager loads that may already be defined on a model.
+        return is_null($class = $this->getAttributeFromArray($type)) || $class === ''
+                    ? $this->morphEagerTo($name, $type, $id, $ownerKey)
+                    : $this->morphInstanceTo($class, $name, $type, $id, $ownerKey);
+    }
+
+    /**
+     * Define a polymorphic, inverse one-to-one or many relationship.
+     *
+     * @param  string  $name
+     * @param  string  $type
+     * @param  string  $id
+     * @param  string  $ownerKey
+     * @return \Illuminate\Database\Eloquent\Relations\MorphTo
+     */
+    protected function morphEagerTo($name, $type, $id, $ownerKey)
+    {
+        return $this->newMorphTo(
+            $this->newQuery()->setEagerLoads([]), $this, $id, $ownerKey, $type, $name
+        );
+    }
+
+    /**
+     * Define a polymorphic, inverse one-to-one or many relationship.
+     *
+     * @param  string  $target
+     * @param  string  $name
+     * @param  string  $type
+     * @param  string  $id
+     * @param  string  $ownerKey
+     * @return \Illuminate\Database\Eloquent\Relations\MorphTo
+     */
+    protected function morphInstanceTo($target, $name, $type, $id, $ownerKey)
+    {
+        $instance = $this->newRelatedInstance(
+            static::getActualClassNameForMorph($target)
+        );
+
+        return $this->newMorphTo(
+            $instance->newQuery(), $this, $id, $ownerKey ?? $instance->getKeyName(), $type, $name
+        );
+    }
+
+    /**
+     * Instantiate a new MorphTo relationship.
+     *
+     * @param  \Illuminate\Database\Eloquent\Builder  $query
+     * @param  \Illuminate\Database\Eloquent\Model  $parent
+     * @param  string  $foreignKey
+     * @param  string  $ownerKey
+     * @param  string  $type
+     * @param  string  $relation
+     * @return \Illuminate\Database\Eloquent\Relations\MorphTo
+     */
+    protected function newMorphTo(Builder $query, Model $parent, $foreignKey, $ownerKey, $type, $relation)
+    {
+        return new MorphTo($query, $parent, $foreignKey, $ownerKey, $type, $relation);
+    }
+
+    /**
+     * Retrieve the actual class name for a given morph class.
+     *
+     * @param  string  $class
+     * @return string
+     */
+    public static function getActualClassNameForMorph($class)
+    {
+        return Arr::get(Relation::morphMap() ?: [], $class, $class);
+    }
+
+    /**
+     * Guess the "belongs to" relationship name.
+     *
+     * @return string
+     */
+    protected function guessBelongsToRelation()
+    {
+        [$one, $two, $caller] = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, 3);
+
+        return $caller['function'];
+    }
+
+    /**
+     * Create a pending has-many-through or has-one-through relationship.
+     *
+     * @param  string|\Illuminate\Database\Eloquent\Relations\HasMany|\Illuminate\Database\Eloquent\Relations\HasOne  $relationship
+     * @return \Illuminate\Database\Eloquent\PendingHasThroughRelationship
+     */
+    public function through($relationship)
+    {
+        if (is_string($relationship)) {
+            $relationship = $this->{$relationship}();
+        }
+
+        return new PendingHasThroughRelationship($this, $relationship);
+    }
+
+    /**
+     * Define a one-to-many relationship.
+     *
+     * @param  string  $related
+     * @param  string|null  $foreignKey
+     * @param  string|null  $localKey
+     * @return \Illuminate\Database\Eloquent\Relations\HasMany
+     */
+    public function hasMany($related, $foreignKey = null, $localKey = null)
+    {
+        $instance = $this->newRelatedInstance($related);
+
+        $foreignKey = $foreignKey ?: $this->getForeignKey();
+
+        $localKey = $localKey ?: $this->getKeyName();
+
+        return $this->newHasMany(
+            $instance->newQuery(), $this, $instance->getTable().'.'.$foreignKey, $localKey
+        );
+    }
+
+    /**
+     * Instantiate a new HasMany relationship.
+     *
+     * @param  \Illuminate\Database\Eloquent\Builder  $query
+     * @param  \Illuminate\Database\Eloquent\Model  $parent
+     * @param  string  $foreignKey
+     * @param  string  $localKey
+     * @return \Illuminate\Database\Eloquent\Relations\HasMany
+     */
+    protected function newHasMany(Builder $query, Model $parent, $foreignKey, $localKey)
+    {
+        return new HasMany($query, $parent, $foreignKey, $localKey);
+    }
+
+    /**
+     * Define a has-many-through relationship.
+     *
+     * @param  string  $related
+     * @param  string  $through
+     * @param  string|null  $firstKey
+     * @param  string|null  $secondKey
+     * @param  string|null  $localKey
+     * @param  string|null  $secondLocalKey
+     * @return \Illuminate\Database\Eloquent\Relations\HasManyThrough
+     */
+    public function hasManyThrough($related, $through, $firstKey = null, $secondKey = null, $localKey = null, $secondLocalKey = null)
+    {
+        $through = $this->newRelatedThroughInstance($through);
+
+        $firstKey = $firstKey ?: $this->getForeignKey();
+
+        $secondKey = $secondKey ?: $through->getForeignKey();
+
+        return $this->newHasManyThrough(
+            $this->newRelatedInstance($related)->newQuery(),
+            $this,
+            $through,
+            $firstKey,
+            $secondKey,
+            $localKey ?: $this->getKeyName(),
+            $secondLocalKey ?: $through->getKeyName()
+        );
+    }
+
+    /**
+     * Instantiate a new HasManyThrough relationship.
+     *
+     * @param  \Illuminate\Database\Eloquent\Builder  $query
+     * @param  \Illuminate\Database\Eloquent\Model  $farParent
+     * @param  \Illuminate\Database\Eloquent\Model  $throughParent
+     * @param  string  $firstKey
+     * @param  string  $secondKey
+     * @param  string  $localKey
+     * @param  string  $secondLocalKey
+     * @return \Illuminate\Database\Eloquent\Relations\HasManyThrough
+     */
+    protected function newHasManyThrough(Builder $query, Model $farParent, Model $throughParent, $firstKey, $secondKey, $localKey, $secondLocalKey)
+    {
+        return new HasManyThrough($query, $farParent, $throughParent, $firstKey, $secondKey, $localKey, $secondLocalKey);
+    }
+
+    /**
+     * Define a polymorphic one-to-many relationship.
+     *
+     * @param  string  $related
+     * @param  string  $name
+     * @param  string|null  $type
+     * @param  string|null  $id
+     * @param  string|null  $localKey
+     * @return \Illuminate\Database\Eloquent\Relations\MorphMany
+     */
+    public function morphMany($related, $name, $type = null, $id = null, $localKey = null)
+    {
+        $instance = $this->newRelatedInstance($related);
+
+        // Here we will gather up the morph type and ID for the relationship so that we
+        // can properly query the intermediate table of a relation. Finally, we will
+        // get the table and create the relationship instances for the developers.
+        [$type, $id] = $this->getMorphs($name, $type, $id);
+
+        $table = $instance->getTable();
+
+        $localKey = $localKey ?: $this->getKeyName();
+
+        return $this->newMorphMany($instance->newQuery(), $this, $table.'.'.$type, $table.'.'.$id, $localKey);
+    }
+
+    /**
+     * Instantiate a new MorphMany relationship.
+     *
+     * @param  \Illuminate\Database\Eloquent\Builder  $query
+     * @param  \Illuminate\Database\Eloquent\Model  $parent
+     * @param  string  $type
+     * @param  string  $id
+     * @param  string  $localKey
+     * @return \Illuminate\Database\Eloquent\Relations\MorphMany
+     */
+    protected function newMorphMany(Builder $query, Model $parent, $type, $id, $localKey)
+    {
+        return new MorphMany($query, $parent, $type, $id, $localKey);
+    }
+
+    /**
+     * Define a many-to-many relationship.
+     *
+     * @param  string  $related
+     * @param  string|null  $table
+     * @param  string|null  $foreignPivotKey
+     * @param  string|null  $relatedPivotKey
+     * @param  string|null  $parentKey
+     * @param  string|null  $relatedKey
+     * @param  string|null  $relation
+     * @return \Illuminate\Database\Eloquent\Relations\BelongsToMany
+     */
+    public function belongsToMany($related, $table = null, $foreignPivotKey = null, $relatedPivotKey = null,
+                                  $parentKey = null, $relatedKey = null, $relation = null)
+    {
+        // If no relationship name was passed, we will pull backtraces to get the
+        // name of the calling function. We will use that function name as the
+        // title of this relation since that is a great convention to apply.
+        if (is_null($relation)) {
+            $relation = $this->guessBelongsToManyRelation();
+        }
+
+        // First, we'll need to determine the foreign key and "other key" for the
+        // relationship. Once we have determined the keys we'll make the query
+        // instances as well as the relationship instances we need for this.
+        $instance = $this->newRelatedInstance($related);
+
+        $foreignPivotKey = $foreignPivotKey ?: $this->getForeignKey();
+
+        $relatedPivotKey = $relatedPivotKey ?: $instance->getForeignKey();
+
+        // If no table name was provided, we can guess it by concatenating the two
+        // models using underscores in alphabetical order. The two model names
+        // are transformed to snake case from their default CamelCase also.
+        if (is_null($table)) {
+            $table = $this->joiningTable($related, $instance);
+        }
+
+        return $this->newBelongsToMany(
+            $instance->newQuery(), $this, $table, $foreignPivotKey,
+            $relatedPivotKey, $parentKey ?: $this->getKeyName(),
+            $relatedKey ?: $instance->getKeyName(), $relation
+        );
+    }
+
+    /**
+     * Instantiate a new BelongsToMany relationship.
+     *
+     * @param  \Illuminate\Database\Eloquent\Builder  $query
+     * @param  \Illuminate\Database\Eloquent\Model  $parent
+     * @param  string  $table
+     * @param  string  $foreignPivotKey
+     * @param  string  $relatedPivotKey
+     * @param  string  $parentKey
+     * @param  string  $relatedKey
+     * @param  string|null  $relationName
+     * @return \Illuminate\Database\Eloquent\Relations\BelongsToMany
+     */
+    protected function newBelongsToMany(Builder $query, Model $parent, $table, $foreignPivotKey, $relatedPivotKey,
+                                        $parentKey, $relatedKey, $relationName = null)
+    {
+        return new BelongsToMany($query, $parent, $table, $foreignPivotKey, $relatedPivotKey, $parentKey, $relatedKey, $relationName);
+    }
+
+    /**
+     * Define a polymorphic many-to-many relationship.
+     *
+     * @param  string  $related
+     * @param  string  $name
+     * @param  string|null  $table
+     * @param  string|null  $foreignPivotKey
+     * @param  string|null  $relatedPivotKey
+     * @param  string|null  $parentKey
+     * @param  string|null  $relatedKey
+     * @param  bool  $inverse
+     * @return \Illuminate\Database\Eloquent\Relations\MorphToMany
+     */
+    public function morphToMany($related, $name, $table = null, $foreignPivotKey = null,
+                                $relatedPivotKey = null, $parentKey = null,
+                                $relatedKey = null, $inverse = false)
+    {
+        $caller = $this->guessBelongsToManyRelation();
+
+        // First, we will need to determine the foreign key and "other key" for the
+        // relationship. Once we have determined the keys we will make the query
+        // instances, as well as the relationship instances we need for these.
+        $instance = $this->newRelatedInstance($related);
+
+        $foreignPivotKey = $foreignPivotKey ?: $name.'_id';
+
+        $relatedPivotKey = $relatedPivotKey ?: $instance->getForeignKey();
+
+        // Now we're ready to create a new query builder for the related model and
+        // the relationship instances for this relation. This relation will set
+        // appropriate query constraints then entirely manage the hydrations.
+        if (! $table) {
+            $words = preg_split('/(_)/u', $name, -1, PREG_SPLIT_DELIM_CAPTURE);
+
+            $lastWord = array_pop($words);
+
+            $table = implode('', $words).Str::plural($lastWord);
+        }
+
+        return $this->newMorphToMany(
+            $instance->newQuery(), $this, $name, $table,
+            $foreignPivotKey, $relatedPivotKey, $parentKey ?: $this->getKeyName(),
+            $relatedKey ?: $instance->getKeyName(), $caller, $inverse
+        );
+    }
+
+    /**
+     * Instantiate a new MorphToMany relationship.
+     *
+     * @param  \Illuminate\Database\Eloquent\Builder  $query
+     * @param  \Illuminate\Database\Eloquent\Model  $parent
+     * @param  string  $name
+     * @param  string  $table
+     * @param  string  $foreignPivotKey
+     * @param  string  $relatedPivotKey
+     * @param  string  $parentKey
+     * @param  string  $relatedKey
+     * @param  string|null  $relationName
+     * @param  bool  $inverse
+     * @return \Illuminate\Database\Eloquent\Relations\MorphToMany
+     */
+    protected function newMorphToMany(Builder $query, Model $parent, $name, $table, $foreignPivotKey,
+                                      $relatedPivotKey, $parentKey, $relatedKey,
+                                      $relationName = null, $inverse = false)
+    {
+        return new MorphToMany($query, $parent, $name, $table, $foreignPivotKey, $relatedPivotKey, $parentKey, $relatedKey,
+            $relationName, $inverse);
+    }
+
+    /**
+     * Define a polymorphic, inverse many-to-many relationship.
+     *
+     * @param  string  $related
+     * @param  string  $name
+     * @param  string|null  $table
+     * @param  string|null  $foreignPivotKey
+     * @param  string|null  $relatedPivotKey
+     * @param  string|null  $parentKey
+     * @param  string|null  $relatedKey
+     * @return \Illuminate\Database\Eloquent\Relations\MorphToMany
+     */
+    public function morphedByMany($related, $name, $table = null, $foreignPivotKey = null,
+                                  $relatedPivotKey = null, $parentKey = null, $relatedKey = null)
+    {
+        $foreignPivotKey = $foreignPivotKey ?: $this->getForeignKey();
+
+        // For the inverse of the polymorphic many-to-many relations, we will change
+        // the way we determine the foreign and other keys, as it is the opposite
+        // of the morph-to-many method since we're figuring out these inverses.
+        $relatedPivotKey = $relatedPivotKey ?: $name.'_id';
+
+        return $this->morphToMany(
+            $related, $name, $table, $foreignPivotKey,
+            $relatedPivotKey, $parentKey, $relatedKey, true
+        );
+    }
+
+    /**
+     * Get the relationship name of the belongsToMany relationship.
+     *
+     * @return string|null
+     */
+    protected function guessBelongsToManyRelation()
+    {
+        $caller = Arr::first(debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS), function ($trace) {
+            return ! in_array(
+                $trace['function'],
+                array_merge(static::$manyMethods, ['guessBelongsToManyRelation'])
+            );
+        });
+
+        return ! is_null($caller) ? $caller['function'] : null;
+    }
+
+    /**
+     * Get the joining table name for a many-to-many relation.
+     *
+     * @param  string  $related
+     * @param  \Illuminate\Database\Eloquent\Model|null  $instance
+     * @return string
+     */
+    public function joiningTable($related, $instance = null)
+    {
+        // The joining table name, by convention, is simply the snake cased models
+        // sorted alphabetically and concatenated with an underscore, so we can
+        // just sort the models and join them together to get the table name.
+        $segments = [
+            $instance ? $instance->joiningTableSegment()
+                      : Str::snake(class_basename($related)),
+            $this->joiningTableSegment(),
+        ];
+
+        // Now that we have the model names in an array we can just sort them and
+        // use the implode function to join them together with an underscores,
+        // which is typically used by convention within the database system.
+        sort($segments);
+
+        return strtolower(implode('_', $segments));
+    }
+
+    /**
+     * Get this model's half of the intermediate table name for belongsToMany relationships.
+     *
+     * @return string
+     */
+    public function joiningTableSegment()
+    {
+        return Str::snake(class_basename($this));
+    }
+
+    /**
+     * Determine if the model touches a given relation.
+     *
+     * @param  string  $relation
+     * @return bool
+     */
+    public function touches($relation)
+    {
+        return in_array($relation, $this->getTouchedRelations());
+    }
+
+    /**
+     * Touch the owning relations of the model.
+     *
+     * @return void
+     */
+    public function touchOwners()
+    {
+        foreach ($this->getTouchedRelations() as $relation) {
+            $this->$relation()->touch();
+
+            if ($this->$relation instanceof self) {
+                $this->$relation->fireModelEvent('saved', false);
+
+                $this->$relation->touchOwners();
+            } elseif ($this->$relation instanceof Collection) {
+                $this->$relation->each->touchOwners();
+            }
+        }
+    }
+
+    /**
+     * Get the polymorphic relationship columns.
+     *
+     * @param  string  $name
+     * @param  string  $type
+     * @param  string  $id
+     * @return array
+     */
+    protected function getMorphs($name, $type, $id)
+    {
+        return [$type ?: $name.'_type', $id ?: $name.'_id'];
+    }
+
+    /**
+     * Get the class name for polymorphic relations.
+     *
+     * @return string
+     */
+    public function getMorphClass()
+    {
+        $morphMap = Relation::morphMap();
+
+        if (! empty($morphMap) && in_array(static::class, $morphMap)) {
+            return array_search(static::class, $morphMap, true);
+        }
+
+        if (static::class === Pivot::class) {
+            return static::class;
+        }
+
+        if (Relation::requiresMorphMap()) {
+            throw new ClassMorphViolationException($this);
+        }
+
+        return static::class;
+    }
+
+    /**
+     * Create a new model instance for a related model.
+     *
+     * @param  string  $class
+     * @return mixed
+     */
+    protected function newRelatedInstance($class)
+    {
+        return tap(new $class, function ($instance) {
+            if (! $instance->getConnectionName()) {
+                $instance->setConnection($this->connection);
+            }
+        });
+    }
+
+    /**
+     * Create a new model instance for a related "through" model.
+     *
+     * @param  string  $class
+     * @return mixed
+     */
+    protected function newRelatedThroughInstance($class)
+    {
+        return new $class;
+    }
+
+    /**
+     * Get all the loaded relations for the instance.
+     *
+     * @return array
+     */
+    public function getRelations()
+    {
+        return $this->relations;
+    }
+
+    /**
+     * Get a specified relationship.
+     *
+     * @param  string  $relation
+     * @return mixed
+     */
+    public function getRelation($relation)
+    {
+        return $this->relations[$relation];
+    }
+
+    /**
+     * Determine if the given relation is loaded.
+     *
+     * @param  string  $key
+     * @return bool
+     */
+    public function relationLoaded($key)
+    {
+        return array_key_exists($key, $this->relations);
+    }
+
+    /**
+     * Set the given relationship on the model.
+     *
+     * @param  string  $relation
+     * @param  mixed  $value
+     * @return $this
+     */
+    public function setRelation($relation, $value)
+    {
+        $this->relations[$relation] = $value;
+
+        return $this;
+    }
+
+    /**
+     * Unset a loaded relationship.
+     *
+     * @param  string  $relation
+     * @return $this
+     */
+    public function unsetRelation($relation)
+    {
+        unset($this->relations[$relation]);
+
+        return $this;
+    }
+
+    /**
+     * Set the entire relations array on the model.
+     *
+     * @param  array  $relations
+     * @return $this
+     */
+    public function setRelations(array $relations)
+    {
+        $this->relations = $relations;
+
+        return $this;
+    }
+
+    /**
+     * Duplicate the instance and unset all the loaded relations.
+     *
+     * @return $this
+     */
+    public function withoutRelations()
+    {
+        $model = clone $this;
+
+        return $model->unsetRelations();
+    }
+
+    /**
+     * Unset all the loaded relations for the instance.
+     *
+     * @return $this
+     */
+    public function unsetRelations()
+    {
+        $this->relations = [];
+
+        return $this;
+    }
+
+    /**
+     * Get the relationships that are touched on save.
+     *
+     * @return array
+     */
+    public function getTouchedRelations()
+    {
+        return $this->touches;
+    }
+
+    /**
+     * Set the relationships that are touched on save.
+     *
+     * @param  array  $touches
+     * @return $this
+     */
+    public function setTouchedRelations(array $touches)
+    {
+        $this->touches = $touches;
+
+        return $this;
+    }
+}
diff --git a/vendor/illuminate/database/Eloquent/Concerns/HasTimestamps.php b/vendor/illuminate/database/Eloquent/Concerns/HasTimestamps.php
new file mode 100644
index 0000000..2b6dfab
--- /dev/null
+++ b/vendor/illuminate/database/Eloquent/Concerns/HasTimestamps.php
@@ -0,0 +1,224 @@
+$attribute = $this->freshTimestamp();
+
+            return $this->save();
+        }
+
+        if (! $this->usesTimestamps()) {
+            return false;
+        }
+
+        $this->updateTimestamps();
+
+        return $this->save();
+    }
+
+    /**
+     * Update the model's update timestamp without raising any events.
+     *
+     * @param  string|null  $attribute
+     * @return bool
+     */
+    public function touchQuietly($attribute = null)
+    {
+        return static::withoutEvents(fn () => $this->touch($attribute));
+    }
+
+    /**
+     * Update the creation and update timestamps.
+     *
+     * @return $this
+     */
+    public function updateTimestamps()
+    {
+        $time = $this->freshTimestamp();
+
+        $updatedAtColumn = $this->getUpdatedAtColumn();
+
+        if (! is_null($updatedAtColumn) && ! $this->isDirty($updatedAtColumn)) {
+            $this->setUpdatedAt($time);
+        }
+
+        $createdAtColumn = $this->getCreatedAtColumn();
+
+        if (! $this->exists && ! is_null($createdAtColumn) && ! $this->isDirty($createdAtColumn)) {
+            $this->setCreatedAt($time);
+        }
+
+        return $this;
+    }
+
+    /**
+     * Set the value of the "created at" attribute.
+     *
+     * @param  mixed  $value
+     * @return $this
+     */
+    public function setCreatedAt($value)
+    {
+        $this->{$this->getCreatedAtColumn()} = $value;
+
+        return $this;
+    }
+
+    /**
+     * Set the value of the "updated at" attribute.
+     *
+     * @param  mixed  $value
+     * @return $this
+     */
+    public function setUpdatedAt($value)
+    {
+        $this->{$this->getUpdatedAtColumn()} = $value;
+
+        return $this;
+    }
+
+    /**
+     * Get a fresh timestamp for the model.
+     *
+     * @return \Illuminate\Support\Carbon
+     */
+    public function freshTimestamp()
+    {
+        return Date::now();
+    }
+
+    /**
+     * Get a fresh timestamp for the model.
+     *
+     * @return string
+     */
+    public function freshTimestampString()
+    {
+        return $this->fromDateTime($this->freshTimestamp());
+    }
+
+    /**
+     * Determine if the model uses timestamps.
+     *
+     * @return bool
+     */
+    public function usesTimestamps()
+    {
+        return $this->timestamps && ! static::isIgnoringTimestamps($this::class);
+    }
+
+    /**
+     * Get the name of the "created at" column.
+     *
+     * @return string|null
+     */
+    public function getCreatedAtColumn()
+    {
+        return static::CREATED_AT;
+    }
+
+    /**
+     * Get the name of the "updated at" column.
+     *
+     * @return string|null
+     */
+    public function getUpdatedAtColumn()
+    {
+        return static::UPDATED_AT;
+    }
+
+    /**
+     * Get the fully qualified "created at" column.
+     *
+     * @return string|null
+     */
+    public function getQualifiedCreatedAtColumn()
+    {
+        return $this->qualifyColumn($this->getCreatedAtColumn());
+    }
+
+    /**
+     * Get the fully qualified "updated at" column.
+     *
+     * @return string|null
+     */
+    public function getQualifiedUpdatedAtColumn()
+    {
+        return $this->qualifyColumn($this->getUpdatedAtColumn());
+    }
+
+    /**
+     * Disable timestamps for the current class during the given callback scope.
+     *
+     * @param  callable  $callback
+     * @return mixed
+     */
+    public static function withoutTimestamps(callable $callback)
+    {
+        return static::withoutTimestampsOn([static::class], $callback);
+    }
+
+    /**
+     * Disable timestamps for the given model classes during the given callback scope.
+     *
+     * @param  array  $models
+     * @param  callable  $callback
+     * @return mixed
+     */
+    public static function withoutTimestampsOn($models, $callback)
+    {
+        static::$ignoreTimestampsOn = array_values(array_merge(static::$ignoreTimestampsOn, $models));
+
+        try {
+            return $callback();
+        } finally {
+            static::$ignoreTimestampsOn = array_values(array_diff(static::$ignoreTimestampsOn, $models));
+        }
+    }
+
+    /**
+     * Determine if the given model is ignoring timestamps / touches.
+     *
+     * @param  string|null  $class
+     * @return bool
+     */
+    public static function isIgnoringTimestamps($class = null)
+    {
+        $class ??= static::class;
+
+        foreach (static::$ignoreTimestampsOn as $ignoredClass) {
+            if ($class === $ignoredClass || is_subclass_of($class, $ignoredClass)) {
+                return true;
+            }
+        }
+
+        return false;
+    }
+}
diff --git a/vendor/illuminate/database/Eloquent/Concerns/HasUlids.php b/vendor/illuminate/database/Eloquent/Concerns/HasUlids.php
new file mode 100644
index 0000000..b944c5d
--- /dev/null
+++ b/vendor/illuminate/database/Eloquent/Concerns/HasUlids.php
@@ -0,0 +1,96 @@
+uniqueIds() as $column) {
+                if (empty($model->{$column})) {
+                    $model->{$column} = $model->newUniqueId();
+                }
+            }
+        });
+    }
+
+    /**
+     * Generate a new ULID for the model.
+     *
+     * @return string
+     */
+    public function newUniqueId()
+    {
+        return strtolower((string) Str::ulid());
+    }
+
+    /**
+     * Retrieve the model for a bound value.
+     *
+     * @param  \Illuminate\Database\Eloquent\Model|\Illuminate\Database\Eloquent\Relations\Relation  $query
+     * @param  mixed  $value
+     * @param  string|null  $field
+     * @return \Illuminate\Database\Eloquent\Relations\Relation
+     *
+     * @throws \Illuminate\Database\Eloquent\ModelNotFoundException
+     */
+    public function resolveRouteBindingQuery($query, $value, $field = null)
+    {
+        if ($field && in_array($field, $this->uniqueIds()) && ! Str::isUlid($value)) {
+            throw (new ModelNotFoundException)->setModel(get_class($this), $value);
+        }
+
+        if (! $field && in_array($this->getRouteKeyName(), $this->uniqueIds()) && ! Str::isUlid($value)) {
+            throw (new ModelNotFoundException)->setModel(get_class($this), $value);
+        }
+
+        return parent::resolveRouteBindingQuery($query, $value, $field);
+    }
+
+    /**
+     * Get the columns that should receive a unique identifier.
+     *
+     * @return array
+     */
+    public function uniqueIds()
+    {
+        return [$this->getKeyName()];
+    }
+
+    /**
+     * Get the auto-incrementing key type.
+     *
+     * @return string
+     */
+    public function getKeyType()
+    {
+        if (in_array($this->getKeyName(), $this->uniqueIds())) {
+            return 'string';
+        }
+
+        return $this->keyType;
+    }
+
+    /**
+     * Get the value indicating whether the IDs are incrementing.
+     *
+     * @return bool
+     */
+    public function getIncrementing()
+    {
+        if (in_array($this->getKeyName(), $this->uniqueIds())) {
+            return false;
+        }
+
+        return $this->incrementing;
+    }
+}
diff --git a/vendor/illuminate/database/Eloquent/Concerns/HasUuids.php b/vendor/illuminate/database/Eloquent/Concerns/HasUuids.php
new file mode 100644
index 0000000..96a08b6
--- /dev/null
+++ b/vendor/illuminate/database/Eloquent/Concerns/HasUuids.php
@@ -0,0 +1,96 @@
+uniqueIds() as $column) {
+                if (empty($model->{$column})) {
+                    $model->{$column} = $model->newUniqueId();
+                }
+            }
+        });
+    }
+
+    /**
+     * Generate a new UUID for the model.
+     *
+     * @return string
+     */
+    public function newUniqueId()
+    {
+        return (string) Str::orderedUuid();
+    }
+
+    /**
+     * Get the columns that should receive a unique identifier.
+     *
+     * @return array
+     */
+    public function uniqueIds()
+    {
+        return [$this->getKeyName()];
+    }
+
+    /**
+     * Retrieve the model for a bound value.
+     *
+     * @param  \Illuminate\Database\Eloquent\Model|\Illuminate\Database\Eloquent\Relations\Relation  $query
+     * @param  mixed  $value
+     * @param  string|null  $field
+     * @return \Illuminate\Database\Eloquent\Relations\Relation
+     *
+     * @throws \Illuminate\Database\Eloquent\ModelNotFoundException
+     */
+    public function resolveRouteBindingQuery($query, $value, $field = null)
+    {
+        if ($field && in_array($field, $this->uniqueIds()) && ! Str::isUuid($value)) {
+            throw (new ModelNotFoundException)->setModel(get_class($this), $value);
+        }
+
+        if (! $field && in_array($this->getRouteKeyName(), $this->uniqueIds()) && ! Str::isUuid($value)) {
+            throw (new ModelNotFoundException)->setModel(get_class($this), $value);
+        }
+
+        return parent::resolveRouteBindingQuery($query, $value, $field);
+    }
+
+    /**
+     * Get the auto-incrementing key type.
+     *
+     * @return string
+     */
+    public function getKeyType()
+    {
+        if (in_array($this->getKeyName(), $this->uniqueIds())) {
+            return 'string';
+        }
+
+        return $this->keyType;
+    }
+
+    /**
+     * Get the value indicating whether the IDs are incrementing.
+     *
+     * @return bool
+     */
+    public function getIncrementing()
+    {
+        if (in_array($this->getKeyName(), $this->uniqueIds())) {
+            return false;
+        }
+
+        return $this->incrementing;
+    }
+}
diff --git a/vendor/illuminate/database/Eloquent/Concerns/HidesAttributes.php b/vendor/illuminate/database/Eloquent/Concerns/HidesAttributes.php
new file mode 100644
index 0000000..5a7e3ba
--- /dev/null
+++ b/vendor/illuminate/database/Eloquent/Concerns/HidesAttributes.php
@@ -0,0 +1,124 @@
+
+     */
+    protected $hidden = [];
+
+    /**
+     * The attributes that should be visible in serialization.
+     *
+     * @var array
+     */
+    protected $visible = [];
+
+    /**
+     * Get the hidden attributes for the model.
+     *
+     * @return array
+     */
+    public function getHidden()
+    {
+        return $this->hidden;
+    }
+
+    /**
+     * Set the hidden attributes for the model.
+     *
+     * @param  array  $hidden
+     * @return $this
+     */
+    public function setHidden(array $hidden)
+    {
+        $this->hidden = $hidden;
+
+        return $this;
+    }
+
+    /**
+     * Get the visible attributes for the model.
+     *
+     * @return array
+     */
+    public function getVisible()
+    {
+        return $this->visible;
+    }
+
+    /**
+     * Set the visible attributes for the model.
+     *
+     * @param  array  $visible
+     * @return $this
+     */
+    public function setVisible(array $visible)
+    {
+        $this->visible = $visible;
+
+        return $this;
+    }
+
+    /**
+     * Make the given, typically hidden, attributes visible.
+     *
+     * @param  array|string|null  $attributes
+     * @return $this
+     */
+    public function makeVisible($attributes)
+    {
+        $attributes = is_array($attributes) ? $attributes : func_get_args();
+
+        $this->hidden = array_diff($this->hidden, $attributes);
+
+        if (! empty($this->visible)) {
+            $this->visible = array_merge($this->visible, $attributes);
+        }
+
+        return $this;
+    }
+
+    /**
+     * Make the given, typically hidden, attributes visible if the given truth test passes.
+     *
+     * @param  bool|\Closure  $condition
+     * @param  array|string|null  $attributes
+     * @return $this
+     */
+    public function makeVisibleIf($condition, $attributes)
+    {
+        return value($condition, $this) ? $this->makeVisible($attributes) : $this;
+    }
+
+    /**
+     * Make the given, typically visible, attributes hidden.
+     *
+     * @param  array|string|null  $attributes
+     * @return $this
+     */
+    public function makeHidden($attributes)
+    {
+        $this->hidden = array_merge(
+            $this->hidden, is_array($attributes) ? $attributes : func_get_args()
+        );
+
+        return $this;
+    }
+
+    /**
+     * Make the given, typically visible, attributes hidden if the given truth test passes.
+     *
+     * @param  bool|\Closure  $condition
+     * @param  array|string|null  $attributes
+     * @return $this
+     */
+    public function makeHiddenIf($condition, $attributes)
+    {
+        return value($condition, $this) ? $this->makeHidden($attributes) : $this;
+    }
+}
diff --git a/vendor/illuminate/database/Eloquent/Concerns/QueriesRelationships.php b/vendor/illuminate/database/Eloquent/Concerns/QueriesRelationships.php
new file mode 100644
index 0000000..6f64884
--- /dev/null
+++ b/vendor/illuminate/database/Eloquent/Concerns/QueriesRelationships.php
@@ -0,0 +1,879 @@
+=', $count = 1, $boolean = 'and', Closure $callback = null)
+    {
+        if (is_string($relation)) {
+            if (str_contains($relation, '.')) {
+                return $this->hasNested($relation, $operator, $count, $boolean, $callback);
+            }
+
+            $relation = $this->getRelationWithoutConstraints($relation);
+        }
+
+        if ($relation instanceof MorphTo) {
+            return $this->hasMorph($relation, ['*'], $operator, $count, $boolean, $callback);
+        }
+
+        // If we only need to check for the existence of the relation, then we can optimize
+        // the subquery to only run a "where exists" clause instead of this full "count"
+        // clause. This will make these queries run much faster compared with a count.
+        $method = $this->canUseExistsForExistenceCheck($operator, $count)
+                        ? 'getRelationExistenceQuery'
+                        : 'getRelationExistenceCountQuery';
+
+        $hasQuery = $relation->{$method}(
+            $relation->getRelated()->newQueryWithoutRelationships(), $this
+        );
+
+        // Next we will call any given callback as an "anonymous" scope so they can get the
+        // proper logical grouping of the where clauses if needed by this Eloquent query
+        // builder. Then, we will be ready to finalize and return this query instance.
+        if ($callback) {
+            $hasQuery->callScope($callback);
+        }
+
+        return $this->addHasWhere(
+            $hasQuery, $relation, $operator, $count, $boolean
+        );
+    }
+
+    /**
+     * Add nested relationship count / exists conditions to the query.
+     *
+     * Sets up recursive call to whereHas until we finish the nested relation.
+     *
+     * @param  string  $relations
+     * @param  string  $operator
+     * @param  int  $count
+     * @param  string  $boolean
+     * @param  \Closure|null  $callback
+     * @return \Illuminate\Database\Eloquent\Builder|static
+     */
+    protected function hasNested($relations, $operator = '>=', $count = 1, $boolean = 'and', $callback = null)
+    {
+        $relations = explode('.', $relations);
+
+        $doesntHave = $operator === '<' && $count === 1;
+
+        if ($doesntHave) {
+            $operator = '>=';
+            $count = 1;
+        }
+
+        $closure = function ($q) use (&$closure, &$relations, $operator, $count, $callback) {
+            // In order to nest "has", we need to add count relation constraints on the
+            // callback Closure. We'll do this by simply passing the Closure its own
+            // reference to itself so it calls itself recursively on each segment.
+            count($relations) > 1
+                ? $q->whereHas(array_shift($relations), $closure)
+                : $q->has(array_shift($relations), $operator, $count, 'and', $callback);
+        };
+
+        return $this->has(array_shift($relations), $doesntHave ? '<' : '>=', 1, $boolean, $closure);
+    }
+
+    /**
+     * Add a relationship count / exists condition to the query with an "or".
+     *
+     * @param  string  $relation
+     * @param  string  $operator
+     * @param  int  $count
+     * @return \Illuminate\Database\Eloquent\Builder|static
+     */
+    public function orHas($relation, $operator = '>=', $count = 1)
+    {
+        return $this->has($relation, $operator, $count, 'or');
+    }
+
+    /**
+     * Add a relationship count / exists condition to the query.
+     *
+     * @param  string  $relation
+     * @param  string  $boolean
+     * @param  \Closure|null  $callback
+     * @return \Illuminate\Database\Eloquent\Builder|static
+     */
+    public function doesntHave($relation, $boolean = 'and', Closure $callback = null)
+    {
+        return $this->has($relation, '<', 1, $boolean, $callback);
+    }
+
+    /**
+     * Add a relationship count / exists condition to the query with an "or".
+     *
+     * @param  string  $relation
+     * @return \Illuminate\Database\Eloquent\Builder|static
+     */
+    public function orDoesntHave($relation)
+    {
+        return $this->doesntHave($relation, 'or');
+    }
+
+    /**
+     * Add a relationship count / exists condition to the query with where clauses.
+     *
+     * @param  string  $relation
+     * @param  \Closure|null  $callback
+     * @param  string  $operator
+     * @param  int  $count
+     * @return \Illuminate\Database\Eloquent\Builder|static
+     */
+    public function whereHas($relation, Closure $callback = null, $operator = '>=', $count = 1)
+    {
+        return $this->has($relation, $operator, $count, 'and', $callback);
+    }
+
+    /**
+     * Add a relationship count / exists condition to the query with where clauses.
+     *
+     * Also load the relationship with same condition.
+     *
+     * @param  string  $relation
+     * @param  \Closure|null  $callback
+     * @param  string  $operator
+     * @param  int  $count
+     * @return \Illuminate\Database\Eloquent\Builder|static
+     */
+    public function withWhereHas($relation, Closure $callback = null, $operator = '>=', $count = 1)
+    {
+        return $this->whereHas(Str::before($relation, ':'), $callback, $operator, $count)
+            ->with($callback ? [$relation => fn ($query) => $callback($query)] : $relation);
+    }
+
+    /**
+     * Add a relationship count / exists condition to the query with where clauses and an "or".
+     *
+     * @param  string  $relation
+     * @param  \Closure|null  $callback
+     * @param  string  $operator
+     * @param  int  $count
+     * @return \Illuminate\Database\Eloquent\Builder|static
+     */
+    public function orWhereHas($relation, Closure $callback = null, $operator = '>=', $count = 1)
+    {
+        return $this->has($relation, $operator, $count, 'or', $callback);
+    }
+
+    /**
+     * Add a relationship count / exists condition to the query with where clauses.
+     *
+     * @param  string  $relation
+     * @param  \Closure|null  $callback
+     * @return \Illuminate\Database\Eloquent\Builder|static
+     */
+    public function whereDoesntHave($relation, Closure $callback = null)
+    {
+        return $this->doesntHave($relation, 'and', $callback);
+    }
+
+    /**
+     * Add a relationship count / exists condition to the query with where clauses and an "or".
+     *
+     * @param  string  $relation
+     * @param  \Closure|null  $callback
+     * @return \Illuminate\Database\Eloquent\Builder|static
+     */
+    public function orWhereDoesntHave($relation, Closure $callback = null)
+    {
+        return $this->doesntHave($relation, 'or', $callback);
+    }
+
+    /**
+     * Add a polymorphic relationship count / exists condition to the query.
+     *
+     * @param  \Illuminate\Database\Eloquent\Relations\MorphTo|string  $relation
+     * @param  string|array  $types
+     * @param  string  $operator
+     * @param  int  $count
+     * @param  string  $boolean
+     * @param  \Closure|null  $callback
+     * @return \Illuminate\Database\Eloquent\Builder|static
+     */
+    public function hasMorph($relation, $types, $operator = '>=', $count = 1, $boolean = 'and', Closure $callback = null)
+    {
+        if (is_string($relation)) {
+            $relation = $this->getRelationWithoutConstraints($relation);
+        }
+
+        $types = (array) $types;
+
+        if ($types === ['*']) {
+            $types = $this->model->newModelQuery()->distinct()->pluck($relation->getMorphType())->filter()->all();
+        }
+
+        foreach ($types as &$type) {
+            $type = Relation::getMorphedModel($type) ?? $type;
+        }
+
+        return $this->where(function ($query) use ($relation, $callback, $operator, $count, $types) {
+            foreach ($types as $type) {
+                $query->orWhere(function ($query) use ($relation, $callback, $operator, $count, $type) {
+                    $belongsTo = $this->getBelongsToRelation($relation, $type);
+
+                    if ($callback) {
+                        $callback = function ($query) use ($callback, $type) {
+                            return $callback($query, $type);
+                        };
+                    }
+
+                    $query->where($this->qualifyColumn($relation->getMorphType()), '=', (new $type)->getMorphClass())
+                                ->whereHas($belongsTo, $callback, $operator, $count);
+                });
+            }
+        }, null, null, $boolean);
+    }
+
+    /**
+     * Get the BelongsTo relationship for a single polymorphic type.
+     *
+     * @param  \Illuminate\Database\Eloquent\Relations\MorphTo  $relation
+     * @param  string  $type
+     * @return \Illuminate\Database\Eloquent\Relations\BelongsTo
+     */
+    protected function getBelongsToRelation(MorphTo $relation, $type)
+    {
+        $belongsTo = Relation::noConstraints(function () use ($relation, $type) {
+            return $this->model->belongsTo(
+                $type,
+                $relation->getForeignKeyName(),
+                $relation->getOwnerKeyName()
+            );
+        });
+
+        $belongsTo->getQuery()->mergeConstraintsFrom($relation->getQuery());
+
+        return $belongsTo;
+    }
+
+    /**
+     * Add a polymorphic relationship count / exists condition to the query with an "or".
+     *
+     * @param  \Illuminate\Database\Eloquent\Relations\MorphTo|string  $relation
+     * @param  string|array  $types
+     * @param  string  $operator
+     * @param  int  $count
+     * @return \Illuminate\Database\Eloquent\Builder|static
+     */
+    public function orHasMorph($relation, $types, $operator = '>=', $count = 1)
+    {
+        return $this->hasMorph($relation, $types, $operator, $count, 'or');
+    }
+
+    /**
+     * Add a polymorphic relationship count / exists condition to the query.
+     *
+     * @param  \Illuminate\Database\Eloquent\Relations\MorphTo|string  $relation
+     * @param  string|array  $types
+     * @param  string  $boolean
+     * @param  \Closure|null  $callback
+     * @return \Illuminate\Database\Eloquent\Builder|static
+     */
+    public function doesntHaveMorph($relation, $types, $boolean = 'and', Closure $callback = null)
+    {
+        return $this->hasMorph($relation, $types, '<', 1, $boolean, $callback);
+    }
+
+    /**
+     * Add a polymorphic relationship count / exists condition to the query with an "or".
+     *
+     * @param  \Illuminate\Database\Eloquent\Relations\MorphTo|string  $relation
+     * @param  string|array  $types
+     * @return \Illuminate\Database\Eloquent\Builder|static
+     */
+    public function orDoesntHaveMorph($relation, $types)
+    {
+        return $this->doesntHaveMorph($relation, $types, 'or');
+    }
+
+    /**
+     * Add a polymorphic relationship count / exists condition to the query with where clauses.
+     *
+     * @param  \Illuminate\Database\Eloquent\Relations\MorphTo|string  $relation
+     * @param  string|array  $types
+     * @param  \Closure|null  $callback
+     * @param  string  $operator
+     * @param  int  $count
+     * @return \Illuminate\Database\Eloquent\Builder|static
+     */
+    public function whereHasMorph($relation, $types, Closure $callback = null, $operator = '>=', $count = 1)
+    {
+        return $this->hasMorph($relation, $types, $operator, $count, 'and', $callback);
+    }
+
+    /**
+     * Add a polymorphic relationship count / exists condition to the query with where clauses and an "or".
+     *
+     * @param  \Illuminate\Database\Eloquent\Relations\MorphTo|string  $relation
+     * @param  string|array  $types
+     * @param  \Closure|null  $callback
+     * @param  string  $operator
+     * @param  int  $count
+     * @return \Illuminate\Database\Eloquent\Builder|static
+     */
+    public function orWhereHasMorph($relation, $types, Closure $callback = null, $operator = '>=', $count = 1)
+    {
+        return $this->hasMorph($relation, $types, $operator, $count, 'or', $callback);
+    }
+
+    /**
+     * Add a polymorphic relationship count / exists condition to the query with where clauses.
+     *
+     * @param  \Illuminate\Database\Eloquent\Relations\MorphTo|string  $relation
+     * @param  string|array  $types
+     * @param  \Closure|null  $callback
+     * @return \Illuminate\Database\Eloquent\Builder|static
+     */
+    public function whereDoesntHaveMorph($relation, $types, Closure $callback = null)
+    {
+        return $this->doesntHaveMorph($relation, $types, 'and', $callback);
+    }
+
+    /**
+     * Add a polymorphic relationship count / exists condition to the query with where clauses and an "or".
+     *
+     * @param  \Illuminate\Database\Eloquent\Relations\MorphTo|string  $relation
+     * @param  string|array  $types
+     * @param  \Closure|null  $callback
+     * @return \Illuminate\Database\Eloquent\Builder|static
+     */
+    public function orWhereDoesntHaveMorph($relation, $types, Closure $callback = null)
+    {
+        return $this->doesntHaveMorph($relation, $types, 'or', $callback);
+    }
+
+    /**
+     * Add a basic where clause to a relationship query.
+     *
+     * @param  string  $relation
+     * @param  \Closure|string|array|\Illuminate\Database\Query\Expression  $column
+     * @param  mixed  $operator
+     * @param  mixed  $value
+     * @return \Illuminate\Database\Eloquent\Builder|static
+     */
+    public function whereRelation($relation, $column, $operator = null, $value = null)
+    {
+        return $this->whereHas($relation, function ($query) use ($column, $operator, $value) {
+            if ($column instanceof Closure) {
+                $column($query);
+            } else {
+                $query->where($column, $operator, $value);
+            }
+        });
+    }
+
+    /**
+     * Add an "or where" clause to a relationship query.
+     *
+     * @param  string  $relation
+     * @param  \Closure|string|array|\Illuminate\Database\Query\Expression  $column
+     * @param  mixed  $operator
+     * @param  mixed  $value
+     * @return \Illuminate\Database\Eloquent\Builder|static
+     */
+    public function orWhereRelation($relation, $column, $operator = null, $value = null)
+    {
+        return $this->orWhereHas($relation, function ($query) use ($column, $operator, $value) {
+            if ($column instanceof Closure) {
+                $column($query);
+            } else {
+                $query->where($column, $operator, $value);
+            }
+        });
+    }
+
+    /**
+     * Add a polymorphic relationship condition to the query with a where clause.
+     *
+     * @param  \Illuminate\Database\Eloquent\Relations\MorphTo|string  $relation
+     * @param  string|array  $types
+     * @param  \Closure|string|array|\Illuminate\Database\Query\Expression  $column
+     * @param  mixed  $operator
+     * @param  mixed  $value
+     * @return \Illuminate\Database\Eloquent\Builder|static
+     */
+    public function whereMorphRelation($relation, $types, $column, $operator = null, $value = null)
+    {
+        return $this->whereHasMorph($relation, $types, function ($query) use ($column, $operator, $value) {
+            $query->where($column, $operator, $value);
+        });
+    }
+
+    /**
+     * Add a polymorphic relationship condition to the query with an "or where" clause.
+     *
+     * @param  \Illuminate\Database\Eloquent\Relations\MorphTo|string  $relation
+     * @param  string|array  $types
+     * @param  \Closure|string|array|\Illuminate\Database\Query\Expression  $column
+     * @param  mixed  $operator
+     * @param  mixed  $value
+     * @return \Illuminate\Database\Eloquent\Builder|static
+     */
+    public function orWhereMorphRelation($relation, $types, $column, $operator = null, $value = null)
+    {
+        return $this->orWhereHasMorph($relation, $types, function ($query) use ($column, $operator, $value) {
+            $query->where($column, $operator, $value);
+        });
+    }
+
+    /**
+     * Add a morph-to relationship condition to the query.
+     *
+     * @param  \Illuminate\Database\Eloquent\Relations\MorphTo|string  $relation
+     * @param  \Illuminate\Database\Eloquent\Model|string  $model
+     * @return \Illuminate\Database\Eloquent\Builder|static
+     */
+    public function whereMorphedTo($relation, $model, $boolean = 'and')
+    {
+        if (is_string($relation)) {
+            $relation = $this->getRelationWithoutConstraints($relation);
+        }
+
+        if (is_string($model)) {
+            $morphMap = Relation::morphMap();
+
+            if (! empty($morphMap) && in_array($model, $morphMap)) {
+                $model = array_search($model, $morphMap, true);
+            }
+
+            return $this->where($relation->getMorphType(), $model, null, $boolean);
+        }
+
+        return $this->where(function ($query) use ($relation, $model) {
+            $query->where($relation->getMorphType(), $model->getMorphClass())
+                ->where($relation->getForeignKeyName(), $model->getKey());
+        }, null, null, $boolean);
+    }
+
+    /**
+     * Add a not morph-to relationship condition to the query.
+     *
+     * @param  \Illuminate\Database\Eloquent\Relations\MorphTo|string  $relation
+     * @param  \Illuminate\Database\Eloquent\Model|string  $model
+     * @return \Illuminate\Database\Eloquent\Builder|static
+     */
+    public function whereNotMorphedTo($relation, $model, $boolean = 'and')
+    {
+        if (is_string($relation)) {
+            $relation = $this->getRelationWithoutConstraints($relation);
+        }
+
+        if (is_string($model)) {
+            $morphMap = Relation::morphMap();
+
+            if (! empty($morphMap) && in_array($model, $morphMap)) {
+                $model = array_search($model, $morphMap, true);
+            }
+
+            return $this->whereNot($relation->getMorphType(), '<=>', $model, $boolean);
+        }
+
+        return $this->whereNot(function ($query) use ($relation, $model) {
+            $query->where($relation->getMorphType(), '<=>', $model->getMorphClass())
+                ->where($relation->getForeignKeyName(), '<=>', $model->getKey());
+        }, null, null, $boolean);
+    }
+
+    /**
+     * Add a morph-to relationship condition to the query with an "or where" clause.
+     *
+     * @param  \Illuminate\Database\Eloquent\Relations\MorphTo|string  $relation
+     * @param  \Illuminate\Database\Eloquent\Model|string  $model
+     * @return \Illuminate\Database\Eloquent\Builder|static
+     */
+    public function orWhereMorphedTo($relation, $model)
+    {
+        return $this->whereMorphedTo($relation, $model, 'or');
+    }
+
+    /**
+     * Add a not morph-to relationship condition to the query with an "or where" clause.
+     *
+     * @param  \Illuminate\Database\Eloquent\Relations\MorphTo|string  $relation
+     * @param  \Illuminate\Database\Eloquent\Model|string  $model
+     * @return \Illuminate\Database\Eloquent\Builder|static
+     */
+    public function orWhereNotMorphedTo($relation, $model)
+    {
+        return $this->whereNotMorphedTo($relation, $model, 'or');
+    }
+
+    /**
+     * Add a "belongs to" relationship where clause to the query.
+     *
+     * @param  \Illuminate\Database\Eloquent\Model|\Illuminate\Database\Eloquent\Collection<\Illuminate\Database\Eloquent\Model>  $related
+     * @param  string|null  $relationshipName
+     * @param  string  $boolean
+     * @return $this
+     *
+     * @throws \Illuminate\Database\Eloquent\RelationNotFoundException
+     */
+    public function whereBelongsTo($related, $relationshipName = null, $boolean = 'and')
+    {
+        if (! $related instanceof Collection) {
+            $relatedCollection = $related->newCollection([$related]);
+        } else {
+            $relatedCollection = $related;
+
+            $related = $relatedCollection->first();
+        }
+
+        if ($relatedCollection->isEmpty()) {
+            throw new InvalidArgumentException('Collection given to whereBelongsTo method may not be empty.');
+        }
+
+        if ($relationshipName === null) {
+            $relationshipName = Str::camel(class_basename($related));
+        }
+
+        try {
+            $relationship = $this->model->{$relationshipName}();
+        } catch (BadMethodCallException $exception) {
+            throw RelationNotFoundException::make($this->model, $relationshipName);
+        }
+
+        if (! $relationship instanceof BelongsTo) {
+            throw RelationNotFoundException::make($this->model, $relationshipName, BelongsTo::class);
+        }
+
+        $this->whereIn(
+            $relationship->getQualifiedForeignKeyName(),
+            $relatedCollection->pluck($relationship->getOwnerKeyName())->toArray(),
+            $boolean,
+        );
+
+        return $this;
+    }
+
+    /**
+     * Add an "BelongsTo" relationship with an "or where" clause to the query.
+     *
+     * @param  \Illuminate\Database\Eloquent\Model  $related
+     * @param  string|null  $relationshipName
+     * @return $this
+     *
+     * @throws \RuntimeException
+     */
+    public function orWhereBelongsTo($related, $relationshipName = null)
+    {
+        return $this->whereBelongsTo($related, $relationshipName, 'or');
+    }
+
+    /**
+     * Add subselect queries to include an aggregate value for a relationship.
+     *
+     * @param  mixed  $relations
+     * @param  string  $column
+     * @param  string  $function
+     * @return $this
+     */
+    public function withAggregate($relations, $column, $function = null)
+    {
+        if (empty($relations)) {
+            return $this;
+        }
+
+        if (is_null($this->query->columns)) {
+            $this->query->select([$this->query->from.'.*']);
+        }
+
+        $relations = is_array($relations) ? $relations : [$relations];
+
+        foreach ($this->parseWithRelations($relations) as $name => $constraints) {
+            // First we will determine if the name has been aliased using an "as" clause on the name
+            // and if it has we will extract the actual relationship name and the desired name of
+            // the resulting column. This allows multiple aggregates on the same relationships.
+            $segments = explode(' ', $name);
+
+            unset($alias);
+
+            if (count($segments) === 3 && Str::lower($segments[1]) === 'as') {
+                [$name, $alias] = [$segments[0], $segments[2]];
+            }
+
+            $relation = $this->getRelationWithoutConstraints($name);
+
+            if ($function) {
+                $hashedColumn = $this->getRelationHashedColumn($column, $relation);
+
+                $wrappedColumn = $this->getQuery()->getGrammar()->wrap(
+                    $column === '*' ? $column : $relation->getRelated()->qualifyColumn($hashedColumn)
+                );
+
+                $expression = $function === 'exists' ? $wrappedColumn : sprintf('%s(%s)', $function, $wrappedColumn);
+            } else {
+                $expression = $column;
+            }
+
+            // Here, we will grab the relationship sub-query and prepare to add it to the main query
+            // as a sub-select. First, we'll get the "has" query and use that to get the relation
+            // sub-query. We'll format this relationship name and append this column if needed.
+            $query = $relation->getRelationExistenceQuery(
+                $relation->getRelated()->newQuery(), $this, new Expression($expression)
+            )->setBindings([], 'select');
+
+            $query->callScope($constraints);
+
+            $query = $query->mergeConstraintsFrom($relation->getQuery())->toBase();
+
+            // If the query contains certain elements like orderings / more than one column selected
+            // then we will remove those elements from the query so that it will execute properly
+            // when given to the database. Otherwise, we may receive SQL errors or poor syntax.
+            $query->orders = null;
+            $query->setBindings([], 'order');
+
+            if (count($query->columns) > 1) {
+                $query->columns = [$query->columns[0]];
+                $query->bindings['select'] = [];
+            }
+
+            // Finally, we will make the proper column alias to the query and run this sub-select on
+            // the query builder. Then, we will return the builder instance back to the developer
+            // for further constraint chaining that needs to take place on the query as needed.
+            $alias ??= Str::snake(
+                preg_replace('/[^[:alnum:][:space:]_]/u', '', "$name $function $column")
+            );
+
+            if ($function === 'exists') {
+                $this->selectRaw(
+                    sprintf('exists(%s) as %s', $query->toSql(), $this->getQuery()->grammar->wrap($alias)),
+                    $query->getBindings()
+                )->withCasts([$alias => 'bool']);
+            } else {
+                $this->selectSub(
+                    $function ? $query : $query->limit(1),
+                    $alias
+                );
+            }
+        }
+
+        return $this;
+    }
+
+    /**
+     * Get the relation hashed column name for the given column and relation.
+     *
+     * @param  string  $column
+     * @param  \Illuminate\Database\Eloquent\Relations\Relationship  $relation
+     * @return string
+     */
+    protected function getRelationHashedColumn($column, $relation)
+    {
+        if (str_contains($column, '.')) {
+            return $column;
+        }
+
+        return $this->getQuery()->from === $relation->getQuery()->getQuery()->from
+            ? "{$relation->getRelationCountHash(false)}.$column"
+            : $column;
+    }
+
+    /**
+     * Add subselect queries to count the relations.
+     *
+     * @param  mixed  $relations
+     * @return $this
+     */
+    public function withCount($relations)
+    {
+        return $this->withAggregate(is_array($relations) ? $relations : func_get_args(), '*', 'count');
+    }
+
+    /**
+     * Add subselect queries to include the max of the relation's column.
+     *
+     * @param  string|array  $relation
+     * @param  string  $column
+     * @return $this
+     */
+    public function withMax($relation, $column)
+    {
+        return $this->withAggregate($relation, $column, 'max');
+    }
+
+    /**
+     * Add subselect queries to include the min of the relation's column.
+     *
+     * @param  string|array  $relation
+     * @param  string  $column
+     * @return $this
+     */
+    public function withMin($relation, $column)
+    {
+        return $this->withAggregate($relation, $column, 'min');
+    }
+
+    /**
+     * Add subselect queries to include the sum of the relation's column.
+     *
+     * @param  string|array  $relation
+     * @param  string  $column
+     * @return $this
+     */
+    public function withSum($relation, $column)
+    {
+        return $this->withAggregate($relation, $column, 'sum');
+    }
+
+    /**
+     * Add subselect queries to include the average of the relation's column.
+     *
+     * @param  string|array  $relation
+     * @param  string  $column
+     * @return $this
+     */
+    public function withAvg($relation, $column)
+    {
+        return $this->withAggregate($relation, $column, 'avg');
+    }
+
+    /**
+     * Add subselect queries to include the existence of related models.
+     *
+     * @param  string|array  $relation
+     * @return $this
+     */
+    public function withExists($relation)
+    {
+        return $this->withAggregate($relation, '*', 'exists');
+    }
+
+    /**
+     * Add the "has" condition where clause to the query.
+     *
+     * @param  \Illuminate\Database\Eloquent\Builder  $hasQuery
+     * @param  \Illuminate\Database\Eloquent\Relations\Relation  $relation
+     * @param  string  $operator
+     * @param  int  $count
+     * @param  string  $boolean
+     * @return \Illuminate\Database\Eloquent\Builder|static
+     */
+    protected function addHasWhere(Builder $hasQuery, Relation $relation, $operator, $count, $boolean)
+    {
+        $hasQuery->mergeConstraintsFrom($relation->getQuery());
+
+        return $this->canUseExistsForExistenceCheck($operator, $count)
+                ? $this->addWhereExistsQuery($hasQuery->toBase(), $boolean, $operator === '<' && $count === 1)
+                : $this->addWhereCountQuery($hasQuery->toBase(), $operator, $count, $boolean);
+    }
+
+    /**
+     * Merge the where constraints from another query to the current query.
+     *
+     * @param  \Illuminate\Database\Eloquent\Builder  $from
+     * @return \Illuminate\Database\Eloquent\Builder|static
+     */
+    public function mergeConstraintsFrom(Builder $from)
+    {
+        $whereBindings = $from->getQuery()->getRawBindings()['where'] ?? [];
+
+        $wheres = $from->getQuery()->from !== $this->getQuery()->from
+            ? $this->requalifyWhereTables(
+                $from->getQuery()->wheres,
+                $from->getQuery()->from,
+                $this->getModel()->getTable()
+            ) : $from->getQuery()->wheres;
+
+        // Here we have some other query that we want to merge the where constraints from. We will
+        // copy over any where constraints on the query as well as remove any global scopes the
+        // query might have removed. Then we will return ourselves with the finished merging.
+        return $this->withoutGlobalScopes(
+            $from->removedScopes()
+        )->mergeWheres(
+            $wheres, $whereBindings
+        );
+    }
+
+    /**
+     * Updates the table name for any columns with a new qualified name.
+     *
+     * @param  array  $wheres
+     * @param  string  $from
+     * @param  string  $to
+     * @return array
+     */
+    protected function requalifyWhereTables(array $wheres, string $from, string $to): array
+    {
+        return collect($wheres)->map(function ($where) use ($from, $to) {
+            return collect($where)->map(function ($value) use ($from, $to) {
+                return is_string($value) && str_starts_with($value, $from.'.')
+                    ? $to.'.'.Str::afterLast($value, '.')
+                    : $value;
+            });
+        })->toArray();
+    }
+
+    /**
+     * Add a sub-query count clause to this query.
+     *
+     * @param  \Illuminate\Database\Query\Builder  $query
+     * @param  string  $operator
+     * @param  int  $count
+     * @param  string  $boolean
+     * @return $this
+     */
+    protected function addWhereCountQuery(QueryBuilder $query, $operator = '>=', $count = 1, $boolean = 'and')
+    {
+        $this->query->addBinding($query->getBindings(), 'where');
+
+        return $this->where(
+            new Expression('('.$query->toSql().')'),
+            $operator,
+            is_numeric($count) ? new Expression($count) : $count,
+            $boolean
+        );
+    }
+
+    /**
+     * Get the "has relation" base query instance.
+     *
+     * @param  string  $relation
+     * @return \Illuminate\Database\Eloquent\Relations\Relation
+     */
+    protected function getRelationWithoutConstraints($relation)
+    {
+        return Relation::noConstraints(function () use ($relation) {
+            return $this->getModel()->{$relation}();
+        });
+    }
+
+    /**
+     * Check if we can run an "exists" query to optimize performance.
+     *
+     * @param  string  $operator
+     * @param  int  $count
+     * @return bool
+     */
+    protected function canUseExistsForExistenceCheck($operator, $count)
+    {
+        return ($operator === '>=' || $operator === '<') && $count === 1;
+    }
+}
diff --git a/vendor/illuminate/database/Eloquent/Factories/BelongsToManyRelationship.php b/vendor/illuminate/database/Eloquent/Factories/BelongsToManyRelationship.php
new file mode 100644
index 0000000..8e40261
--- /dev/null
+++ b/vendor/illuminate/database/Eloquent/Factories/BelongsToManyRelationship.php
@@ -0,0 +1,76 @@
+factory = $factory;
+        $this->pivot = $pivot;
+        $this->relationship = $relationship;
+    }
+
+    /**
+     * Create the attached relationship for the given model.
+     *
+     * @param  \Illuminate\Database\Eloquent\Model  $model
+     * @return void
+     */
+    public function createFor(Model $model)
+    {
+        Collection::wrap($this->factory instanceof Factory ? $this->factory->create([], $model) : $this->factory)->each(function ($attachable) use ($model) {
+            $model->{$this->relationship}()->attach(
+                $attachable,
+                is_callable($this->pivot) ? call_user_func($this->pivot, $model) : $this->pivot
+            );
+        });
+    }
+
+    /**
+     * Specify the model instances to always use when creating relationships.
+     *
+     * @param  \Illuminate\Support\Collection  $recycle
+     * @return $this
+     */
+    public function recycle($recycle)
+    {
+        if ($this->factory instanceof Factory) {
+            $this->factory = $this->factory->recycle($recycle);
+        }
+
+        return $this;
+    }
+}
diff --git a/vendor/illuminate/database/Eloquent/Factories/BelongsToRelationship.php b/vendor/illuminate/database/Eloquent/Factories/BelongsToRelationship.php
new file mode 100644
index 0000000..b2fb1b2
--- /dev/null
+++ b/vendor/illuminate/database/Eloquent/Factories/BelongsToRelationship.php
@@ -0,0 +1,97 @@
+factory = $factory;
+        $this->relationship = $relationship;
+    }
+
+    /**
+     * Get the parent model attributes and resolvers for the given child model.
+     *
+     * @param  \Illuminate\Database\Eloquent\Model  $model
+     * @return array
+     */
+    public function attributesFor(Model $model)
+    {
+        $relationship = $model->{$this->relationship}();
+
+        return $relationship instanceof MorphTo ? [
+            $relationship->getMorphType() => $this->factory instanceof Factory ? $this->factory->newModel()->getMorphClass() : $this->factory->getMorphClass(),
+            $relationship->getForeignKeyName() => $this->resolver($relationship->getOwnerKeyName()),
+        ] : [
+            $relationship->getForeignKeyName() => $this->resolver($relationship->getOwnerKeyName()),
+        ];
+    }
+
+    /**
+     * Get the deferred resolver for this relationship's parent ID.
+     *
+     * @param  string|null  $key
+     * @return \Closure
+     */
+    protected function resolver($key)
+    {
+        return function () use ($key) {
+            if (! $this->resolved) {
+                $instance = $this->factory instanceof Factory
+                    ? ($this->factory->getRandomRecycledModel($this->factory->modelName()) ?? $this->factory->create())
+                    : $this->factory;
+
+                return $this->resolved = $key ? $instance->{$key} : $instance->getKey();
+            }
+
+            return $this->resolved;
+        };
+    }
+
+    /**
+     * Specify the model instances to always use when creating relationships.
+     *
+     * @param  \Illuminate\Support\Collection  $recycle
+     * @return $this
+     */
+    public function recycle($recycle)
+    {
+        if ($this->factory instanceof Factory) {
+            $this->factory = $this->factory->recycle($recycle);
+        }
+
+        return $this;
+    }
+}
diff --git a/vendor/illuminate/database/Eloquent/Factories/CrossJoinSequence.php b/vendor/illuminate/database/Eloquent/Factories/CrossJoinSequence.php
new file mode 100644
index 0000000..3270b30
--- /dev/null
+++ b/vendor/illuminate/database/Eloquent/Factories/CrossJoinSequence.php
@@ -0,0 +1,26 @@
+
+     */
+    protected $model;
+
+    /**
+     * The number of models that should be generated.
+     *
+     * @var int|null
+     */
+    protected $count;
+
+    /**
+     * The state transformations that will be applied to the model.
+     *
+     * @var \Illuminate\Support\Collection
+     */
+    protected $states;
+
+    /**
+     * The parent relationships that will be applied to the model.
+     *
+     * @var \Illuminate\Support\Collection
+     */
+    protected $has;
+
+    /**
+     * The child relationships that will be applied to the model.
+     *
+     * @var \Illuminate\Support\Collection
+     */
+    protected $for;
+
+    /**
+     * The model instances to always use when creating relationships.
+     *
+     * @var \Illuminate\Support\Collection
+     */
+    protected $recycle;
+
+    /**
+     * The "after making" callbacks that will be applied to the model.
+     *
+     * @var \Illuminate\Support\Collection
+     */
+    protected $afterMaking;
+
+    /**
+     * The "after creating" callbacks that will be applied to the model.
+     *
+     * @var \Illuminate\Support\Collection
+     */
+    protected $afterCreating;
+
+    /**
+     * The name of the database connection that will be used to create the models.
+     *
+     * @var string|null
+     */
+    protected $connection;
+
+    /**
+     * The current Faker instance.
+     *
+     * @var \Faker\Generator
+     */
+    protected $faker;
+
+    /**
+     * The default namespace where factories reside.
+     *
+     * @var string
+     */
+    protected static $namespace = 'Database\\Factories\\';
+
+    /**
+     * The default model name resolver.
+     *
+     * @var callable
+     */
+    protected static $modelNameResolver;
+
+    /**
+     * The factory name resolver.
+     *
+     * @var callable
+     */
+    protected static $factoryNameResolver;
+
+    /**
+     * Create a new factory instance.
+     *
+     * @param  int|null  $count
+     * @param  \Illuminate\Support\Collection|null  $states
+     * @param  \Illuminate\Support\Collection|null  $has
+     * @param  \Illuminate\Support\Collection|null  $for
+     * @param  \Illuminate\Support\Collection|null  $afterMaking
+     * @param  \Illuminate\Support\Collection|null  $afterCreating
+     * @param  string|null  $connection
+     * @param  \Illuminate\Support\Collection|null  $recycle
+     * @return void
+     */
+    public function __construct($count = null,
+                                ?Collection $states = null,
+                                ?Collection $has = null,
+                                ?Collection $for = null,
+                                ?Collection $afterMaking = null,
+                                ?Collection $afterCreating = null,
+                                $connection = null,
+                                ?Collection $recycle = null)
+    {
+        $this->count = $count;
+        $this->states = $states ?? new Collection;
+        $this->has = $has ?? new Collection;
+        $this->for = $for ?? new Collection;
+        $this->afterMaking = $afterMaking ?? new Collection;
+        $this->afterCreating = $afterCreating ?? new Collection;
+        $this->connection = $connection;
+        $this->recycle = $recycle ?? new Collection;
+        $this->faker = $this->withFaker();
+    }
+
+    /**
+     * Define the model's default state.
+     *
+     * @return array
+     */
+    abstract public function definition();
+
+    /**
+     * Get a new factory instance for the given attributes.
+     *
+     * @param  (callable(array): array)|array  $attributes
+     * @return static
+     */
+    public static function new($attributes = [])
+    {
+        return (new static)->state($attributes)->configure();
+    }
+
+    /**
+     * Get a new factory instance for the given number of models.
+     *
+     * @param  int  $count
+     * @return static
+     */
+    public static function times(int $count)
+    {
+        return static::new()->count($count);
+    }
+
+    /**
+     * Configure the factory.
+     *
+     * @return $this
+     */
+    public function configure()
+    {
+        return $this;
+    }
+
+    /**
+     * Get the raw attributes generated by the factory.
+     *
+     * @param  (callable(array): array)|array  $attributes
+     * @param  \Illuminate\Database\Eloquent\Model|null  $parent
+     * @return array
+     */
+    public function raw($attributes = [], ?Model $parent = null)
+    {
+        if ($this->count === null) {
+            return $this->state($attributes)->getExpandedAttributes($parent);
+        }
+
+        return array_map(function () use ($attributes, $parent) {
+            return $this->state($attributes)->getExpandedAttributes($parent);
+        }, range(1, $this->count));
+    }
+
+    /**
+     * Create a single model and persist it to the database.
+     *
+     * @param  (callable(array): array)|array  $attributes
+     * @return \Illuminate\Database\Eloquent\Model|TModel
+     */
+    public function createOne($attributes = [])
+    {
+        return $this->count(null)->create($attributes);
+    }
+
+    /**
+     * Create a single model and persist it to the database without dispatching any model events.
+     *
+     * @param  (callable(array): array)|array  $attributes
+     * @return \Illuminate\Database\Eloquent\Model|TModel
+     */
+    public function createOneQuietly($attributes = [])
+    {
+        return $this->count(null)->createQuietly($attributes);
+    }
+
+    /**
+     * Create a collection of models and persist them to the database.
+     *
+     * @param  iterable>  $records
+     * @return \Illuminate\Database\Eloquent\Collection
+     */
+    public function createMany(iterable $records)
+    {
+        return new EloquentCollection(
+            collect($records)->map(function ($record) {
+                return $this->state($record)->create();
+            })
+        );
+    }
+
+    /**
+     * Create a collection of models and persist them to the database without dispatching any model events.
+     *
+     * @param  iterable>  $records
+     * @return \Illuminate\Database\Eloquent\Collection
+     */
+    public function createManyQuietly(iterable $records)
+    {
+        return Model::withoutEvents(function () use ($records) {
+            return $this->createMany($records);
+        });
+    }
+
+    /**
+     * Create a collection of models and persist them to the database.
+     *
+     * @param  (callable(array): array)|array  $attributes
+     * @param  \Illuminate\Database\Eloquent\Model|null  $parent
+     * @return \Illuminate\Database\Eloquent\Collection|\Illuminate\Database\Eloquent\Model|TModel
+     */
+    public function create($attributes = [], ?Model $parent = null)
+    {
+        if (! empty($attributes)) {
+            return $this->state($attributes)->create([], $parent);
+        }
+
+        $results = $this->make($attributes, $parent);
+
+        if ($results instanceof Model) {
+            $this->store(collect([$results]));
+
+            $this->callAfterCreating(collect([$results]), $parent);
+        } else {
+            $this->store($results);
+
+            $this->callAfterCreating($results, $parent);
+        }
+
+        return $results;
+    }
+
+    /**
+     * Create a collection of models and persist them to the database without dispatching any model events.
+     *
+     * @param  (callable(array): array)|array  $attributes
+     * @param  \Illuminate\Database\Eloquent\Model|null  $parent
+     * @return \Illuminate\Database\Eloquent\Collection|\Illuminate\Database\Eloquent\Model|TModel
+     */
+    public function createQuietly($attributes = [], ?Model $parent = null)
+    {
+        return Model::withoutEvents(function () use ($attributes, $parent) {
+            return $this->create($attributes, $parent);
+        });
+    }
+
+    /**
+     * Create a callback that persists a model in the database when invoked.
+     *
+     * @param  array  $attributes
+     * @param  \Illuminate\Database\Eloquent\Model|null  $parent
+     * @return \Closure(): (\Illuminate\Database\Eloquent\Collection|\Illuminate\Database\Eloquent\Model|TModel)
+     */
+    public function lazy(array $attributes = [], ?Model $parent = null)
+    {
+        return fn () => $this->create($attributes, $parent);
+    }
+
+    /**
+     * Set the connection name on the results and store them.
+     *
+     * @param  \Illuminate\Support\Collection  $results
+     * @return void
+     */
+    protected function store(Collection $results)
+    {
+        $results->each(function ($model) {
+            if (! isset($this->connection)) {
+                $model->setConnection($model->newQueryWithoutScopes()->getConnection()->getName());
+            }
+
+            $model->save();
+
+            foreach ($model->getRelations() as $name => $items) {
+                if ($items instanceof Enumerable && $items->isEmpty()) {
+                    $model->unsetRelation($name);
+                }
+            }
+
+            $this->createChildren($model);
+        });
+    }
+
+    /**
+     * Create the children for the given model.
+     *
+     * @param  \Illuminate\Database\Eloquent\Model  $model
+     * @return void
+     */
+    protected function createChildren(Model $model)
+    {
+        Model::unguarded(function () use ($model) {
+            $this->has->each(function ($has) use ($model) {
+                $has->recycle($this->recycle)->createFor($model);
+            });
+        });
+    }
+
+    /**
+     * Make a single instance of the model.
+     *
+     * @param  (callable(array): array)|array  $attributes
+     * @return \Illuminate\Database\Eloquent\Model|TModel
+     */
+    public function makeOne($attributes = [])
+    {
+        return $this->count(null)->make($attributes);
+    }
+
+    /**
+     * Create a collection of models.
+     *
+     * @param  (callable(array): array)|array  $attributes
+     * @param  \Illuminate\Database\Eloquent\Model|null  $parent
+     * @return \Illuminate\Database\Eloquent\Collection|\Illuminate\Database\Eloquent\Model|TModel
+     */
+    public function make($attributes = [], ?Model $parent = null)
+    {
+        if (! empty($attributes)) {
+            return $this->state($attributes)->make([], $parent);
+        }
+
+        if ($this->count === null) {
+            return tap($this->makeInstance($parent), function ($instance) {
+                $this->callAfterMaking(collect([$instance]));
+            });
+        }
+
+        if ($this->count < 1) {
+            return $this->newModel()->newCollection();
+        }
+
+        $instances = $this->newModel()->newCollection(array_map(function () use ($parent) {
+            return $this->makeInstance($parent);
+        }, range(1, $this->count)));
+
+        $this->callAfterMaking($instances);
+
+        return $instances;
+    }
+
+    /**
+     * Make an instance of the model with the given attributes.
+     *
+     * @param  \Illuminate\Database\Eloquent\Model|null  $parent
+     * @return \Illuminate\Database\Eloquent\Model
+     */
+    protected function makeInstance(?Model $parent)
+    {
+        return Model::unguarded(function () use ($parent) {
+            return tap($this->newModel($this->getExpandedAttributes($parent)), function ($instance) {
+                if (isset($this->connection)) {
+                    $instance->setConnection($this->connection);
+                }
+            });
+        });
+    }
+
+    /**
+     * Get a raw attributes array for the model.
+     *
+     * @param  \Illuminate\Database\Eloquent\Model|null  $parent
+     * @return mixed
+     */
+    protected function getExpandedAttributes(?Model $parent)
+    {
+        return $this->expandAttributes($this->getRawAttributes($parent));
+    }
+
+    /**
+     * Get the raw attributes for the model as an array.
+     *
+     * @param  \Illuminate\Database\Eloquent\Model|null  $parent
+     * @return array
+     */
+    protected function getRawAttributes(?Model $parent)
+    {
+        return $this->states->pipe(function ($states) {
+            return $this->for->isEmpty() ? $states : new Collection(array_merge([function () {
+                return $this->parentResolvers();
+            }], $states->all()));
+        })->reduce(function ($carry, $state) use ($parent) {
+            if ($state instanceof Closure) {
+                $state = $state->bindTo($this);
+            }
+
+            return array_merge($carry, $state($carry, $parent));
+        }, $this->definition());
+    }
+
+    /**
+     * Create the parent relationship resolvers (as deferred Closures).
+     *
+     * @return array
+     */
+    protected function parentResolvers()
+    {
+        $model = $this->newModel();
+
+        return $this->for->map(function (BelongsToRelationship $for) use ($model) {
+            return $for->recycle($this->recycle)->attributesFor($model);
+        })->collapse()->all();
+    }
+
+    /**
+     * Expand all attributes to their underlying values.
+     *
+     * @param  array  $definition
+     * @return array
+     */
+    protected function expandAttributes(array $definition)
+    {
+        return collect($definition)
+            ->map($evaluateRelations = function ($attribute) {
+                if ($attribute instanceof self) {
+                    $attribute = $this->getRandomRecycledModel($attribute->modelName())
+                        ?? $attribute->recycle($this->recycle)->create()->getKey();
+                } elseif ($attribute instanceof Model) {
+                    $attribute = $attribute->getKey();
+                }
+
+                return $attribute;
+            })
+            ->map(function ($attribute, $key) use (&$definition, $evaluateRelations) {
+                if (is_callable($attribute) && ! is_string($attribute) && ! is_array($attribute)) {
+                    $attribute = $attribute($definition);
+                }
+
+                $attribute = $evaluateRelations($attribute);
+
+                $definition[$key] = $attribute;
+
+                return $attribute;
+            })
+            ->all();
+    }
+
+    /**
+     * Add a new state transformation to the model definition.
+     *
+     * @param  (callable(array, \Illuminate\Database\Eloquent\Model|null): array)|array  $state
+     * @return static
+     */
+    public function state($state)
+    {
+        return $this->newInstance([
+            'states' => $this->states->concat([
+                is_callable($state) ? $state : function () use ($state) {
+                    return $state;
+                },
+            ]),
+        ]);
+    }
+
+    /**
+     * Set a single model attribute.
+     *
+     * @param  string|int  $key
+     * @param  mixed  $value
+     * @return static
+     */
+    public function set($key, $value)
+    {
+        return $this->state([$key => $value]);
+    }
+
+    /**
+     * Add a new sequenced state transformation to the model definition.
+     *
+     * @param  mixed  ...$sequence
+     * @return static
+     */
+    public function sequence(...$sequence)
+    {
+        return $this->state(new Sequence(...$sequence));
+    }
+
+    /**
+     * Add a new sequenced state transformation to the model definition and update the pending creation count to the size of the sequence.
+     *
+     * @param  array  ...$sequence
+     * @return static
+     */
+    public function forEachSequence(...$sequence)
+    {
+        return $this->state(new Sequence(...$sequence))->count(count($sequence));
+    }
+
+    /**
+     * Add a new cross joined sequenced state transformation to the model definition.
+     *
+     * @param  array  ...$sequence
+     * @return static
+     */
+    public function crossJoinSequence(...$sequence)
+    {
+        return $this->state(new CrossJoinSequence(...$sequence));
+    }
+
+    /**
+     * Define a child relationship for the model.
+     *
+     * @param  \Illuminate\Database\Eloquent\Factories\Factory  $factory
+     * @param  string|null  $relationship
+     * @return static
+     */
+    public function has(self $factory, $relationship = null)
+    {
+        return $this->newInstance([
+            'has' => $this->has->concat([new Relationship(
+                $factory, $relationship ?? $this->guessRelationship($factory->modelName())
+            )]),
+        ]);
+    }
+
+    /**
+     * Attempt to guess the relationship name for a "has" relationship.
+     *
+     * @param  string  $related
+     * @return string
+     */
+    protected function guessRelationship(string $related)
+    {
+        $guess = Str::camel(Str::plural(class_basename($related)));
+
+        return method_exists($this->modelName(), $guess) ? $guess : Str::singular($guess);
+    }
+
+    /**
+     * Define an attached relationship for the model.
+     *
+     * @param  \Illuminate\Database\Eloquent\Factories\Factory|\Illuminate\Support\Collection|\Illuminate\Database\Eloquent\Model|array  $factory
+     * @param  (callable(): array)|array  $pivot
+     * @param  string|null  $relationship
+     * @return static
+     */
+    public function hasAttached($factory, $pivot = [], $relationship = null)
+    {
+        return $this->newInstance([
+            'has' => $this->has->concat([new BelongsToManyRelationship(
+                $factory,
+                $pivot,
+                $relationship ?? Str::camel(Str::plural(class_basename(
+                    $factory instanceof Factory
+                        ? $factory->modelName()
+                        : Collection::wrap($factory)->first()
+                )))
+            )]),
+        ]);
+    }
+
+    /**
+     * Define a parent relationship for the model.
+     *
+     * @param  \Illuminate\Database\Eloquent\Factories\Factory|\Illuminate\Database\Eloquent\Model  $factory
+     * @param  string|null  $relationship
+     * @return static
+     */
+    public function for($factory, $relationship = null)
+    {
+        return $this->newInstance(['for' => $this->for->concat([new BelongsToRelationship(
+            $factory,
+            $relationship ?? Str::camel(class_basename(
+                $factory instanceof Factory ? $factory->modelName() : $factory
+            ))
+        )])]);
+    }
+
+    /**
+     * Provide model instances to use instead of any nested factory calls when creating relationships.
+     *
+     * @param  \Illuminate\Database\Eloquent\Model|\Illuminate\Support\Collection|array  $model
+     * @return static
+     */
+    public function recycle($model)
+    {
+        // Group provided models by the type and merge them into existing recycle collection
+        return $this->newInstance([
+            'recycle' => $this->recycle
+                ->flatten()
+                ->merge(
+                    Collection::wrap($model instanceof Model ? func_get_args() : $model)
+                        ->flatten()
+                )->groupBy(fn ($model) => get_class($model)),
+        ]);
+    }
+
+    /**
+     * Retrieve a random model of a given type from previously provided models to recycle.
+     *
+     * @param  string  $modelClassName
+     * @return \Illuminate\Database\Eloquent\Model|null
+     */
+    public function getRandomRecycledModel($modelClassName)
+    {
+        return $this->recycle->get($modelClassName)?->random();
+    }
+
+    /**
+     * Add a new "after making" callback to the model definition.
+     *
+     * @param  \Closure(\Illuminate\Database\Eloquent\Model|TModel): mixed  $callback
+     * @return static
+     */
+    public function afterMaking(Closure $callback)
+    {
+        return $this->newInstance(['afterMaking' => $this->afterMaking->concat([$callback])]);
+    }
+
+    /**
+     * Add a new "after creating" callback to the model definition.
+     *
+     * @param  \Closure(\Illuminate\Database\Eloquent\Model|TModel): mixed  $callback
+     * @return static
+     */
+    public function afterCreating(Closure $callback)
+    {
+        return $this->newInstance(['afterCreating' => $this->afterCreating->concat([$callback])]);
+    }
+
+    /**
+     * Call the "after making" callbacks for the given model instances.
+     *
+     * @param  \Illuminate\Support\Collection  $instances
+     * @return void
+     */
+    protected function callAfterMaking(Collection $instances)
+    {
+        $instances->each(function ($model) {
+            $this->afterMaking->each(function ($callback) use ($model) {
+                $callback($model);
+            });
+        });
+    }
+
+    /**
+     * Call the "after creating" callbacks for the given model instances.
+     *
+     * @param  \Illuminate\Support\Collection  $instances
+     * @param  \Illuminate\Database\Eloquent\Model|null  $parent
+     * @return void
+     */
+    protected function callAfterCreating(Collection $instances, ?Model $parent = null)
+    {
+        $instances->each(function ($model) use ($parent) {
+            $this->afterCreating->each(function ($callback) use ($model, $parent) {
+                $callback($model, $parent);
+            });
+        });
+    }
+
+    /**
+     * Specify how many models should be generated.
+     *
+     * @param  int|null  $count
+     * @return static
+     */
+    public function count(?int $count)
+    {
+        return $this->newInstance(['count' => $count]);
+    }
+
+    /**
+     * Specify the database connection that should be used to generate models.
+     *
+     * @param  string  $connection
+     * @return static
+     */
+    public function connection(string $connection)
+    {
+        return $this->newInstance(['connection' => $connection]);
+    }
+
+    /**
+     * Create a new instance of the factory builder with the given mutated properties.
+     *
+     * @param  array  $arguments
+     * @return static
+     */
+    protected function newInstance(array $arguments = [])
+    {
+        return new static(...array_values(array_merge([
+            'count' => $this->count,
+            'states' => $this->states,
+            'has' => $this->has,
+            'for' => $this->for,
+            'afterMaking' => $this->afterMaking,
+            'afterCreating' => $this->afterCreating,
+            'connection' => $this->connection,
+            'recycle' => $this->recycle,
+        ], $arguments)));
+    }
+
+    /**
+     * Get a new model instance.
+     *
+     * @param  array  $attributes
+     * @return \Illuminate\Database\Eloquent\Model|TModel
+     */
+    public function newModel(array $attributes = [])
+    {
+        $model = $this->modelName();
+
+        return new $model($attributes);
+    }
+
+    /**
+     * Get the name of the model that is generated by the factory.
+     *
+     * @return class-string<\Illuminate\Database\Eloquent\Model|TModel>
+     */
+    public function modelName()
+    {
+        $resolver = static::$modelNameResolver ?? function (self $factory) {
+            $namespacedFactoryBasename = Str::replaceLast(
+                'Factory', '', Str::replaceFirst(static::$namespace, '', get_class($factory))
+            );
+
+            $factoryBasename = Str::replaceLast('Factory', '', class_basename($factory));
+
+            $appNamespace = static::appNamespace();
+
+            return class_exists($appNamespace.'Models\\'.$namespacedFactoryBasename)
+                        ? $appNamespace.'Models\\'.$namespacedFactoryBasename
+                        : $appNamespace.$factoryBasename;
+        };
+
+        return $this->model ?? $resolver($this);
+    }
+
+    /**
+     * Specify the callback that should be invoked to guess model names based on factory names.
+     *
+     * @param  callable(self): class-string<\Illuminate\Database\Eloquent\Model|TModel>  $callback
+     * @return void
+     */
+    public static function guessModelNamesUsing(callable $callback)
+    {
+        static::$modelNameResolver = $callback;
+    }
+
+    /**
+     * Specify the default namespace that contains the application's model factories.
+     *
+     * @param  string  $namespace
+     * @return void
+     */
+    public static function useNamespace(string $namespace)
+    {
+        static::$namespace = $namespace;
+    }
+
+    /**
+     * Get a new factory instance for the given model name.
+     *
+     * @param  class-string<\Illuminate\Database\Eloquent\Model>  $modelName
+     * @return \Illuminate\Database\Eloquent\Factories\Factory
+     */
+    public static function factoryForModel(string $modelName)
+    {
+        $factory = static::resolveFactoryName($modelName);
+
+        return $factory::new();
+    }
+
+    /**
+     * Specify the callback that should be invoked to guess factory names based on dynamic relationship names.
+     *
+     * @param  callable(class-string<\Illuminate\Database\Eloquent\Model>): class-string<\Illuminate\Database\Eloquent\Factories\Factory>  $callback
+     * @return void
+     */
+    public static function guessFactoryNamesUsing(callable $callback)
+    {
+        static::$factoryNameResolver = $callback;
+    }
+
+    /**
+     * Get a new Faker instance.
+     *
+     * @return \Faker\Generator
+     */
+    protected function withFaker()
+    {
+        return Container::getInstance()->make(Generator::class);
+    }
+
+    /**
+     * Get the factory name for the given model name.
+     *
+     * @param  class-string<\Illuminate\Database\Eloquent\Model>  $modelName
+     * @return class-string<\Illuminate\Database\Eloquent\Factories\Factory>
+     */
+    public static function resolveFactoryName(string $modelName)
+    {
+        $resolver = static::$factoryNameResolver ?? function (string $modelName) {
+            $appNamespace = static::appNamespace();
+
+            $modelName = Str::startsWith($modelName, $appNamespace.'Models\\')
+                ? Str::after($modelName, $appNamespace.'Models\\')
+                : Str::after($modelName, $appNamespace);
+
+            return static::$namespace.$modelName.'Factory';
+        };
+
+        return $resolver($modelName);
+    }
+
+    /**
+     * Get the application namespace for the application.
+     *
+     * @return string
+     */
+    protected static function appNamespace()
+    {
+        try {
+            return Container::getInstance()
+                            ->make(Application::class)
+                            ->getNamespace();
+        } catch (Throwable $e) {
+            return 'App\\';
+        }
+    }
+
+    /**
+     * Proxy dynamic factory methods onto their proper methods.
+     *
+     * @param  string  $method
+     * @param  array  $parameters
+     * @return mixed
+     */
+    public function __call($method, $parameters)
+    {
+        if (static::hasMacro($method)) {
+            return $this->macroCall($method, $parameters);
+        }
+
+        if ($method === 'trashed' && in_array(SoftDeletes::class, class_uses_recursive($this->modelName()))) {
+            return $this->state([
+                $this->newModel()->getDeletedAtColumn() => $parameters[0] ?? Carbon::now()->subDay(),
+            ]);
+        }
+
+        if (! Str::startsWith($method, ['for', 'has'])) {
+            static::throwBadMethodCallException($method);
+        }
+
+        $relationship = Str::camel(Str::substr($method, 3));
+
+        $relatedModel = get_class($this->newModel()->{$relationship}()->getRelated());
+
+        if (method_exists($relatedModel, 'newFactory')) {
+            $factory = $relatedModel::newFactory() ?? static::factoryForModel($relatedModel);
+        } else {
+            $factory = static::factoryForModel($relatedModel);
+        }
+
+        if (str_starts_with($method, 'for')) {
+            return $this->for($factory->state($parameters[0] ?? []), $relationship);
+        } elseif (str_starts_with($method, 'has')) {
+            return $this->has(
+                $factory
+                    ->count(is_numeric($parameters[0] ?? null) ? $parameters[0] : 1)
+                    ->state((is_callable($parameters[0] ?? null) || is_array($parameters[0] ?? null)) ? $parameters[0] : ($parameters[1] ?? [])),
+                $relationship
+            );
+        }
+    }
+}
diff --git a/vendor/illuminate/database/Eloquent/Factories/HasFactory.php b/vendor/illuminate/database/Eloquent/Factories/HasFactory.php
new file mode 100644
index 0000000..f10281d
--- /dev/null
+++ b/vendor/illuminate/database/Eloquent/Factories/HasFactory.php
@@ -0,0 +1,32 @@
+
+     */
+    public static function factory($count = null, $state = [])
+    {
+        $factory = static::newFactory() ?: Factory::factoryForModel(get_called_class());
+
+        return $factory
+                    ->count(is_numeric($count) ? $count : null)
+                    ->state(is_callable($count) || is_array($count) ? $count : $state);
+    }
+
+    /**
+     * Create a new factory instance for the model.
+     *
+     * @return \Illuminate\Database\Eloquent\Factories\Factory
+     */
+    protected static function newFactory()
+    {
+        //
+    }
+}
diff --git a/vendor/illuminate/database/Eloquent/Factories/Relationship.php b/vendor/illuminate/database/Eloquent/Factories/Relationship.php
new file mode 100644
index 0000000..3eb62da
--- /dev/null
+++ b/vendor/illuminate/database/Eloquent/Factories/Relationship.php
@@ -0,0 +1,75 @@
+factory = $factory;
+        $this->relationship = $relationship;
+    }
+
+    /**
+     * Create the child relationship for the given parent model.
+     *
+     * @param  \Illuminate\Database\Eloquent\Model  $parent
+     * @return void
+     */
+    public function createFor(Model $parent)
+    {
+        $relationship = $parent->{$this->relationship}();
+
+        if ($relationship instanceof MorphOneOrMany) {
+            $this->factory->state([
+                $relationship->getMorphType() => $relationship->getMorphClass(),
+                $relationship->getForeignKeyName() => $relationship->getParentKey(),
+            ])->create([], $parent);
+        } elseif ($relationship instanceof HasOneOrMany) {
+            $this->factory->state([
+                $relationship->getForeignKeyName() => $relationship->getParentKey(),
+            ])->create([], $parent);
+        } elseif ($relationship instanceof BelongsToMany) {
+            $relationship->attach($this->factory->create([], $parent));
+        }
+    }
+
+    /**
+     * Specify the model instances to always use when creating relationships.
+     *
+     * @param  \Illuminate\Support\Collection  $recycle
+     * @return $this
+     */
+    public function recycle($recycle)
+    {
+        $this->factory = $this->factory->recycle($recycle);
+
+        return $this;
+    }
+}
diff --git a/vendor/illuminate/database/Eloquent/Factories/Sequence.php b/vendor/illuminate/database/Eloquent/Factories/Sequence.php
new file mode 100644
index 0000000..e523fb3
--- /dev/null
+++ b/vendor/illuminate/database/Eloquent/Factories/Sequence.php
@@ -0,0 +1,63 @@
+sequence = $sequence;
+        $this->count = count($sequence);
+    }
+
+    /**
+     * Get the current count of the sequence items.
+     *
+     * @return int
+     */
+    public function count(): int
+    {
+        return $this->count;
+    }
+
+    /**
+     * Get the next value in the sequence.
+     *
+     * @return mixed
+     */
+    public function __invoke()
+    {
+        return tap(value($this->sequence[$this->index % $this->count], $this), function () {
+            $this->index = $this->index + 1;
+        });
+    }
+}
diff --git a/vendor/illuminate/database/Eloquent/HigherOrderBuilderProxy.php b/vendor/illuminate/database/Eloquent/HigherOrderBuilderProxy.php
new file mode 100644
index 0000000..16b49a1
--- /dev/null
+++ b/vendor/illuminate/database/Eloquent/HigherOrderBuilderProxy.php
@@ -0,0 +1,50 @@
+method = $method;
+        $this->builder = $builder;
+    }
+
+    /**
+     * Proxy a scope call onto the query builder.
+     *
+     * @param  string  $method
+     * @param  array  $parameters
+     * @return mixed
+     */
+    public function __call($method, $parameters)
+    {
+        return $this->builder->{$this->method}(function ($value) use ($method, $parameters) {
+            return $value->{$method}(...$parameters);
+        });
+    }
+}
diff --git a/vendor/illuminate/database/Eloquent/InvalidCastException.php b/vendor/illuminate/database/Eloquent/InvalidCastException.php
new file mode 100644
index 0000000..9d00eb3
--- /dev/null
+++ b/vendor/illuminate/database/Eloquent/InvalidCastException.php
@@ -0,0 +1,48 @@
+model = $class;
+        $this->column = $column;
+        $this->castType = $castType;
+    }
+}
diff --git a/vendor/illuminate/database/Eloquent/JsonEncodingException.php b/vendor/illuminate/database/Eloquent/JsonEncodingException.php
new file mode 100644
index 0000000..f62abd4
--- /dev/null
+++ b/vendor/illuminate/database/Eloquent/JsonEncodingException.php
@@ -0,0 +1,49 @@
+getKey().'] to JSON: '.$message);
+    }
+
+    /**
+     * Create a new JSON encoding exception for the resource.
+     *
+     * @param  \Illuminate\Http\Resources\Json\JsonResource  $resource
+     * @param  string  $message
+     * @return static
+     */
+    public static function forResource($resource, $message)
+    {
+        $model = $resource->resource;
+
+        return new static('Error encoding resource ['.get_class($resource).'] with model ['.get_class($model).'] with ID ['.$model->getKey().'] to JSON: '.$message);
+    }
+
+    /**
+     * Create a new JSON encoding exception for an attribute.
+     *
+     * @param  mixed  $model
+     * @param  mixed  $key
+     * @param  string  $message
+     * @return static
+     */
+    public static function forAttribute($model, $key, $message)
+    {
+        $class = get_class($model);
+
+        return new static("Unable to encode attribute [{$key}] for model [{$class}] to JSON: {$message}.");
+    }
+}
diff --git a/vendor/illuminate/database/Eloquent/MassAssignmentException.php b/vendor/illuminate/database/Eloquent/MassAssignmentException.php
new file mode 100755
index 0000000..7c81aae
--- /dev/null
+++ b/vendor/illuminate/database/Eloquent/MassAssignmentException.php
@@ -0,0 +1,10 @@
+prunable(), function ($query) use ($chunkSize) {
+            $query->when(! $query->getQuery()->limit, function ($query) use ($chunkSize) {
+                $query->limit($chunkSize);
+            });
+        });
+
+        $total = 0;
+
+        do {
+            $total += $count = in_array(SoftDeletes::class, class_uses_recursive(get_class($this)))
+                        ? $query->forceDelete()
+                        : $query->delete();
+
+            if ($count > 0) {
+                event(new ModelsPruned(static::class, $total));
+            }
+        } while ($count > 0);
+
+        return $total;
+    }
+
+    /**
+     * Get the prunable model query.
+     *
+     * @return \Illuminate\Database\Eloquent\Builder
+     */
+    public function prunable()
+    {
+        throw new LogicException('Please implement the prunable method on your model.');
+    }
+}
diff --git a/vendor/illuminate/database/Eloquent/MissingAttributeException.php b/vendor/illuminate/database/Eloquent/MissingAttributeException.php
new file mode 100755
index 0000000..87935c1
--- /dev/null
+++ b/vendor/illuminate/database/Eloquent/MissingAttributeException.php
@@ -0,0 +1,23 @@
+bootIfNotBooted();
+
+        $this->initializeTraits();
+
+        $this->syncOriginal();
+
+        $this->fill($attributes);
+    }
+
+    /**
+     * Check if the model needs to be booted and if so, do it.
+     *
+     * @return void
+     */
+    protected function bootIfNotBooted()
+    {
+        if (! isset(static::$booted[static::class])) {
+            static::$booted[static::class] = true;
+
+            $this->fireModelEvent('booting', false);
+
+            static::booting();
+            static::boot();
+            static::booted();
+
+            $this->fireModelEvent('booted', false);
+        }
+    }
+
+    /**
+     * Perform any actions required before the model boots.
+     *
+     * @return void
+     */
+    protected static function booting()
+    {
+        //
+    }
+
+    /**
+     * Bootstrap the model and its traits.
+     *
+     * @return void
+     */
+    protected static function boot()
+    {
+        static::bootTraits();
+    }
+
+    /**
+     * Boot all of the bootable traits on the model.
+     *
+     * @return void
+     */
+    protected static function bootTraits()
+    {
+        $class = static::class;
+
+        $booted = [];
+
+        static::$traitInitializers[$class] = [];
+
+        foreach (class_uses_recursive($class) as $trait) {
+            $method = 'boot'.class_basename($trait);
+
+            if (method_exists($class, $method) && ! in_array($method, $booted)) {
+                forward_static_call([$class, $method]);
+
+                $booted[] = $method;
+            }
+
+            if (method_exists($class, $method = 'initialize'.class_basename($trait))) {
+                static::$traitInitializers[$class][] = $method;
+
+                static::$traitInitializers[$class] = array_unique(
+                    static::$traitInitializers[$class]
+                );
+            }
+        }
+    }
+
+    /**
+     * Initialize any initializable traits on the model.
+     *
+     * @return void
+     */
+    protected function initializeTraits()
+    {
+        foreach (static::$traitInitializers[static::class] as $method) {
+            $this->{$method}();
+        }
+    }
+
+    /**
+     * Perform any actions required after the model boots.
+     *
+     * @return void
+     */
+    protected static function booted()
+    {
+        //
+    }
+
+    /**
+     * Clear the list of booted models so they will be re-booted.
+     *
+     * @return void
+     */
+    public static function clearBootedModels()
+    {
+        static::$booted = [];
+
+        static::$globalScopes = [];
+    }
+
+    /**
+     * Disables relationship model touching for the current class during given callback scope.
+     *
+     * @param  callable  $callback
+     * @return void
+     */
+    public static function withoutTouching(callable $callback)
+    {
+        static::withoutTouchingOn([static::class], $callback);
+    }
+
+    /**
+     * Disables relationship model touching for the given model classes during given callback scope.
+     *
+     * @param  array  $models
+     * @param  callable  $callback
+     * @return void
+     */
+    public static function withoutTouchingOn(array $models, callable $callback)
+    {
+        static::$ignoreOnTouch = array_values(array_merge(static::$ignoreOnTouch, $models));
+
+        try {
+            $callback();
+        } finally {
+            static::$ignoreOnTouch = array_values(array_diff(static::$ignoreOnTouch, $models));
+        }
+    }
+
+    /**
+     * Determine if the given model is ignoring touches.
+     *
+     * @param  string|null  $class
+     * @return bool
+     */
+    public static function isIgnoringTouch($class = null)
+    {
+        $class = $class ?: static::class;
+
+        if (! get_class_vars($class)['timestamps'] || ! $class::UPDATED_AT) {
+            return true;
+        }
+
+        foreach (static::$ignoreOnTouch as $ignoredClass) {
+            if ($class === $ignoredClass || is_subclass_of($class, $ignoredClass)) {
+                return true;
+            }
+        }
+
+        return false;
+    }
+
+    /**
+     * Indicate that models should prevent lazy loading, silently discarding attributes, and accessing missing attributes.
+     *
+     * @param  bool  $shouldBeStrict
+     * @return void
+     */
+    public static function shouldBeStrict(bool $shouldBeStrict = true)
+    {
+        static::preventLazyLoading($shouldBeStrict);
+        static::preventSilentlyDiscardingAttributes($shouldBeStrict);
+        static::preventAccessingMissingAttributes($shouldBeStrict);
+    }
+
+    /**
+     * Prevent model relationships from being lazy loaded.
+     *
+     * @param  bool  $value
+     * @return void
+     */
+    public static function preventLazyLoading($value = true)
+    {
+        static::$modelsShouldPreventLazyLoading = $value;
+    }
+
+    /**
+     * Register a callback that is responsible for handling lazy loading violations.
+     *
+     * @param  callable|null  $callback
+     * @return void
+     */
+    public static function handleLazyLoadingViolationUsing(?callable $callback)
+    {
+        static::$lazyLoadingViolationCallback = $callback;
+    }
+
+    /**
+     * Prevent non-fillable attributes from being silently discarded.
+     *
+     * @param  bool  $value
+     * @return void
+     */
+    public static function preventSilentlyDiscardingAttributes($value = true)
+    {
+        static::$modelsShouldPreventSilentlyDiscardingAttributes = $value;
+    }
+
+    /**
+     * Register a callback that is responsible for handling discarded attribute violations.
+     *
+     * @param  callable|null  $callback
+     * @return void
+     */
+    public static function handleDiscardedAttributeViolationUsing(?callable $callback)
+    {
+        static::$discardedAttributeViolationCallback = $callback;
+    }
+
+    /**
+     * Prevent accessing missing attributes on retrieved models.
+     *
+     * @param  bool  $value
+     * @return void
+     */
+    public static function preventAccessingMissingAttributes($value = true)
+    {
+        static::$modelsShouldPreventAccessingMissingAttributes = $value;
+    }
+
+    /**
+     * Register a callback that is responsible for handling lazy loading violations.
+     *
+     * @param  callable|null  $callback
+     * @return void
+     */
+    public static function handleMissingAttributeViolationUsing(?callable $callback)
+    {
+        static::$missingAttributeViolationCallback = $callback;
+    }
+
+    /**
+     * Execute a callback without broadcasting any model events for all model types.
+     *
+     * @param  callable  $callback
+     * @return mixed
+     */
+    public static function withoutBroadcasting(callable $callback)
+    {
+        $isBroadcasting = static::$isBroadcasting;
+
+        static::$isBroadcasting = false;
+
+        try {
+            return $callback();
+        } finally {
+            static::$isBroadcasting = $isBroadcasting;
+        }
+    }
+
+    /**
+     * Fill the model with an array of attributes.
+     *
+     * @param  array  $attributes
+     * @return $this
+     *
+     * @throws \Illuminate\Database\Eloquent\MassAssignmentException
+     */
+    public function fill(array $attributes)
+    {
+        $totallyGuarded = $this->totallyGuarded();
+
+        $fillable = $this->fillableFromArray($attributes);
+
+        foreach ($fillable as $key => $value) {
+            // The developers may choose to place some attributes in the "fillable" array
+            // which means only those attributes may be set through mass assignment to
+            // the model, and all others will just get ignored for security reasons.
+            if ($this->isFillable($key)) {
+                $this->setAttribute($key, $value);
+            } elseif ($totallyGuarded || static::preventsSilentlyDiscardingAttributes()) {
+                if (isset(static::$discardedAttributeViolationCallback)) {
+                    call_user_func(static::$discardedAttributeViolationCallback, $this, [$key]);
+                } else {
+                    throw new MassAssignmentException(sprintf(
+                        'Add [%s] to fillable property to allow mass assignment on [%s].',
+                        $key, get_class($this)
+                    ));
+                }
+            }
+        }
+
+        if (count($attributes) !== count($fillable) &&
+            static::preventsSilentlyDiscardingAttributes()) {
+            $keys = array_diff(array_keys($attributes), array_keys($fillable));
+
+            if (isset(static::$discardedAttributeViolationCallback)) {
+                call_user_func(static::$discardedAttributeViolationCallback, $this, $keys);
+            } else {
+                throw new MassAssignmentException(sprintf(
+                    'Add fillable property [%s] to allow mass assignment on [%s].',
+                    implode(', ', $keys),
+                    get_class($this)
+                ));
+            }
+        }
+
+        return $this;
+    }
+
+    /**
+     * Fill the model with an array of attributes. Force mass assignment.
+     *
+     * @param  array  $attributes
+     * @return $this
+     */
+    public function forceFill(array $attributes)
+    {
+        return static::unguarded(fn () => $this->fill($attributes));
+    }
+
+    /**
+     * Qualify the given column name by the model's table.
+     *
+     * @param  string  $column
+     * @return string
+     */
+    public function qualifyColumn($column)
+    {
+        if (str_contains($column, '.')) {
+            return $column;
+        }
+
+        return $this->getTable().'.'.$column;
+    }
+
+    /**
+     * Qualify the given columns with the model's table.
+     *
+     * @param  array  $columns
+     * @return array
+     */
+    public function qualifyColumns($columns)
+    {
+        return collect($columns)->map(function ($column) {
+            return $this->qualifyColumn($column);
+        })->all();
+    }
+
+    /**
+     * Create a new instance of the given model.
+     *
+     * @param  array  $attributes
+     * @param  bool  $exists
+     * @return static
+     */
+    public function newInstance($attributes = [], $exists = false)
+    {
+        // This method just provides a convenient way for us to generate fresh model
+        // instances of this current model. It is particularly useful during the
+        // hydration of new objects via the Eloquent query builder instances.
+        $model = new static;
+
+        $model->exists = $exists;
+
+        $model->setConnection(
+            $this->getConnectionName()
+        );
+
+        $model->setTable($this->getTable());
+
+        $model->mergeCasts($this->casts);
+
+        $model->fill((array) $attributes);
+
+        return $model;
+    }
+
+    /**
+     * Create a new model instance that is existing.
+     *
+     * @param  array  $attributes
+     * @param  string|null  $connection
+     * @return static
+     */
+    public function newFromBuilder($attributes = [], $connection = null)
+    {
+        $model = $this->newInstance([], true);
+
+        $model->setRawAttributes((array) $attributes, true);
+
+        $model->setConnection($connection ?: $this->getConnectionName());
+
+        $model->fireModelEvent('retrieved', false);
+
+        return $model;
+    }
+
+    /**
+     * Begin querying the model on a given connection.
+     *
+     * @param  string|null  $connection
+     * @return \Illuminate\Database\Eloquent\Builder
+     */
+    public static function on($connection = null)
+    {
+        // First we will just create a fresh instance of this model, and then we can set the
+        // connection on the model so that it is used for the queries we execute, as well
+        // as being set on every relation we retrieve without a custom connection name.
+        $instance = new static;
+
+        $instance->setConnection($connection);
+
+        return $instance->newQuery();
+    }
+
+    /**
+     * Begin querying the model on the write connection.
+     *
+     * @return \Illuminate\Database\Eloquent\Builder
+     */
+    public static function onWriteConnection()
+    {
+        return static::query()->useWritePdo();
+    }
+
+    /**
+     * Get all of the models from the database.
+     *
+     * @param  array|string  $columns
+     * @return \Illuminate\Database\Eloquent\Collection
+     */
+    public static function all($columns = ['*'])
+    {
+        return static::query()->get(
+            is_array($columns) ? $columns : func_get_args()
+        );
+    }
+
+    /**
+     * Begin querying a model with eager loading.
+     *
+     * @param  array|string  $relations
+     * @return \Illuminate\Database\Eloquent\Builder
+     */
+    public static function with($relations)
+    {
+        return static::query()->with(
+            is_string($relations) ? func_get_args() : $relations
+        );
+    }
+
+    /**
+     * Eager load relations on the model.
+     *
+     * @param  array|string  $relations
+     * @return $this
+     */
+    public function load($relations)
+    {
+        $query = $this->newQueryWithoutRelationships()->with(
+            is_string($relations) ? func_get_args() : $relations
+        );
+
+        $query->eagerLoadRelations([$this]);
+
+        return $this;
+    }
+
+    /**
+     * Eager load relationships on the polymorphic relation of a model.
+     *
+     * @param  string  $relation
+     * @param  array  $relations
+     * @return $this
+     */
+    public function loadMorph($relation, $relations)
+    {
+        if (! $this->{$relation}) {
+            return $this;
+        }
+
+        $className = get_class($this->{$relation});
+
+        $this->{$relation}->load($relations[$className] ?? []);
+
+        return $this;
+    }
+
+    /**
+     * Eager load relations on the model if they are not already eager loaded.
+     *
+     * @param  array|string  $relations
+     * @return $this
+     */
+    public function loadMissing($relations)
+    {
+        $relations = is_string($relations) ? func_get_args() : $relations;
+
+        $this->newCollection([$this])->loadMissing($relations);
+
+        return $this;
+    }
+
+    /**
+     * Eager load relation's column aggregations on the model.
+     *
+     * @param  array|string  $relations
+     * @param  string  $column
+     * @param  string  $function
+     * @return $this
+     */
+    public function loadAggregate($relations, $column, $function = null)
+    {
+        $this->newCollection([$this])->loadAggregate($relations, $column, $function);
+
+        return $this;
+    }
+
+    /**
+     * Eager load relation counts on the model.
+     *
+     * @param  array|string  $relations
+     * @return $this
+     */
+    public function loadCount($relations)
+    {
+        $relations = is_string($relations) ? func_get_args() : $relations;
+
+        return $this->loadAggregate($relations, '*', 'count');
+    }
+
+    /**
+     * Eager load relation max column values on the model.
+     *
+     * @param  array|string  $relations
+     * @param  string  $column
+     * @return $this
+     */
+    public function loadMax($relations, $column)
+    {
+        return $this->loadAggregate($relations, $column, 'max');
+    }
+
+    /**
+     * Eager load relation min column values on the model.
+     *
+     * @param  array|string  $relations
+     * @param  string  $column
+     * @return $this
+     */
+    public function loadMin($relations, $column)
+    {
+        return $this->loadAggregate($relations, $column, 'min');
+    }
+
+    /**
+     * Eager load relation's column summations on the model.
+     *
+     * @param  array|string  $relations
+     * @param  string  $column
+     * @return $this
+     */
+    public function loadSum($relations, $column)
+    {
+        return $this->loadAggregate($relations, $column, 'sum');
+    }
+
+    /**
+     * Eager load relation average column values on the model.
+     *
+     * @param  array|string  $relations
+     * @param  string  $column
+     * @return $this
+     */
+    public function loadAvg($relations, $column)
+    {
+        return $this->loadAggregate($relations, $column, 'avg');
+    }
+
+    /**
+     * Eager load related model existence values on the model.
+     *
+     * @param  array|string  $relations
+     * @return $this
+     */
+    public function loadExists($relations)
+    {
+        return $this->loadAggregate($relations, '*', 'exists');
+    }
+
+    /**
+     * Eager load relationship column aggregation on the polymorphic relation of a model.
+     *
+     * @param  string  $relation
+     * @param  array  $relations
+     * @param  string  $column
+     * @param  string  $function
+     * @return $this
+     */
+    public function loadMorphAggregate($relation, $relations, $column, $function = null)
+    {
+        if (! $this->{$relation}) {
+            return $this;
+        }
+
+        $className = get_class($this->{$relation});
+
+        $this->{$relation}->loadAggregate($relations[$className] ?? [], $column, $function);
+
+        return $this;
+    }
+
+    /**
+     * Eager load relationship counts on the polymorphic relation of a model.
+     *
+     * @param  string  $relation
+     * @param  array  $relations
+     * @return $this
+     */
+    public function loadMorphCount($relation, $relations)
+    {
+        return $this->loadMorphAggregate($relation, $relations, '*', 'count');
+    }
+
+    /**
+     * Eager load relationship max column values on the polymorphic relation of a model.
+     *
+     * @param  string  $relation
+     * @param  array  $relations
+     * @param  string  $column
+     * @return $this
+     */
+    public function loadMorphMax($relation, $relations, $column)
+    {
+        return $this->loadMorphAggregate($relation, $relations, $column, 'max');
+    }
+
+    /**
+     * Eager load relationship min column values on the polymorphic relation of a model.
+     *
+     * @param  string  $relation
+     * @param  array  $relations
+     * @param  string  $column
+     * @return $this
+     */
+    public function loadMorphMin($relation, $relations, $column)
+    {
+        return $this->loadMorphAggregate($relation, $relations, $column, 'min');
+    }
+
+    /**
+     * Eager load relationship column summations on the polymorphic relation of a model.
+     *
+     * @param  string  $relation
+     * @param  array  $relations
+     * @param  string  $column
+     * @return $this
+     */
+    public function loadMorphSum($relation, $relations, $column)
+    {
+        return $this->loadMorphAggregate($relation, $relations, $column, 'sum');
+    }
+
+    /**
+     * Eager load relationship average column values on the polymorphic relation of a model.
+     *
+     * @param  string  $relation
+     * @param  array  $relations
+     * @param  string  $column
+     * @return $this
+     */
+    public function loadMorphAvg($relation, $relations, $column)
+    {
+        return $this->loadMorphAggregate($relation, $relations, $column, 'avg');
+    }
+
+    /**
+     * Increment a column's value by a given amount.
+     *
+     * @param  string  $column
+     * @param  float|int  $amount
+     * @param  array  $extra
+     * @return int
+     */
+    protected function increment($column, $amount = 1, array $extra = [])
+    {
+        return $this->incrementOrDecrement($column, $amount, $extra, 'increment');
+    }
+
+    /**
+     * Decrement a column's value by a given amount.
+     *
+     * @param  string  $column
+     * @param  float|int  $amount
+     * @param  array  $extra
+     * @return int
+     */
+    protected function decrement($column, $amount = 1, array $extra = [])
+    {
+        return $this->incrementOrDecrement($column, $amount, $extra, 'decrement');
+    }
+
+    /**
+     * Run the increment or decrement method on the model.
+     *
+     * @param  string  $column
+     * @param  float|int  $amount
+     * @param  array  $extra
+     * @param  string  $method
+     * @return int
+     */
+    protected function incrementOrDecrement($column, $amount, $extra, $method)
+    {
+        $query = $this->newQueryWithoutRelationships();
+
+        if (! $this->exists) {
+            return $query->{$method}($column, $amount, $extra);
+        }
+
+        $this->{$column} = $this->isClassDeviable($column)
+            ? $this->deviateClassCastableAttribute($method, $column, $amount)
+            : $this->{$column} + ($method === 'increment' ? $amount : $amount * -1);
+
+        $this->forceFill($extra);
+
+        if ($this->fireModelEvent('updating') === false) {
+            return false;
+        }
+
+        return tap($this->setKeysForSaveQuery($query)->{$method}($column, $amount, $extra), function () use ($column) {
+            $this->syncChanges();
+
+            $this->fireModelEvent('updated', false);
+
+            $this->syncOriginalAttribute($column);
+        });
+    }
+
+    /**
+     * Update the model in the database.
+     *
+     * @param  array  $attributes
+     * @param  array  $options
+     * @return bool
+     */
+    public function update(array $attributes = [], array $options = [])
+    {
+        if (! $this->exists) {
+            return false;
+        }
+
+        return $this->fill($attributes)->save($options);
+    }
+
+    /**
+     * Update the model in the database within a transaction.
+     *
+     * @param  array  $attributes
+     * @param  array  $options
+     * @return bool
+     *
+     * @throws \Throwable
+     */
+    public function updateOrFail(array $attributes = [], array $options = [])
+    {
+        if (! $this->exists) {
+            return false;
+        }
+
+        return $this->fill($attributes)->saveOrFail($options);
+    }
+
+    /**
+     * Update the model in the database without raising any events.
+     *
+     * @param  array  $attributes
+     * @param  array  $options
+     * @return bool
+     */
+    public function updateQuietly(array $attributes = [], array $options = [])
+    {
+        if (! $this->exists) {
+            return false;
+        }
+
+        return $this->fill($attributes)->saveQuietly($options);
+    }
+
+    /**
+     * Increment a column's value by a given amount without raising any events.
+     *
+     * @param  string  $column
+     * @param  float|int  $amount
+     * @param  array  $extra
+     * @return int
+     */
+    protected function incrementQuietly($column, $amount = 1, array $extra = [])
+    {
+        return static::withoutEvents(function () use ($column, $amount, $extra) {
+            return $this->incrementOrDecrement($column, $amount, $extra, 'increment');
+        });
+    }
+
+    /**
+     * Decrement a column's value by a given amount without raising any events.
+     *
+     * @param  string  $column
+     * @param  float|int  $amount
+     * @param  array  $extra
+     * @return int
+     */
+    protected function decrementQuietly($column, $amount = 1, array $extra = [])
+    {
+        return static::withoutEvents(function () use ($column, $amount, $extra) {
+            return $this->incrementOrDecrement($column, $amount, $extra, 'decrement');
+        });
+    }
+
+    /**
+     * Save the model and all of its relationships.
+     *
+     * @return bool
+     */
+    public function push()
+    {
+        if (! $this->save()) {
+            return false;
+        }
+
+        // To sync all of the relationships to the database, we will simply spin through
+        // the relationships and save each model via this "push" method, which allows
+        // us to recurse into all of these nested relations for the model instance.
+        foreach ($this->relations as $models) {
+            $models = $models instanceof Collection
+                ? $models->all() : [$models];
+
+            foreach (array_filter($models) as $model) {
+                if (! $model->push()) {
+                    return false;
+                }
+            }
+        }
+
+        return true;
+    }
+
+    /**
+     * Save the model and all of its relationships without raising any events to the parent model.
+     *
+     * @return bool
+     */
+    public function pushQuietly()
+    {
+        return static::withoutEvents(fn () => $this->push());
+    }
+
+    /**
+     * Save the model to the database without raising any events.
+     *
+     * @param  array  $options
+     * @return bool
+     */
+    public function saveQuietly(array $options = [])
+    {
+        return static::withoutEvents(fn () => $this->save($options));
+    }
+
+    /**
+     * Save the model to the database.
+     *
+     * @param  array  $options
+     * @return bool
+     */
+    public function save(array $options = [])
+    {
+        $this->mergeAttributesFromCachedCasts();
+
+        $query = $this->newModelQuery();
+
+        // If the "saving" event returns false we'll bail out of the save and return
+        // false, indicating that the save failed. This provides a chance for any
+        // listeners to cancel save operations if validations fail or whatever.
+        if ($this->fireModelEvent('saving') === false) {
+            return false;
+        }
+
+        // If the model already exists in the database we can just update our record
+        // that is already in this database using the current IDs in this "where"
+        // clause to only update this model. Otherwise, we'll just insert them.
+        if ($this->exists) {
+            $saved = $this->isDirty() ?
+                $this->performUpdate($query) : true;
+        }
+
+        // If the model is brand new, we'll insert it into our database and set the
+        // ID attribute on the model to the value of the newly inserted row's ID
+        // which is typically an auto-increment value managed by the database.
+        else {
+            $saved = $this->performInsert($query);
+
+            if (! $this->getConnectionName() &&
+                $connection = $query->getConnection()) {
+                $this->setConnection($connection->getName());
+            }
+        }
+
+        // If the model is successfully saved, we need to do a few more things once
+        // that is done. We will call the "saved" method here to run any actions
+        // we need to happen after a model gets successfully saved right here.
+        if ($saved) {
+            $this->finishSave($options);
+        }
+
+        return $saved;
+    }
+
+    /**
+     * Save the model to the database within a transaction.
+     *
+     * @param  array  $options
+     * @return bool
+     *
+     * @throws \Throwable
+     */
+    public function saveOrFail(array $options = [])
+    {
+        return $this->getConnection()->transaction(fn () => $this->save($options));
+    }
+
+    /**
+     * Perform any actions that are necessary after the model is saved.
+     *
+     * @param  array  $options
+     * @return void
+     */
+    protected function finishSave(array $options)
+    {
+        $this->fireModelEvent('saved', false);
+
+        if ($this->isDirty() && ($options['touch'] ?? true)) {
+            $this->touchOwners();
+        }
+
+        $this->syncOriginal();
+    }
+
+    /**
+     * Perform a model update operation.
+     *
+     * @param  \Illuminate\Database\Eloquent\Builder  $query
+     * @return bool
+     */
+    protected function performUpdate(Builder $query)
+    {
+        // If the updating event returns false, we will cancel the update operation so
+        // developers can hook Validation systems into their models and cancel this
+        // operation if the model does not pass validation. Otherwise, we update.
+        if ($this->fireModelEvent('updating') === false) {
+            return false;
+        }
+
+        // First we need to create a fresh query instance and touch the creation and
+        // update timestamp on the model which are maintained by us for developer
+        // convenience. Then we will just continue saving the model instances.
+        if ($this->usesTimestamps()) {
+            $this->updateTimestamps();
+        }
+
+        // Once we have run the update operation, we will fire the "updated" event for
+        // this model instance. This will allow developers to hook into these after
+        // models are updated, giving them a chance to do any special processing.
+        $dirty = $this->getDirty();
+
+        if (count($dirty) > 0) {
+            $this->setKeysForSaveQuery($query)->update($dirty);
+
+            $this->syncChanges();
+
+            $this->fireModelEvent('updated', false);
+        }
+
+        return true;
+    }
+
+    /**
+     * Set the keys for a select query.
+     *
+     * @param  \Illuminate\Database\Eloquent\Builder  $query
+     * @return \Illuminate\Database\Eloquent\Builder
+     */
+    protected function setKeysForSelectQuery($query)
+    {
+        $query->where($this->getKeyName(), '=', $this->getKeyForSelectQuery());
+
+        return $query;
+    }
+
+    /**
+     * Get the primary key value for a select query.
+     *
+     * @return mixed
+     */
+    protected function getKeyForSelectQuery()
+    {
+        return $this->original[$this->getKeyName()] ?? $this->getKey();
+    }
+
+    /**
+     * Set the keys for a save update query.
+     *
+     * @param  \Illuminate\Database\Eloquent\Builder  $query
+     * @return \Illuminate\Database\Eloquent\Builder
+     */
+    protected function setKeysForSaveQuery($query)
+    {
+        $query->where($this->getKeyName(), '=', $this->getKeyForSaveQuery());
+
+        return $query;
+    }
+
+    /**
+     * Get the primary key value for a save query.
+     *
+     * @return mixed
+     */
+    protected function getKeyForSaveQuery()
+    {
+        return $this->original[$this->getKeyName()] ?? $this->getKey();
+    }
+
+    /**
+     * Perform a model insert operation.
+     *
+     * @param  \Illuminate\Database\Eloquent\Builder  $query
+     * @return bool
+     */
+    protected function performInsert(Builder $query)
+    {
+        if ($this->fireModelEvent('creating') === false) {
+            return false;
+        }
+
+        // First we'll need to create a fresh query instance and touch the creation and
+        // update timestamps on this model, which are maintained by us for developer
+        // convenience. After, we will just continue saving these model instances.
+        if ($this->usesTimestamps()) {
+            $this->updateTimestamps();
+        }
+
+        // If the model has an incrementing key, we can use the "insertGetId" method on
+        // the query builder, which will give us back the final inserted ID for this
+        // table from the database. Not all tables have to be incrementing though.
+        $attributes = $this->getAttributesForInsert();
+
+        if ($this->getIncrementing()) {
+            $this->insertAndSetId($query, $attributes);
+        }
+
+        // If the table isn't incrementing we'll simply insert these attributes as they
+        // are. These attribute arrays must contain an "id" column previously placed
+        // there by the developer as the manually determined key for these models.
+        else {
+            if (empty($attributes)) {
+                return true;
+            }
+
+            $query->insert($attributes);
+        }
+
+        // We will go ahead and set the exists property to true, so that it is set when
+        // the created event is fired, just in case the developer tries to update it
+        // during the event. This will allow them to do so and run an update here.
+        $this->exists = true;
+
+        $this->wasRecentlyCreated = true;
+
+        $this->fireModelEvent('created', false);
+
+        return true;
+    }
+
+    /**
+     * Insert the given attributes and set the ID on the model.
+     *
+     * @param  \Illuminate\Database\Eloquent\Builder  $query
+     * @param  array  $attributes
+     * @return void
+     */
+    protected function insertAndSetId(Builder $query, $attributes)
+    {
+        $id = $query->insertGetId($attributes, $keyName = $this->getKeyName());
+
+        $this->setAttribute($keyName, $id);
+    }
+
+    /**
+     * Destroy the models for the given IDs.
+     *
+     * @param  \Illuminate\Support\Collection|array|int|string  $ids
+     * @return int
+     */
+    public static function destroy($ids)
+    {
+        if ($ids instanceof EloquentCollection) {
+            $ids = $ids->modelKeys();
+        }
+
+        if ($ids instanceof BaseCollection) {
+            $ids = $ids->all();
+        }
+
+        $ids = is_array($ids) ? $ids : func_get_args();
+
+        if (count($ids) === 0) {
+            return 0;
+        }
+
+        // We will actually pull the models from the database table and call delete on
+        // each of them individually so that their events get fired properly with a
+        // correct set of attributes in case the developers wants to check these.
+        $key = ($instance = new static)->getKeyName();
+
+        $count = 0;
+
+        foreach ($instance->whereIn($key, $ids)->get() as $model) {
+            if ($model->delete()) {
+                $count++;
+            }
+        }
+
+        return $count;
+    }
+
+    /**
+     * Delete the model from the database.
+     *
+     * @return bool|null
+     *
+     * @throws \LogicException
+     */
+    public function delete()
+    {
+        $this->mergeAttributesFromCachedCasts();
+
+        if (is_null($this->getKeyName())) {
+            throw new LogicException('No primary key defined on model.');
+        }
+
+        // If the model doesn't exist, there is nothing to delete so we'll just return
+        // immediately and not do anything else. Otherwise, we will continue with a
+        // deletion process on the model, firing the proper events, and so forth.
+        if (! $this->exists) {
+            return;
+        }
+
+        if ($this->fireModelEvent('deleting') === false) {
+            return false;
+        }
+
+        // Here, we'll touch the owning models, verifying these timestamps get updated
+        // for the models. This will allow any caching to get broken on the parents
+        // by the timestamp. Then we will go ahead and delete the model instance.
+        $this->touchOwners();
+
+        $this->performDeleteOnModel();
+
+        // Once the model has been deleted, we will fire off the deleted event so that
+        // the developers may hook into post-delete operations. We will then return
+        // a boolean true as the delete is presumably successful on the database.
+        $this->fireModelEvent('deleted', false);
+
+        return true;
+    }
+
+    /**
+     * Delete the model from the database without raising any events.
+     *
+     * @return bool
+     */
+    public function deleteQuietly()
+    {
+        return static::withoutEvents(fn () => $this->delete());
+    }
+
+    /**
+     * Delete the model from the database within a transaction.
+     *
+     * @return bool|null
+     *
+     * @throws \Throwable
+     */
+    public function deleteOrFail()
+    {
+        if (! $this->exists) {
+            return false;
+        }
+
+        return $this->getConnection()->transaction(fn () => $this->delete());
+    }
+
+    /**
+     * Force a hard delete on a soft deleted model.
+     *
+     * This method protects developers from running forceDelete when the trait is missing.
+     *
+     * @return bool|null
+     */
+    public function forceDelete()
+    {
+        return $this->delete();
+    }
+
+    /**
+     * Perform the actual delete query on this model instance.
+     *
+     * @return void
+     */
+    protected function performDeleteOnModel()
+    {
+        $this->setKeysForSaveQuery($this->newModelQuery())->delete();
+
+        $this->exists = false;
+    }
+
+    /**
+     * Begin querying the model.
+     *
+     * @return \Illuminate\Database\Eloquent\Builder
+     */
+    public static function query()
+    {
+        return (new static)->newQuery();
+    }
+
+    /**
+     * Get a new query builder for the model's table.
+     *
+     * @return \Illuminate\Database\Eloquent\Builder
+     */
+    public function newQuery()
+    {
+        return $this->registerGlobalScopes($this->newQueryWithoutScopes());
+    }
+
+    /**
+     * Get a new query builder that doesn't have any global scopes or eager loading.
+     *
+     * @return \Illuminate\Database\Eloquent\Builder|static
+     */
+    public function newModelQuery()
+    {
+        return $this->newEloquentBuilder(
+            $this->newBaseQueryBuilder()
+        )->setModel($this);
+    }
+
+    /**
+     * Get a new query builder with no relationships loaded.
+     *
+     * @return \Illuminate\Database\Eloquent\Builder
+     */
+    public function newQueryWithoutRelationships()
+    {
+        return $this->registerGlobalScopes($this->newModelQuery());
+    }
+
+    /**
+     * Register the global scopes for this builder instance.
+     *
+     * @param  \Illuminate\Database\Eloquent\Builder  $builder
+     * @return \Illuminate\Database\Eloquent\Builder
+     */
+    public function registerGlobalScopes($builder)
+    {
+        foreach ($this->getGlobalScopes() as $identifier => $scope) {
+            $builder->withGlobalScope($identifier, $scope);
+        }
+
+        return $builder;
+    }
+
+    /**
+     * Get a new query builder that doesn't have any global scopes.
+     *
+     * @return \Illuminate\Database\Eloquent\Builder|static
+     */
+    public function newQueryWithoutScopes()
+    {
+        return $this->newModelQuery()
+            ->with($this->with)
+            ->withCount($this->withCount);
+    }
+
+    /**
+     * Get a new query instance without a given scope.
+     *
+     * @param  \Illuminate\Database\Eloquent\Scope|string  $scope
+     * @return \Illuminate\Database\Eloquent\Builder
+     */
+    public function newQueryWithoutScope($scope)
+    {
+        return $this->newQuery()->withoutGlobalScope($scope);
+    }
+
+    /**
+     * Get a new query to restore one or more models by their queueable IDs.
+     *
+     * @param  array|int  $ids
+     * @return \Illuminate\Database\Eloquent\Builder
+     */
+    public function newQueryForRestoration($ids)
+    {
+        return $this->newQueryWithoutScopes()->whereKey($ids);
+    }
+
+    /**
+     * Create a new Eloquent query builder for the model.
+     *
+     * @param  \Illuminate\Database\Query\Builder  $query
+     * @return \Illuminate\Database\Eloquent\Builder|static
+     */
+    public function newEloquentBuilder($query)
+    {
+        return new Builder($query);
+    }
+
+    /**
+     * Get a new query builder instance for the connection.
+     *
+     * @return \Illuminate\Database\Query\Builder
+     */
+    protected function newBaseQueryBuilder()
+    {
+        return $this->getConnection()->query();
+    }
+
+    /**
+     * Create a new Eloquent Collection instance.
+     *
+     * @param  array  $models
+     * @return \Illuminate\Database\Eloquent\Collection
+     */
+    public function newCollection(array $models = [])
+    {
+        return new Collection($models);
+    }
+
+    /**
+     * Create a new pivot model instance.
+     *
+     * @param  \Illuminate\Database\Eloquent\Model  $parent
+     * @param  array  $attributes
+     * @param  string  $table
+     * @param  bool  $exists
+     * @param  string|null  $using
+     * @return \Illuminate\Database\Eloquent\Relations\Pivot
+     */
+    public function newPivot(self $parent, array $attributes, $table, $exists, $using = null)
+    {
+        return $using ? $using::fromRawAttributes($parent, $attributes, $table, $exists)
+            : Pivot::fromAttributes($parent, $attributes, $table, $exists);
+    }
+
+    /**
+     * Determine if the model has a given scope.
+     *
+     * @param  string  $scope
+     * @return bool
+     */
+    public function hasNamedScope($scope)
+    {
+        return method_exists($this, 'scope'.ucfirst($scope));
+    }
+
+    /**
+     * Apply the given named scope if possible.
+     *
+     * @param  string  $scope
+     * @param  array  $parameters
+     * @return mixed
+     */
+    public function callNamedScope($scope, array $parameters = [])
+    {
+        return $this->{'scope'.ucfirst($scope)}(...$parameters);
+    }
+
+    /**
+     * Convert the model instance to an array.
+     *
+     * @return array
+     */
+    public function toArray()
+    {
+        return array_merge($this->attributesToArray(), $this->relationsToArray());
+    }
+
+    /**
+     * Convert the model instance to JSON.
+     *
+     * @param  int  $options
+     * @return string
+     *
+     * @throws \Illuminate\Database\Eloquent\JsonEncodingException
+     */
+    public function toJson($options = 0)
+    {
+        $json = json_encode($this->jsonSerialize(), $options);
+
+        if (json_last_error() !== JSON_ERROR_NONE) {
+            throw JsonEncodingException::forModel($this, json_last_error_msg());
+        }
+
+        return $json;
+    }
+
+    /**
+     * Convert the object into something JSON serializable.
+     *
+     * @return mixed
+     */
+    public function jsonSerialize(): mixed
+    {
+        return $this->toArray();
+    }
+
+    /**
+     * Reload a fresh model instance from the database.
+     *
+     * @param  array|string  $with
+     * @return static|null
+     */
+    public function fresh($with = [])
+    {
+        if (! $this->exists) {
+            return;
+        }
+
+        return $this->setKeysForSelectQuery($this->newQueryWithoutScopes())
+            ->useWritePdo()
+            ->with(is_string($with) ? func_get_args() : $with)
+            ->first();
+    }
+
+    /**
+     * Reload the current model instance with fresh attributes from the database.
+     *
+     * @return $this
+     */
+    public function refresh()
+    {
+        if (! $this->exists) {
+            return $this;
+        }
+
+        $this->setRawAttributes(
+            $this->setKeysForSelectQuery($this->newQueryWithoutScopes())
+                ->useWritePdo()
+                ->firstOrFail()
+                ->attributes
+        );
+
+        $this->load(collect($this->relations)->reject(function ($relation) {
+            return $relation instanceof Pivot
+                || (is_object($relation) && in_array(AsPivot::class, class_uses_recursive($relation), true));
+        })->keys()->all());
+
+        $this->syncOriginal();
+
+        return $this;
+    }
+
+    /**
+     * Clone the model into a new, non-existing instance.
+     *
+     * @param  array|null  $except
+     * @return static
+     */
+    public function replicate(array $except = null)
+    {
+        $defaults = array_values(array_filter([
+            $this->getKeyName(),
+            $this->getCreatedAtColumn(),
+            $this->getUpdatedAtColumn(),
+        ]));
+
+        $attributes = Arr::except(
+            $this->getAttributes(), $except ? array_unique(array_merge($except, $defaults)) : $defaults
+        );
+
+        return tap(new static, function ($instance) use ($attributes) {
+            $instance->setRawAttributes($attributes);
+
+            $instance->setRelations($this->relations);
+
+            $instance->fireModelEvent('replicating', false);
+        });
+    }
+
+    /**
+     * Clone the model into a new, non-existing instance without raising any events.
+     *
+     * @param  array|null  $except
+     * @return static
+     */
+    public function replicateQuietly(array $except = null)
+    {
+        return static::withoutEvents(fn () => $this->replicate($except));
+    }
+
+    /**
+     * Determine if two models have the same ID and belong to the same table.
+     *
+     * @param  \Illuminate\Database\Eloquent\Model|null  $model
+     * @return bool
+     */
+    public function is($model)
+    {
+        return ! is_null($model) &&
+            $this->getKey() === $model->getKey() &&
+            $this->getTable() === $model->getTable() &&
+            $this->getConnectionName() === $model->getConnectionName();
+    }
+
+    /**
+     * Determine if two models are not the same.
+     *
+     * @param  \Illuminate\Database\Eloquent\Model|null  $model
+     * @return bool
+     */
+    public function isNot($model)
+    {
+        return ! $this->is($model);
+    }
+
+    /**
+     * Get the database connection for the model.
+     *
+     * @return \Illuminate\Database\Connection
+     */
+    public function getConnection()
+    {
+        return static::resolveConnection($this->getConnectionName());
+    }
+
+    /**
+     * Get the current connection name for the model.
+     *
+     * @return string|null
+     */
+    public function getConnectionName()
+    {
+        return $this->connection;
+    }
+
+    /**
+     * Set the connection associated with the model.
+     *
+     * @param  string|null  $name
+     * @return $this
+     */
+    public function setConnection($name)
+    {
+        $this->connection = $name;
+
+        return $this;
+    }
+
+    /**
+     * Resolve a connection instance.
+     *
+     * @param  string|null  $connection
+     * @return \Illuminate\Database\Connection
+     */
+    public static function resolveConnection($connection = null)
+    {
+        return static::$resolver->connection($connection);
+    }
+
+    /**
+     * Get the connection resolver instance.
+     *
+     * @return \Illuminate\Database\ConnectionResolverInterface
+     */
+    public static function getConnectionResolver()
+    {
+        return static::$resolver;
+    }
+
+    /**
+     * Set the connection resolver instance.
+     *
+     * @param  \Illuminate\Database\ConnectionResolverInterface  $resolver
+     * @return void
+     */
+    public static function setConnectionResolver(Resolver $resolver)
+    {
+        static::$resolver = $resolver;
+    }
+
+    /**
+     * Unset the connection resolver for models.
+     *
+     * @return void
+     */
+    public static function unsetConnectionResolver()
+    {
+        static::$resolver = null;
+    }
+
+    /**
+     * Get the table associated with the model.
+     *
+     * @return string
+     */
+    public function getTable()
+    {
+        return $this->table ?? Str::snake(Str::pluralStudly(class_basename($this)));
+    }
+
+    /**
+     * Set the table associated with the model.
+     *
+     * @param  string  $table
+     * @return $this
+     */
+    public function setTable($table)
+    {
+        $this->table = $table;
+
+        return $this;
+    }
+
+    /**
+     * Get the primary key for the model.
+     *
+     * @return string
+     */
+    public function getKeyName()
+    {
+        return $this->primaryKey;
+    }
+
+    /**
+     * Set the primary key for the model.
+     *
+     * @param  string  $key
+     * @return $this
+     */
+    public function setKeyName($key)
+    {
+        $this->primaryKey = $key;
+
+        return $this;
+    }
+
+    /**
+     * Get the table qualified key name.
+     *
+     * @return string
+     */
+    public function getQualifiedKeyName()
+    {
+        return $this->qualifyColumn($this->getKeyName());
+    }
+
+    /**
+     * Get the auto-incrementing key type.
+     *
+     * @return string
+     */
+    public function getKeyType()
+    {
+        return $this->keyType;
+    }
+
+    /**
+     * Set the data type for the primary key.
+     *
+     * @param  string  $type
+     * @return $this
+     */
+    public function setKeyType($type)
+    {
+        $this->keyType = $type;
+
+        return $this;
+    }
+
+    /**
+     * Get the value indicating whether the IDs are incrementing.
+     *
+     * @return bool
+     */
+    public function getIncrementing()
+    {
+        return $this->incrementing;
+    }
+
+    /**
+     * Set whether IDs are incrementing.
+     *
+     * @param  bool  $value
+     * @return $this
+     */
+    public function setIncrementing($value)
+    {
+        $this->incrementing = $value;
+
+        return $this;
+    }
+
+    /**
+     * Get the value of the model's primary key.
+     *
+     * @return mixed
+     */
+    public function getKey()
+    {
+        return $this->getAttribute($this->getKeyName());
+    }
+
+    /**
+     * Get the queueable identity for the entity.
+     *
+     * @return mixed
+     */
+    public function getQueueableId()
+    {
+        return $this->getKey();
+    }
+
+    /**
+     * Get the queueable relationships for the entity.
+     *
+     * @return array
+     */
+    public function getQueueableRelations()
+    {
+        $relations = [];
+
+        foreach ($this->getRelations() as $key => $relation) {
+            if (! method_exists($this, $key)) {
+                continue;
+            }
+
+            $relations[] = $key;
+
+            if ($relation instanceof QueueableCollection) {
+                foreach ($relation->getQueueableRelations() as $collectionValue) {
+                    $relations[] = $key.'.'.$collectionValue;
+                }
+            }
+
+            if ($relation instanceof QueueableEntity) {
+                foreach ($relation->getQueueableRelations() as $entityValue) {
+                    $relations[] = $key.'.'.$entityValue;
+                }
+            }
+        }
+
+        return array_unique($relations);
+    }
+
+    /**
+     * Get the queueable connection for the entity.
+     *
+     * @return string|null
+     */
+    public function getQueueableConnection()
+    {
+        return $this->getConnectionName();
+    }
+
+    /**
+     * Get the value of the model's route key.
+     *
+     * @return mixed
+     */
+    public function getRouteKey()
+    {
+        return $this->getAttribute($this->getRouteKeyName());
+    }
+
+    /**
+     * Get the route key for the model.
+     *
+     * @return string
+     */
+    public function getRouteKeyName()
+    {
+        return $this->getKeyName();
+    }
+
+    /**
+     * Retrieve the model for a bound value.
+     *
+     * @param  mixed  $value
+     * @param  string|null  $field
+     * @return \Illuminate\Database\Eloquent\Model|null
+     */
+    public function resolveRouteBinding($value, $field = null)
+    {
+        return $this->resolveRouteBindingQuery($this, $value, $field)->first();
+    }
+
+    /**
+     * Retrieve the model for a bound value.
+     *
+     * @param  mixed  $value
+     * @param  string|null  $field
+     * @return \Illuminate\Database\Eloquent\Model|null
+     */
+    public function resolveSoftDeletableRouteBinding($value, $field = null)
+    {
+        return $this->resolveRouteBindingQuery($this, $value, $field)->withTrashed()->first();
+    }
+
+    /**
+     * Retrieve the child model for a bound value.
+     *
+     * @param  string  $childType
+     * @param  mixed  $value
+     * @param  string|null  $field
+     * @return \Illuminate\Database\Eloquent\Model|null
+     */
+    public function resolveChildRouteBinding($childType, $value, $field)
+    {
+        return $this->resolveChildRouteBindingQuery($childType, $value, $field)->first();
+    }
+
+    /**
+     * Retrieve the child model for a bound value.
+     *
+     * @param  string  $childType
+     * @param  mixed  $value
+     * @param  string|null  $field
+     * @return \Illuminate\Database\Eloquent\Model|null
+     */
+    public function resolveSoftDeletableChildRouteBinding($childType, $value, $field)
+    {
+        return $this->resolveChildRouteBindingQuery($childType, $value, $field)->withTrashed()->first();
+    }
+
+    /**
+     * Retrieve the child model query for a bound value.
+     *
+     * @param  string  $childType
+     * @param  mixed  $value
+     * @param  string|null  $field
+     * @return \Illuminate\Database\Eloquent\Relations\Relation
+     */
+    protected function resolveChildRouteBindingQuery($childType, $value, $field)
+    {
+        $relationship = $this->{$this->childRouteBindingRelationshipName($childType)}();
+
+        $field = $field ?: $relationship->getRelated()->getRouteKeyName();
+
+        if ($relationship instanceof HasManyThrough ||
+            $relationship instanceof BelongsToMany) {
+            $field = $relationship->getRelated()->getTable().'.'.$field;
+        }
+
+        return $relationship instanceof Model
+            ? $relationship->resolveRouteBindingQuery($relationship, $value, $field)
+            : $relationship->getRelated()->resolveRouteBindingQuery($relationship, $value, $field);
+    }
+
+    /**
+     * Retrieve the child route model binding relationship name for the given child type.
+     *
+     * @param  string  $childType
+     * @return string
+     */
+    protected function childRouteBindingRelationshipName($childType)
+    {
+        return Str::plural(Str::camel($childType));
+    }
+
+    /**
+     * Retrieve the model for a bound value.
+     *
+     * @param  \Illuminate\Database\Eloquent\Model|\Illuminate\Database\Eloquent\Relations\Relation  $query
+     * @param  mixed  $value
+     * @param  string|null  $field
+     * @return \Illuminate\Database\Eloquent\Relations\Relation
+     */
+    public function resolveRouteBindingQuery($query, $value, $field = null)
+    {
+        return $query->where($field ?? $this->getRouteKeyName(), $value);
+    }
+
+    /**
+     * Get the default foreign key name for the model.
+     *
+     * @return string
+     */
+    public function getForeignKey()
+    {
+        return Str::snake(class_basename($this)).'_'.$this->getKeyName();
+    }
+
+    /**
+     * Get the number of models to return per page.
+     *
+     * @return int
+     */
+    public function getPerPage()
+    {
+        return $this->perPage;
+    }
+
+    /**
+     * Set the number of models to return per page.
+     *
+     * @param  int  $perPage
+     * @return $this
+     */
+    public function setPerPage($perPage)
+    {
+        $this->perPage = $perPage;
+
+        return $this;
+    }
+
+    /**
+     * Determine if lazy loading is disabled.
+     *
+     * @return bool
+     */
+    public static function preventsLazyLoading()
+    {
+        return static::$modelsShouldPreventLazyLoading;
+    }
+
+    /**
+     * Determine if discarding guarded attribute fills is disabled.
+     *
+     * @return bool
+     */
+    public static function preventsSilentlyDiscardingAttributes()
+    {
+        return static::$modelsShouldPreventSilentlyDiscardingAttributes;
+    }
+
+    /**
+     * Determine if accessing missing attributes is disabled.
+     *
+     * @return bool
+     */
+    public static function preventsAccessingMissingAttributes()
+    {
+        return static::$modelsShouldPreventAccessingMissingAttributes;
+    }
+
+    /**
+     * Get the broadcast channel route definition that is associated with the given entity.
+     *
+     * @return string
+     */
+    public function broadcastChannelRoute()
+    {
+        return str_replace('\\', '.', get_class($this)).'.{'.Str::camel(class_basename($this)).'}';
+    }
+
+    /**
+     * Get the broadcast channel name that is associated with the given entity.
+     *
+     * @return string
+     */
+    public function broadcastChannel()
+    {
+        return str_replace('\\', '.', get_class($this)).'.'.$this->getKey();
+    }
+
+    /**
+     * Dynamically retrieve attributes on the model.
+     *
+     * @param  string  $key
+     * @return mixed
+     */
+    public function __get($key)
+    {
+        return $this->getAttribute($key);
+    }
+
+    /**
+     * Dynamically set attributes on the model.
+     *
+     * @param  string  $key
+     * @param  mixed  $value
+     * @return void
+     */
+    public function __set($key, $value)
+    {
+        $this->setAttribute($key, $value);
+    }
+
+    /**
+     * Determine if the given attribute exists.
+     *
+     * @param  mixed  $offset
+     * @return bool
+     */
+    public function offsetExists($offset): bool
+    {
+        try {
+            return ! is_null($this->getAttribute($offset));
+        } catch (MissingAttributeException) {
+            return false;
+        }
+    }
+
+    /**
+     * Get the value for a given offset.
+     *
+     * @param  mixed  $offset
+     * @return mixed
+     */
+    public function offsetGet($offset): mixed
+    {
+        return $this->getAttribute($offset);
+    }
+
+    /**
+     * Set the value for a given offset.
+     *
+     * @param  mixed  $offset
+     * @param  mixed  $value
+     * @return void
+     */
+    public function offsetSet($offset, $value): void
+    {
+        $this->setAttribute($offset, $value);
+    }
+
+    /**
+     * Unset the value for a given offset.
+     *
+     * @param  mixed  $offset
+     * @return void
+     */
+    public function offsetUnset($offset): void
+    {
+        unset($this->attributes[$offset], $this->relations[$offset]);
+    }
+
+    /**
+     * Determine if an attribute or relation exists on the model.
+     *
+     * @param  string  $key
+     * @return bool
+     */
+    public function __isset($key)
+    {
+        return $this->offsetExists($key);
+    }
+
+    /**
+     * Unset an attribute on the model.
+     *
+     * @param  string  $key
+     * @return void
+     */
+    public function __unset($key)
+    {
+        $this->offsetUnset($key);
+    }
+
+    /**
+     * Handle dynamic method calls into the model.
+     *
+     * @param  string  $method
+     * @param  array  $parameters
+     * @return mixed
+     */
+    public function __call($method, $parameters)
+    {
+        if (in_array($method, ['increment', 'decrement'])) {
+            return $this->$method(...$parameters);
+        }
+
+        if ($resolver = $this->relationResolver(static::class, $method)) {
+            return $resolver($this);
+        }
+
+        if (Str::startsWith($method, 'through') &&
+            method_exists($this, $relationMethod = Str::of($method)->after('through')->lcfirst()->toString())) {
+            return $this->through($relationMethod);
+        }
+
+        return $this->forwardCallTo($this->newQuery(), $method, $parameters);
+    }
+
+    /**
+     * Handle dynamic static method calls into the model.
+     *
+     * @param  string  $method
+     * @param  array  $parameters
+     * @return mixed
+     */
+    public static function __callStatic($method, $parameters)
+    {
+        return (new static)->$method(...$parameters);
+    }
+
+    /**
+     * Convert the model to its string representation.
+     *
+     * @return string
+     */
+    public function __toString()
+    {
+        return $this->escapeWhenCastingToString
+            ? e($this->toJson())
+            : $this->toJson();
+    }
+
+    /**
+     * Indicate that the object's string representation should be escaped when __toString is invoked.
+     *
+     * @param  bool  $escape
+     * @return $this
+     */
+    public function escapeWhenCastingToString($escape = true)
+    {
+        $this->escapeWhenCastingToString = $escape;
+
+        return $this;
+    }
+
+    /**
+     * Prepare the object for serialization.
+     *
+     * @return array
+     */
+    public function __sleep()
+    {
+        $this->mergeAttributesFromCachedCasts();
+
+        $this->classCastCache = [];
+        $this->attributeCastCache = [];
+
+        return array_keys(get_object_vars($this));
+    }
+
+    /**
+     * When a model is being unserialized, check if it needs to be booted.
+     *
+     * @return void
+     */
+    public function __wakeup()
+    {
+        $this->bootIfNotBooted();
+
+        $this->initializeTraits();
+    }
+}
diff --git a/vendor/illuminate/database/Eloquent/ModelNotFoundException.php b/vendor/illuminate/database/Eloquent/ModelNotFoundException.php
new file mode 100755
index 0000000..79ae8a3
--- /dev/null
+++ b/vendor/illuminate/database/Eloquent/ModelNotFoundException.php
@@ -0,0 +1,69 @@
+
+     */
+    protected $model;
+
+    /**
+     * The affected model IDs.
+     *
+     * @var array
+     */
+    protected $ids;
+
+    /**
+     * Set the affected Eloquent model and instance ids.
+     *
+     * @param  class-string  $model
+     * @param  array|int|string  $ids
+     * @return $this
+     */
+    public function setModel($model, $ids = [])
+    {
+        $this->model = $model;
+        $this->ids = Arr::wrap($ids);
+
+        $this->message = "No query results for model [{$model}]";
+
+        if (count($this->ids) > 0) {
+            $this->message .= ' '.implode(', ', $this->ids);
+        } else {
+            $this->message .= '.';
+        }
+
+        return $this;
+    }
+
+    /**
+     * Get the affected Eloquent model.
+     *
+     * @return class-string
+     */
+    public function getModel()
+    {
+        return $this->model;
+    }
+
+    /**
+     * Get the affected Eloquent model IDs.
+     *
+     * @return array
+     */
+    public function getIds()
+    {
+        return $this->ids;
+    }
+}
diff --git a/vendor/illuminate/database/Eloquent/PendingHasThroughRelationship.php b/vendor/illuminate/database/Eloquent/PendingHasThroughRelationship.php
new file mode 100644
index 0000000..612c51e
--- /dev/null
+++ b/vendor/illuminate/database/Eloquent/PendingHasThroughRelationship.php
@@ -0,0 +1,90 @@
+rootModel = $rootModel;
+
+        $this->localRelationship = $localRelationship;
+    }
+
+    /**
+     * Define the distant relationship that this model has.
+     *
+     * @param  string|(callable(\Illuminate\Database\Eloquent\Model): (\Illuminate\Database\Eloquent\Relations\HasOne|\Illuminate\Database\Eloquent\Relations\HasMany))  $callback
+     * @return \Illuminate\Database\Eloquent\Relations\HasManyThrough|\Illuminate\Database\Eloquent\Relations\HasOneThrough
+     */
+    public function has($callback)
+    {
+        if (is_string($callback)) {
+            $callback = fn () => $this->localRelationship->getRelated()->{$callback}();
+        }
+
+        $distantRelation = $callback($this->localRelationship->getRelated());
+
+        if ($distantRelation instanceof HasMany) {
+            return $this->rootModel->hasManyThrough(
+                $distantRelation->getRelated()::class,
+                $this->localRelationship->getRelated()::class,
+                $this->localRelationship->getForeignKeyName(),
+                $distantRelation->getForeignKeyName(),
+                $this->localRelationship->getLocalKeyName(),
+                $distantRelation->getLocalKeyName(),
+            );
+        }
+
+        return $this->rootModel->hasOneThrough(
+            $distantRelation->getRelated()::class,
+            $this->localRelationship->getRelated()::class,
+            $this->localRelationship->getForeignKeyName(),
+            $distantRelation->getForeignKeyName(),
+            $this->localRelationship->getLocalKeyName(),
+            $distantRelation->getLocalKeyName(),
+        );
+    }
+
+    /**
+     * Handle dynamic method calls into the model.
+     *
+     * @param  string  $method
+     * @param  array  $parameters
+     * @return mixed
+     */
+    public function __call($method, $parameters)
+    {
+        if (Str::startsWith($method, 'has')) {
+            return $this->has(Str::of($method)->after('has')->lcfirst()->toString());
+        }
+
+        throw new BadMethodCallException(sprintf(
+            'Call to undefined method %s::%s()', static::class, $method
+        ));
+    }
+}
diff --git a/vendor/illuminate/database/Eloquent/Prunable.php b/vendor/illuminate/database/Eloquent/Prunable.php
new file mode 100644
index 0000000..b4ce1b0
--- /dev/null
+++ b/vendor/illuminate/database/Eloquent/Prunable.php
@@ -0,0 +1,67 @@
+prunable()
+            ->when(in_array(SoftDeletes::class, class_uses_recursive(get_class($this))), function ($query) {
+                $query->withTrashed();
+            })->chunkById($chunkSize, function ($models) use (&$total) {
+                $models->each->prune();
+
+                $total += $models->count();
+
+                event(new ModelsPruned(static::class, $total));
+            });
+
+        return $total;
+    }
+
+    /**
+     * Get the prunable model query.
+     *
+     * @return \Illuminate\Database\Eloquent\Builder
+     */
+    public function prunable()
+    {
+        throw new LogicException('Please implement the prunable method on your model.');
+    }
+
+    /**
+     * Prune the model in the database.
+     *
+     * @return bool|null
+     */
+    public function prune()
+    {
+        $this->pruning();
+
+        return in_array(SoftDeletes::class, class_uses_recursive(get_class($this)))
+                ? $this->forceDelete()
+                : $this->delete();
+    }
+
+    /**
+     * Prepare the model for pruning.
+     *
+     * @return void
+     */
+    protected function pruning()
+    {
+        //
+    }
+}
diff --git a/vendor/illuminate/database/Eloquent/QueueEntityResolver.php b/vendor/illuminate/database/Eloquent/QueueEntityResolver.php
new file mode 100644
index 0000000..22fccf2
--- /dev/null
+++ b/vendor/illuminate/database/Eloquent/QueueEntityResolver.php
@@ -0,0 +1,29 @@
+find($id);
+
+        if ($instance) {
+            return $instance;
+        }
+
+        throw new EntityNotFoundException($type, $id);
+    }
+}
diff --git a/vendor/illuminate/database/Eloquent/RelationNotFoundException.php b/vendor/illuminate/database/Eloquent/RelationNotFoundException.php
new file mode 100755
index 0000000..73257bb
--- /dev/null
+++ b/vendor/illuminate/database/Eloquent/RelationNotFoundException.php
@@ -0,0 +1,46 @@
+model = $class;
+        $instance->relation = $relation;
+
+        return $instance;
+    }
+}
diff --git a/vendor/illuminate/database/Eloquent/Relations/BelongsTo.php b/vendor/illuminate/database/Eloquent/Relations/BelongsTo.php
new file mode 100755
index 0000000..c17b733
--- /dev/null
+++ b/vendor/illuminate/database/Eloquent/Relations/BelongsTo.php
@@ -0,0 +1,383 @@
+ownerKey = $ownerKey;
+        $this->relationName = $relationName;
+        $this->foreignKey = $foreignKey;
+
+        // In the underlying base relationship class, this variable is referred to as
+        // the "parent" since most relationships are not inversed. But, since this
+        // one is we will create a "child" variable for much better readability.
+        $this->child = $child;
+
+        parent::__construct($query, $child);
+    }
+
+    /**
+     * Get the results of the relationship.
+     *
+     * @return mixed
+     */
+    public function getResults()
+    {
+        if (is_null($this->child->{$this->foreignKey})) {
+            return $this->getDefaultFor($this->parent);
+        }
+
+        return $this->query->first() ?: $this->getDefaultFor($this->parent);
+    }
+
+    /**
+     * Set the base constraints on the relation query.
+     *
+     * @return void
+     */
+    public function addConstraints()
+    {
+        if (static::$constraints) {
+            // For belongs to relationships, which are essentially the inverse of has one
+            // or has many relationships, we need to actually query on the primary key
+            // of the related models matching on the foreign key that's on a parent.
+            $table = $this->related->getTable();
+
+            $this->query->where($table.'.'.$this->ownerKey, '=', $this->child->{$this->foreignKey});
+        }
+    }
+
+    /**
+     * Set the constraints for an eager load of the relation.
+     *
+     * @param  array  $models
+     * @return void
+     */
+    public function addEagerConstraints(array $models)
+    {
+        // We'll grab the primary key name of the related models since it could be set to
+        // a non-standard name and not "id". We will then construct the constraint for
+        // our eagerly loading query so it returns the proper models from execution.
+        $key = $this->related->getTable().'.'.$this->ownerKey;
+
+        $whereIn = $this->whereInMethod($this->related, $this->ownerKey);
+
+        $this->query->{$whereIn}($key, $this->getEagerModelKeys($models));
+    }
+
+    /**
+     * Gather the keys from an array of related models.
+     *
+     * @param  array  $models
+     * @return array
+     */
+    protected function getEagerModelKeys(array $models)
+    {
+        $keys = [];
+
+        // First we need to gather all of the keys from the parent models so we know what
+        // to query for via the eager loading query. We will add them to an array then
+        // execute a "where in" statement to gather up all of those related records.
+        foreach ($models as $model) {
+            if (! is_null($value = $model->{$this->foreignKey})) {
+                $keys[] = $value;
+            }
+        }
+
+        sort($keys);
+
+        return array_values(array_unique($keys));
+    }
+
+    /**
+     * Initialize the relation on a set of models.
+     *
+     * @param  array  $models
+     * @param  string  $relation
+     * @return array
+     */
+    public function initRelation(array $models, $relation)
+    {
+        foreach ($models as $model) {
+            $model->setRelation($relation, $this->getDefaultFor($model));
+        }
+
+        return $models;
+    }
+
+    /**
+     * Match the eagerly loaded results to their parents.
+     *
+     * @param  array  $models
+     * @param  \Illuminate\Database\Eloquent\Collection  $results
+     * @param  string  $relation
+     * @return array
+     */
+    public function match(array $models, Collection $results, $relation)
+    {
+        $foreign = $this->foreignKey;
+
+        $owner = $this->ownerKey;
+
+        // First we will get to build a dictionary of the child models by their primary
+        // key of the relationship, then we can easily match the children back onto
+        // the parents using that dictionary and the primary key of the children.
+        $dictionary = [];
+
+        foreach ($results as $result) {
+            $attribute = $this->getDictionaryKey($result->getAttribute($owner));
+
+            $dictionary[$attribute] = $result;
+        }
+
+        // Once we have the dictionary constructed, we can loop through all the parents
+        // and match back onto their children using these keys of the dictionary and
+        // the primary key of the children to map them onto the correct instances.
+        foreach ($models as $model) {
+            $attribute = $this->getDictionaryKey($model->{$foreign});
+
+            if (isset($dictionary[$attribute])) {
+                $model->setRelation($relation, $dictionary[$attribute]);
+            }
+        }
+
+        return $models;
+    }
+
+    /**
+     * Associate the model instance to the given parent.
+     *
+     * @param  \Illuminate\Database\Eloquent\Model|int|string|null  $model
+     * @return \Illuminate\Database\Eloquent\Model
+     */
+    public function associate($model)
+    {
+        $ownerKey = $model instanceof Model ? $model->getAttribute($this->ownerKey) : $model;
+
+        $this->child->setAttribute($this->foreignKey, $ownerKey);
+
+        if ($model instanceof Model) {
+            $this->child->setRelation($this->relationName, $model);
+        } else {
+            $this->child->unsetRelation($this->relationName);
+        }
+
+        return $this->child;
+    }
+
+    /**
+     * Dissociate previously associated model from the given parent.
+     *
+     * @return \Illuminate\Database\Eloquent\Model
+     */
+    public function dissociate()
+    {
+        $this->child->setAttribute($this->foreignKey, null);
+
+        return $this->child->setRelation($this->relationName, null);
+    }
+
+    /**
+     * Alias of "dissociate" method.
+     *
+     * @return \Illuminate\Database\Eloquent\Model
+     */
+    public function disassociate()
+    {
+        return $this->dissociate();
+    }
+
+    /**
+     * Add the constraints for a relationship query.
+     *
+     * @param  \Illuminate\Database\Eloquent\Builder  $query
+     * @param  \Illuminate\Database\Eloquent\Builder  $parentQuery
+     * @param  array|mixed  $columns
+     * @return \Illuminate\Database\Eloquent\Builder
+     */
+    public function getRelationExistenceQuery(Builder $query, Builder $parentQuery, $columns = ['*'])
+    {
+        if ($parentQuery->getQuery()->from == $query->getQuery()->from) {
+            return $this->getRelationExistenceQueryForSelfRelation($query, $parentQuery, $columns);
+        }
+
+        return $query->select($columns)->whereColumn(
+            $this->getQualifiedForeignKeyName(), '=', $query->qualifyColumn($this->ownerKey)
+        );
+    }
+
+    /**
+     * Add the constraints for a relationship query on the same table.
+     *
+     * @param  \Illuminate\Database\Eloquent\Builder  $query
+     * @param  \Illuminate\Database\Eloquent\Builder  $parentQuery
+     * @param  array|mixed  $columns
+     * @return \Illuminate\Database\Eloquent\Builder
+     */
+    public function getRelationExistenceQueryForSelfRelation(Builder $query, Builder $parentQuery, $columns = ['*'])
+    {
+        $query->select($columns)->from(
+            $query->getModel()->getTable().' as '.$hash = $this->getRelationCountHash()
+        );
+
+        $query->getModel()->setTable($hash);
+
+        return $query->whereColumn(
+            $hash.'.'.$this->ownerKey, '=', $this->getQualifiedForeignKeyName()
+        );
+    }
+
+    /**
+     * Determine if the related model has an auto-incrementing ID.
+     *
+     * @return bool
+     */
+    protected function relationHasIncrementingId()
+    {
+        return $this->related->getIncrementing() &&
+            in_array($this->related->getKeyType(), ['int', 'integer']);
+    }
+
+    /**
+     * Make a new related instance for the given model.
+     *
+     * @param  \Illuminate\Database\Eloquent\Model  $parent
+     * @return \Illuminate\Database\Eloquent\Model
+     */
+    protected function newRelatedInstanceFor(Model $parent)
+    {
+        return $this->related->newInstance();
+    }
+
+    /**
+     * Get the child of the relationship.
+     *
+     * @return \Illuminate\Database\Eloquent\Model
+     */
+    public function getChild()
+    {
+        return $this->child;
+    }
+
+    /**
+     * Get the foreign key of the relationship.
+     *
+     * @return string
+     */
+    public function getForeignKeyName()
+    {
+        return $this->foreignKey;
+    }
+
+    /**
+     * Get the fully qualified foreign key of the relationship.
+     *
+     * @return string
+     */
+    public function getQualifiedForeignKeyName()
+    {
+        return $this->child->qualifyColumn($this->foreignKey);
+    }
+
+    /**
+     * Get the key value of the child's foreign key.
+     *
+     * @return mixed
+     */
+    public function getParentKey()
+    {
+        return $this->child->{$this->foreignKey};
+    }
+
+    /**
+     * Get the associated key of the relationship.
+     *
+     * @return string
+     */
+    public function getOwnerKeyName()
+    {
+        return $this->ownerKey;
+    }
+
+    /**
+     * Get the fully qualified associated key of the relationship.
+     *
+     * @return string
+     */
+    public function getQualifiedOwnerKeyName()
+    {
+        return $this->related->qualifyColumn($this->ownerKey);
+    }
+
+    /**
+     * Get the value of the model's associated key.
+     *
+     * @param  \Illuminate\Database\Eloquent\Model  $model
+     * @return mixed
+     */
+    protected function getRelatedKeyFrom(Model $model)
+    {
+        return $model->{$this->ownerKey};
+    }
+
+    /**
+     * Get the name of the relationship.
+     *
+     * @return string
+     */
+    public function getRelationName()
+    {
+        return $this->relationName;
+    }
+}
diff --git a/vendor/illuminate/database/Eloquent/Relations/BelongsToMany.php b/vendor/illuminate/database/Eloquent/Relations/BelongsToMany.php
new file mode 100755
index 0000000..6a9ec9e
--- /dev/null
+++ b/vendor/illuminate/database/Eloquent/Relations/BelongsToMany.php
@@ -0,0 +1,1503 @@
+parentKey = $parentKey;
+        $this->relatedKey = $relatedKey;
+        $this->relationName = $relationName;
+        $this->relatedPivotKey = $relatedPivotKey;
+        $this->foreignPivotKey = $foreignPivotKey;
+        $this->table = $this->resolveTableName($table);
+
+        parent::__construct($query, $parent);
+    }
+
+    /**
+     * Attempt to resolve the intermediate table name from the given string.
+     *
+     * @param  string  $table
+     * @return string
+     */
+    protected function resolveTableName($table)
+    {
+        if (! str_contains($table, '\\') || ! class_exists($table)) {
+            return $table;
+        }
+
+        $model = new $table;
+
+        if (! $model instanceof Model) {
+            return $table;
+        }
+
+        if (in_array(AsPivot::class, class_uses_recursive($model))) {
+            $this->using($table);
+        }
+
+        return $model->getTable();
+    }
+
+    /**
+     * Set the base constraints on the relation query.
+     *
+     * @return void
+     */
+    public function addConstraints()
+    {
+        $this->performJoin();
+
+        if (static::$constraints) {
+            $this->addWhereConstraints();
+        }
+    }
+
+    /**
+     * Set the join clause for the relation query.
+     *
+     * @param  \Illuminate\Database\Eloquent\Builder|null  $query
+     * @return $this
+     */
+    protected function performJoin($query = null)
+    {
+        $query = $query ?: $this->query;
+
+        // We need to join to the intermediate table on the related model's primary
+        // key column with the intermediate table's foreign key for the related
+        // model instance. Then we can set the "where" for the parent models.
+        $query->join(
+            $this->table,
+            $this->getQualifiedRelatedKeyName(),
+            '=',
+            $this->getQualifiedRelatedPivotKeyName()
+        );
+
+        return $this;
+    }
+
+    /**
+     * Set the where clause for the relation query.
+     *
+     * @return $this
+     */
+    protected function addWhereConstraints()
+    {
+        $this->query->where(
+            $this->getQualifiedForeignPivotKeyName(), '=', $this->parent->{$this->parentKey}
+        );
+
+        return $this;
+    }
+
+    /**
+     * Set the constraints for an eager load of the relation.
+     *
+     * @param  array  $models
+     * @return void
+     */
+    public function addEagerConstraints(array $models)
+    {
+        $whereIn = $this->whereInMethod($this->parent, $this->parentKey);
+
+        $this->query->{$whereIn}(
+            $this->getQualifiedForeignPivotKeyName(),
+            $this->getKeys($models, $this->parentKey)
+        );
+    }
+
+    /**
+     * Initialize the relation on a set of models.
+     *
+     * @param  array  $models
+     * @param  string  $relation
+     * @return array
+     */
+    public function initRelation(array $models, $relation)
+    {
+        foreach ($models as $model) {
+            $model->setRelation($relation, $this->related->newCollection());
+        }
+
+        return $models;
+    }
+
+    /**
+     * Match the eagerly loaded results to their parents.
+     *
+     * @param  array  $models
+     * @param  \Illuminate\Database\Eloquent\Collection  $results
+     * @param  string  $relation
+     * @return array
+     */
+    public function match(array $models, Collection $results, $relation)
+    {
+        $dictionary = $this->buildDictionary($results);
+
+        // Once we have an array dictionary of child objects we can easily match the
+        // children back to their parent using the dictionary and the keys on the
+        // parent models. Then we should return these hydrated models back out.
+        foreach ($models as $model) {
+            $key = $this->getDictionaryKey($model->{$this->parentKey});
+
+            if (isset($dictionary[$key])) {
+                $model->setRelation(
+                    $relation, $this->related->newCollection($dictionary[$key])
+                );
+            }
+        }
+
+        return $models;
+    }
+
+    /**
+     * Build model dictionary keyed by the relation's foreign key.
+     *
+     * @param  \Illuminate\Database\Eloquent\Collection  $results
+     * @return array
+     */
+    protected function buildDictionary(Collection $results)
+    {
+        // First we'll build a dictionary of child models keyed by the foreign key
+        // of the relation so that we will easily and quickly match them to the
+        // parents without having a possibly slow inner loop for every model.
+        $dictionary = [];
+
+        foreach ($results as $result) {
+            $value = $this->getDictionaryKey($result->{$this->accessor}->{$this->foreignPivotKey});
+
+            $dictionary[$value][] = $result;
+        }
+
+        return $dictionary;
+    }
+
+    /**
+     * Get the class being used for pivot models.
+     *
+     * @return string
+     */
+    public function getPivotClass()
+    {
+        return $this->using ?? Pivot::class;
+    }
+
+    /**
+     * Specify the custom pivot model to use for the relationship.
+     *
+     * @param  string  $class
+     * @return $this
+     */
+    public function using($class)
+    {
+        $this->using = $class;
+
+        return $this;
+    }
+
+    /**
+     * Specify the custom pivot accessor to use for the relationship.
+     *
+     * @param  string  $accessor
+     * @return $this
+     */
+    public function as($accessor)
+    {
+        $this->accessor = $accessor;
+
+        return $this;
+    }
+
+    /**
+     * Set a where clause for a pivot table column.
+     *
+     * @param  string  $column
+     * @param  mixed  $operator
+     * @param  mixed  $value
+     * @param  string  $boolean
+     * @return $this
+     */
+    public function wherePivot($column, $operator = null, $value = null, $boolean = 'and')
+    {
+        $this->pivotWheres[] = func_get_args();
+
+        return $this->where($this->qualifyPivotColumn($column), $operator, $value, $boolean);
+    }
+
+    /**
+     * Set a "where between" clause for a pivot table column.
+     *
+     * @param  string  $column
+     * @param  array  $values
+     * @param  string  $boolean
+     * @param  bool  $not
+     * @return $this
+     */
+    public function wherePivotBetween($column, array $values, $boolean = 'and', $not = false)
+    {
+        return $this->whereBetween($this->qualifyPivotColumn($column), $values, $boolean, $not);
+    }
+
+    /**
+     * Set a "or where between" clause for a pivot table column.
+     *
+     * @param  string  $column
+     * @param  array  $values
+     * @return $this
+     */
+    public function orWherePivotBetween($column, array $values)
+    {
+        return $this->wherePivotBetween($column, $values, 'or');
+    }
+
+    /**
+     * Set a "where pivot not between" clause for a pivot table column.
+     *
+     * @param  string  $column
+     * @param  array  $values
+     * @param  string  $boolean
+     * @return $this
+     */
+    public function wherePivotNotBetween($column, array $values, $boolean = 'and')
+    {
+        return $this->wherePivotBetween($column, $values, $boolean, true);
+    }
+
+    /**
+     * Set a "or where not between" clause for a pivot table column.
+     *
+     * @param  string  $column
+     * @param  array  $values
+     * @return $this
+     */
+    public function orWherePivotNotBetween($column, array $values)
+    {
+        return $this->wherePivotBetween($column, $values, 'or', true);
+    }
+
+    /**
+     * Set a "where in" clause for a pivot table column.
+     *
+     * @param  string  $column
+     * @param  mixed  $values
+     * @param  string  $boolean
+     * @param  bool  $not
+     * @return $this
+     */
+    public function wherePivotIn($column, $values, $boolean = 'and', $not = false)
+    {
+        $this->pivotWhereIns[] = func_get_args();
+
+        return $this->whereIn($this->qualifyPivotColumn($column), $values, $boolean, $not);
+    }
+
+    /**
+     * Set an "or where" clause for a pivot table column.
+     *
+     * @param  string  $column
+     * @param  mixed  $operator
+     * @param  mixed  $value
+     * @return $this
+     */
+    public function orWherePivot($column, $operator = null, $value = null)
+    {
+        return $this->wherePivot($column, $operator, $value, 'or');
+    }
+
+    /**
+     * Set a where clause for a pivot table column.
+     *
+     * In addition, new pivot records will receive this value.
+     *
+     * @param  string|array  $column
+     * @param  mixed  $value
+     * @return $this
+     *
+     * @throws \InvalidArgumentException
+     */
+    public function withPivotValue($column, $value = null)
+    {
+        if (is_array($column)) {
+            foreach ($column as $name => $value) {
+                $this->withPivotValue($name, $value);
+            }
+
+            return $this;
+        }
+
+        if (is_null($value)) {
+            throw new InvalidArgumentException('The provided value may not be null.');
+        }
+
+        $this->pivotValues[] = compact('column', 'value');
+
+        return $this->wherePivot($column, '=', $value);
+    }
+
+    /**
+     * Set an "or where in" clause for a pivot table column.
+     *
+     * @param  string  $column
+     * @param  mixed  $values
+     * @return $this
+     */
+    public function orWherePivotIn($column, $values)
+    {
+        return $this->wherePivotIn($column, $values, 'or');
+    }
+
+    /**
+     * Set a "where not in" clause for a pivot table column.
+     *
+     * @param  string  $column
+     * @param  mixed  $values
+     * @param  string  $boolean
+     * @return $this
+     */
+    public function wherePivotNotIn($column, $values, $boolean = 'and')
+    {
+        return $this->wherePivotIn($column, $values, $boolean, true);
+    }
+
+    /**
+     * Set an "or where not in" clause for a pivot table column.
+     *
+     * @param  string  $column
+     * @param  mixed  $values
+     * @return $this
+     */
+    public function orWherePivotNotIn($column, $values)
+    {
+        return $this->wherePivotNotIn($column, $values, 'or');
+    }
+
+    /**
+     * Set a "where null" clause for a pivot table column.
+     *
+     * @param  string  $column
+     * @param  string  $boolean
+     * @param  bool  $not
+     * @return $this
+     */
+    public function wherePivotNull($column, $boolean = 'and', $not = false)
+    {
+        $this->pivotWhereNulls[] = func_get_args();
+
+        return $this->whereNull($this->qualifyPivotColumn($column), $boolean, $not);
+    }
+
+    /**
+     * Set a "where not null" clause for a pivot table column.
+     *
+     * @param  string  $column
+     * @param  string  $boolean
+     * @return $this
+     */
+    public function wherePivotNotNull($column, $boolean = 'and')
+    {
+        return $this->wherePivotNull($column, $boolean, true);
+    }
+
+    /**
+     * Set a "or where null" clause for a pivot table column.
+     *
+     * @param  string  $column
+     * @param  bool  $not
+     * @return $this
+     */
+    public function orWherePivotNull($column, $not = false)
+    {
+        return $this->wherePivotNull($column, 'or', $not);
+    }
+
+    /**
+     * Set a "or where not null" clause for a pivot table column.
+     *
+     * @param  string  $column
+     * @return $this
+     */
+    public function orWherePivotNotNull($column)
+    {
+        return $this->orWherePivotNull($column, true);
+    }
+
+    /**
+     * Add an "order by" clause for a pivot table column.
+     *
+     * @param  string  $column
+     * @param  string  $direction
+     * @return $this
+     */
+    public function orderByPivot($column, $direction = 'asc')
+    {
+        return $this->orderBy($this->qualifyPivotColumn($column), $direction);
+    }
+
+    /**
+     * Find a related model by its primary key or return a new instance of the related model.
+     *
+     * @param  mixed  $id
+     * @param  array  $columns
+     * @return \Illuminate\Support\Collection|\Illuminate\Database\Eloquent\Model
+     */
+    public function findOrNew($id, $columns = ['*'])
+    {
+        if (is_null($instance = $this->find($id, $columns))) {
+            $instance = $this->related->newInstance();
+        }
+
+        return $instance;
+    }
+
+    /**
+     * Get the first related model record matching the attributes or instantiate it.
+     *
+     * @param  array  $attributes
+     * @param  array  $values
+     * @return \Illuminate\Database\Eloquent\Model
+     */
+    public function firstOrNew(array $attributes = [], array $values = [])
+    {
+        if (is_null($instance = $this->related->where($attributes)->first())) {
+            $instance = $this->related->newInstance(array_merge($attributes, $values));
+        }
+
+        return $instance;
+    }
+
+    /**
+     * Get the first related record matching the attributes or create it.
+     *
+     * @param  array  $attributes
+     * @param  array  $values
+     * @param  array  $joining
+     * @param  bool  $touch
+     * @return \Illuminate\Database\Eloquent\Model
+     */
+    public function firstOrCreate(array $attributes = [], array $values = [], array $joining = [], $touch = true)
+    {
+        if (is_null($instance = (clone $this)->where($attributes)->first())) {
+            if (is_null($instance = $this->related->where($attributes)->first())) {
+                $instance = $this->create(array_merge($attributes, $values), $joining, $touch);
+            } else {
+                $this->attach($instance, $joining, $touch);
+            }
+        }
+
+        return $instance;
+    }
+
+    /**
+     * Create or update a related record matching the attributes, and fill it with values.
+     *
+     * @param  array  $attributes
+     * @param  array  $values
+     * @param  array  $joining
+     * @param  bool  $touch
+     * @return \Illuminate\Database\Eloquent\Model
+     */
+    public function updateOrCreate(array $attributes, array $values = [], array $joining = [], $touch = true)
+    {
+        if (is_null($instance = (clone $this)->where($attributes)->first())) {
+            if (is_null($instance = $this->related->where($attributes)->first())) {
+                return $this->create(array_merge($attributes, $values), $joining, $touch);
+            } else {
+                $this->attach($instance, $joining, $touch);
+            }
+        }
+
+        $instance->fill($values);
+
+        $instance->save(['touch' => false]);
+
+        return $instance;
+    }
+
+    /**
+     * Find a related model by its primary key.
+     *
+     * @param  mixed  $id
+     * @param  array  $columns
+     * @return \Illuminate\Database\Eloquent\Model|\Illuminate\Database\Eloquent\Collection|null
+     */
+    public function find($id, $columns = ['*'])
+    {
+        if (! $id instanceof Model && (is_array($id) || $id instanceof Arrayable)) {
+            return $this->findMany($id, $columns);
+        }
+
+        return $this->where(
+            $this->getRelated()->getQualifiedKeyName(), '=', $this->parseId($id)
+        )->first($columns);
+    }
+
+    /**
+     * Find multiple related models by their primary keys.
+     *
+     * @param  \Illuminate\Contracts\Support\Arrayable|array  $ids
+     * @param  array  $columns
+     * @return \Illuminate\Database\Eloquent\Collection
+     */
+    public function findMany($ids, $columns = ['*'])
+    {
+        $ids = $ids instanceof Arrayable ? $ids->toArray() : $ids;
+
+        if (empty($ids)) {
+            return $this->getRelated()->newCollection();
+        }
+
+        return $this->whereKey(
+            $this->parseIds($ids)
+        )->get($columns);
+    }
+
+    /**
+     * Find a related model by its primary key or throw an exception.
+     *
+     * @param  mixed  $id
+     * @param  array  $columns
+     * @return \Illuminate\Database\Eloquent\Model|\Illuminate\Database\Eloquent\Collection
+     *
+     * @throws \Illuminate\Database\Eloquent\ModelNotFoundException<\Illuminate\Database\Eloquent\Model>
+     */
+    public function findOrFail($id, $columns = ['*'])
+    {
+        $result = $this->find($id, $columns);
+
+        $id = $id instanceof Arrayable ? $id->toArray() : $id;
+
+        if (is_array($id)) {
+            if (count($result) === count(array_unique($id))) {
+                return $result;
+            }
+        } elseif (! is_null($result)) {
+            return $result;
+        }
+
+        throw (new ModelNotFoundException)->setModel(get_class($this->related), $id);
+    }
+
+    /**
+     * Find a related model by its primary key or call a callback.
+     *
+     * @param  mixed  $id
+     * @param  \Closure|array  $columns
+     * @param  \Closure|null  $callback
+     * @return \Illuminate\Database\Eloquent\Model|\Illuminate\Database\Eloquent\Collection|mixed
+     */
+    public function findOr($id, $columns = ['*'], Closure $callback = null)
+    {
+        if ($columns instanceof Closure) {
+            $callback = $columns;
+
+            $columns = ['*'];
+        }
+
+        $result = $this->find($id, $columns);
+
+        $id = $id instanceof Arrayable ? $id->toArray() : $id;
+
+        if (is_array($id)) {
+            if (count($result) === count(array_unique($id))) {
+                return $result;
+            }
+        } elseif (! is_null($result)) {
+            return $result;
+        }
+
+        return $callback();
+    }
+
+    /**
+     * Add a basic where clause to the query, and return the first result.
+     *
+     * @param  \Closure|string|array  $column
+     * @param  mixed  $operator
+     * @param  mixed  $value
+     * @param  string  $boolean
+     * @return \Illuminate\Database\Eloquent\Model|static
+     */
+    public function firstWhere($column, $operator = null, $value = null, $boolean = 'and')
+    {
+        return $this->where($column, $operator, $value, $boolean)->first();
+    }
+
+    /**
+     * Execute the query and get the first result.
+     *
+     * @param  array  $columns
+     * @return mixed
+     */
+    public function first($columns = ['*'])
+    {
+        $results = $this->take(1)->get($columns);
+
+        return count($results) > 0 ? $results->first() : null;
+    }
+
+    /**
+     * Execute the query and get the first result or throw an exception.
+     *
+     * @param  array  $columns
+     * @return \Illuminate\Database\Eloquent\Model|static
+     *
+     * @throws \Illuminate\Database\Eloquent\ModelNotFoundException<\Illuminate\Database\Eloquent\Model>
+     */
+    public function firstOrFail($columns = ['*'])
+    {
+        if (! is_null($model = $this->first($columns))) {
+            return $model;
+        }
+
+        throw (new ModelNotFoundException)->setModel(get_class($this->related));
+    }
+
+    /**
+     * Execute the query and get the first result or call a callback.
+     *
+     * @param  \Closure|array  $columns
+     * @param  \Closure|null  $callback
+     * @return \Illuminate\Database\Eloquent\Model|static|mixed
+     */
+    public function firstOr($columns = ['*'], Closure $callback = null)
+    {
+        if ($columns instanceof Closure) {
+            $callback = $columns;
+
+            $columns = ['*'];
+        }
+
+        if (! is_null($model = $this->first($columns))) {
+            return $model;
+        }
+
+        return $callback();
+    }
+
+    /**
+     * Get the results of the relationship.
+     *
+     * @return mixed
+     */
+    public function getResults()
+    {
+        return ! is_null($this->parent->{$this->parentKey})
+                ? $this->get()
+                : $this->related->newCollection();
+    }
+
+    /**
+     * Execute the query as a "select" statement.
+     *
+     * @param  array  $columns
+     * @return \Illuminate\Database\Eloquent\Collection
+     */
+    public function get($columns = ['*'])
+    {
+        // First we'll add the proper select columns onto the query so it is run with
+        // the proper columns. Then, we will get the results and hydrate our pivot
+        // models with the result of those columns as a separate model relation.
+        $builder = $this->query->applyScopes();
+
+        $columns = $builder->getQuery()->columns ? [] : $columns;
+
+        $models = $builder->addSelect(
+            $this->shouldSelect($columns)
+        )->getModels();
+
+        $this->hydratePivotRelation($models);
+
+        // If we actually found models we will also eager load any relationships that
+        // have been specified as needing to be eager loaded. This will solve the
+        // n + 1 query problem for the developer and also increase performance.
+        if (count($models) > 0) {
+            $models = $builder->eagerLoadRelations($models);
+        }
+
+        return $this->related->newCollection($models);
+    }
+
+    /**
+     * Get the select columns for the relation query.
+     *
+     * @param  array  $columns
+     * @return array
+     */
+    protected function shouldSelect(array $columns = ['*'])
+    {
+        if ($columns == ['*']) {
+            $columns = [$this->related->getTable().'.*'];
+        }
+
+        return array_merge($columns, $this->aliasedPivotColumns());
+    }
+
+    /**
+     * Get the pivot columns for the relation.
+     *
+     * "pivot_" is prefixed at each column for easy removal later.
+     *
+     * @return array
+     */
+    protected function aliasedPivotColumns()
+    {
+        $defaults = [$this->foreignPivotKey, $this->relatedPivotKey];
+
+        return collect(array_merge($defaults, $this->pivotColumns))->map(function ($column) {
+            return $this->qualifyPivotColumn($column).' as pivot_'.$column;
+        })->unique()->all();
+    }
+
+    /**
+     * Get a paginator for the "select" statement.
+     *
+     * @param  int|null  $perPage
+     * @param  array  $columns
+     * @param  string  $pageName
+     * @param  int|null  $page
+     * @return \Illuminate\Contracts\Pagination\LengthAwarePaginator
+     */
+    public function paginate($perPage = null, $columns = ['*'], $pageName = 'page', $page = null)
+    {
+        $this->query->addSelect($this->shouldSelect($columns));
+
+        return tap($this->query->paginate($perPage, $columns, $pageName, $page), function ($paginator) {
+            $this->hydratePivotRelation($paginator->items());
+        });
+    }
+
+    /**
+     * Paginate the given query into a simple paginator.
+     *
+     * @param  int|null  $perPage
+     * @param  array  $columns
+     * @param  string  $pageName
+     * @param  int|null  $page
+     * @return \Illuminate\Contracts\Pagination\Paginator
+     */
+    public function simplePaginate($perPage = null, $columns = ['*'], $pageName = 'page', $page = null)
+    {
+        $this->query->addSelect($this->shouldSelect($columns));
+
+        return tap($this->query->simplePaginate($perPage, $columns, $pageName, $page), function ($paginator) {
+            $this->hydratePivotRelation($paginator->items());
+        });
+    }
+
+    /**
+     * Paginate the given query into a cursor paginator.
+     *
+     * @param  int|null  $perPage
+     * @param  array  $columns
+     * @param  string  $cursorName
+     * @param  string|null  $cursor
+     * @return \Illuminate\Contracts\Pagination\CursorPaginator
+     */
+    public function cursorPaginate($perPage = null, $columns = ['*'], $cursorName = 'cursor', $cursor = null)
+    {
+        $this->query->addSelect($this->shouldSelect($columns));
+
+        return tap($this->query->cursorPaginate($perPage, $columns, $cursorName, $cursor), function ($paginator) {
+            $this->hydratePivotRelation($paginator->items());
+        });
+    }
+
+    /**
+     * Chunk the results of the query.
+     *
+     * @param  int  $count
+     * @param  callable  $callback
+     * @return bool
+     */
+    public function chunk($count, callable $callback)
+    {
+        return $this->prepareQueryBuilder()->chunk($count, function ($results, $page) use ($callback) {
+            $this->hydratePivotRelation($results->all());
+
+            return $callback($results, $page);
+        });
+    }
+
+    /**
+     * Chunk the results of a query by comparing numeric IDs.
+     *
+     * @param  int  $count
+     * @param  callable  $callback
+     * @param  string|null  $column
+     * @param  string|null  $alias
+     * @return bool
+     */
+    public function chunkById($count, callable $callback, $column = null, $alias = null)
+    {
+        $this->prepareQueryBuilder();
+
+        $column ??= $this->getRelated()->qualifyColumn(
+            $this->getRelatedKeyName()
+        );
+
+        $alias ??= $this->getRelatedKeyName();
+
+        return $this->query->chunkById($count, function ($results) use ($callback) {
+            $this->hydratePivotRelation($results->all());
+
+            return $callback($results);
+        }, $column, $alias);
+    }
+
+    /**
+     * Execute a callback over each item while chunking.
+     *
+     * @param  callable  $callback
+     * @param  int  $count
+     * @return bool
+     */
+    public function each(callable $callback, $count = 1000)
+    {
+        return $this->chunk($count, function ($results) use ($callback) {
+            foreach ($results as $key => $value) {
+                if ($callback($value, $key) === false) {
+                    return false;
+                }
+            }
+        });
+    }
+
+    /**
+     * Query lazily, by chunks of the given size.
+     *
+     * @param  int  $chunkSize
+     * @return \Illuminate\Support\LazyCollection
+     */
+    public function lazy($chunkSize = 1000)
+    {
+        return $this->prepareQueryBuilder()->lazy($chunkSize)->map(function ($model) {
+            $this->hydratePivotRelation([$model]);
+
+            return $model;
+        });
+    }
+
+    /**
+     * Query lazily, by chunking the results of a query by comparing IDs.
+     *
+     * @param  int  $chunkSize
+     * @param  string|null  $column
+     * @param  string|null  $alias
+     * @return \Illuminate\Support\LazyCollection
+     */
+    public function lazyById($chunkSize = 1000, $column = null, $alias = null)
+    {
+        $column ??= $this->getRelated()->qualifyColumn(
+            $this->getRelatedKeyName()
+        );
+
+        $alias ??= $this->getRelatedKeyName();
+
+        return $this->prepareQueryBuilder()->lazyById($chunkSize, $column, $alias)->map(function ($model) {
+            $this->hydratePivotRelation([$model]);
+
+            return $model;
+        });
+    }
+
+    /**
+     * Get a lazy collection for the given query.
+     *
+     * @return \Illuminate\Support\LazyCollection
+     */
+    public function cursor()
+    {
+        return $this->prepareQueryBuilder()->cursor()->map(function ($model) {
+            $this->hydratePivotRelation([$model]);
+
+            return $model;
+        });
+    }
+
+    /**
+     * Prepare the query builder for query execution.
+     *
+     * @return \Illuminate\Database\Eloquent\Builder
+     */
+    protected function prepareQueryBuilder()
+    {
+        return $this->query->addSelect($this->shouldSelect());
+    }
+
+    /**
+     * Hydrate the pivot table relationship on the models.
+     *
+     * @param  array  $models
+     * @return void
+     */
+    protected function hydratePivotRelation(array $models)
+    {
+        // To hydrate the pivot relationship, we will just gather the pivot attributes
+        // and create a new Pivot model, which is basically a dynamic model that we
+        // will set the attributes, table, and connections on it so it will work.
+        foreach ($models as $model) {
+            $model->setRelation($this->accessor, $this->newExistingPivot(
+                $this->migratePivotAttributes($model)
+            ));
+        }
+    }
+
+    /**
+     * Get the pivot attributes from a model.
+     *
+     * @param  \Illuminate\Database\Eloquent\Model  $model
+     * @return array
+     */
+    protected function migratePivotAttributes(Model $model)
+    {
+        $values = [];
+
+        foreach ($model->getAttributes() as $key => $value) {
+            // To get the pivots attributes we will just take any of the attributes which
+            // begin with "pivot_" and add those to this arrays, as well as unsetting
+            // them from the parent's models since they exist in a different table.
+            if (str_starts_with($key, 'pivot_')) {
+                $values[substr($key, 6)] = $value;
+
+                unset($model->$key);
+            }
+        }
+
+        return $values;
+    }
+
+    /**
+     * If we're touching the parent model, touch.
+     *
+     * @return void
+     */
+    public function touchIfTouching()
+    {
+        if ($this->touchingParent()) {
+            $this->getParent()->touch();
+        }
+
+        if ($this->getParent()->touches($this->relationName)) {
+            $this->touch();
+        }
+    }
+
+    /**
+     * Determine if we should touch the parent on sync.
+     *
+     * @return bool
+     */
+    protected function touchingParent()
+    {
+        return $this->getRelated()->touches($this->guessInverseRelation());
+    }
+
+    /**
+     * Attempt to guess the name of the inverse of the relation.
+     *
+     * @return string
+     */
+    protected function guessInverseRelation()
+    {
+        return Str::camel(Str::pluralStudly(class_basename($this->getParent())));
+    }
+
+    /**
+     * Touch all of the related models for the relationship.
+     *
+     * E.g.: Touch all roles associated with this user.
+     *
+     * @return void
+     */
+    public function touch()
+    {
+        $columns = [
+            $this->related->getUpdatedAtColumn() => $this->related->freshTimestampString(),
+        ];
+
+        // If we actually have IDs for the relation, we will run the query to update all
+        // the related model's timestamps, to make sure these all reflect the changes
+        // to the parent models. This will help us keep any caching synced up here.
+        if (count($ids = $this->allRelatedIds()) > 0) {
+            $this->getRelated()->newQueryWithoutRelationships()->whereKey($ids)->update($columns);
+        }
+    }
+
+    /**
+     * Get all of the IDs for the related models.
+     *
+     * @return \Illuminate\Support\Collection
+     */
+    public function allRelatedIds()
+    {
+        return $this->newPivotQuery()->pluck($this->relatedPivotKey);
+    }
+
+    /**
+     * Save a new model and attach it to the parent model.
+     *
+     * @param  \Illuminate\Database\Eloquent\Model  $model
+     * @param  array  $pivotAttributes
+     * @param  bool  $touch
+     * @return \Illuminate\Database\Eloquent\Model
+     */
+    public function save(Model $model, array $pivotAttributes = [], $touch = true)
+    {
+        $model->save(['touch' => false]);
+
+        $this->attach($model, $pivotAttributes, $touch);
+
+        return $model;
+    }
+
+    /**
+     * Save a new model without raising any events and attach it to the parent model.
+     *
+     * @param  \Illuminate\Database\Eloquent\Model  $model
+     * @param  array  $pivotAttributes
+     * @param  bool  $touch
+     * @return \Illuminate\Database\Eloquent\Model
+     */
+    public function saveQuietly(Model $model, array $pivotAttributes = [], $touch = true)
+    {
+        return Model::withoutEvents(function () use ($model, $pivotAttributes, $touch) {
+            return $this->save($model, $pivotAttributes, $touch);
+        });
+    }
+
+    /**
+     * Save an array of new models and attach them to the parent model.
+     *
+     * @param  \Illuminate\Support\Collection|array  $models
+     * @param  array  $pivotAttributes
+     * @return array
+     */
+    public function saveMany($models, array $pivotAttributes = [])
+    {
+        foreach ($models as $key => $model) {
+            $this->save($model, (array) ($pivotAttributes[$key] ?? []), false);
+        }
+
+        $this->touchIfTouching();
+
+        return $models;
+    }
+
+    /**
+     * Save an array of new models without raising any events and attach them to the parent model.
+     *
+     * @param  \Illuminate\Support\Collection|array  $models
+     * @param  array  $pivotAttributes
+     * @return array
+     */
+    public function saveManyQuietly($models, array $pivotAttributes = [])
+    {
+        return Model::withoutEvents(function () use ($models, $pivotAttributes) {
+            return $this->saveMany($models, $pivotAttributes);
+        });
+    }
+
+    /**
+     * Create a new instance of the related model.
+     *
+     * @param  array  $attributes
+     * @param  array  $joining
+     * @param  bool  $touch
+     * @return \Illuminate\Database\Eloquent\Model
+     */
+    public function create(array $attributes = [], array $joining = [], $touch = true)
+    {
+        $instance = $this->related->newInstance($attributes);
+
+        // Once we save the related model, we need to attach it to the base model via
+        // through intermediate table so we'll use the existing "attach" method to
+        // accomplish this which will insert the record and any more attributes.
+        $instance->save(['touch' => false]);
+
+        $this->attach($instance, $joining, $touch);
+
+        return $instance;
+    }
+
+    /**
+     * Create an array of new instances of the related models.
+     *
+     * @param  iterable  $records
+     * @param  array  $joinings
+     * @return array
+     */
+    public function createMany(iterable $records, array $joinings = [])
+    {
+        $instances = [];
+
+        foreach ($records as $key => $record) {
+            $instances[] = $this->create($record, (array) ($joinings[$key] ?? []), false);
+        }
+
+        $this->touchIfTouching();
+
+        return $instances;
+    }
+
+    /**
+     * Add the constraints for a relationship query.
+     *
+     * @param  \Illuminate\Database\Eloquent\Builder  $query
+     * @param  \Illuminate\Database\Eloquent\Builder  $parentQuery
+     * @param  array|mixed  $columns
+     * @return \Illuminate\Database\Eloquent\Builder
+     */
+    public function getRelationExistenceQuery(Builder $query, Builder $parentQuery, $columns = ['*'])
+    {
+        if ($parentQuery->getQuery()->from == $query->getQuery()->from) {
+            return $this->getRelationExistenceQueryForSelfJoin($query, $parentQuery, $columns);
+        }
+
+        $this->performJoin($query);
+
+        return parent::getRelationExistenceQuery($query, $parentQuery, $columns);
+    }
+
+    /**
+     * Add the constraints for a relationship query on the same table.
+     *
+     * @param  \Illuminate\Database\Eloquent\Builder  $query
+     * @param  \Illuminate\Database\Eloquent\Builder  $parentQuery
+     * @param  array|mixed  $columns
+     * @return \Illuminate\Database\Eloquent\Builder
+     */
+    public function getRelationExistenceQueryForSelfJoin(Builder $query, Builder $parentQuery, $columns = ['*'])
+    {
+        $query->select($columns);
+
+        $query->from($this->related->getTable().' as '.$hash = $this->getRelationCountHash());
+
+        $this->related->setTable($hash);
+
+        $this->performJoin($query);
+
+        return parent::getRelationExistenceQuery($query, $parentQuery, $columns);
+    }
+
+    /**
+     * Get the key for comparing against the parent key in "has" query.
+     *
+     * @return string
+     */
+    public function getExistenceCompareKey()
+    {
+        return $this->getQualifiedForeignPivotKeyName();
+    }
+
+    /**
+     * Specify that the pivot table has creation and update timestamps.
+     *
+     * @param  mixed  $createdAt
+     * @param  mixed  $updatedAt
+     * @return $this
+     */
+    public function withTimestamps($createdAt = null, $updatedAt = null)
+    {
+        $this->withTimestamps = true;
+
+        $this->pivotCreatedAt = $createdAt;
+        $this->pivotUpdatedAt = $updatedAt;
+
+        return $this->withPivot($this->createdAt(), $this->updatedAt());
+    }
+
+    /**
+     * Get the name of the "created at" column.
+     *
+     * @return string
+     */
+    public function createdAt()
+    {
+        return $this->pivotCreatedAt ?: $this->parent->getCreatedAtColumn();
+    }
+
+    /**
+     * Get the name of the "updated at" column.
+     *
+     * @return string
+     */
+    public function updatedAt()
+    {
+        return $this->pivotUpdatedAt ?: $this->parent->getUpdatedAtColumn();
+    }
+
+    /**
+     * Get the foreign key for the relation.
+     *
+     * @return string
+     */
+    public function getForeignPivotKeyName()
+    {
+        return $this->foreignPivotKey;
+    }
+
+    /**
+     * Get the fully qualified foreign key for the relation.
+     *
+     * @return string
+     */
+    public function getQualifiedForeignPivotKeyName()
+    {
+        return $this->qualifyPivotColumn($this->foreignPivotKey);
+    }
+
+    /**
+     * Get the "related key" for the relation.
+     *
+     * @return string
+     */
+    public function getRelatedPivotKeyName()
+    {
+        return $this->relatedPivotKey;
+    }
+
+    /**
+     * Get the fully qualified "related key" for the relation.
+     *
+     * @return string
+     */
+    public function getQualifiedRelatedPivotKeyName()
+    {
+        return $this->qualifyPivotColumn($this->relatedPivotKey);
+    }
+
+    /**
+     * Get the parent key for the relationship.
+     *
+     * @return string
+     */
+    public function getParentKeyName()
+    {
+        return $this->parentKey;
+    }
+
+    /**
+     * Get the fully qualified parent key name for the relation.
+     *
+     * @return string
+     */
+    public function getQualifiedParentKeyName()
+    {
+        return $this->parent->qualifyColumn($this->parentKey);
+    }
+
+    /**
+     * Get the related key for the relationship.
+     *
+     * @return string
+     */
+    public function getRelatedKeyName()
+    {
+        return $this->relatedKey;
+    }
+
+    /**
+     * Get the fully qualified related key name for the relation.
+     *
+     * @return string
+     */
+    public function getQualifiedRelatedKeyName()
+    {
+        return $this->related->qualifyColumn($this->relatedKey);
+    }
+
+    /**
+     * Get the intermediate table for the relationship.
+     *
+     * @return string
+     */
+    public function getTable()
+    {
+        return $this->table;
+    }
+
+    /**
+     * Get the relationship name for the relationship.
+     *
+     * @return string
+     */
+    public function getRelationName()
+    {
+        return $this->relationName;
+    }
+
+    /**
+     * Get the name of the pivot accessor for this relationship.
+     *
+     * @return string
+     */
+    public function getPivotAccessor()
+    {
+        return $this->accessor;
+    }
+
+    /**
+     * Get the pivot columns for this relationship.
+     *
+     * @return array
+     */
+    public function getPivotColumns()
+    {
+        return $this->pivotColumns;
+    }
+
+    /**
+     * Qualify the given column name by the pivot table.
+     *
+     * @param  string  $column
+     * @return string
+     */
+    public function qualifyPivotColumn($column)
+    {
+        return str_contains($column, '.')
+                    ? $column
+                    : $this->table.'.'.$column;
+    }
+}
diff --git a/vendor/illuminate/database/Eloquent/Relations/Concerns/AsPivot.php b/vendor/illuminate/database/Eloquent/Relations/Concerns/AsPivot.php
new file mode 100644
index 0000000..e6f9f23
--- /dev/null
+++ b/vendor/illuminate/database/Eloquent/Relations/Concerns/AsPivot.php
@@ -0,0 +1,333 @@
+timestamps = $instance->hasTimestampAttributes($attributes);
+
+        // The pivot model is a "dynamic" model since we will set the tables dynamically
+        // for the instance. This allows it work for any intermediate tables for the
+        // many to many relationship that are defined by this developer's classes.
+        $instance->setConnection($parent->getConnectionName())
+            ->setTable($table)
+            ->forceFill($attributes)
+            ->syncOriginal();
+
+        // We store off the parent instance so we will access the timestamp column names
+        // for the model, since the pivot model timestamps aren't easily configurable
+        // from the developer's point of view. We can use the parents to get these.
+        $instance->pivotParent = $parent;
+
+        $instance->exists = $exists;
+
+        return $instance;
+    }
+
+    /**
+     * Create a new pivot model from raw values returned from a query.
+     *
+     * @param  \Illuminate\Database\Eloquent\Model  $parent
+     * @param  array  $attributes
+     * @param  string  $table
+     * @param  bool  $exists
+     * @return static
+     */
+    public static function fromRawAttributes(Model $parent, $attributes, $table, $exists = false)
+    {
+        $instance = static::fromAttributes($parent, [], $table, $exists);
+
+        $instance->timestamps = $instance->hasTimestampAttributes($attributes);
+
+        $instance->setRawAttributes(
+            array_merge($instance->getRawOriginal(), $attributes), $exists
+        );
+
+        return $instance;
+    }
+
+    /**
+     * Set the keys for a select query.
+     *
+     * @param  \Illuminate\Database\Eloquent\Builder  $query
+     * @return \Illuminate\Database\Eloquent\Builder
+     */
+    protected function setKeysForSelectQuery($query)
+    {
+        if (isset($this->attributes[$this->getKeyName()])) {
+            return parent::setKeysForSelectQuery($query);
+        }
+
+        $query->where($this->foreignKey, $this->getOriginal(
+            $this->foreignKey, $this->getAttribute($this->foreignKey)
+        ));
+
+        return $query->where($this->relatedKey, $this->getOriginal(
+            $this->relatedKey, $this->getAttribute($this->relatedKey)
+        ));
+    }
+
+    /**
+     * Set the keys for a save update query.
+     *
+     * @param  \Illuminate\Database\Eloquent\Builder  $query
+     * @return \Illuminate\Database\Eloquent\Builder
+     */
+    protected function setKeysForSaveQuery($query)
+    {
+        return $this->setKeysForSelectQuery($query);
+    }
+
+    /**
+     * Delete the pivot model record from the database.
+     *
+     * @return int
+     */
+    public function delete()
+    {
+        if (isset($this->attributes[$this->getKeyName()])) {
+            return (int) parent::delete();
+        }
+
+        if ($this->fireModelEvent('deleting') === false) {
+            return 0;
+        }
+
+        $this->touchOwners();
+
+        return tap($this->getDeleteQuery()->delete(), function () {
+            $this->exists = false;
+
+            $this->fireModelEvent('deleted', false);
+        });
+    }
+
+    /**
+     * Get the query builder for a delete operation on the pivot.
+     *
+     * @return \Illuminate\Database\Eloquent\Builder
+     */
+    protected function getDeleteQuery()
+    {
+        return $this->newQueryWithoutRelationships()->where([
+            $this->foreignKey => $this->getOriginal($this->foreignKey, $this->getAttribute($this->foreignKey)),
+            $this->relatedKey => $this->getOriginal($this->relatedKey, $this->getAttribute($this->relatedKey)),
+        ]);
+    }
+
+    /**
+     * Get the table associated with the model.
+     *
+     * @return string
+     */
+    public function getTable()
+    {
+        if (! isset($this->table)) {
+            $this->setTable(str_replace(
+                '\\', '', Str::snake(Str::singular(class_basename($this)))
+            ));
+        }
+
+        return $this->table;
+    }
+
+    /**
+     * Get the foreign key column name.
+     *
+     * @return string
+     */
+    public function getForeignKey()
+    {
+        return $this->foreignKey;
+    }
+
+    /**
+     * Get the "related key" column name.
+     *
+     * @return string
+     */
+    public function getRelatedKey()
+    {
+        return $this->relatedKey;
+    }
+
+    /**
+     * Get the "related key" column name.
+     *
+     * @return string
+     */
+    public function getOtherKey()
+    {
+        return $this->getRelatedKey();
+    }
+
+    /**
+     * Set the key names for the pivot model instance.
+     *
+     * @param  string  $foreignKey
+     * @param  string  $relatedKey
+     * @return $this
+     */
+    public function setPivotKeys($foreignKey, $relatedKey)
+    {
+        $this->foreignKey = $foreignKey;
+
+        $this->relatedKey = $relatedKey;
+
+        return $this;
+    }
+
+    /**
+     * Determine if the pivot model or given attributes has timestamp attributes.
+     *
+     * @param  array|null  $attributes
+     * @return bool
+     */
+    public function hasTimestampAttributes($attributes = null)
+    {
+        return array_key_exists($this->getCreatedAtColumn(), $attributes ?? $this->attributes);
+    }
+
+    /**
+     * Get the name of the "created at" column.
+     *
+     * @return string
+     */
+    public function getCreatedAtColumn()
+    {
+        return $this->pivotParent
+            ? $this->pivotParent->getCreatedAtColumn()
+            : parent::getCreatedAtColumn();
+    }
+
+    /**
+     * Get the name of the "updated at" column.
+     *
+     * @return string
+     */
+    public function getUpdatedAtColumn()
+    {
+        return $this->pivotParent
+            ? $this->pivotParent->getUpdatedAtColumn()
+            : parent::getUpdatedAtColumn();
+    }
+
+    /**
+     * Get the queueable identity for the entity.
+     *
+     * @return mixed
+     */
+    public function getQueueableId()
+    {
+        if (isset($this->attributes[$this->getKeyName()])) {
+            return $this->getKey();
+        }
+
+        return sprintf(
+            '%s:%s:%s:%s',
+            $this->foreignKey, $this->getAttribute($this->foreignKey),
+            $this->relatedKey, $this->getAttribute($this->relatedKey)
+        );
+    }
+
+    /**
+     * Get a new query to restore one or more models by their queueable IDs.
+     *
+     * @param  int[]|string[]|string  $ids
+     * @return \Illuminate\Database\Eloquent\Builder
+     */
+    public function newQueryForRestoration($ids)
+    {
+        if (is_array($ids)) {
+            return $this->newQueryForCollectionRestoration($ids);
+        }
+
+        if (! str_contains($ids, ':')) {
+            return parent::newQueryForRestoration($ids);
+        }
+
+        $segments = explode(':', $ids);
+
+        return $this->newQueryWithoutScopes()
+            ->where($segments[0], $segments[1])
+            ->where($segments[2], $segments[3]);
+    }
+
+    /**
+     * Get a new query to restore multiple models by their queueable IDs.
+     *
+     * @param  int[]|string[]  $ids
+     * @return \Illuminate\Database\Eloquent\Builder
+     */
+    protected function newQueryForCollectionRestoration(array $ids)
+    {
+        $ids = array_values($ids);
+
+        if (! str_contains($ids[0], ':')) {
+            return parent::newQueryForRestoration($ids);
+        }
+
+        $query = $this->newQueryWithoutScopes();
+
+        foreach ($ids as $id) {
+            $segments = explode(':', $id);
+
+            $query->orWhere(function ($query) use ($segments) {
+                return $query->where($segments[0], $segments[1])
+                    ->where($segments[2], $segments[3]);
+            });
+        }
+
+        return $query;
+    }
+
+    /**
+     * Unset all the loaded relations for the instance.
+     *
+     * @return $this
+     */
+    public function unsetRelations()
+    {
+        $this->pivotParent = null;
+        $this->relations = [];
+
+        return $this;
+    }
+}
diff --git a/vendor/illuminate/database/Eloquent/Relations/Concerns/CanBeOneOfMany.php b/vendor/illuminate/database/Eloquent/Relations/Concerns/CanBeOneOfMany.php
new file mode 100644
index 0000000..25b9a58
--- /dev/null
+++ b/vendor/illuminate/database/Eloquent/Relations/Concerns/CanBeOneOfMany.php
@@ -0,0 +1,310 @@
+isOneOfMany = true;
+
+        $this->relationName = $relation ?: $this->getDefaultOneOfManyJoinAlias(
+            $this->guessRelationship()
+        );
+
+        $keyName = $this->query->getModel()->getKeyName();
+
+        $columns = is_string($columns = $column) ? [
+            $column => $aggregate,
+            $keyName => $aggregate,
+        ] : $column;
+
+        if (! array_key_exists($keyName, $columns)) {
+            $columns[$keyName] = 'MAX';
+        }
+
+        if ($aggregate instanceof Closure) {
+            $closure = $aggregate;
+        }
+
+        foreach ($columns as $column => $aggregate) {
+            if (! in_array(strtolower($aggregate), ['min', 'max'])) {
+                throw new InvalidArgumentException("Invalid aggregate [{$aggregate}] used within ofMany relation. Available aggregates: MIN, MAX");
+            }
+
+            $subQuery = $this->newOneOfManySubQuery(
+                $this->getOneOfManySubQuerySelectColumns(),
+                $column, $aggregate
+            );
+
+            if (isset($previous)) {
+                $this->addOneOfManyJoinSubQuery($subQuery, $previous['subQuery'], $previous['column']);
+            }
+
+            if (isset($closure)) {
+                $closure($subQuery);
+            }
+
+            if (! isset($previous)) {
+                $this->oneOfManySubQuery = $subQuery;
+            }
+
+            if (array_key_last($columns) == $column) {
+                $this->addOneOfManyJoinSubQuery($this->query, $subQuery, $column);
+            }
+
+            $previous = [
+                'subQuery' => $subQuery,
+                'column' => $column,
+            ];
+        }
+
+        $this->addConstraints();
+
+        $columns = $this->query->getQuery()->columns;
+
+        if (is_null($columns) || $columns === ['*']) {
+            $this->select([$this->qualifyColumn('*')]);
+        }
+
+        return $this;
+    }
+
+    /**
+     * Indicate that the relation is the latest single result of a larger one-to-many relationship.
+     *
+     * @param  string|array|null  $column
+     * @param  string|null  $relation
+     * @return $this
+     */
+    public function latestOfMany($column = 'id', $relation = null)
+    {
+        return $this->ofMany(collect(Arr::wrap($column))->mapWithKeys(function ($column) {
+            return [$column => 'MAX'];
+        })->all(), 'MAX', $relation);
+    }
+
+    /**
+     * Indicate that the relation is the oldest single result of a larger one-to-many relationship.
+     *
+     * @param  string|array|null  $column
+     * @param  string|null  $relation
+     * @return $this
+     */
+    public function oldestOfMany($column = 'id', $relation = null)
+    {
+        return $this->ofMany(collect(Arr::wrap($column))->mapWithKeys(function ($column) {
+            return [$column => 'MIN'];
+        })->all(), 'MIN', $relation);
+    }
+
+    /**
+     * Get the default alias for the one of many inner join clause.
+     *
+     * @param  string  $relation
+     * @return string
+     */
+    protected function getDefaultOneOfManyJoinAlias($relation)
+    {
+        return $relation == $this->query->getModel()->getTable()
+            ? $relation.'_of_many'
+            : $relation;
+    }
+
+    /**
+     * Get a new query for the related model, grouping the query by the given column, often the foreign key of the relationship.
+     *
+     * @param  string|array  $groupBy
+     * @param  string|null  $column
+     * @param  string|null  $aggregate
+     * @return \Illuminate\Database\Eloquent\Builder
+     */
+    protected function newOneOfManySubQuery($groupBy, $column = null, $aggregate = null)
+    {
+        $subQuery = $this->query->getModel()
+            ->newQuery()
+            ->withoutGlobalScopes($this->removedScopes());
+
+        foreach (Arr::wrap($groupBy) as $group) {
+            $subQuery->groupBy($this->qualifyRelatedColumn($group));
+        }
+
+        if (! is_null($column)) {
+            $subQuery->selectRaw($aggregate.'('.$subQuery->getQuery()->grammar->wrap($subQuery->qualifyColumn($column)).') as '.$subQuery->getQuery()->grammar->wrap($column.'_aggregate'));
+        }
+
+        $this->addOneOfManySubQueryConstraints($subQuery, $groupBy, $column, $aggregate);
+
+        return $subQuery;
+    }
+
+    /**
+     * Add the join subquery to the given query on the given column and the relationship's foreign key.
+     *
+     * @param  \Illuminate\Database\Eloquent\Builder  $parent
+     * @param  \Illuminate\Database\Eloquent\Builder  $subQuery
+     * @param  string  $on
+     * @return void
+     */
+    protected function addOneOfManyJoinSubQuery(Builder $parent, Builder $subQuery, $on)
+    {
+        $parent->beforeQuery(function ($parent) use ($subQuery, $on) {
+            $subQuery->applyBeforeQueryCallbacks();
+
+            $parent->joinSub($subQuery, $this->relationName, function ($join) use ($on) {
+                $join->on($this->qualifySubSelectColumn($on.'_aggregate'), '=', $this->qualifyRelatedColumn($on));
+
+                $this->addOneOfManyJoinSubQueryConstraints($join, $on);
+            });
+        });
+    }
+
+    /**
+     * Merge the relationship query joins to the given query builder.
+     *
+     * @param  \Illuminate\Database\Eloquent\Builder  $query
+     * @return void
+     */
+    protected function mergeOneOfManyJoinsTo(Builder $query)
+    {
+        $query->getQuery()->beforeQueryCallbacks = $this->query->getQuery()->beforeQueryCallbacks;
+
+        $query->applyBeforeQueryCallbacks();
+    }
+
+    /**
+     * Get the query builder that will contain the relationship constraints.
+     *
+     * @return \Illuminate\Database\Eloquent\Builder
+     */
+    protected function getRelationQuery()
+    {
+        return $this->isOneOfMany()
+            ? $this->oneOfManySubQuery
+            : $this->query;
+    }
+
+    /**
+     * Get the one of many inner join subselect builder instance.
+     *
+     * @return \Illuminate\Database\Eloquent\Builder|void
+     */
+    public function getOneOfManySubQuery()
+    {
+        return $this->oneOfManySubQuery;
+    }
+
+    /**
+     * Get the qualified column name for the one-of-many relationship using the subselect join query's alias.
+     *
+     * @param  string  $column
+     * @return string
+     */
+    public function qualifySubSelectColumn($column)
+    {
+        return $this->getRelationName().'.'.last(explode('.', $column));
+    }
+
+    /**
+     * Qualify related column using the related table name if it is not already qualified.
+     *
+     * @param  string  $column
+     * @return string
+     */
+    protected function qualifyRelatedColumn($column)
+    {
+        return str_contains($column, '.') ? $column : $this->query->getModel()->getTable().'.'.$column;
+    }
+
+    /**
+     * Guess the "hasOne" relationship's name via backtrace.
+     *
+     * @return string
+     */
+    protected function guessRelationship()
+    {
+        return debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, 3)[2]['function'];
+    }
+
+    /**
+     * Determine whether the relationship is a one-of-many relationship.
+     *
+     * @return bool
+     */
+    public function isOneOfMany()
+    {
+        return $this->isOneOfMany;
+    }
+
+    /**
+     * Get the name of the relationship.
+     *
+     * @return string
+     */
+    public function getRelationName()
+    {
+        return $this->relationName;
+    }
+}
diff --git a/vendor/illuminate/database/Eloquent/Relations/Concerns/ComparesRelatedModels.php b/vendor/illuminate/database/Eloquent/Relations/Concerns/ComparesRelatedModels.php
new file mode 100644
index 0000000..ca06698
--- /dev/null
+++ b/vendor/illuminate/database/Eloquent/Relations/Concerns/ComparesRelatedModels.php
@@ -0,0 +1,77 @@
+compareKeys($this->getParentKey(), $this->getRelatedKeyFrom($model)) &&
+               $this->related->getTable() === $model->getTable() &&
+               $this->related->getConnectionName() === $model->getConnectionName();
+
+        if ($match && $this instanceof SupportsPartialRelations && $this->isOneOfMany()) {
+            return $this->query
+                        ->whereKey($model->getKey())
+                        ->exists();
+        }
+
+        return $match;
+    }
+
+    /**
+     * Determine if the model is not the related instance of the relationship.
+     *
+     * @param  \Illuminate\Database\Eloquent\Model|null  $model
+     * @return bool
+     */
+    public function isNot($model)
+    {
+        return ! $this->is($model);
+    }
+
+    /**
+     * Get the value of the parent model's key.
+     *
+     * @return mixed
+     */
+    abstract public function getParentKey();
+
+    /**
+     * Get the value of the model's related key.
+     *
+     * @param  \Illuminate\Database\Eloquent\Model  $model
+     * @return mixed
+     */
+    abstract protected function getRelatedKeyFrom(Model $model);
+
+    /**
+     * Compare the parent key with the related key.
+     *
+     * @param  mixed  $parentKey
+     * @param  mixed  $relatedKey
+     * @return bool
+     */
+    protected function compareKeys($parentKey, $relatedKey)
+    {
+        if (empty($parentKey) || empty($relatedKey)) {
+            return false;
+        }
+
+        if (is_int($parentKey) || is_int($relatedKey)) {
+            return (int) $parentKey === (int) $relatedKey;
+        }
+
+        return $parentKey === $relatedKey;
+    }
+}
diff --git a/vendor/illuminate/database/Eloquent/Relations/Concerns/InteractsWithDictionary.php b/vendor/illuminate/database/Eloquent/Relations/Concerns/InteractsWithDictionary.php
new file mode 100644
index 0000000..91b3bf5
--- /dev/null
+++ b/vendor/illuminate/database/Eloquent/Relations/Concerns/InteractsWithDictionary.php
@@ -0,0 +1,36 @@
+__toString();
+            }
+
+            if (function_exists('enum_exists') &&
+                $attribute instanceof UnitEnum) {
+                return $attribute instanceof BackedEnum ? $attribute->value : $attribute->name;
+            }
+
+            throw new InvalidArgumentException('Model attribute value is an object but does not have a __toString method.');
+        }
+
+        return $attribute;
+    }
+}
diff --git a/vendor/illuminate/database/Eloquent/Relations/Concerns/InteractsWithPivotTable.php b/vendor/illuminate/database/Eloquent/Relations/Concerns/InteractsWithPivotTable.php
new file mode 100644
index 0000000..2241719
--- /dev/null
+++ b/vendor/illuminate/database/Eloquent/Relations/Concerns/InteractsWithPivotTable.php
@@ -0,0 +1,681 @@
+ [], 'detached' => [],
+        ];
+
+        $records = $this->formatRecordsList($this->parseIds($ids));
+
+        // Next, we will determine which IDs should get removed from the join table by
+        // checking which of the given ID/records is in the list of current records
+        // and removing all of those rows from this "intermediate" joining table.
+        $detach = array_values(array_intersect(
+            $this->newPivotQuery()->pluck($this->relatedPivotKey)->all(),
+            array_keys($records)
+        ));
+
+        if (count($detach) > 0) {
+            $this->detach($detach, false);
+
+            $changes['detached'] = $this->castKeys($detach);
+        }
+
+        // Finally, for all of the records which were not "detached", we'll attach the
+        // records into the intermediate table. Then, we will add those attaches to
+        // this change list and get ready to return these results to the callers.
+        $attach = array_diff_key($records, array_flip($detach));
+
+        if (count($attach) > 0) {
+            $this->attach($attach, [], false);
+
+            $changes['attached'] = array_keys($attach);
+        }
+
+        // Once we have finished attaching or detaching the records, we will see if we
+        // have done any attaching or detaching, and if we have we will touch these
+        // relationships if they are configured to touch on any database updates.
+        if ($touch && (count($changes['attached']) ||
+                       count($changes['detached']))) {
+            $this->touchIfTouching();
+        }
+
+        return $changes;
+    }
+
+    /**
+     * Sync the intermediate tables with a list of IDs without detaching.
+     *
+     * @param  \Illuminate\Support\Collection|\Illuminate\Database\Eloquent\Model|array  $ids
+     * @return array
+     */
+    public function syncWithoutDetaching($ids)
+    {
+        return $this->sync($ids, false);
+    }
+
+    /**
+     * Sync the intermediate tables with a list of IDs or collection of models.
+     *
+     * @param  \Illuminate\Support\Collection|\Illuminate\Database\Eloquent\Model|array  $ids
+     * @param  bool  $detaching
+     * @return array
+     */
+    public function sync($ids, $detaching = true)
+    {
+        $changes = [
+            'attached' => [], 'detached' => [], 'updated' => [],
+        ];
+
+        // First we need to attach any of the associated models that are not currently
+        // in this joining table. We'll spin through the given IDs, checking to see
+        // if they exist in the array of current ones, and if not we will insert.
+        $current = $this->getCurrentlyAttachedPivots()
+                        ->pluck($this->relatedPivotKey)->all();
+
+        $records = $this->formatRecordsList($this->parseIds($ids));
+
+        // Next, we will take the differences of the currents and given IDs and detach
+        // all of the entities that exist in the "current" array but are not in the
+        // array of the new IDs given to the method which will complete the sync.
+        if ($detaching) {
+            $detach = array_diff($current, array_keys($records));
+
+            if (count($detach) > 0) {
+                $this->detach($detach);
+
+                $changes['detached'] = $this->castKeys($detach);
+            }
+        }
+
+        // Now we are finally ready to attach the new records. Note that we'll disable
+        // touching until after the entire operation is complete so we don't fire a
+        // ton of touch operations until we are totally done syncing the records.
+        $changes = array_merge(
+            $changes, $this->attachNew($records, $current, false)
+        );
+
+        // Once we have finished attaching or detaching the records, we will see if we
+        // have done any attaching or detaching, and if we have we will touch these
+        // relationships if they are configured to touch on any database updates.
+        if (count($changes['attached']) ||
+            count($changes['updated']) ||
+            count($changes['detached'])) {
+            $this->touchIfTouching();
+        }
+
+        return $changes;
+    }
+
+    /**
+     * Sync the intermediate tables with a list of IDs or collection of models with the given pivot values.
+     *
+     * @param  \Illuminate\Support\Collection|\Illuminate\Database\Eloquent\Model|array  $ids
+     * @param  array  $values
+     * @param  bool  $detaching
+     * @return array
+     */
+    public function syncWithPivotValues($ids, array $values, bool $detaching = true)
+    {
+        return $this->sync(collect($this->parseIds($ids))->mapWithKeys(function ($id) use ($values) {
+            return [$id => $values];
+        }), $detaching);
+    }
+
+    /**
+     * Format the sync / toggle record list so that it is keyed by ID.
+     *
+     * @param  array  $records
+     * @return array
+     */
+    protected function formatRecordsList(array $records)
+    {
+        return collect($records)->mapWithKeys(function ($attributes, $id) {
+            if (! is_array($attributes)) {
+                [$id, $attributes] = [$attributes, []];
+            }
+
+            return [$id => $attributes];
+        })->all();
+    }
+
+    /**
+     * Attach all of the records that aren't in the given current records.
+     *
+     * @param  array  $records
+     * @param  array  $current
+     * @param  bool  $touch
+     * @return array
+     */
+    protected function attachNew(array $records, array $current, $touch = true)
+    {
+        $changes = ['attached' => [], 'updated' => []];
+
+        foreach ($records as $id => $attributes) {
+            // If the ID is not in the list of existing pivot IDs, we will insert a new pivot
+            // record, otherwise, we will just update this existing record on this joining
+            // table, so that the developers will easily update these records pain free.
+            if (! in_array($id, $current)) {
+                $this->attach($id, $attributes, $touch);
+
+                $changes['attached'][] = $this->castKey($id);
+            }
+
+            // Now we'll try to update an existing pivot record with the attributes that were
+            // given to the method. If the model is actually updated we will add it to the
+            // list of updated pivot records so we return them back out to the consumer.
+            elseif (count($attributes) > 0 &&
+                $this->updateExistingPivot($id, $attributes, $touch)) {
+                $changes['updated'][] = $this->castKey($id);
+            }
+        }
+
+        return $changes;
+    }
+
+    /**
+     * Update an existing pivot record on the table.
+     *
+     * @param  mixed  $id
+     * @param  array  $attributes
+     * @param  bool  $touch
+     * @return int
+     */
+    public function updateExistingPivot($id, array $attributes, $touch = true)
+    {
+        if ($this->using &&
+            empty($this->pivotWheres) &&
+            empty($this->pivotWhereIns) &&
+            empty($this->pivotWhereNulls)) {
+            return $this->updateExistingPivotUsingCustomClass($id, $attributes, $touch);
+        }
+
+        if ($this->hasPivotColumn($this->updatedAt())) {
+            $attributes = $this->addTimestampsToAttachment($attributes, true);
+        }
+
+        $updated = $this->newPivotStatementForId($this->parseId($id))->update(
+            $this->castAttributes($attributes)
+        );
+
+        if ($touch) {
+            $this->touchIfTouching();
+        }
+
+        return $updated;
+    }
+
+    /**
+     * Update an existing pivot record on the table via a custom class.
+     *
+     * @param  mixed  $id
+     * @param  array  $attributes
+     * @param  bool  $touch
+     * @return int
+     */
+    protected function updateExistingPivotUsingCustomClass($id, array $attributes, $touch)
+    {
+        $pivot = $this->getCurrentlyAttachedPivots()
+                    ->where($this->foreignPivotKey, $this->parent->{$this->parentKey})
+                    ->where($this->relatedPivotKey, $this->parseId($id))
+                    ->first();
+
+        $updated = $pivot ? $pivot->fill($attributes)->isDirty() : false;
+
+        if ($updated) {
+            $pivot->save();
+        }
+
+        if ($touch) {
+            $this->touchIfTouching();
+        }
+
+        return (int) $updated;
+    }
+
+    /**
+     * Attach a model to the parent.
+     *
+     * @param  mixed  $id
+     * @param  array  $attributes
+     * @param  bool  $touch
+     * @return void
+     */
+    public function attach($id, array $attributes = [], $touch = true)
+    {
+        if ($this->using) {
+            $this->attachUsingCustomClass($id, $attributes);
+        } else {
+            // Here we will insert the attachment records into the pivot table. Once we have
+            // inserted the records, we will touch the relationships if necessary and the
+            // function will return. We can parse the IDs before inserting the records.
+            $this->newPivotStatement()->insert($this->formatAttachRecords(
+                $this->parseIds($id), $attributes
+            ));
+        }
+
+        if ($touch) {
+            $this->touchIfTouching();
+        }
+    }
+
+    /**
+     * Attach a model to the parent using a custom class.
+     *
+     * @param  mixed  $id
+     * @param  array  $attributes
+     * @return void
+     */
+    protected function attachUsingCustomClass($id, array $attributes)
+    {
+        $records = $this->formatAttachRecords(
+            $this->parseIds($id), $attributes
+        );
+
+        foreach ($records as $record) {
+            $this->newPivot($record, false)->save();
+        }
+    }
+
+    /**
+     * Create an array of records to insert into the pivot table.
+     *
+     * @param  array  $ids
+     * @param  array  $attributes
+     * @return array
+     */
+    protected function formatAttachRecords($ids, array $attributes)
+    {
+        $records = [];
+
+        $hasTimestamps = ($this->hasPivotColumn($this->createdAt()) ||
+                  $this->hasPivotColumn($this->updatedAt()));
+
+        // To create the attachment records, we will simply spin through the IDs given
+        // and create a new record to insert for each ID. Each ID may actually be a
+        // key in the array, with extra attributes to be placed in other columns.
+        foreach ($ids as $key => $value) {
+            $records[] = $this->formatAttachRecord(
+                $key, $value, $attributes, $hasTimestamps
+            );
+        }
+
+        return $records;
+    }
+
+    /**
+     * Create a full attachment record payload.
+     *
+     * @param  int  $key
+     * @param  mixed  $value
+     * @param  array  $attributes
+     * @param  bool  $hasTimestamps
+     * @return array
+     */
+    protected function formatAttachRecord($key, $value, $attributes, $hasTimestamps)
+    {
+        [$id, $attributes] = $this->extractAttachIdAndAttributes($key, $value, $attributes);
+
+        return array_merge(
+            $this->baseAttachRecord($id, $hasTimestamps), $this->castAttributes($attributes)
+        );
+    }
+
+    /**
+     * Get the attach record ID and extra attributes.
+     *
+     * @param  mixed  $key
+     * @param  mixed  $value
+     * @param  array  $attributes
+     * @return array
+     */
+    protected function extractAttachIdAndAttributes($key, $value, array $attributes)
+    {
+        return is_array($value)
+                    ? [$key, array_merge($value, $attributes)]
+                    : [$value, $attributes];
+    }
+
+    /**
+     * Create a new pivot attachment record.
+     *
+     * @param  int  $id
+     * @param  bool  $timed
+     * @return array
+     */
+    protected function baseAttachRecord($id, $timed)
+    {
+        $record[$this->relatedPivotKey] = $id;
+
+        $record[$this->foreignPivotKey] = $this->parent->{$this->parentKey};
+
+        // If the record needs to have creation and update timestamps, we will make
+        // them by calling the parent model's "freshTimestamp" method which will
+        // provide us with a fresh timestamp in this model's preferred format.
+        if ($timed) {
+            $record = $this->addTimestampsToAttachment($record);
+        }
+
+        foreach ($this->pivotValues as $value) {
+            $record[$value['column']] = $value['value'];
+        }
+
+        return $record;
+    }
+
+    /**
+     * Set the creation and update timestamps on an attach record.
+     *
+     * @param  array  $record
+     * @param  bool  $exists
+     * @return array
+     */
+    protected function addTimestampsToAttachment(array $record, $exists = false)
+    {
+        $fresh = $this->parent->freshTimestamp();
+
+        if ($this->using) {
+            $pivotModel = new $this->using;
+
+            $fresh = $fresh->format($pivotModel->getDateFormat());
+        }
+
+        if (! $exists && $this->hasPivotColumn($this->createdAt())) {
+            $record[$this->createdAt()] = $fresh;
+        }
+
+        if ($this->hasPivotColumn($this->updatedAt())) {
+            $record[$this->updatedAt()] = $fresh;
+        }
+
+        return $record;
+    }
+
+    /**
+     * Determine whether the given column is defined as a pivot column.
+     *
+     * @param  string  $column
+     * @return bool
+     */
+    public function hasPivotColumn($column)
+    {
+        return in_array($column, $this->pivotColumns);
+    }
+
+    /**
+     * Detach models from the relationship.
+     *
+     * @param  mixed  $ids
+     * @param  bool  $touch
+     * @return int
+     */
+    public function detach($ids = null, $touch = true)
+    {
+        if ($this->using &&
+            ! empty($ids) &&
+            empty($this->pivotWheres) &&
+            empty($this->pivotWhereIns) &&
+            empty($this->pivotWhereNulls)) {
+            $results = $this->detachUsingCustomClass($ids);
+        } else {
+            $query = $this->newPivotQuery();
+
+            // If associated IDs were passed to the method we will only delete those
+            // associations, otherwise all of the association ties will be broken.
+            // We'll return the numbers of affected rows when we do the deletes.
+            if (! is_null($ids)) {
+                $ids = $this->parseIds($ids);
+
+                if (empty($ids)) {
+                    return 0;
+                }
+
+                $query->whereIn($this->getQualifiedRelatedPivotKeyName(), (array) $ids);
+            }
+
+            // Once we have all of the conditions set on the statement, we are ready
+            // to run the delete on the pivot table. Then, if the touch parameter
+            // is true, we will go ahead and touch all related models to sync.
+            $results = $query->delete();
+        }
+
+        if ($touch) {
+            $this->touchIfTouching();
+        }
+
+        return $results;
+    }
+
+    /**
+     * Detach models from the relationship using a custom class.
+     *
+     * @param  mixed  $ids
+     * @return int
+     */
+    protected function detachUsingCustomClass($ids)
+    {
+        $results = 0;
+
+        foreach ($this->parseIds($ids) as $id) {
+            $results += $this->newPivot([
+                $this->foreignPivotKey => $this->parent->{$this->parentKey},
+                $this->relatedPivotKey => $id,
+            ], true)->delete();
+        }
+
+        return $results;
+    }
+
+    /**
+     * Get the pivot models that are currently attached.
+     *
+     * @return \Illuminate\Support\Collection
+     */
+    protected function getCurrentlyAttachedPivots()
+    {
+        return $this->newPivotQuery()->get()->map(function ($record) {
+            $class = $this->using ?: Pivot::class;
+
+            $pivot = $class::fromRawAttributes($this->parent, (array) $record, $this->getTable(), true);
+
+            return $pivot->setPivotKeys($this->foreignPivotKey, $this->relatedPivotKey);
+        });
+    }
+
+    /**
+     * Create a new pivot model instance.
+     *
+     * @param  array  $attributes
+     * @param  bool  $exists
+     * @return \Illuminate\Database\Eloquent\Relations\Pivot
+     */
+    public function newPivot(array $attributes = [], $exists = false)
+    {
+        $pivot = $this->related->newPivot(
+            $this->parent, $attributes, $this->table, $exists, $this->using
+        );
+
+        return $pivot->setPivotKeys($this->foreignPivotKey, $this->relatedPivotKey);
+    }
+
+    /**
+     * Create a new existing pivot model instance.
+     *
+     * @param  array  $attributes
+     * @return \Illuminate\Database\Eloquent\Relations\Pivot
+     */
+    public function newExistingPivot(array $attributes = [])
+    {
+        return $this->newPivot($attributes, true);
+    }
+
+    /**
+     * Get a new plain query builder for the pivot table.
+     *
+     * @return \Illuminate\Database\Query\Builder
+     */
+    public function newPivotStatement()
+    {
+        return $this->query->getQuery()->newQuery()->from($this->table);
+    }
+
+    /**
+     * Get a new pivot statement for a given "other" ID.
+     *
+     * @param  mixed  $id
+     * @return \Illuminate\Database\Query\Builder
+     */
+    public function newPivotStatementForId($id)
+    {
+        return $this->newPivotQuery()->whereIn($this->relatedPivotKey, $this->parseIds($id));
+    }
+
+    /**
+     * Create a new query builder for the pivot table.
+     *
+     * @return \Illuminate\Database\Query\Builder
+     */
+    public function newPivotQuery()
+    {
+        $query = $this->newPivotStatement();
+
+        foreach ($this->pivotWheres as $arguments) {
+            $query->where(...$arguments);
+        }
+
+        foreach ($this->pivotWhereIns as $arguments) {
+            $query->whereIn(...$arguments);
+        }
+
+        foreach ($this->pivotWhereNulls as $arguments) {
+            $query->whereNull(...$arguments);
+        }
+
+        return $query->where($this->getQualifiedForeignPivotKeyName(), $this->parent->{$this->parentKey});
+    }
+
+    /**
+     * Set the columns on the pivot table to retrieve.
+     *
+     * @param  array|mixed  $columns
+     * @return $this
+     */
+    public function withPivot($columns)
+    {
+        $this->pivotColumns = array_merge(
+            $this->pivotColumns, is_array($columns) ? $columns : func_get_args()
+        );
+
+        return $this;
+    }
+
+    /**
+     * Get all of the IDs from the given mixed value.
+     *
+     * @param  mixed  $value
+     * @return array
+     */
+    protected function parseIds($value)
+    {
+        if ($value instanceof Model) {
+            return [$value->{$this->relatedKey}];
+        }
+
+        if ($value instanceof Collection) {
+            return $value->pluck($this->relatedKey)->all();
+        }
+
+        if ($value instanceof BaseCollection) {
+            return $value->toArray();
+        }
+
+        return (array) $value;
+    }
+
+    /**
+     * Get the ID from the given mixed value.
+     *
+     * @param  mixed  $value
+     * @return mixed
+     */
+    protected function parseId($value)
+    {
+        return $value instanceof Model ? $value->{$this->relatedKey} : $value;
+    }
+
+    /**
+     * Cast the given keys to integers if they are numeric and string otherwise.
+     *
+     * @param  array  $keys
+     * @return array
+     */
+    protected function castKeys(array $keys)
+    {
+        return array_map(function ($v) {
+            return $this->castKey($v);
+        }, $keys);
+    }
+
+    /**
+     * Cast the given key to convert to primary key type.
+     *
+     * @param  mixed  $key
+     * @return mixed
+     */
+    protected function castKey($key)
+    {
+        return $this->getTypeSwapValue(
+            $this->related->getKeyType(),
+            $key
+        );
+    }
+
+    /**
+     * Cast the given pivot attributes.
+     *
+     * @param  array  $attributes
+     * @return array
+     */
+    protected function castAttributes($attributes)
+    {
+        return $this->using
+                    ? $this->newPivot()->fill($attributes)->getAttributes()
+                    : $attributes;
+    }
+
+    /**
+     * Converts a given value to a given type value.
+     *
+     * @param  string  $type
+     * @param  mixed  $value
+     * @return mixed
+     */
+    protected function getTypeSwapValue($type, $value)
+    {
+        return match (strtolower($type)) {
+            'int', 'integer' => (int) $value,
+            'real', 'float', 'double' => (float) $value,
+            'string' => (string) $value,
+            default => $value,
+        };
+    }
+}
diff --git a/vendor/illuminate/database/Eloquent/Relations/Concerns/SupportsDefaultModels.php b/vendor/illuminate/database/Eloquent/Relations/Concerns/SupportsDefaultModels.php
new file mode 100644
index 0000000..74e758f
--- /dev/null
+++ b/vendor/illuminate/database/Eloquent/Relations/Concerns/SupportsDefaultModels.php
@@ -0,0 +1,63 @@
+withDefault = $callback;
+
+        return $this;
+    }
+
+    /**
+     * Get the default value for this relation.
+     *
+     * @param  \Illuminate\Database\Eloquent\Model  $parent
+     * @return \Illuminate\Database\Eloquent\Model|null
+     */
+    protected function getDefaultFor(Model $parent)
+    {
+        if (! $this->withDefault) {
+            return;
+        }
+
+        $instance = $this->newRelatedInstanceFor($parent);
+
+        if (is_callable($this->withDefault)) {
+            return call_user_func($this->withDefault, $instance, $parent) ?: $instance;
+        }
+
+        if (is_array($this->withDefault)) {
+            $instance->forceFill($this->withDefault);
+        }
+
+        return $instance;
+    }
+}
diff --git a/vendor/illuminate/database/Eloquent/Relations/HasMany.php b/vendor/illuminate/database/Eloquent/Relations/HasMany.php
new file mode 100755
index 0000000..b005d4f
--- /dev/null
+++ b/vendor/illuminate/database/Eloquent/Relations/HasMany.php
@@ -0,0 +1,49 @@
+getParentKey())
+                ? $this->query->get()
+                : $this->related->newCollection();
+    }
+
+    /**
+     * Initialize the relation on a set of models.
+     *
+     * @param  array  $models
+     * @param  string  $relation
+     * @return array
+     */
+    public function initRelation(array $models, $relation)
+    {
+        foreach ($models as $model) {
+            $model->setRelation($relation, $this->related->newCollection());
+        }
+
+        return $models;
+    }
+
+    /**
+     * Match the eagerly loaded results to their parents.
+     *
+     * @param  array  $models
+     * @param  \Illuminate\Database\Eloquent\Collection  $results
+     * @param  string  $relation
+     * @return array
+     */
+    public function match(array $models, Collection $results, $relation)
+    {
+        return $this->matchMany($models, $results, $relation);
+    }
+}
diff --git a/vendor/illuminate/database/Eloquent/Relations/HasManyThrough.php b/vendor/illuminate/database/Eloquent/Relations/HasManyThrough.php
new file mode 100644
index 0000000..b6ca908
--- /dev/null
+++ b/vendor/illuminate/database/Eloquent/Relations/HasManyThrough.php
@@ -0,0 +1,772 @@
+localKey = $localKey;
+        $this->firstKey = $firstKey;
+        $this->secondKey = $secondKey;
+        $this->farParent = $farParent;
+        $this->throughParent = $throughParent;
+        $this->secondLocalKey = $secondLocalKey;
+
+        parent::__construct($query, $throughParent);
+    }
+
+    /**
+     * Set the base constraints on the relation query.
+     *
+     * @return void
+     */
+    public function addConstraints()
+    {
+        $localValue = $this->farParent[$this->localKey];
+
+        $this->performJoin();
+
+        if (static::$constraints) {
+            $this->query->where($this->getQualifiedFirstKeyName(), '=', $localValue);
+        }
+    }
+
+    /**
+     * Set the join clause on the query.
+     *
+     * @param  \Illuminate\Database\Eloquent\Builder|null  $query
+     * @return void
+     */
+    protected function performJoin(Builder $query = null)
+    {
+        $query = $query ?: $this->query;
+
+        $farKey = $this->getQualifiedFarKeyName();
+
+        $query->join($this->throughParent->getTable(), $this->getQualifiedParentKeyName(), '=', $farKey);
+
+        if ($this->throughParentSoftDeletes()) {
+            $query->withGlobalScope('SoftDeletableHasManyThrough', function ($query) {
+                $query->whereNull($this->throughParent->getQualifiedDeletedAtColumn());
+            });
+        }
+    }
+
+    /**
+     * Get the fully qualified parent key name.
+     *
+     * @return string
+     */
+    public function getQualifiedParentKeyName()
+    {
+        return $this->parent->qualifyColumn($this->secondLocalKey);
+    }
+
+    /**
+     * Determine whether "through" parent of the relation uses Soft Deletes.
+     *
+     * @return bool
+     */
+    public function throughParentSoftDeletes()
+    {
+        return in_array(SoftDeletes::class, class_uses_recursive($this->throughParent));
+    }
+
+    /**
+     * Indicate that trashed "through" parents should be included in the query.
+     *
+     * @return $this
+     */
+    public function withTrashedParents()
+    {
+        $this->query->withoutGlobalScope('SoftDeletableHasManyThrough');
+
+        return $this;
+    }
+
+    /**
+     * Set the constraints for an eager load of the relation.
+     *
+     * @param  array  $models
+     * @return void
+     */
+    public function addEagerConstraints(array $models)
+    {
+        $whereIn = $this->whereInMethod($this->farParent, $this->localKey);
+
+        $this->query->{$whereIn}(
+            $this->getQualifiedFirstKeyName(), $this->getKeys($models, $this->localKey)
+        );
+    }
+
+    /**
+     * Initialize the relation on a set of models.
+     *
+     * @param  array  $models
+     * @param  string  $relation
+     * @return array
+     */
+    public function initRelation(array $models, $relation)
+    {
+        foreach ($models as $model) {
+            $model->setRelation($relation, $this->related->newCollection());
+        }
+
+        return $models;
+    }
+
+    /**
+     * Match the eagerly loaded results to their parents.
+     *
+     * @param  array  $models
+     * @param  \Illuminate\Database\Eloquent\Collection  $results
+     * @param  string  $relation
+     * @return array
+     */
+    public function match(array $models, Collection $results, $relation)
+    {
+        $dictionary = $this->buildDictionary($results);
+
+        // Once we have the dictionary we can simply spin through the parent models to
+        // link them up with their children using the keyed dictionary to make the
+        // matching very convenient and easy work. Then we'll just return them.
+        foreach ($models as $model) {
+            if (isset($dictionary[$key = $this->getDictionaryKey($model->getAttribute($this->localKey))])) {
+                $model->setRelation(
+                    $relation, $this->related->newCollection($dictionary[$key])
+                );
+            }
+        }
+
+        return $models;
+    }
+
+    /**
+     * Build model dictionary keyed by the relation's foreign key.
+     *
+     * @param  \Illuminate\Database\Eloquent\Collection  $results
+     * @return array
+     */
+    protected function buildDictionary(Collection $results)
+    {
+        $dictionary = [];
+
+        // First we will create a dictionary of models keyed by the foreign key of the
+        // relationship as this will allow us to quickly access all of the related
+        // models without having to do nested looping which will be quite slow.
+        foreach ($results as $result) {
+            $dictionary[$result->laravel_through_key][] = $result;
+        }
+
+        return $dictionary;
+    }
+
+    /**
+     * Get the first related model record matching the attributes or instantiate it.
+     *
+     * @param  array  $attributes
+     * @return \Illuminate\Database\Eloquent\Model
+     */
+    public function firstOrNew(array $attributes)
+    {
+        if (is_null($instance = $this->where($attributes)->first())) {
+            $instance = $this->related->newInstance($attributes);
+        }
+
+        return $instance;
+    }
+
+    /**
+     * Create or update a related record matching the attributes, and fill it with values.
+     *
+     * @param  array  $attributes
+     * @param  array  $values
+     * @return \Illuminate\Database\Eloquent\Model
+     */
+    public function updateOrCreate(array $attributes, array $values = [])
+    {
+        $instance = $this->firstOrNew($attributes);
+
+        $instance->fill($values)->save();
+
+        return $instance;
+    }
+
+    /**
+     * Add a basic where clause to the query, and return the first result.
+     *
+     * @param  \Closure|string|array  $column
+     * @param  mixed  $operator
+     * @param  mixed  $value
+     * @param  string  $boolean
+     * @return \Illuminate\Database\Eloquent\Model|static
+     */
+    public function firstWhere($column, $operator = null, $value = null, $boolean = 'and')
+    {
+        return $this->where($column, $operator, $value, $boolean)->first();
+    }
+
+    /**
+     * Execute the query and get the first related model.
+     *
+     * @param  array  $columns
+     * @return mixed
+     */
+    public function first($columns = ['*'])
+    {
+        $results = $this->take(1)->get($columns);
+
+        return count($results) > 0 ? $results->first() : null;
+    }
+
+    /**
+     * Execute the query and get the first result or throw an exception.
+     *
+     * @param  array  $columns
+     * @return \Illuminate\Database\Eloquent\Model|static
+     *
+     * @throws \Illuminate\Database\Eloquent\ModelNotFoundException<\Illuminate\Database\Eloquent\Model>
+     */
+    public function firstOrFail($columns = ['*'])
+    {
+        if (! is_null($model = $this->first($columns))) {
+            return $model;
+        }
+
+        throw (new ModelNotFoundException)->setModel(get_class($this->related));
+    }
+
+    /**
+     * Execute the query and get the first result or call a callback.
+     *
+     * @param  \Closure|array  $columns
+     * @param  \Closure|null  $callback
+     * @return \Illuminate\Database\Eloquent\Model|static|mixed
+     */
+    public function firstOr($columns = ['*'], Closure $callback = null)
+    {
+        if ($columns instanceof Closure) {
+            $callback = $columns;
+
+            $columns = ['*'];
+        }
+
+        if (! is_null($model = $this->first($columns))) {
+            return $model;
+        }
+
+        return $callback();
+    }
+
+    /**
+     * Find a related model by its primary key.
+     *
+     * @param  mixed  $id
+     * @param  array  $columns
+     * @return \Illuminate\Database\Eloquent\Model|\Illuminate\Database\Eloquent\Collection|null
+     */
+    public function find($id, $columns = ['*'])
+    {
+        if (is_array($id) || $id instanceof Arrayable) {
+            return $this->findMany($id, $columns);
+        }
+
+        return $this->where(
+            $this->getRelated()->getQualifiedKeyName(), '=', $id
+        )->first($columns);
+    }
+
+    /**
+     * Find multiple related models by their primary keys.
+     *
+     * @param  \Illuminate\Contracts\Support\Arrayable|array  $ids
+     * @param  array  $columns
+     * @return \Illuminate\Database\Eloquent\Collection
+     */
+    public function findMany($ids, $columns = ['*'])
+    {
+        $ids = $ids instanceof Arrayable ? $ids->toArray() : $ids;
+
+        if (empty($ids)) {
+            return $this->getRelated()->newCollection();
+        }
+
+        return $this->whereIn(
+            $this->getRelated()->getQualifiedKeyName(), $ids
+        )->get($columns);
+    }
+
+    /**
+     * Find a related model by its primary key or throw an exception.
+     *
+     * @param  mixed  $id
+     * @param  array  $columns
+     * @return \Illuminate\Database\Eloquent\Model|\Illuminate\Database\Eloquent\Collection
+     *
+     * @throws \Illuminate\Database\Eloquent\ModelNotFoundException<\Illuminate\Database\Eloquent\Model>
+     */
+    public function findOrFail($id, $columns = ['*'])
+    {
+        $result = $this->find($id, $columns);
+
+        $id = $id instanceof Arrayable ? $id->toArray() : $id;
+
+        if (is_array($id)) {
+            if (count($result) === count(array_unique($id))) {
+                return $result;
+            }
+        } elseif (! is_null($result)) {
+            return $result;
+        }
+
+        throw (new ModelNotFoundException)->setModel(get_class($this->related), $id);
+    }
+
+    /**
+     * Find a related model by its primary key or call a callback.
+     *
+     * @param  mixed  $id
+     * @param  \Closure|array  $columns
+     * @param  \Closure|null  $callback
+     * @return \Illuminate\Database\Eloquent\Model|\Illuminate\Database\Eloquent\Collection|mixed
+     */
+    public function findOr($id, $columns = ['*'], Closure $callback = null)
+    {
+        if ($columns instanceof Closure) {
+            $callback = $columns;
+
+            $columns = ['*'];
+        }
+
+        $result = $this->find($id, $columns);
+
+        $id = $id instanceof Arrayable ? $id->toArray() : $id;
+
+        if (is_array($id)) {
+            if (count($result) === count(array_unique($id))) {
+                return $result;
+            }
+        } elseif (! is_null($result)) {
+            return $result;
+        }
+
+        return $callback();
+    }
+
+    /**
+     * Get the results of the relationship.
+     *
+     * @return mixed
+     */
+    public function getResults()
+    {
+        return ! is_null($this->farParent->{$this->localKey})
+                ? $this->get()
+                : $this->related->newCollection();
+    }
+
+    /**
+     * Execute the query as a "select" statement.
+     *
+     * @param  array  $columns
+     * @return \Illuminate\Database\Eloquent\Collection
+     */
+    public function get($columns = ['*'])
+    {
+        $builder = $this->prepareQueryBuilder($columns);
+
+        $models = $builder->getModels();
+
+        // If we actually found models we will also eager load any relationships that
+        // have been specified as needing to be eager loaded. This will solve the
+        // n + 1 query problem for the developer and also increase performance.
+        if (count($models) > 0) {
+            $models = $builder->eagerLoadRelations($models);
+        }
+
+        return $this->related->newCollection($models);
+    }
+
+    /**
+     * Get a paginator for the "select" statement.
+     *
+     * @param  int|null  $perPage
+     * @param  array  $columns
+     * @param  string  $pageName
+     * @param  int  $page
+     * @return \Illuminate\Contracts\Pagination\LengthAwarePaginator
+     */
+    public function paginate($perPage = null, $columns = ['*'], $pageName = 'page', $page = null)
+    {
+        $this->query->addSelect($this->shouldSelect($columns));
+
+        return $this->query->paginate($perPage, $columns, $pageName, $page);
+    }
+
+    /**
+     * Paginate the given query into a simple paginator.
+     *
+     * @param  int|null  $perPage
+     * @param  array  $columns
+     * @param  string  $pageName
+     * @param  int|null  $page
+     * @return \Illuminate\Contracts\Pagination\Paginator
+     */
+    public function simplePaginate($perPage = null, $columns = ['*'], $pageName = 'page', $page = null)
+    {
+        $this->query->addSelect($this->shouldSelect($columns));
+
+        return $this->query->simplePaginate($perPage, $columns, $pageName, $page);
+    }
+
+    /**
+     * Paginate the given query into a cursor paginator.
+     *
+     * @param  int|null  $perPage
+     * @param  array  $columns
+     * @param  string  $cursorName
+     * @param  string|null  $cursor
+     * @return \Illuminate\Contracts\Pagination\CursorPaginator
+     */
+    public function cursorPaginate($perPage = null, $columns = ['*'], $cursorName = 'cursor', $cursor = null)
+    {
+        $this->query->addSelect($this->shouldSelect($columns));
+
+        return $this->query->cursorPaginate($perPage, $columns, $cursorName, $cursor);
+    }
+
+    /**
+     * Set the select clause for the relation query.
+     *
+     * @param  array  $columns
+     * @return array
+     */
+    protected function shouldSelect(array $columns = ['*'])
+    {
+        if ($columns == ['*']) {
+            $columns = [$this->related->getTable().'.*'];
+        }
+
+        return array_merge($columns, [$this->getQualifiedFirstKeyName().' as laravel_through_key']);
+    }
+
+    /**
+     * Chunk the results of the query.
+     *
+     * @param  int  $count
+     * @param  callable  $callback
+     * @return bool
+     */
+    public function chunk($count, callable $callback)
+    {
+        return $this->prepareQueryBuilder()->chunk($count, $callback);
+    }
+
+    /**
+     * Chunk the results of a query by comparing numeric IDs.
+     *
+     * @param  int  $count
+     * @param  callable  $callback
+     * @param  string|null  $column
+     * @param  string|null  $alias
+     * @return bool
+     */
+    public function chunkById($count, callable $callback, $column = null, $alias = null)
+    {
+        $column ??= $this->getRelated()->getQualifiedKeyName();
+
+        $alias ??= $this->getRelated()->getKeyName();
+
+        return $this->prepareQueryBuilder()->chunkById($count, $callback, $column, $alias);
+    }
+
+    /**
+     * Get a generator for the given query.
+     *
+     * @return \Illuminate\Support\LazyCollection
+     */
+    public function cursor()
+    {
+        return $this->prepareQueryBuilder()->cursor();
+    }
+
+    /**
+     * Execute a callback over each item while chunking.
+     *
+     * @param  callable  $callback
+     * @param  int  $count
+     * @return bool
+     */
+    public function each(callable $callback, $count = 1000)
+    {
+        return $this->chunk($count, function ($results) use ($callback) {
+            foreach ($results as $key => $value) {
+                if ($callback($value, $key) === false) {
+                    return false;
+                }
+            }
+        });
+    }
+
+    /**
+     * Query lazily, by chunks of the given size.
+     *
+     * @param  int  $chunkSize
+     * @return \Illuminate\Support\LazyCollection
+     */
+    public function lazy($chunkSize = 1000)
+    {
+        return $this->prepareQueryBuilder()->lazy($chunkSize);
+    }
+
+    /**
+     * Query lazily, by chunking the results of a query by comparing IDs.
+     *
+     * @param  int  $chunkSize
+     * @param  string|null  $column
+     * @param  string|null  $alias
+     * @return \Illuminate\Support\LazyCollection
+     */
+    public function lazyById($chunkSize = 1000, $column = null, $alias = null)
+    {
+        $column ??= $this->getRelated()->getQualifiedKeyName();
+
+        $alias ??= $this->getRelated()->getKeyName();
+
+        return $this->prepareQueryBuilder()->lazyById($chunkSize, $column, $alias);
+    }
+
+    /**
+     * Prepare the query builder for query execution.
+     *
+     * @param  array  $columns
+     * @return \Illuminate\Database\Eloquent\Builder
+     */
+    protected function prepareQueryBuilder($columns = ['*'])
+    {
+        $builder = $this->query->applyScopes();
+
+        return $builder->addSelect(
+            $this->shouldSelect($builder->getQuery()->columns ? [] : $columns)
+        );
+    }
+
+    /**
+     * Add the constraints for a relationship query.
+     *
+     * @param  \Illuminate\Database\Eloquent\Builder  $query
+     * @param  \Illuminate\Database\Eloquent\Builder  $parentQuery
+     * @param  array|mixed  $columns
+     * @return \Illuminate\Database\Eloquent\Builder
+     */
+    public function getRelationExistenceQuery(Builder $query, Builder $parentQuery, $columns = ['*'])
+    {
+        if ($parentQuery->getQuery()->from === $query->getQuery()->from) {
+            return $this->getRelationExistenceQueryForSelfRelation($query, $parentQuery, $columns);
+        }
+
+        if ($parentQuery->getQuery()->from === $this->throughParent->getTable()) {
+            return $this->getRelationExistenceQueryForThroughSelfRelation($query, $parentQuery, $columns);
+        }
+
+        $this->performJoin($query);
+
+        return $query->select($columns)->whereColumn(
+            $this->getQualifiedLocalKeyName(), '=', $this->getQualifiedFirstKeyName()
+        );
+    }
+
+    /**
+     * Add the constraints for a relationship query on the same table.
+     *
+     * @param  \Illuminate\Database\Eloquent\Builder  $query
+     * @param  \Illuminate\Database\Eloquent\Builder  $parentQuery
+     * @param  array|mixed  $columns
+     * @return \Illuminate\Database\Eloquent\Builder
+     */
+    public function getRelationExistenceQueryForSelfRelation(Builder $query, Builder $parentQuery, $columns = ['*'])
+    {
+        $query->from($query->getModel()->getTable().' as '.$hash = $this->getRelationCountHash());
+
+        $query->join($this->throughParent->getTable(), $this->getQualifiedParentKeyName(), '=', $hash.'.'.$this->secondKey);
+
+        if ($this->throughParentSoftDeletes()) {
+            $query->whereNull($this->throughParent->getQualifiedDeletedAtColumn());
+        }
+
+        $query->getModel()->setTable($hash);
+
+        return $query->select($columns)->whereColumn(
+            $parentQuery->getQuery()->from.'.'.$this->localKey, '=', $this->getQualifiedFirstKeyName()
+        );
+    }
+
+    /**
+     * Add the constraints for a relationship query on the same table as the through parent.
+     *
+     * @param  \Illuminate\Database\Eloquent\Builder  $query
+     * @param  \Illuminate\Database\Eloquent\Builder  $parentQuery
+     * @param  array|mixed  $columns
+     * @return \Illuminate\Database\Eloquent\Builder
+     */
+    public function getRelationExistenceQueryForThroughSelfRelation(Builder $query, Builder $parentQuery, $columns = ['*'])
+    {
+        $table = $this->throughParent->getTable().' as '.$hash = $this->getRelationCountHash();
+
+        $query->join($table, $hash.'.'.$this->secondLocalKey, '=', $this->getQualifiedFarKeyName());
+
+        if ($this->throughParentSoftDeletes()) {
+            $query->whereNull($hash.'.'.$this->throughParent->getDeletedAtColumn());
+        }
+
+        return $query->select($columns)->whereColumn(
+            $parentQuery->getQuery()->from.'.'.$this->localKey, '=', $hash.'.'.$this->firstKey
+        );
+    }
+
+    /**
+     * Get the qualified foreign key on the related model.
+     *
+     * @return string
+     */
+    public function getQualifiedFarKeyName()
+    {
+        return $this->getQualifiedForeignKeyName();
+    }
+
+    /**
+     * Get the foreign key on the "through" model.
+     *
+     * @return string
+     */
+    public function getFirstKeyName()
+    {
+        return $this->firstKey;
+    }
+
+    /**
+     * Get the qualified foreign key on the "through" model.
+     *
+     * @return string
+     */
+    public function getQualifiedFirstKeyName()
+    {
+        return $this->throughParent->qualifyColumn($this->firstKey);
+    }
+
+    /**
+     * Get the foreign key on the related model.
+     *
+     * @return string
+     */
+    public function getForeignKeyName()
+    {
+        return $this->secondKey;
+    }
+
+    /**
+     * Get the qualified foreign key on the related model.
+     *
+     * @return string
+     */
+    public function getQualifiedForeignKeyName()
+    {
+        return $this->related->qualifyColumn($this->secondKey);
+    }
+
+    /**
+     * Get the local key on the far parent model.
+     *
+     * @return string
+     */
+    public function getLocalKeyName()
+    {
+        return $this->localKey;
+    }
+
+    /**
+     * Get the qualified local key on the far parent model.
+     *
+     * @return string
+     */
+    public function getQualifiedLocalKeyName()
+    {
+        return $this->farParent->qualifyColumn($this->localKey);
+    }
+
+    /**
+     * Get the local key on the intermediary model.
+     *
+     * @return string
+     */
+    public function getSecondLocalKeyName()
+    {
+        return $this->secondLocalKey;
+    }
+}
diff --git a/vendor/illuminate/database/Eloquent/Relations/HasOne.php b/vendor/illuminate/database/Eloquent/Relations/HasOne.php
new file mode 100755
index 0000000..ed85f1e
--- /dev/null
+++ b/vendor/illuminate/database/Eloquent/Relations/HasOne.php
@@ -0,0 +1,137 @@
+getParentKey())) {
+            return $this->getDefaultFor($this->parent);
+        }
+
+        return $this->query->first() ?: $this->getDefaultFor($this->parent);
+    }
+
+    /**
+     * Initialize the relation on a set of models.
+     *
+     * @param  array  $models
+     * @param  string  $relation
+     * @return array
+     */
+    public function initRelation(array $models, $relation)
+    {
+        foreach ($models as $model) {
+            $model->setRelation($relation, $this->getDefaultFor($model));
+        }
+
+        return $models;
+    }
+
+    /**
+     * Match the eagerly loaded results to their parents.
+     *
+     * @param  array  $models
+     * @param  \Illuminate\Database\Eloquent\Collection  $results
+     * @param  string  $relation
+     * @return array
+     */
+    public function match(array $models, Collection $results, $relation)
+    {
+        return $this->matchOne($models, $results, $relation);
+    }
+
+    /**
+     * Add the constraints for an internal relationship existence query.
+     *
+     * Essentially, these queries compare on column names like "whereColumn".
+     *
+     * @param  \Illuminate\Database\Eloquent\Builder  $query
+     * @param  \Illuminate\Database\Eloquent\Builder  $parentQuery
+     * @param  array|mixed  $columns
+     * @return \Illuminate\Database\Eloquent\Builder
+     */
+    public function getRelationExistenceQuery(Builder $query, Builder $parentQuery, $columns = ['*'])
+    {
+        if ($this->isOneOfMany()) {
+            $this->mergeOneOfManyJoinsTo($query);
+        }
+
+        return parent::getRelationExistenceQuery($query, $parentQuery, $columns);
+    }
+
+    /**
+     * Add constraints for inner join subselect for one of many relationships.
+     *
+     * @param  \Illuminate\Database\Eloquent\Builder  $query
+     * @param  string|null  $column
+     * @param  string|null  $aggregate
+     * @return void
+     */
+    public function addOneOfManySubQueryConstraints(Builder $query, $column = null, $aggregate = null)
+    {
+        $query->addSelect($this->foreignKey);
+    }
+
+    /**
+     * Get the columns that should be selected by the one of many subquery.
+     *
+     * @return array|string
+     */
+    public function getOneOfManySubQuerySelectColumns()
+    {
+        return $this->foreignKey;
+    }
+
+    /**
+     * Add join query constraints for one of many relationships.
+     *
+     * @param  \Illuminate\Database\Query\JoinClause  $join
+     * @return void
+     */
+    public function addOneOfManyJoinSubQueryConstraints(JoinClause $join)
+    {
+        $join->on($this->qualifySubSelectColumn($this->foreignKey), '=', $this->qualifyRelatedColumn($this->foreignKey));
+    }
+
+    /**
+     * Make a new related instance for the given model.
+     *
+     * @param  \Illuminate\Database\Eloquent\Model  $parent
+     * @return \Illuminate\Database\Eloquent\Model
+     */
+    public function newRelatedInstanceFor(Model $parent)
+    {
+        return $this->related->newInstance()->setAttribute(
+            $this->getForeignKeyName(), $parent->{$this->localKey}
+        );
+    }
+
+    /**
+     * Get the value of the model's foreign key.
+     *
+     * @param  \Illuminate\Database\Eloquent\Model  $model
+     * @return mixed
+     */
+    protected function getRelatedKeyFrom(Model $model)
+    {
+        return $model->getAttribute($this->getForeignKeyName());
+    }
+}
diff --git a/vendor/illuminate/database/Eloquent/Relations/HasOneOrMany.php b/vendor/illuminate/database/Eloquent/Relations/HasOneOrMany.php
new file mode 100755
index 0000000..01f0c1e
--- /dev/null
+++ b/vendor/illuminate/database/Eloquent/Relations/HasOneOrMany.php
@@ -0,0 +1,486 @@
+localKey = $localKey;
+        $this->foreignKey = $foreignKey;
+
+        parent::__construct($query, $parent);
+    }
+
+    /**
+     * Create and return an un-saved instance of the related model.
+     *
+     * @param  array  $attributes
+     * @return \Illuminate\Database\Eloquent\Model
+     */
+    public function make(array $attributes = [])
+    {
+        return tap($this->related->newInstance($attributes), function ($instance) {
+            $this->setForeignAttributesForCreate($instance);
+        });
+    }
+
+    /**
+     * Create and return an un-saved instance of the related models.
+     *
+     * @param  iterable  $records
+     * @return \Illuminate\Database\Eloquent\Collection
+     */
+    public function makeMany($records)
+    {
+        $instances = $this->related->newCollection();
+
+        foreach ($records as $record) {
+            $instances->push($this->make($record));
+        }
+
+        return $instances;
+    }
+
+    /**
+     * Set the base constraints on the relation query.
+     *
+     * @return void
+     */
+    public function addConstraints()
+    {
+        if (static::$constraints) {
+            $query = $this->getRelationQuery();
+
+            $query->where($this->foreignKey, '=', $this->getParentKey());
+
+            $query->whereNotNull($this->foreignKey);
+        }
+    }
+
+    /**
+     * Set the constraints for an eager load of the relation.
+     *
+     * @param  array  $models
+     * @return void
+     */
+    public function addEagerConstraints(array $models)
+    {
+        $whereIn = $this->whereInMethod($this->parent, $this->localKey);
+
+        $this->getRelationQuery()->{$whereIn}(
+            $this->foreignKey, $this->getKeys($models, $this->localKey)
+        );
+    }
+
+    /**
+     * Match the eagerly loaded results to their single parents.
+     *
+     * @param  array  $models
+     * @param  \Illuminate\Database\Eloquent\Collection  $results
+     * @param  string  $relation
+     * @return array
+     */
+    public function matchOne(array $models, Collection $results, $relation)
+    {
+        return $this->matchOneOrMany($models, $results, $relation, 'one');
+    }
+
+    /**
+     * Match the eagerly loaded results to their many parents.
+     *
+     * @param  array  $models
+     * @param  \Illuminate\Database\Eloquent\Collection  $results
+     * @param  string  $relation
+     * @return array
+     */
+    public function matchMany(array $models, Collection $results, $relation)
+    {
+        return $this->matchOneOrMany($models, $results, $relation, 'many');
+    }
+
+    /**
+     * Match the eagerly loaded results to their many parents.
+     *
+     * @param  array  $models
+     * @param  \Illuminate\Database\Eloquent\Collection  $results
+     * @param  string  $relation
+     * @param  string  $type
+     * @return array
+     */
+    protected function matchOneOrMany(array $models, Collection $results, $relation, $type)
+    {
+        $dictionary = $this->buildDictionary($results);
+
+        // Once we have the dictionary we can simply spin through the parent models to
+        // link them up with their children using the keyed dictionary to make the
+        // matching very convenient and easy work. Then we'll just return them.
+        foreach ($models as $model) {
+            if (isset($dictionary[$key = $this->getDictionaryKey($model->getAttribute($this->localKey))])) {
+                $model->setRelation(
+                    $relation, $this->getRelationValue($dictionary, $key, $type)
+                );
+            }
+        }
+
+        return $models;
+    }
+
+    /**
+     * Get the value of a relationship by one or many type.
+     *
+     * @param  array  $dictionary
+     * @param  string  $key
+     * @param  string  $type
+     * @return mixed
+     */
+    protected function getRelationValue(array $dictionary, $key, $type)
+    {
+        $value = $dictionary[$key];
+
+        return $type === 'one' ? reset($value) : $this->related->newCollection($value);
+    }
+
+    /**
+     * Build model dictionary keyed by the relation's foreign key.
+     *
+     * @param  \Illuminate\Database\Eloquent\Collection  $results
+     * @return array
+     */
+    protected function buildDictionary(Collection $results)
+    {
+        $foreign = $this->getForeignKeyName();
+
+        return $results->mapToDictionary(function ($result) use ($foreign) {
+            return [$this->getDictionaryKey($result->{$foreign}) => $result];
+        })->all();
+    }
+
+    /**
+     * Find a model by its primary key or return a new instance of the related model.
+     *
+     * @param  mixed  $id
+     * @param  array  $columns
+     * @return \Illuminate\Support\Collection|\Illuminate\Database\Eloquent\Model
+     */
+    public function findOrNew($id, $columns = ['*'])
+    {
+        if (is_null($instance = $this->find($id, $columns))) {
+            $instance = $this->related->newInstance();
+
+            $this->setForeignAttributesForCreate($instance);
+        }
+
+        return $instance;
+    }
+
+    /**
+     * Get the first related model record matching the attributes or instantiate it.
+     *
+     * @param  array  $attributes
+     * @param  array  $values
+     * @return \Illuminate\Database\Eloquent\Model
+     */
+    public function firstOrNew(array $attributes = [], array $values = [])
+    {
+        if (is_null($instance = $this->where($attributes)->first())) {
+            $instance = $this->related->newInstance(array_merge($attributes, $values));
+
+            $this->setForeignAttributesForCreate($instance);
+        }
+
+        return $instance;
+    }
+
+    /**
+     * Get the first related record matching the attributes or create it.
+     *
+     * @param  array  $attributes
+     * @param  array  $values
+     * @return \Illuminate\Database\Eloquent\Model
+     */
+    public function firstOrCreate(array $attributes = [], array $values = [])
+    {
+        if (is_null($instance = $this->where($attributes)->first())) {
+            $instance = $this->create(array_merge($attributes, $values));
+        }
+
+        return $instance;
+    }
+
+    /**
+     * Create or update a related record matching the attributes, and fill it with values.
+     *
+     * @param  array  $attributes
+     * @param  array  $values
+     * @return \Illuminate\Database\Eloquent\Model
+     */
+    public function updateOrCreate(array $attributes, array $values = [])
+    {
+        return tap($this->firstOrNew($attributes), function ($instance) use ($values) {
+            $instance->fill($values);
+
+            $instance->save();
+        });
+    }
+
+    /**
+     * Attach a model instance to the parent model.
+     *
+     * @param  \Illuminate\Database\Eloquent\Model  $model
+     * @return \Illuminate\Database\Eloquent\Model|false
+     */
+    public function save(Model $model)
+    {
+        $this->setForeignAttributesForCreate($model);
+
+        return $model->save() ? $model : false;
+    }
+
+    /**
+     * Attach a model instance without raising any events to the parent model.
+     *
+     * @param  \Illuminate\Database\Eloquent\Model  $model
+     * @return \Illuminate\Database\Eloquent\Model|false
+     */
+    public function saveQuietly(Model $model)
+    {
+        return Model::withoutEvents(function () use ($model) {
+            return $this->save($model);
+        });
+    }
+
+    /**
+     * Attach a collection of models to the parent instance.
+     *
+     * @param  iterable  $models
+     * @return iterable
+     */
+    public function saveMany($models)
+    {
+        foreach ($models as $model) {
+            $this->save($model);
+        }
+
+        return $models;
+    }
+
+    /**
+     * Attach a collection of models to the parent instance without raising any events to the parent model.
+     *
+     * @param  iterable  $models
+     * @return iterable
+     */
+    public function saveManyQuietly($models)
+    {
+        return Model::withoutEvents(function () use ($models) {
+            return $this->saveMany($models);
+        });
+    }
+
+    /**
+     * Create a new instance of the related model.
+     *
+     * @param  array  $attributes
+     * @return \Illuminate\Database\Eloquent\Model
+     */
+    public function create(array $attributes = [])
+    {
+        return tap($this->related->newInstance($attributes), function ($instance) {
+            $this->setForeignAttributesForCreate($instance);
+
+            $instance->save();
+        });
+    }
+
+    /**
+     * Create a new instance of the related model without raising any events to the parent model.
+     *
+     * @param  array  $attributes
+     * @return \Illuminate\Database\Eloquent\Model
+     */
+    public function createQuietly(array $attributes = [])
+    {
+        return Model::withoutEvents(fn () => $this->create($attributes));
+    }
+
+    /**
+     * Create a new instance of the related model. Allow mass-assignment.
+     *
+     * @param  array  $attributes
+     * @return \Illuminate\Database\Eloquent\Model
+     */
+    public function forceCreate(array $attributes = [])
+    {
+        $attributes[$this->getForeignKeyName()] = $this->getParentKey();
+
+        return $this->related->forceCreate($attributes);
+    }
+
+    /**
+     * Create a Collection of new instances of the related model.
+     *
+     * @param  iterable  $records
+     * @return \Illuminate\Database\Eloquent\Collection
+     */
+    public function createMany(iterable $records)
+    {
+        $instances = $this->related->newCollection();
+
+        foreach ($records as $record) {
+            $instances->push($this->create($record));
+        }
+
+        return $instances;
+    }
+
+    /**
+     * Create a Collection of new instances of the related model without raising any events to the parent model.
+     *
+     * @param  iterable  $records
+     * @return \Illuminate\Database\Eloquent\Collection
+     */
+    public function createManyQuietly(iterable $records)
+    {
+        return Model::withoutEvents(fn () => $this->createMany($records));
+    }
+
+    /**
+     * Set the foreign ID for creating a related model.
+     *
+     * @param  \Illuminate\Database\Eloquent\Model  $model
+     * @return void
+     */
+    protected function setForeignAttributesForCreate(Model $model)
+    {
+        $model->setAttribute($this->getForeignKeyName(), $this->getParentKey());
+    }
+
+    /**
+     * Add the constraints for a relationship query.
+     *
+     * @param  \Illuminate\Database\Eloquent\Builder  $query
+     * @param  \Illuminate\Database\Eloquent\Builder  $parentQuery
+     * @param  array|mixed  $columns
+     * @return \Illuminate\Database\Eloquent\Builder
+     */
+    public function getRelationExistenceQuery(Builder $query, Builder $parentQuery, $columns = ['*'])
+    {
+        if ($query->getQuery()->from == $parentQuery->getQuery()->from) {
+            return $this->getRelationExistenceQueryForSelfRelation($query, $parentQuery, $columns);
+        }
+
+        return parent::getRelationExistenceQuery($query, $parentQuery, $columns);
+    }
+
+    /**
+     * Add the constraints for a relationship query on the same table.
+     *
+     * @param  \Illuminate\Database\Eloquent\Builder  $query
+     * @param  \Illuminate\Database\Eloquent\Builder  $parentQuery
+     * @param  array|mixed  $columns
+     * @return \Illuminate\Database\Eloquent\Builder
+     */
+    public function getRelationExistenceQueryForSelfRelation(Builder $query, Builder $parentQuery, $columns = ['*'])
+    {
+        $query->from($query->getModel()->getTable().' as '.$hash = $this->getRelationCountHash());
+
+        $query->getModel()->setTable($hash);
+
+        return $query->select($columns)->whereColumn(
+            $this->getQualifiedParentKeyName(), '=', $hash.'.'.$this->getForeignKeyName()
+        );
+    }
+
+    /**
+     * Get the key for comparing against the parent key in "has" query.
+     *
+     * @return string
+     */
+    public function getExistenceCompareKey()
+    {
+        return $this->getQualifiedForeignKeyName();
+    }
+
+    /**
+     * Get the key value of the parent's local key.
+     *
+     * @return mixed
+     */
+    public function getParentKey()
+    {
+        return $this->parent->getAttribute($this->localKey);
+    }
+
+    /**
+     * Get the fully qualified parent key name.
+     *
+     * @return string
+     */
+    public function getQualifiedParentKeyName()
+    {
+        return $this->parent->qualifyColumn($this->localKey);
+    }
+
+    /**
+     * Get the plain foreign key.
+     *
+     * @return string
+     */
+    public function getForeignKeyName()
+    {
+        $segments = explode('.', $this->getQualifiedForeignKeyName());
+
+        return end($segments);
+    }
+
+    /**
+     * Get the foreign key for the relationship.
+     *
+     * @return string
+     */
+    public function getQualifiedForeignKeyName()
+    {
+        return $this->foreignKey;
+    }
+
+    /**
+     * Get the local key for the relationship.
+     *
+     * @return string
+     */
+    public function getLocalKeyName()
+    {
+        return $this->localKey;
+    }
+}
diff --git a/vendor/illuminate/database/Eloquent/Relations/HasOneThrough.php b/vendor/illuminate/database/Eloquent/Relations/HasOneThrough.php
new file mode 100644
index 0000000..ed9c7ba
--- /dev/null
+++ b/vendor/illuminate/database/Eloquent/Relations/HasOneThrough.php
@@ -0,0 +1,77 @@
+first() ?: $this->getDefaultFor($this->farParent);
+    }
+
+    /**
+     * Initialize the relation on a set of models.
+     *
+     * @param  array  $models
+     * @param  string  $relation
+     * @return array
+     */
+    public function initRelation(array $models, $relation)
+    {
+        foreach ($models as $model) {
+            $model->setRelation($relation, $this->getDefaultFor($model));
+        }
+
+        return $models;
+    }
+
+    /**
+     * Match the eagerly loaded results to their parents.
+     *
+     * @param  array  $models
+     * @param  \Illuminate\Database\Eloquent\Collection  $results
+     * @param  string  $relation
+     * @return array
+     */
+    public function match(array $models, Collection $results, $relation)
+    {
+        $dictionary = $this->buildDictionary($results);
+
+        // Once we have the dictionary we can simply spin through the parent models to
+        // link them up with their children using the keyed dictionary to make the
+        // matching very convenient and easy work. Then we'll just return them.
+        foreach ($models as $model) {
+            if (isset($dictionary[$key = $this->getDictionaryKey($model->getAttribute($this->localKey))])) {
+                $value = $dictionary[$key];
+                $model->setRelation(
+                    $relation, reset($value)
+                );
+            }
+        }
+
+        return $models;
+    }
+
+    /**
+     * Make a new related instance for the given model.
+     *
+     * @param  \Illuminate\Database\Eloquent\Model  $parent
+     * @return \Illuminate\Database\Eloquent\Model
+     */
+    public function newRelatedInstanceFor(Model $parent)
+    {
+        return $this->related->newInstance();
+    }
+}
diff --git a/vendor/illuminate/database/Eloquent/Relations/MorphMany.php b/vendor/illuminate/database/Eloquent/Relations/MorphMany.php
new file mode 100755
index 0000000..282ba2e
--- /dev/null
+++ b/vendor/illuminate/database/Eloquent/Relations/MorphMany.php
@@ -0,0 +1,62 @@
+getParentKey())
+                ? $this->query->get()
+                : $this->related->newCollection();
+    }
+
+    /**
+     * Initialize the relation on a set of models.
+     *
+     * @param  array  $models
+     * @param  string  $relation
+     * @return array
+     */
+    public function initRelation(array $models, $relation)
+    {
+        foreach ($models as $model) {
+            $model->setRelation($relation, $this->related->newCollection());
+        }
+
+        return $models;
+    }
+
+    /**
+     * Match the eagerly loaded results to their parents.
+     *
+     * @param  array  $models
+     * @param  \Illuminate\Database\Eloquent\Collection  $results
+     * @param  string  $relation
+     * @return array
+     */
+    public function match(array $models, Collection $results, $relation)
+    {
+        return $this->matchMany($models, $results, $relation);
+    }
+
+    /**
+     * Create a new instance of the related model. Allow mass-assignment.
+     *
+     * @param  array  $attributes
+     * @return \Illuminate\Database\Eloquent\Model
+     */
+    public function forceCreate(array $attributes = [])
+    {
+        $attributes[$this->getMorphType()] = $this->morphClass;
+
+        return parent::forceCreate($attributes);
+    }
+}
diff --git a/vendor/illuminate/database/Eloquent/Relations/MorphOne.php b/vendor/illuminate/database/Eloquent/Relations/MorphOne.php
new file mode 100755
index 0000000..fc8f4dc
--- /dev/null
+++ b/vendor/illuminate/database/Eloquent/Relations/MorphOne.php
@@ -0,0 +1,137 @@
+getParentKey())) {
+            return $this->getDefaultFor($this->parent);
+        }
+
+        return $this->query->first() ?: $this->getDefaultFor($this->parent);
+    }
+
+    /**
+     * Initialize the relation on a set of models.
+     *
+     * @param  array  $models
+     * @param  string  $relation
+     * @return array
+     */
+    public function initRelation(array $models, $relation)
+    {
+        foreach ($models as $model) {
+            $model->setRelation($relation, $this->getDefaultFor($model));
+        }
+
+        return $models;
+    }
+
+    /**
+     * Match the eagerly loaded results to their parents.
+     *
+     * @param  array  $models
+     * @param  \Illuminate\Database\Eloquent\Collection  $results
+     * @param  string  $relation
+     * @return array
+     */
+    public function match(array $models, Collection $results, $relation)
+    {
+        return $this->matchOne($models, $results, $relation);
+    }
+
+    /**
+     * Get the relationship query.
+     *
+     * @param  \Illuminate\Database\Eloquent\Builder  $query
+     * @param  \Illuminate\Database\Eloquent\Builder  $parentQuery
+     * @param  array|mixed  $columns
+     * @return \Illuminate\Database\Eloquent\Builder
+     */
+    public function getRelationExistenceQuery(Builder $query, Builder $parentQuery, $columns = ['*'])
+    {
+        if ($this->isOneOfMany()) {
+            $this->mergeOneOfManyJoinsTo($query);
+        }
+
+        return parent::getRelationExistenceQuery($query, $parentQuery, $columns);
+    }
+
+    /**
+     * Add constraints for inner join subselect for one of many relationships.
+     *
+     * @param  \Illuminate\Database\Eloquent\Builder  $query
+     * @param  string|null  $column
+     * @param  string|null  $aggregate
+     * @return void
+     */
+    public function addOneOfManySubQueryConstraints(Builder $query, $column = null, $aggregate = null)
+    {
+        $query->addSelect($this->foreignKey, $this->morphType);
+    }
+
+    /**
+     * Get the columns that should be selected by the one of many subquery.
+     *
+     * @return array|string
+     */
+    public function getOneOfManySubQuerySelectColumns()
+    {
+        return [$this->foreignKey, $this->morphType];
+    }
+
+    /**
+     * Add join query constraints for one of many relationships.
+     *
+     * @param  \Illuminate\Database\Query\JoinClause  $join
+     * @return void
+     */
+    public function addOneOfManyJoinSubQueryConstraints(JoinClause $join)
+    {
+        $join
+            ->on($this->qualifySubSelectColumn($this->morphType), '=', $this->qualifyRelatedColumn($this->morphType))
+            ->on($this->qualifySubSelectColumn($this->foreignKey), '=', $this->qualifyRelatedColumn($this->foreignKey));
+    }
+
+    /**
+     * Make a new related instance for the given model.
+     *
+     * @param  \Illuminate\Database\Eloquent\Model  $parent
+     * @return \Illuminate\Database\Eloquent\Model
+     */
+    public function newRelatedInstanceFor(Model $parent)
+    {
+        return $this->related->newInstance()
+                    ->setAttribute($this->getForeignKeyName(), $parent->{$this->localKey})
+                    ->setAttribute($this->getMorphType(), $this->morphClass);
+    }
+
+    /**
+     * Get the value of the model's foreign key.
+     *
+     * @param  \Illuminate\Database\Eloquent\Model  $model
+     * @return mixed
+     */
+    protected function getRelatedKeyFrom(Model $model)
+    {
+        return $model->getAttribute($this->getForeignKeyName());
+    }
+}
diff --git a/vendor/illuminate/database/Eloquent/Relations/MorphOneOrMany.php b/vendor/illuminate/database/Eloquent/Relations/MorphOneOrMany.php
new file mode 100755
index 0000000..6e2297f
--- /dev/null
+++ b/vendor/illuminate/database/Eloquent/Relations/MorphOneOrMany.php
@@ -0,0 +1,127 @@
+morphType = $type;
+
+        $this->morphClass = $parent->getMorphClass();
+
+        parent::__construct($query, $parent, $id, $localKey);
+    }
+
+    /**
+     * Set the base constraints on the relation query.
+     *
+     * @return void
+     */
+    public function addConstraints()
+    {
+        if (static::$constraints) {
+            $this->getRelationQuery()->where($this->morphType, $this->morphClass);
+
+            parent::addConstraints();
+        }
+    }
+
+    /**
+     * Set the constraints for an eager load of the relation.
+     *
+     * @param  array  $models
+     * @return void
+     */
+    public function addEagerConstraints(array $models)
+    {
+        parent::addEagerConstraints($models);
+
+        $this->getRelationQuery()->where($this->morphType, $this->morphClass);
+    }
+
+    /**
+     * Set the foreign ID and type for creating a related model.
+     *
+     * @param  \Illuminate\Database\Eloquent\Model  $model
+     * @return void
+     */
+    protected function setForeignAttributesForCreate(Model $model)
+    {
+        $model->{$this->getForeignKeyName()} = $this->getParentKey();
+
+        $model->{$this->getMorphType()} = $this->morphClass;
+    }
+
+    /**
+     * Get the relationship query.
+     *
+     * @param  \Illuminate\Database\Eloquent\Builder  $query
+     * @param  \Illuminate\Database\Eloquent\Builder  $parentQuery
+     * @param  array|mixed  $columns
+     * @return \Illuminate\Database\Eloquent\Builder
+     */
+    public function getRelationExistenceQuery(Builder $query, Builder $parentQuery, $columns = ['*'])
+    {
+        return parent::getRelationExistenceQuery($query, $parentQuery, $columns)->where(
+            $query->qualifyColumn($this->getMorphType()), $this->morphClass
+        );
+    }
+
+    /**
+     * Get the foreign key "type" name.
+     *
+     * @return string
+     */
+    public function getQualifiedMorphType()
+    {
+        return $this->morphType;
+    }
+
+    /**
+     * Get the plain morph type name without the table.
+     *
+     * @return string
+     */
+    public function getMorphType()
+    {
+        return last(explode('.', $this->morphType));
+    }
+
+    /**
+     * Get the class name of the parent model.
+     *
+     * @return string
+     */
+    public function getMorphClass()
+    {
+        return $this->morphClass;
+    }
+}
diff --git a/vendor/illuminate/database/Eloquent/Relations/MorphPivot.php b/vendor/illuminate/database/Eloquent/Relations/MorphPivot.php
new file mode 100644
index 0000000..5ca8b48
--- /dev/null
+++ b/vendor/illuminate/database/Eloquent/Relations/MorphPivot.php
@@ -0,0 +1,182 @@
+where($this->morphType, $this->morphClass);
+
+        return parent::setKeysForSaveQuery($query);
+    }
+
+    /**
+     * Set the keys for a select query.
+     *
+     * @param  \Illuminate\Database\Eloquent\Builder  $query
+     * @return \Illuminate\Database\Eloquent\Builder
+     */
+    protected function setKeysForSelectQuery($query)
+    {
+        $query->where($this->morphType, $this->morphClass);
+
+        return parent::setKeysForSelectQuery($query);
+    }
+
+    /**
+     * Delete the pivot model record from the database.
+     *
+     * @return int
+     */
+    public function delete()
+    {
+        if (isset($this->attributes[$this->getKeyName()])) {
+            return (int) parent::delete();
+        }
+
+        if ($this->fireModelEvent('deleting') === false) {
+            return 0;
+        }
+
+        $query = $this->getDeleteQuery();
+
+        $query->where($this->morphType, $this->morphClass);
+
+        return tap($query->delete(), function () {
+            $this->fireModelEvent('deleted', false);
+        });
+    }
+
+    /**
+     * Get the morph type for the pivot.
+     *
+     * @return string
+     */
+    public function getMorphType()
+    {
+        return $this->morphType;
+    }
+
+    /**
+     * Set the morph type for the pivot.
+     *
+     * @param  string  $morphType
+     * @return $this
+     */
+    public function setMorphType($morphType)
+    {
+        $this->morphType = $morphType;
+
+        return $this;
+    }
+
+    /**
+     * Set the morph class for the pivot.
+     *
+     * @param  string  $morphClass
+     * @return \Illuminate\Database\Eloquent\Relations\MorphPivot
+     */
+    public function setMorphClass($morphClass)
+    {
+        $this->morphClass = $morphClass;
+
+        return $this;
+    }
+
+    /**
+     * Get the queueable identity for the entity.
+     *
+     * @return mixed
+     */
+    public function getQueueableId()
+    {
+        if (isset($this->attributes[$this->getKeyName()])) {
+            return $this->getKey();
+        }
+
+        return sprintf(
+            '%s:%s:%s:%s:%s:%s',
+            $this->foreignKey, $this->getAttribute($this->foreignKey),
+            $this->relatedKey, $this->getAttribute($this->relatedKey),
+            $this->morphType, $this->morphClass
+        );
+    }
+
+    /**
+     * Get a new query to restore one or more models by their queueable IDs.
+     *
+     * @param  array|int  $ids
+     * @return \Illuminate\Database\Eloquent\Builder
+     */
+    public function newQueryForRestoration($ids)
+    {
+        if (is_array($ids)) {
+            return $this->newQueryForCollectionRestoration($ids);
+        }
+
+        if (! str_contains($ids, ':')) {
+            return parent::newQueryForRestoration($ids);
+        }
+
+        $segments = explode(':', $ids);
+
+        return $this->newQueryWithoutScopes()
+                        ->where($segments[0], $segments[1])
+                        ->where($segments[2], $segments[3])
+                        ->where($segments[4], $segments[5]);
+    }
+
+    /**
+     * Get a new query to restore multiple models by their queueable IDs.
+     *
+     * @param  array  $ids
+     * @return \Illuminate\Database\Eloquent\Builder
+     */
+    protected function newQueryForCollectionRestoration(array $ids)
+    {
+        $ids = array_values($ids);
+
+        if (! str_contains($ids[0], ':')) {
+            return parent::newQueryForRestoration($ids);
+        }
+
+        $query = $this->newQueryWithoutScopes();
+
+        foreach ($ids as $id) {
+            $segments = explode(':', $id);
+
+            $query->orWhere(function ($query) use ($segments) {
+                return $query->where($segments[0], $segments[1])
+                             ->where($segments[2], $segments[3])
+                             ->where($segments[4], $segments[5]);
+            });
+        }
+
+        return $query;
+    }
+}
diff --git a/vendor/illuminate/database/Eloquent/Relations/MorphTo.php b/vendor/illuminate/database/Eloquent/Relations/MorphTo.php
new file mode 100644
index 0000000..262741f
--- /dev/null
+++ b/vendor/illuminate/database/Eloquent/Relations/MorphTo.php
@@ -0,0 +1,396 @@
+morphType = $type;
+
+        parent::__construct($query, $parent, $foreignKey, $ownerKey, $relation);
+    }
+
+    /**
+     * Set the constraints for an eager load of the relation.
+     *
+     * @param  array  $models
+     * @return void
+     */
+    public function addEagerConstraints(array $models)
+    {
+        $this->buildDictionary($this->models = Collection::make($models));
+    }
+
+    /**
+     * Build a dictionary with the models.
+     *
+     * @param  \Illuminate\Database\Eloquent\Collection  $models
+     * @return void
+     */
+    protected function buildDictionary(Collection $models)
+    {
+        foreach ($models as $model) {
+            if ($model->{$this->morphType}) {
+                $morphTypeKey = $this->getDictionaryKey($model->{$this->morphType});
+                $foreignKeyKey = $this->getDictionaryKey($model->{$this->foreignKey});
+
+                $this->dictionary[$morphTypeKey][$foreignKeyKey][] = $model;
+            }
+        }
+    }
+
+    /**
+     * Get the results of the relationship.
+     *
+     * Called via eager load method of Eloquent query builder.
+     *
+     * @return mixed
+     */
+    public function getEager()
+    {
+        foreach (array_keys($this->dictionary) as $type) {
+            $this->matchToMorphParents($type, $this->getResultsByType($type));
+        }
+
+        return $this->models;
+    }
+
+    /**
+     * Get all of the relation results for a type.
+     *
+     * @param  string  $type
+     * @return \Illuminate\Database\Eloquent\Collection
+     */
+    protected function getResultsByType($type)
+    {
+        $instance = $this->createModelByType($type);
+
+        $ownerKey = $this->ownerKey ?? $instance->getKeyName();
+
+        $query = $this->replayMacros($instance->newQuery())
+                            ->mergeConstraintsFrom($this->getQuery())
+                            ->with(array_merge(
+                                $this->getQuery()->getEagerLoads(),
+                                (array) ($this->morphableEagerLoads[get_class($instance)] ?? [])
+                            ))
+                            ->withCount(
+                                (array) ($this->morphableEagerLoadCounts[get_class($instance)] ?? [])
+                            );
+
+        if ($callback = ($this->morphableConstraints[get_class($instance)] ?? null)) {
+            $callback($query);
+        }
+
+        $whereIn = $this->whereInMethod($instance, $ownerKey);
+
+        return $query->{$whereIn}(
+            $instance->getTable().'.'.$ownerKey, $this->gatherKeysByType($type, $instance->getKeyType())
+        )->get();
+    }
+
+    /**
+     * Gather all of the foreign keys for a given type.
+     *
+     * @param  string  $type
+     * @param  string  $keyType
+     * @return array
+     */
+    protected function gatherKeysByType($type, $keyType)
+    {
+        return $keyType !== 'string'
+                    ? array_keys($this->dictionary[$type])
+                    : array_map(function ($modelId) {
+                        return (string) $modelId;
+                    }, array_filter(array_keys($this->dictionary[$type])));
+    }
+
+    /**
+     * Create a new model instance by type.
+     *
+     * @param  string  $type
+     * @return \Illuminate\Database\Eloquent\Model
+     */
+    public function createModelByType($type)
+    {
+        $class = Model::getActualClassNameForMorph($type);
+
+        return tap(new $class, function ($instance) {
+            if (! $instance->getConnectionName()) {
+                $instance->setConnection($this->getConnection()->getName());
+            }
+        });
+    }
+
+    /**
+     * Match the eagerly loaded results to their parents.
+     *
+     * @param  array  $models
+     * @param  \Illuminate\Database\Eloquent\Collection  $results
+     * @param  string  $relation
+     * @return array
+     */
+    public function match(array $models, Collection $results, $relation)
+    {
+        return $models;
+    }
+
+    /**
+     * Match the results for a given type to their parents.
+     *
+     * @param  string  $type
+     * @param  \Illuminate\Database\Eloquent\Collection  $results
+     * @return void
+     */
+    protected function matchToMorphParents($type, Collection $results)
+    {
+        foreach ($results as $result) {
+            $ownerKey = ! is_null($this->ownerKey) ? $this->getDictionaryKey($result->{$this->ownerKey}) : $result->getKey();
+
+            if (isset($this->dictionary[$type][$ownerKey])) {
+                foreach ($this->dictionary[$type][$ownerKey] as $model) {
+                    $model->setRelation($this->relationName, $result);
+                }
+            }
+        }
+    }
+
+    /**
+     * Associate the model instance to the given parent.
+     *
+     * @param  \Illuminate\Database\Eloquent\Model  $model
+     * @return \Illuminate\Database\Eloquent\Model
+     */
+    public function associate($model)
+    {
+        if ($model instanceof Model) {
+            $foreignKey = $this->ownerKey && $model->{$this->ownerKey}
+                            ? $this->ownerKey
+                            : $model->getKeyName();
+        }
+
+        $this->parent->setAttribute(
+            $this->foreignKey, $model instanceof Model ? $model->{$foreignKey} : null
+        );
+
+        $this->parent->setAttribute(
+            $this->morphType, $model instanceof Model ? $model->getMorphClass() : null
+        );
+
+        return $this->parent->setRelation($this->relationName, $model);
+    }
+
+    /**
+     * Dissociate previously associated model from the given parent.
+     *
+     * @return \Illuminate\Database\Eloquent\Model
+     */
+    public function dissociate()
+    {
+        $this->parent->setAttribute($this->foreignKey, null);
+
+        $this->parent->setAttribute($this->morphType, null);
+
+        return $this->parent->setRelation($this->relationName, null);
+    }
+
+    /**
+     * Touch all of the related models for the relationship.
+     *
+     * @return void
+     */
+    public function touch()
+    {
+        if (! is_null($this->child->{$this->foreignKey})) {
+            parent::touch();
+        }
+    }
+
+    /**
+     * Make a new related instance for the given model.
+     *
+     * @param  \Illuminate\Database\Eloquent\Model  $parent
+     * @return \Illuminate\Database\Eloquent\Model
+     */
+    protected function newRelatedInstanceFor(Model $parent)
+    {
+        return $parent->{$this->getRelationName()}()->getRelated()->newInstance();
+    }
+
+    /**
+     * Get the foreign key "type" name.
+     *
+     * @return string
+     */
+    public function getMorphType()
+    {
+        return $this->morphType;
+    }
+
+    /**
+     * Get the dictionary used by the relationship.
+     *
+     * @return array
+     */
+    public function getDictionary()
+    {
+        return $this->dictionary;
+    }
+
+    /**
+     * Specify which relations to load for a given morph type.
+     *
+     * @param  array  $with
+     * @return \Illuminate\Database\Eloquent\Relations\MorphTo
+     */
+    public function morphWith(array $with)
+    {
+        $this->morphableEagerLoads = array_merge(
+            $this->morphableEagerLoads, $with
+        );
+
+        return $this;
+    }
+
+    /**
+     * Specify which relationship counts to load for a given morph type.
+     *
+     * @param  array  $withCount
+     * @return \Illuminate\Database\Eloquent\Relations\MorphTo
+     */
+    public function morphWithCount(array $withCount)
+    {
+        $this->morphableEagerLoadCounts = array_merge(
+            $this->morphableEagerLoadCounts, $withCount
+        );
+
+        return $this;
+    }
+
+    /**
+     * Specify constraints on the query for a given morph type.
+     *
+     * @param  array  $callbacks
+     * @return \Illuminate\Database\Eloquent\Relations\MorphTo
+     */
+    public function constrain(array $callbacks)
+    {
+        $this->morphableConstraints = array_merge(
+            $this->morphableConstraints, $callbacks
+        );
+
+        return $this;
+    }
+
+    /**
+     * Replay stored macro calls on the actual related instance.
+     *
+     * @param  \Illuminate\Database\Eloquent\Builder  $query
+     * @return \Illuminate\Database\Eloquent\Builder
+     */
+    protected function replayMacros(Builder $query)
+    {
+        foreach ($this->macroBuffer as $macro) {
+            $query->{$macro['method']}(...$macro['parameters']);
+        }
+
+        return $query;
+    }
+
+    /**
+     * Handle dynamic method calls to the relationship.
+     *
+     * @param  string  $method
+     * @param  array  $parameters
+     * @return mixed
+     */
+    public function __call($method, $parameters)
+    {
+        try {
+            $result = parent::__call($method, $parameters);
+
+            if (in_array($method, ['select', 'selectRaw', 'selectSub', 'addSelect', 'withoutGlobalScopes'])) {
+                $this->macroBuffer[] = compact('method', 'parameters');
+            }
+
+            return $result;
+        }
+
+        // If we tried to call a method that does not exist on the parent Builder instance,
+        // we'll assume that we want to call a query macro (e.g. withTrashed) that only
+        // exists on related models. We will just store the call and replay it later.
+        catch (BadMethodCallException $e) {
+            $this->macroBuffer[] = compact('method', 'parameters');
+
+            return $this;
+        }
+    }
+}
diff --git a/vendor/illuminate/database/Eloquent/Relations/MorphToMany.php b/vendor/illuminate/database/Eloquent/Relations/MorphToMany.php
new file mode 100644
index 0000000..c2d5745
--- /dev/null
+++ b/vendor/illuminate/database/Eloquent/Relations/MorphToMany.php
@@ -0,0 +1,209 @@
+inverse = $inverse;
+        $this->morphType = $name.'_type';
+        $this->morphClass = $inverse ? $query->getModel()->getMorphClass() : $parent->getMorphClass();
+
+        parent::__construct(
+            $query, $parent, $table, $foreignPivotKey,
+            $relatedPivotKey, $parentKey, $relatedKey, $relationName
+        );
+    }
+
+    /**
+     * Set the where clause for the relation query.
+     *
+     * @return $this
+     */
+    protected function addWhereConstraints()
+    {
+        parent::addWhereConstraints();
+
+        $this->query->where($this->qualifyPivotColumn($this->morphType), $this->morphClass);
+
+        return $this;
+    }
+
+    /**
+     * Set the constraints for an eager load of the relation.
+     *
+     * @param  array  $models
+     * @return void
+     */
+    public function addEagerConstraints(array $models)
+    {
+        parent::addEagerConstraints($models);
+
+        $this->query->where($this->qualifyPivotColumn($this->morphType), $this->morphClass);
+    }
+
+    /**
+     * Create a new pivot attachment record.
+     *
+     * @param  int  $id
+     * @param  bool  $timed
+     * @return array
+     */
+    protected function baseAttachRecord($id, $timed)
+    {
+        return Arr::add(
+            parent::baseAttachRecord($id, $timed), $this->morphType, $this->morphClass
+        );
+    }
+
+    /**
+     * Add the constraints for a relationship count query.
+     *
+     * @param  \Illuminate\Database\Eloquent\Builder  $query
+     * @param  \Illuminate\Database\Eloquent\Builder  $parentQuery
+     * @param  array|mixed  $columns
+     * @return \Illuminate\Database\Eloquent\Builder
+     */
+    public function getRelationExistenceQuery(Builder $query, Builder $parentQuery, $columns = ['*'])
+    {
+        return parent::getRelationExistenceQuery($query, $parentQuery, $columns)->where(
+            $this->qualifyPivotColumn($this->morphType), $this->morphClass
+        );
+    }
+
+    /**
+     * Get the pivot models that are currently attached.
+     *
+     * @return \Illuminate\Support\Collection
+     */
+    protected function getCurrentlyAttachedPivots()
+    {
+        return parent::getCurrentlyAttachedPivots()->map(function ($record) {
+            return $record instanceof MorphPivot
+                            ? $record->setMorphType($this->morphType)
+                                     ->setMorphClass($this->morphClass)
+                            : $record;
+        });
+    }
+
+    /**
+     * Create a new query builder for the pivot table.
+     *
+     * @return \Illuminate\Database\Query\Builder
+     */
+    public function newPivotQuery()
+    {
+        return parent::newPivotQuery()->where($this->morphType, $this->morphClass);
+    }
+
+    /**
+     * Create a new pivot model instance.
+     *
+     * @param  array  $attributes
+     * @param  bool  $exists
+     * @return \Illuminate\Database\Eloquent\Relations\Pivot
+     */
+    public function newPivot(array $attributes = [], $exists = false)
+    {
+        $using = $this->using;
+
+        $pivot = $using ? $using::fromRawAttributes($this->parent, $attributes, $this->table, $exists)
+                        : MorphPivot::fromAttributes($this->parent, $attributes, $this->table, $exists);
+
+        $pivot->setPivotKeys($this->foreignPivotKey, $this->relatedPivotKey)
+              ->setMorphType($this->morphType)
+              ->setMorphClass($this->morphClass);
+
+        return $pivot;
+    }
+
+    /**
+     * Get the pivot columns for the relation.
+     *
+     * "pivot_" is prefixed at each column for easy removal later.
+     *
+     * @return array
+     */
+    protected function aliasedPivotColumns()
+    {
+        $defaults = [$this->foreignPivotKey, $this->relatedPivotKey, $this->morphType];
+
+        return collect(array_merge($defaults, $this->pivotColumns))->map(function ($column) {
+            return $this->qualifyPivotColumn($column).' as pivot_'.$column;
+        })->unique()->all();
+    }
+
+    /**
+     * Get the foreign key "type" name.
+     *
+     * @return string
+     */
+    public function getMorphType()
+    {
+        return $this->morphType;
+    }
+
+    /**
+     * Get the class name of the parent model.
+     *
+     * @return string
+     */
+    public function getMorphClass()
+    {
+        return $this->morphClass;
+    }
+
+    /**
+     * Get the indicator for a reverse relationship.
+     *
+     * @return bool
+     */
+    public function getInverse()
+    {
+        return $this->inverse;
+    }
+}
diff --git a/vendor/illuminate/database/Eloquent/Relations/Pivot.php b/vendor/illuminate/database/Eloquent/Relations/Pivot.php
new file mode 100755
index 0000000..a65ecde
--- /dev/null
+++ b/vendor/illuminate/database/Eloquent/Relations/Pivot.php
@@ -0,0 +1,25 @@
+query = $query;
+        $this->parent = $parent;
+        $this->related = $query->getModel();
+
+        $this->addConstraints();
+    }
+
+    /**
+     * Run a callback with constraints disabled on the relation.
+     *
+     * @param  \Closure  $callback
+     * @return mixed
+     */
+    public static function noConstraints(Closure $callback)
+    {
+        $previous = static::$constraints;
+
+        static::$constraints = false;
+
+        // When resetting the relation where clause, we want to shift the first element
+        // off of the bindings, leaving only the constraints that the developers put
+        // as "extra" on the relationships, and not original relation constraints.
+        try {
+            return $callback();
+        } finally {
+            static::$constraints = $previous;
+        }
+    }
+
+    /**
+     * Set the base constraints on the relation query.
+     *
+     * @return void
+     */
+    abstract public function addConstraints();
+
+    /**
+     * Set the constraints for an eager load of the relation.
+     *
+     * @param  array  $models
+     * @return void
+     */
+    abstract public function addEagerConstraints(array $models);
+
+    /**
+     * Initialize the relation on a set of models.
+     *
+     * @param  array  $models
+     * @param  string  $relation
+     * @return array
+     */
+    abstract public function initRelation(array $models, $relation);
+
+    /**
+     * Match the eagerly loaded results to their parents.
+     *
+     * @param  array  $models
+     * @param  \Illuminate\Database\Eloquent\Collection  $results
+     * @param  string  $relation
+     * @return array
+     */
+    abstract public function match(array $models, Collection $results, $relation);
+
+    /**
+     * Get the results of the relationship.
+     *
+     * @return mixed
+     */
+    abstract public function getResults();
+
+    /**
+     * Get the relationship for eager loading.
+     *
+     * @return \Illuminate\Database\Eloquent\Collection
+     */
+    public function getEager()
+    {
+        return $this->get();
+    }
+
+    /**
+     * Execute the query and get the first result if it's the sole matching record.
+     *
+     * @param  array|string  $columns
+     * @return \Illuminate\Database\Eloquent\Model
+     *
+     * @throws \Illuminate\Database\Eloquent\ModelNotFoundException<\Illuminate\Database\Eloquent\Model>
+     * @throws \Illuminate\Database\MultipleRecordsFoundException
+     */
+    public function sole($columns = ['*'])
+    {
+        $result = $this->take(2)->get($columns);
+
+        $count = $result->count();
+
+        if ($count === 0) {
+            throw (new ModelNotFoundException)->setModel(get_class($this->related));
+        }
+
+        if ($count > 1) {
+            throw new MultipleRecordsFoundException($count);
+        }
+
+        return $result->first();
+    }
+
+    /**
+     * Execute the query as a "select" statement.
+     *
+     * @param  array  $columns
+     * @return \Illuminate\Database\Eloquent\Collection
+     */
+    public function get($columns = ['*'])
+    {
+        return $this->query->get($columns);
+    }
+
+    /**
+     * Touch all of the related models for the relationship.
+     *
+     * @return void
+     */
+    public function touch()
+    {
+        $model = $this->getRelated();
+
+        if (! $model::isIgnoringTouch()) {
+            $this->rawUpdate([
+                $model->getUpdatedAtColumn() => $model->freshTimestampString(),
+            ]);
+        }
+    }
+
+    /**
+     * Run a raw update against the base query.
+     *
+     * @param  array  $attributes
+     * @return int
+     */
+    public function rawUpdate(array $attributes = [])
+    {
+        return $this->query->withoutGlobalScopes()->update($attributes);
+    }
+
+    /**
+     * Add the constraints for a relationship count query.
+     *
+     * @param  \Illuminate\Database\Eloquent\Builder  $query
+     * @param  \Illuminate\Database\Eloquent\Builder  $parentQuery
+     * @return \Illuminate\Database\Eloquent\Builder
+     */
+    public function getRelationExistenceCountQuery(Builder $query, Builder $parentQuery)
+    {
+        return $this->getRelationExistenceQuery(
+            $query, $parentQuery, new Expression('count(*)')
+        )->setBindings([], 'select');
+    }
+
+    /**
+     * Add the constraints for an internal relationship existence query.
+     *
+     * Essentially, these queries compare on column names like whereColumn.
+     *
+     * @param  \Illuminate\Database\Eloquent\Builder  $query
+     * @param  \Illuminate\Database\Eloquent\Builder  $parentQuery
+     * @param  array|mixed  $columns
+     * @return \Illuminate\Database\Eloquent\Builder
+     */
+    public function getRelationExistenceQuery(Builder $query, Builder $parentQuery, $columns = ['*'])
+    {
+        return $query->select($columns)->whereColumn(
+            $this->getQualifiedParentKeyName(), '=', $this->getExistenceCompareKey()
+        );
+    }
+
+    /**
+     * Get a relationship join table hash.
+     *
+     * @param  bool  $incrementJoinCount
+     * @return string
+     */
+    public function getRelationCountHash($incrementJoinCount = true)
+    {
+        return 'laravel_reserved_'.($incrementJoinCount ? static::$selfJoinCount++ : static::$selfJoinCount);
+    }
+
+    /**
+     * Get all of the primary keys for an array of models.
+     *
+     * @param  array  $models
+     * @param  string|null  $key
+     * @return array
+     */
+    protected function getKeys(array $models, $key = null)
+    {
+        return collect($models)->map(function ($value) use ($key) {
+            return $key ? $value->getAttribute($key) : $value->getKey();
+        })->values()->unique(null, true)->sort()->all();
+    }
+
+    /**
+     * Get the query builder that will contain the relationship constraints.
+     *
+     * @return \Illuminate\Database\Eloquent\Builder
+     */
+    protected function getRelationQuery()
+    {
+        return $this->query;
+    }
+
+    /**
+     * Get the underlying query for the relation.
+     *
+     * @return \Illuminate\Database\Eloquent\Builder
+     */
+    public function getQuery()
+    {
+        return $this->query;
+    }
+
+    /**
+     * Get the base query builder driving the Eloquent builder.
+     *
+     * @return \Illuminate\Database\Query\Builder
+     */
+    public function getBaseQuery()
+    {
+        return $this->query->getQuery();
+    }
+
+    /**
+     * Get a base query builder instance.
+     *
+     * @return \Illuminate\Database\Query\Builder
+     */
+    public function toBase()
+    {
+        return $this->query->toBase();
+    }
+
+    /**
+     * Get the parent model of the relation.
+     *
+     * @return \Illuminate\Database\Eloquent\Model
+     */
+    public function getParent()
+    {
+        return $this->parent;
+    }
+
+    /**
+     * Get the fully qualified parent key name.
+     *
+     * @return string
+     */
+    public function getQualifiedParentKeyName()
+    {
+        return $this->parent->getQualifiedKeyName();
+    }
+
+    /**
+     * Get the related model of the relation.
+     *
+     * @return \Illuminate\Database\Eloquent\Model
+     */
+    public function getRelated()
+    {
+        return $this->related;
+    }
+
+    /**
+     * Get the name of the "created at" column.
+     *
+     * @return string
+     */
+    public function createdAt()
+    {
+        return $this->parent->getCreatedAtColumn();
+    }
+
+    /**
+     * Get the name of the "updated at" column.
+     *
+     * @return string
+     */
+    public function updatedAt()
+    {
+        return $this->parent->getUpdatedAtColumn();
+    }
+
+    /**
+     * Get the name of the related model's "updated at" column.
+     *
+     * @return string
+     */
+    public function relatedUpdatedAt()
+    {
+        return $this->related->getUpdatedAtColumn();
+    }
+
+    /**
+     * Get the name of the "where in" method for eager loading.
+     *
+     * @param  \Illuminate\Database\Eloquent\Model  $model
+     * @param  string  $key
+     * @return string
+     */
+    protected function whereInMethod(Model $model, $key)
+    {
+        return $model->getKeyName() === last(explode('.', $key))
+                    && in_array($model->getKeyType(), ['int', 'integer'])
+                        ? 'whereIntegerInRaw'
+                        : 'whereIn';
+    }
+
+    /**
+     * Prevent polymorphic relationships from being used without model mappings.
+     *
+     * @param  bool  $requireMorphMap
+     * @return void
+     */
+    public static function requireMorphMap($requireMorphMap = true)
+    {
+        static::$requireMorphMap = $requireMorphMap;
+    }
+
+    /**
+     * Determine if polymorphic relationships require explicit model mapping.
+     *
+     * @return bool
+     */
+    public static function requiresMorphMap()
+    {
+        return static::$requireMorphMap;
+    }
+
+    /**
+     * Define the morph map for polymorphic relations and require all morphed models to be explicitly mapped.
+     *
+     * @param  array  $map
+     * @param  bool  $merge
+     * @return array
+     */
+    public static function enforceMorphMap(array $map, $merge = true)
+    {
+        static::requireMorphMap();
+
+        return static::morphMap($map, $merge);
+    }
+
+    /**
+     * Set or get the morph map for polymorphic relations.
+     *
+     * @param  array|null  $map
+     * @param  bool  $merge
+     * @return array
+     */
+    public static function morphMap(array $map = null, $merge = true)
+    {
+        $map = static::buildMorphMapFromModels($map);
+
+        if (is_array($map)) {
+            static::$morphMap = $merge && static::$morphMap
+                            ? $map + static::$morphMap : $map;
+        }
+
+        return static::$morphMap;
+    }
+
+    /**
+     * Builds a table-keyed array from model class names.
+     *
+     * @param  string[]|null  $models
+     * @return array|null
+     */
+    protected static function buildMorphMapFromModels(array $models = null)
+    {
+        if (is_null($models) || Arr::isAssoc($models)) {
+            return $models;
+        }
+
+        return array_combine(array_map(function ($model) {
+            return (new $model)->getTable();
+        }, $models), $models);
+    }
+
+    /**
+     * Get the model associated with a custom polymorphic type.
+     *
+     * @param  string  $alias
+     * @return string|null
+     */
+    public static function getMorphedModel($alias)
+    {
+        return static::$morphMap[$alias] ?? null;
+    }
+
+    /**
+     * Handle dynamic method calls to the relationship.
+     *
+     * @param  string  $method
+     * @param  array  $parameters
+     * @return mixed
+     */
+    public function __call($method, $parameters)
+    {
+        if (static::hasMacro($method)) {
+            return $this->macroCall($method, $parameters);
+        }
+
+        return $this->forwardDecoratedCallTo($this->query, $method, $parameters);
+    }
+
+    /**
+     * Force a clone of the underlying query builder when cloning.
+     *
+     * @return void
+     */
+    public function __clone()
+    {
+        $this->query = clone $this->query;
+    }
+}
diff --git a/vendor/illuminate/database/Eloquent/Scope.php b/vendor/illuminate/database/Eloquent/Scope.php
new file mode 100644
index 0000000..63cba6a
--- /dev/null
+++ b/vendor/illuminate/database/Eloquent/Scope.php
@@ -0,0 +1,15 @@
+casts[$this->getDeletedAtColumn()])) {
+            $this->casts[$this->getDeletedAtColumn()] = 'datetime';
+        }
+    }
+
+    /**
+     * Force a hard delete on a soft deleted model.
+     *
+     * @return bool|null
+     */
+    public function forceDelete()
+    {
+        if ($this->fireModelEvent('forceDeleting') === false) {
+            return false;
+        }
+
+        $this->forceDeleting = true;
+
+        return tap($this->delete(), function ($deleted) {
+            $this->forceDeleting = false;
+
+            if ($deleted) {
+                $this->fireModelEvent('forceDeleted', false);
+            }
+        });
+    }
+
+    /**
+     * Force a hard delete on a soft deleted model without raising any events.
+     *
+     * @return bool|null
+     */
+    public function forceDeleteQuietly()
+    {
+        return static::withoutEvents(fn () => $this->forceDelete());
+    }
+
+    /**
+     * Perform the actual delete query on this model instance.
+     *
+     * @return mixed
+     */
+    protected function performDeleteOnModel()
+    {
+        if ($this->forceDeleting) {
+            return tap($this->setKeysForSaveQuery($this->newModelQuery())->forceDelete(), function () {
+                $this->exists = false;
+            });
+        }
+
+        return $this->runSoftDelete();
+    }
+
+    /**
+     * Perform the actual delete query on this model instance.
+     *
+     * @return void
+     */
+    protected function runSoftDelete()
+    {
+        $query = $this->setKeysForSaveQuery($this->newModelQuery());
+
+        $time = $this->freshTimestamp();
+
+        $columns = [$this->getDeletedAtColumn() => $this->fromDateTime($time)];
+
+        $this->{$this->getDeletedAtColumn()} = $time;
+
+        if ($this->usesTimestamps() && ! is_null($this->getUpdatedAtColumn())) {
+            $this->{$this->getUpdatedAtColumn()} = $time;
+
+            $columns[$this->getUpdatedAtColumn()] = $this->fromDateTime($time);
+        }
+
+        $query->update($columns);
+
+        $this->syncOriginalAttributes(array_keys($columns));
+
+        $this->fireModelEvent('trashed', false);
+    }
+
+    /**
+     * Restore a soft-deleted model instance.
+     *
+     * @return bool
+     */
+    public function restore()
+    {
+        // If the restoring event does not return false, we will proceed with this
+        // restore operation. Otherwise, we bail out so the developer will stop
+        // the restore totally. We will clear the deleted timestamp and save.
+        if ($this->fireModelEvent('restoring') === false) {
+            return false;
+        }
+
+        $this->{$this->getDeletedAtColumn()} = null;
+
+        // Once we have saved the model, we will fire the "restored" event so this
+        // developer will do anything they need to after a restore operation is
+        // totally finished. Then we will return the result of the save call.
+        $this->exists = true;
+
+        $result = $this->save();
+
+        $this->fireModelEvent('restored', false);
+
+        return $result;
+    }
+
+    /**
+     * Restore a soft-deleted model instance without raising any events.
+     *
+     * @return bool
+     */
+    public function restoreQuietly()
+    {
+        return static::withoutEvents(fn () => $this->restore());
+    }
+
+    /**
+     * Determine if the model instance has been soft-deleted.
+     *
+     * @return bool
+     */
+    public function trashed()
+    {
+        return ! is_null($this->{$this->getDeletedAtColumn()});
+    }
+
+    /**
+     * Register a "softDeleted" model event callback with the dispatcher.
+     *
+     * @param  \Closure|string  $callback
+     * @return void
+     */
+    public static function softDeleted($callback)
+    {
+        static::registerModelEvent('trashed', $callback);
+    }
+
+    /**
+     * Register a "restoring" model event callback with the dispatcher.
+     *
+     * @param  \Closure|string  $callback
+     * @return void
+     */
+    public static function restoring($callback)
+    {
+        static::registerModelEvent('restoring', $callback);
+    }
+
+    /**
+     * Register a "restored" model event callback with the dispatcher.
+     *
+     * @param  \Closure|string  $callback
+     * @return void
+     */
+    public static function restored($callback)
+    {
+        static::registerModelEvent('restored', $callback);
+    }
+
+    /**
+     * Register a "forceDeleting" model event callback with the dispatcher.
+     *
+     * @param  \Closure|string  $callback
+     * @return void
+     */
+    public static function forceDeleting($callback)
+    {
+        static::registerModelEvent('forceDeleting', $callback);
+    }
+
+    /**
+     * Register a "forceDeleted" model event callback with the dispatcher.
+     *
+     * @param  \Closure|string  $callback
+     * @return void
+     */
+    public static function forceDeleted($callback)
+    {
+        static::registerModelEvent('forceDeleted', $callback);
+    }
+
+    /**
+     * Determine if the model is currently force deleting.
+     *
+     * @return bool
+     */
+    public function isForceDeleting()
+    {
+        return $this->forceDeleting;
+    }
+
+    /**
+     * Get the name of the "deleted at" column.
+     *
+     * @return string
+     */
+    public function getDeletedAtColumn()
+    {
+        return defined(static::class.'::DELETED_AT') ? static::DELETED_AT : 'deleted_at';
+    }
+
+    /**
+     * Get the fully qualified "deleted at" column.
+     *
+     * @return string
+     */
+    public function getQualifiedDeletedAtColumn()
+    {
+        return $this->qualifyColumn($this->getDeletedAtColumn());
+    }
+}
diff --git a/vendor/illuminate/database/Eloquent/SoftDeletingScope.php b/vendor/illuminate/database/Eloquent/SoftDeletingScope.php
new file mode 100644
index 0000000..e6d91d9
--- /dev/null
+++ b/vendor/illuminate/database/Eloquent/SoftDeletingScope.php
@@ -0,0 +1,148 @@
+whereNull($model->getQualifiedDeletedAtColumn());
+    }
+
+    /**
+     * Extend the query builder with the needed functions.
+     *
+     * @param  \Illuminate\Database\Eloquent\Builder  $builder
+     * @return void
+     */
+    public function extend(Builder $builder)
+    {
+        foreach ($this->extensions as $extension) {
+            $this->{"add{$extension}"}($builder);
+        }
+
+        $builder->onDelete(function (Builder $builder) {
+            $column = $this->getDeletedAtColumn($builder);
+
+            return $builder->update([
+                $column => $builder->getModel()->freshTimestampString(),
+            ]);
+        });
+    }
+
+    /**
+     * Get the "deleted at" column for the builder.
+     *
+     * @param  \Illuminate\Database\Eloquent\Builder  $builder
+     * @return string
+     */
+    protected function getDeletedAtColumn(Builder $builder)
+    {
+        if (count((array) $builder->getQuery()->joins) > 0) {
+            return $builder->getModel()->getQualifiedDeletedAtColumn();
+        }
+
+        return $builder->getModel()->getDeletedAtColumn();
+    }
+
+    /**
+     * Add the restore extension to the builder.
+     *
+     * @param  \Illuminate\Database\Eloquent\Builder  $builder
+     * @return void
+     */
+    protected function addRestore(Builder $builder)
+    {
+        $builder->macro('restore', function (Builder $builder) {
+            $builder->withTrashed();
+
+            return $builder->update([$builder->getModel()->getDeletedAtColumn() => null]);
+        });
+    }
+
+    /**
+     * Add the restore-or-create extension to the builder.
+     *
+     * @param  \Illuminate\Database\Eloquent\Builder  $builder
+     * @return void
+     */
+    protected function addRestoreOrCreate(Builder $builder)
+    {
+        $builder->macro('restoreOrCreate', function (Builder $builder, array $attributes = [], array $values = []) {
+            $builder->withTrashed();
+
+            return tap($builder->firstOrCreate($attributes, $values), function ($instance) {
+                $instance->restore();
+            });
+        });
+    }
+
+    /**
+     * Add the with-trashed extension to the builder.
+     *
+     * @param  \Illuminate\Database\Eloquent\Builder  $builder
+     * @return void
+     */
+    protected function addWithTrashed(Builder $builder)
+    {
+        $builder->macro('withTrashed', function (Builder $builder, $withTrashed = true) {
+            if (! $withTrashed) {
+                return $builder->withoutTrashed();
+            }
+
+            return $builder->withoutGlobalScope($this);
+        });
+    }
+
+    /**
+     * Add the without-trashed extension to the builder.
+     *
+     * @param  \Illuminate\Database\Eloquent\Builder  $builder
+     * @return void
+     */
+    protected function addWithoutTrashed(Builder $builder)
+    {
+        $builder->macro('withoutTrashed', function (Builder $builder) {
+            $model = $builder->getModel();
+
+            $builder->withoutGlobalScope($this)->whereNull(
+                $model->getQualifiedDeletedAtColumn()
+            );
+
+            return $builder;
+        });
+    }
+
+    /**
+     * Add the only-trashed extension to the builder.
+     *
+     * @param  \Illuminate\Database\Eloquent\Builder  $builder
+     * @return void
+     */
+    protected function addOnlyTrashed(Builder $builder)
+    {
+        $builder->macro('onlyTrashed', function (Builder $builder) {
+            $model = $builder->getModel();
+
+            $builder->withoutGlobalScope($this)->whereNotNull(
+                $model->getQualifiedDeletedAtColumn()
+            );
+
+            return $builder;
+        });
+    }
+}
diff --git a/vendor/illuminate/database/Events/ConnectionEstablished.php b/vendor/illuminate/database/Events/ConnectionEstablished.php
new file mode 100644
index 0000000..22a45b8
--- /dev/null
+++ b/vendor/illuminate/database/Events/ConnectionEstablished.php
@@ -0,0 +1,8 @@
+connection = $connection;
+        $this->connectionName = $connection->getName();
+    }
+}
diff --git a/vendor/illuminate/database/Events/DatabaseBusy.php b/vendor/illuminate/database/Events/DatabaseBusy.php
new file mode 100644
index 0000000..8e903a9
--- /dev/null
+++ b/vendor/illuminate/database/Events/DatabaseBusy.php
@@ -0,0 +1,32 @@
+connectionName = $connectionName;
+        $this->connections = $connections;
+    }
+}
diff --git a/vendor/illuminate/database/Events/DatabaseRefreshed.php b/vendor/illuminate/database/Events/DatabaseRefreshed.php
new file mode 100644
index 0000000..5b1fb45
--- /dev/null
+++ b/vendor/illuminate/database/Events/DatabaseRefreshed.php
@@ -0,0 +1,10 @@
+method = $method;
+        $this->migration = $migration;
+    }
+}
diff --git a/vendor/illuminate/database/Events/MigrationStarted.php b/vendor/illuminate/database/Events/MigrationStarted.php
new file mode 100644
index 0000000..3f206b4
--- /dev/null
+++ b/vendor/illuminate/database/Events/MigrationStarted.php
@@ -0,0 +1,8 @@
+method = $method;
+    }
+}
diff --git a/vendor/illuminate/database/Events/MigrationsStarted.php b/vendor/illuminate/database/Events/MigrationsStarted.php
new file mode 100644
index 0000000..5283b49
--- /dev/null
+++ b/vendor/illuminate/database/Events/MigrationsStarted.php
@@ -0,0 +1,8 @@
+model = $model;
+        $this->count = $count;
+    }
+}
diff --git a/vendor/illuminate/database/Events/NoPendingMigrations.php b/vendor/illuminate/database/Events/NoPendingMigrations.php
new file mode 100644
index 0000000..100f786
--- /dev/null
+++ b/vendor/illuminate/database/Events/NoPendingMigrations.php
@@ -0,0 +1,24 @@
+method = $method;
+    }
+}
diff --git a/vendor/illuminate/database/Events/QueryExecuted.php b/vendor/illuminate/database/Events/QueryExecuted.php
new file mode 100644
index 0000000..833a21e
--- /dev/null
+++ b/vendor/illuminate/database/Events/QueryExecuted.php
@@ -0,0 +1,59 @@
+sql = $sql;
+        $this->time = $time;
+        $this->bindings = $bindings;
+        $this->connection = $connection;
+        $this->connectionName = $connection->getName();
+    }
+}
diff --git a/vendor/illuminate/database/Events/SchemaDumped.php b/vendor/illuminate/database/Events/SchemaDumped.php
new file mode 100644
index 0000000..1cbbfff
--- /dev/null
+++ b/vendor/illuminate/database/Events/SchemaDumped.php
@@ -0,0 +1,41 @@
+connection = $connection;
+        $this->connectionName = $connection->getName();
+        $this->path = $path;
+    }
+}
diff --git a/vendor/illuminate/database/Events/SchemaLoaded.php b/vendor/illuminate/database/Events/SchemaLoaded.php
new file mode 100644
index 0000000..061a079
--- /dev/null
+++ b/vendor/illuminate/database/Events/SchemaLoaded.php
@@ -0,0 +1,41 @@
+connection = $connection;
+        $this->connectionName = $connection->getName();
+        $this->path = $path;
+    }
+}
diff --git a/vendor/illuminate/database/Events/StatementPrepared.php b/vendor/illuminate/database/Events/StatementPrepared.php
new file mode 100644
index 0000000..2f60323
--- /dev/null
+++ b/vendor/illuminate/database/Events/StatementPrepared.php
@@ -0,0 +1,33 @@
+statement = $statement;
+        $this->connection = $connection;
+    }
+}
diff --git a/vendor/illuminate/database/Events/TransactionBeginning.php b/vendor/illuminate/database/Events/TransactionBeginning.php
new file mode 100644
index 0000000..3287b5c
--- /dev/null
+++ b/vendor/illuminate/database/Events/TransactionBeginning.php
@@ -0,0 +1,8 @@
+isExpression($table)) {
+            return $this->wrap($this->tablePrefix.$table, true);
+        }
+
+        return $this->getValue($table);
+    }
+
+    /**
+     * Wrap a value in keyword identifiers.
+     *
+     * @param  \Illuminate\Database\Query\Expression|string  $value
+     * @param  bool  $prefixAlias
+     * @return string
+     */
+    public function wrap($value, $prefixAlias = false)
+    {
+        if ($this->isExpression($value)) {
+            return $this->getValue($value);
+        }
+
+        // If the value being wrapped has a column alias we will need to separate out
+        // the pieces so we can wrap each of the segments of the expression on its
+        // own, and then join these both back together using the "as" connector.
+        if (stripos($value, ' as ') !== false) {
+            return $this->wrapAliasedValue($value, $prefixAlias);
+        }
+
+        // If the given value is a JSON selector we will wrap it differently than a
+        // traditional value. We will need to split this path and wrap each part
+        // wrapped, etc. Otherwise, we will simply wrap the value as a string.
+        if ($this->isJsonSelector($value)) {
+            return $this->wrapJsonSelector($value);
+        }
+
+        return $this->wrapSegments(explode('.', $value));
+    }
+
+    /**
+     * Wrap a value that has an alias.
+     *
+     * @param  string  $value
+     * @param  bool  $prefixAlias
+     * @return string
+     */
+    protected function wrapAliasedValue($value, $prefixAlias = false)
+    {
+        $segments = preg_split('/\s+as\s+/i', $value);
+
+        // If we are wrapping a table we need to prefix the alias with the table prefix
+        // as well in order to generate proper syntax. If this is a column of course
+        // no prefix is necessary. The condition will be true when from wrapTable.
+        if ($prefixAlias) {
+            $segments[1] = $this->tablePrefix.$segments[1];
+        }
+
+        return $this->wrap($segments[0]).' as '.$this->wrapValue($segments[1]);
+    }
+
+    /**
+     * Wrap the given value segments.
+     *
+     * @param  array  $segments
+     * @return string
+     */
+    protected function wrapSegments($segments)
+    {
+        return collect($segments)->map(function ($segment, $key) use ($segments) {
+            return $key == 0 && count($segments) > 1
+                            ? $this->wrapTable($segment)
+                            : $this->wrapValue($segment);
+        })->implode('.');
+    }
+
+    /**
+     * Wrap a single string in keyword identifiers.
+     *
+     * @param  string  $value
+     * @return string
+     */
+    protected function wrapValue($value)
+    {
+        if ($value !== '*') {
+            return '"'.str_replace('"', '""', $value).'"';
+        }
+
+        return $value;
+    }
+
+    /**
+     * Wrap the given JSON selector.
+     *
+     * @param  string  $value
+     * @return string
+     *
+     * @throws \RuntimeException
+     */
+    protected function wrapJsonSelector($value)
+    {
+        throw new RuntimeException('This database engine does not support JSON operations.');
+    }
+
+    /**
+     * Determine if the given string is a JSON selector.
+     *
+     * @param  string  $value
+     * @return bool
+     */
+    protected function isJsonSelector($value)
+    {
+        return str_contains($value, '->');
+    }
+
+    /**
+     * Convert an array of column names into a delimited string.
+     *
+     * @param  array  $columns
+     * @return string
+     */
+    public function columnize(array $columns)
+    {
+        return implode(', ', array_map([$this, 'wrap'], $columns));
+    }
+
+    /**
+     * Create query parameter place-holders for an array.
+     *
+     * @param  array  $values
+     * @return string
+     */
+    public function parameterize(array $values)
+    {
+        return implode(', ', array_map([$this, 'parameter'], $values));
+    }
+
+    /**
+     * Get the appropriate query parameter place-holder for a value.
+     *
+     * @param  mixed  $value
+     * @return string
+     */
+    public function parameter($value)
+    {
+        return $this->isExpression($value) ? $this->getValue($value) : '?';
+    }
+
+    /**
+     * Quote the given string literal.
+     *
+     * @param  string|array  $value
+     * @return string
+     */
+    public function quoteString($value)
+    {
+        if (is_array($value)) {
+            return implode(', ', array_map([$this, __FUNCTION__], $value));
+        }
+
+        return "'$value'";
+    }
+
+    /**
+     * Determine if the given value is a raw expression.
+     *
+     * @param  mixed  $value
+     * @return bool
+     */
+    public function isExpression($value)
+    {
+        return $value instanceof Expression;
+    }
+
+    /**
+     * Get the value of a raw expression.
+     *
+     * @param  \Illuminate\Database\Query\Expression  $expression
+     * @return mixed
+     */
+    public function getValue($expression)
+    {
+        return $expression->getValue();
+    }
+
+    /**
+     * Get the format for database stored dates.
+     *
+     * @return string
+     */
+    public function getDateFormat()
+    {
+        return 'Y-m-d H:i:s';
+    }
+
+    /**
+     * Get the grammar's table prefix.
+     *
+     * @return string
+     */
+    public function getTablePrefix()
+    {
+        return $this->tablePrefix;
+    }
+
+    /**
+     * Set the grammar's table prefix.
+     *
+     * @param  string  $prefix
+     * @return $this
+     */
+    public function setTablePrefix($prefix)
+    {
+        $this->tablePrefix = $prefix;
+
+        return $this;
+    }
+}
diff --git a/vendor/illuminate/database/LICENSE.md b/vendor/illuminate/database/LICENSE.md
new file mode 100644
index 0000000..79810c8
--- /dev/null
+++ b/vendor/illuminate/database/LICENSE.md
@@ -0,0 +1,21 @@
+The MIT License (MIT)
+
+Copyright (c) Taylor Otwell
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
diff --git a/vendor/illuminate/database/LazyLoadingViolationException.php b/vendor/illuminate/database/LazyLoadingViolationException.php
new file mode 100644
index 0000000..1bcd40c
--- /dev/null
+++ b/vendor/illuminate/database/LazyLoadingViolationException.php
@@ -0,0 +1,39 @@
+model = $class;
+        $this->relation = $relation;
+    }
+}
diff --git a/vendor/illuminate/database/LostConnectionException.php b/vendor/illuminate/database/LostConnectionException.php
new file mode 100644
index 0000000..c8e57e3
--- /dev/null
+++ b/vendor/illuminate/database/LostConnectionException.php
@@ -0,0 +1,10 @@
+ MigrateCommand::class,
+        'MigrateFresh' => FreshCommand::class,
+        'MigrateInstall' => InstallCommand::class,
+        'MigrateRefresh' => RefreshCommand::class,
+        'MigrateReset' => ResetCommand::class,
+        'MigrateRollback' => RollbackCommand::class,
+        'MigrateStatus' => StatusCommand::class,
+        'MigrateMake' => MigrateMakeCommand::class,
+    ];
+
+    /**
+     * Register the service provider.
+     *
+     * @return void
+     */
+    public function register()
+    {
+        $this->registerRepository();
+
+        $this->registerMigrator();
+
+        $this->registerCreator();
+
+        $this->registerCommands($this->commands);
+    }
+
+    /**
+     * Register the migration repository service.
+     *
+     * @return void
+     */
+    protected function registerRepository()
+    {
+        $this->app->singleton('migration.repository', function ($app) {
+            $table = $app['config']['database.migrations'];
+
+            return new DatabaseMigrationRepository($app['db'], $table);
+        });
+    }
+
+    /**
+     * Register the migrator service.
+     *
+     * @return void
+     */
+    protected function registerMigrator()
+    {
+        // The migrator is responsible for actually running and rollback the migration
+        // files in the application. We'll pass in our database connection resolver
+        // so the migrator can resolve any of these connections when it needs to.
+        $this->app->singleton('migrator', function ($app) {
+            $repository = $app['migration.repository'];
+
+            return new Migrator($repository, $app['db'], $app['files'], $app['events']);
+        });
+    }
+
+    /**
+     * Register the migration creator.
+     *
+     * @return void
+     */
+    protected function registerCreator()
+    {
+        $this->app->singleton('migration.creator', function ($app) {
+            return new MigrationCreator($app['files'], $app->basePath('stubs'));
+        });
+    }
+
+    /**
+     * Register the given commands.
+     *
+     * @param  array  $commands
+     * @return void
+     */
+    protected function registerCommands(array $commands)
+    {
+        foreach (array_keys($commands) as $command) {
+            $this->{"register{$command}Command"}();
+        }
+
+        $this->commands(array_values($commands));
+    }
+
+    /**
+     * Register the command.
+     *
+     * @return void
+     */
+    protected function registerMigrateCommand()
+    {
+        $this->app->singleton(MigrateCommand::class, function ($app) {
+            return new MigrateCommand($app['migrator'], $app[Dispatcher::class]);
+        });
+    }
+
+    /**
+     * Register the command.
+     *
+     * @return void
+     */
+    protected function registerMigrateFreshCommand()
+    {
+        $this->app->singleton(FreshCommand::class);
+    }
+
+    /**
+     * Register the command.
+     *
+     * @return void
+     */
+    protected function registerMigrateInstallCommand()
+    {
+        $this->app->singleton(InstallCommand::class, function ($app) {
+            return new InstallCommand($app['migration.repository']);
+        });
+    }
+
+    /**
+     * Register the command.
+     *
+     * @return void
+     */
+    protected function registerMigrateMakeCommand()
+    {
+        $this->app->singleton(MigrateMakeCommand::class, function ($app) {
+            // Once we have the migration creator registered, we will create the command
+            // and inject the creator. The creator is responsible for the actual file
+            // creation of the migrations, and may be extended by these developers.
+            $creator = $app['migration.creator'];
+
+            $composer = $app['composer'];
+
+            return new MigrateMakeCommand($creator, $composer);
+        });
+    }
+
+    /**
+     * Register the command.
+     *
+     * @return void
+     */
+    protected function registerMigrateRefreshCommand()
+    {
+        $this->app->singleton(RefreshCommand::class);
+    }
+
+    /**
+     * Register the command.
+     *
+     * @return void
+     */
+    protected function registerMigrateResetCommand()
+    {
+        $this->app->singleton(ResetCommand::class, function ($app) {
+            return new ResetCommand($app['migrator']);
+        });
+    }
+
+    /**
+     * Register the command.
+     *
+     * @return void
+     */
+    protected function registerMigrateRollbackCommand()
+    {
+        $this->app->singleton(RollbackCommand::class, function ($app) {
+            return new RollbackCommand($app['migrator']);
+        });
+    }
+
+    /**
+     * Register the command.
+     *
+     * @return void
+     */
+    protected function registerMigrateStatusCommand()
+    {
+        $this->app->singleton(StatusCommand::class, function ($app) {
+            return new StatusCommand($app['migrator']);
+        });
+    }
+
+    /**
+     * Get the services provided by the provider.
+     *
+     * @return array
+     */
+    public function provides()
+    {
+        return array_merge([
+            'migrator', 'migration.repository', 'migration.creator',
+        ], array_values($this->commands));
+    }
+}
diff --git a/vendor/illuminate/database/Migrations/DatabaseMigrationRepository.php b/vendor/illuminate/database/Migrations/DatabaseMigrationRepository.php
new file mode 100755
index 0000000..ed4ebfb
--- /dev/null
+++ b/vendor/illuminate/database/Migrations/DatabaseMigrationRepository.php
@@ -0,0 +1,224 @@
+table = $table;
+        $this->resolver = $resolver;
+    }
+
+    /**
+     * Get the completed migrations.
+     *
+     * @return array
+     */
+    public function getRan()
+    {
+        return $this->table()
+                ->orderBy('batch', 'asc')
+                ->orderBy('migration', 'asc')
+                ->pluck('migration')->all();
+    }
+
+    /**
+     * Get the list of migrations.
+     *
+     * @param  int  $steps
+     * @return array
+     */
+    public function getMigrations($steps)
+    {
+        $query = $this->table()->where('batch', '>=', '1');
+
+        return $query->orderBy('batch', 'desc')
+                     ->orderBy('migration', 'desc')
+                     ->take($steps)->get()->all();
+    }
+
+    /**
+     * Get the last migration batch.
+     *
+     * @return array
+     */
+    public function getLast()
+    {
+        $query = $this->table()->where('batch', $this->getLastBatchNumber());
+
+        return $query->orderBy('migration', 'desc')->get()->all();
+    }
+
+    /**
+     * Get the completed migrations with their batch numbers.
+     *
+     * @return array
+     */
+    public function getMigrationBatches()
+    {
+        return $this->table()
+                ->orderBy('batch', 'asc')
+                ->orderBy('migration', 'asc')
+                ->pluck('batch', 'migration')->all();
+    }
+
+    /**
+     * Log that a migration was run.
+     *
+     * @param  string  $file
+     * @param  int  $batch
+     * @return void
+     */
+    public function log($file, $batch)
+    {
+        $record = ['migration' => $file, 'batch' => $batch];
+
+        $this->table()->insert($record);
+    }
+
+    /**
+     * Remove a migration from the log.
+     *
+     * @param  object  $migration
+     * @return void
+     */
+    public function delete($migration)
+    {
+        $this->table()->where('migration', $migration->migration)->delete();
+    }
+
+    /**
+     * Get the next migration batch number.
+     *
+     * @return int
+     */
+    public function getNextBatchNumber()
+    {
+        return $this->getLastBatchNumber() + 1;
+    }
+
+    /**
+     * Get the last migration batch number.
+     *
+     * @return int
+     */
+    public function getLastBatchNumber()
+    {
+        return $this->table()->max('batch');
+    }
+
+    /**
+     * Create the migration repository data store.
+     *
+     * @return void
+     */
+    public function createRepository()
+    {
+        $schema = $this->getConnection()->getSchemaBuilder();
+
+        $schema->create($this->table, function ($table) {
+            // The migrations table is responsible for keeping track of which of the
+            // migrations have actually run for the application. We'll create the
+            // table to hold the migration file's path as well as the batch ID.
+            $table->increments('id');
+            $table->string('migration');
+            $table->integer('batch');
+        });
+    }
+
+    /**
+     * Determine if the migration repository exists.
+     *
+     * @return bool
+     */
+    public function repositoryExists()
+    {
+        $schema = $this->getConnection()->getSchemaBuilder();
+
+        return $schema->hasTable($this->table);
+    }
+
+    /**
+     * Delete the migration repository data store.
+     *
+     * @return void
+     */
+    public function deleteRepository()
+    {
+        $schema = $this->getConnection()->getSchemaBuilder();
+
+        $schema->drop($this->table);
+    }
+
+    /**
+     * Get a query builder for the migration table.
+     *
+     * @return \Illuminate\Database\Query\Builder
+     */
+    protected function table()
+    {
+        return $this->getConnection()->table($this->table)->useWritePdo();
+    }
+
+    /**
+     * Get the connection resolver instance.
+     *
+     * @return \Illuminate\Database\ConnectionResolverInterface
+     */
+    public function getConnectionResolver()
+    {
+        return $this->resolver;
+    }
+
+    /**
+     * Resolve the database connection instance.
+     *
+     * @return \Illuminate\Database\Connection
+     */
+    public function getConnection()
+    {
+        return $this->resolver->connection($this->connection);
+    }
+
+    /**
+     * Set the information source to gather data.
+     *
+     * @param  string  $name
+     * @return void
+     */
+    public function setSource($name)
+    {
+        $this->connection = $name;
+    }
+}
diff --git a/vendor/illuminate/database/Migrations/Migration.php b/vendor/illuminate/database/Migrations/Migration.php
new file mode 100755
index 0000000..a58f784
--- /dev/null
+++ b/vendor/illuminate/database/Migrations/Migration.php
@@ -0,0 +1,30 @@
+connection;
+    }
+}
diff --git a/vendor/illuminate/database/Migrations/MigrationCreator.php b/vendor/illuminate/database/Migrations/MigrationCreator.php
new file mode 100755
index 0000000..d8f1ce9
--- /dev/null
+++ b/vendor/illuminate/database/Migrations/MigrationCreator.php
@@ -0,0 +1,231 @@
+files = $files;
+        $this->customStubPath = $customStubPath;
+    }
+
+    /**
+     * Create a new migration at the given path.
+     *
+     * @param  string  $name
+     * @param  string  $path
+     * @param  string|null  $table
+     * @param  bool  $create
+     * @return string
+     *
+     * @throws \Exception
+     */
+    public function create($name, $path, $table = null, $create = false)
+    {
+        $this->ensureMigrationDoesntAlreadyExist($name, $path);
+
+        // First we will get the stub file for the migration, which serves as a type
+        // of template for the migration. Once we have those we will populate the
+        // various place-holders, save the file, and run the post create event.
+        $stub = $this->getStub($table, $create);
+
+        $path = $this->getPath($name, $path);
+
+        $this->files->ensureDirectoryExists(dirname($path));
+
+        $this->files->put(
+            $path, $this->populateStub($stub, $table)
+        );
+
+        // Next, we will fire any hooks that are supposed to fire after a migration is
+        // created. Once that is done we'll be ready to return the full path to the
+        // migration file so it can be used however it's needed by the developer.
+        $this->firePostCreateHooks($table, $path);
+
+        return $path;
+    }
+
+    /**
+     * Ensure that a migration with the given name doesn't already exist.
+     *
+     * @param  string  $name
+     * @param  string  $migrationPath
+     * @return void
+     *
+     * @throws \InvalidArgumentException
+     */
+    protected function ensureMigrationDoesntAlreadyExist($name, $migrationPath = null)
+    {
+        if (! empty($migrationPath)) {
+            $migrationFiles = $this->files->glob($migrationPath.'/*.php');
+
+            foreach ($migrationFiles as $migrationFile) {
+                $this->files->requireOnce($migrationFile);
+            }
+        }
+
+        if (class_exists($className = $this->getClassName($name))) {
+            throw new InvalidArgumentException("A {$className} class already exists.");
+        }
+    }
+
+    /**
+     * Get the migration stub file.
+     *
+     * @param  string|null  $table
+     * @param  bool  $create
+     * @return string
+     */
+    protected function getStub($table, $create)
+    {
+        if (is_null($table)) {
+            $stub = $this->files->exists($customPath = $this->customStubPath.'/migration.stub')
+                            ? $customPath
+                            : $this->stubPath().'/migration.stub';
+        } elseif ($create) {
+            $stub = $this->files->exists($customPath = $this->customStubPath.'/migration.create.stub')
+                            ? $customPath
+                            : $this->stubPath().'/migration.create.stub';
+        } else {
+            $stub = $this->files->exists($customPath = $this->customStubPath.'/migration.update.stub')
+                            ? $customPath
+                            : $this->stubPath().'/migration.update.stub';
+        }
+
+        return $this->files->get($stub);
+    }
+
+    /**
+     * Populate the place-holders in the migration stub.
+     *
+     * @param  string  $stub
+     * @param  string|null  $table
+     * @return string
+     */
+    protected function populateStub($stub, $table)
+    {
+        // Here we will replace the table place-holders with the table specified by
+        // the developer, which is useful for quickly creating a tables creation
+        // or update migration from the console instead of typing it manually.
+        if (! is_null($table)) {
+            $stub = str_replace(
+                ['DummyTable', '{{ table }}', '{{table}}'],
+                $table, $stub
+            );
+        }
+
+        return $stub;
+    }
+
+    /**
+     * Get the class name of a migration name.
+     *
+     * @param  string  $name
+     * @return string
+     */
+    protected function getClassName($name)
+    {
+        return Str::studly($name);
+    }
+
+    /**
+     * Get the full path to the migration.
+     *
+     * @param  string  $name
+     * @param  string  $path
+     * @return string
+     */
+    protected function getPath($name, $path)
+    {
+        return $path.'/'.$this->getDatePrefix().'_'.$name.'.php';
+    }
+
+    /**
+     * Fire the registered post create hooks.
+     *
+     * @param  string|null  $table
+     * @param  string  $path
+     * @return void
+     */
+    protected function firePostCreateHooks($table, $path)
+    {
+        foreach ($this->postCreate as $callback) {
+            $callback($table, $path);
+        }
+    }
+
+    /**
+     * Register a post migration create hook.
+     *
+     * @param  \Closure  $callback
+     * @return void
+     */
+    public function afterCreate(Closure $callback)
+    {
+        $this->postCreate[] = $callback;
+    }
+
+    /**
+     * Get the date prefix for the migration.
+     *
+     * @return string
+     */
+    protected function getDatePrefix()
+    {
+        return date('Y_m_d_His');
+    }
+
+    /**
+     * Get the path to the stubs.
+     *
+     * @return string
+     */
+    public function stubPath()
+    {
+        return __DIR__.'/stubs';
+    }
+
+    /**
+     * Get the filesystem instance.
+     *
+     * @return \Illuminate\Filesystem\Filesystem
+     */
+    public function getFilesystem()
+    {
+        return $this->files;
+    }
+}
diff --git a/vendor/illuminate/database/Migrations/MigrationRepositoryInterface.php b/vendor/illuminate/database/Migrations/MigrationRepositoryInterface.php
new file mode 100755
index 0000000..840a5e1
--- /dev/null
+++ b/vendor/illuminate/database/Migrations/MigrationRepositoryInterface.php
@@ -0,0 +1,88 @@
+
+     */
+    protected static $requiredPathCache = [];
+
+    /**
+     * The output interface implementation.
+     *
+     * @var \Symfony\Component\Console\Output\OutputInterface
+     */
+    protected $output;
+
+    /**
+     * Create a new migrator instance.
+     *
+     * @param  \Illuminate\Database\Migrations\MigrationRepositoryInterface  $repository
+     * @param  \Illuminate\Database\ConnectionResolverInterface  $resolver
+     * @param  \Illuminate\Filesystem\Filesystem  $files
+     * @param  \Illuminate\Contracts\Events\Dispatcher|null  $dispatcher
+     * @return void
+     */
+    public function __construct(MigrationRepositoryInterface $repository,
+                                Resolver $resolver,
+                                Filesystem $files,
+                                Dispatcher $dispatcher = null)
+    {
+        $this->files = $files;
+        $this->events = $dispatcher;
+        $this->resolver = $resolver;
+        $this->repository = $repository;
+    }
+
+    /**
+     * Run the pending migrations at a given path.
+     *
+     * @param  array|string  $paths
+     * @param  array  $options
+     * @return array
+     */
+    public function run($paths = [], array $options = [])
+    {
+        // Once we grab all of the migration files for the path, we will compare them
+        // against the migrations that have already been run for this package then
+        // run each of the outstanding migrations against a database connection.
+        $files = $this->getMigrationFiles($paths);
+
+        $this->requireFiles($migrations = $this->pendingMigrations(
+            $files, $this->repository->getRan()
+        ));
+
+        // Once we have all these migrations that are outstanding we are ready to run
+        // we will go ahead and run them "up". This will execute each migration as
+        // an operation against a database. Then we'll return this list of them.
+        $this->runPending($migrations, $options);
+
+        return $migrations;
+    }
+
+    /**
+     * Get the migration files that have not yet run.
+     *
+     * @param  array  $files
+     * @param  array  $ran
+     * @return array
+     */
+    protected function pendingMigrations($files, $ran)
+    {
+        return Collection::make($files)
+                ->reject(function ($file) use ($ran) {
+                    return in_array($this->getMigrationName($file), $ran);
+                })->values()->all();
+    }
+
+    /**
+     * Run an array of migrations.
+     *
+     * @param  array  $migrations
+     * @param  array  $options
+     * @return void
+     */
+    public function runPending(array $migrations, array $options = [])
+    {
+        // First we will just make sure that there are any migrations to run. If there
+        // aren't, we will just make a note of it to the developer so they're aware
+        // that all of the migrations have been run against this database system.
+        if (count($migrations) === 0) {
+            $this->fireMigrationEvent(new NoPendingMigrations('up'));
+
+            $this->write(Info::class, 'Nothing to migrate');
+
+            return;
+        }
+
+        // Next, we will get the next batch number for the migrations so we can insert
+        // correct batch number in the database migrations repository when we store
+        // each migration's execution. We will also extract a few of the options.
+        $batch = $this->repository->getNextBatchNumber();
+
+        $pretend = $options['pretend'] ?? false;
+
+        $step = $options['step'] ?? false;
+
+        $this->fireMigrationEvent(new MigrationsStarted('up'));
+
+        $this->write(Info::class, 'Running migrations.');
+
+        // Once we have the array of migrations, we will spin through them and run the
+        // migrations "up" so the changes are made to the databases. We'll then log
+        // that the migration was run so we don't repeat it next time we execute.
+        foreach ($migrations as $file) {
+            $this->runUp($file, $batch, $pretend);
+
+            if ($step) {
+                $batch++;
+            }
+        }
+
+        $this->fireMigrationEvent(new MigrationsEnded('up'));
+
+        if ($this->output) {
+            $this->output->writeln('');
+        }
+    }
+
+    /**
+     * Run "up" a migration instance.
+     *
+     * @param  string  $file
+     * @param  int  $batch
+     * @param  bool  $pretend
+     * @return void
+     */
+    protected function runUp($file, $batch, $pretend)
+    {
+        // First we will resolve a "real" instance of the migration class from this
+        // migration file name. Once we have the instances we can run the actual
+        // command such as "up" or "down", or we can just simulate the action.
+        $migration = $this->resolvePath($file);
+
+        $name = $this->getMigrationName($file);
+
+        if ($pretend) {
+            return $this->pretendToRun($migration, 'up');
+        }
+
+        $this->write(Task::class, $name, fn () => $this->runMigration($migration, 'up'));
+
+        // Once we have run a migrations class, we will log that it was run in this
+        // repository so that we don't try to run it next time we do a migration
+        // in the application. A migration repository keeps the migrate order.
+        $this->repository->log($name, $batch);
+    }
+
+    /**
+     * Rollback the last migration operation.
+     *
+     * @param  array|string  $paths
+     * @param  array  $options
+     * @return array
+     */
+    public function rollback($paths = [], array $options = [])
+    {
+        // We want to pull in the last batch of migrations that ran on the previous
+        // migration operation. We'll then reverse those migrations and run each
+        // of them "down" to reverse the last migration "operation" which ran.
+        $migrations = $this->getMigrationsForRollback($options);
+
+        if (count($migrations) === 0) {
+            $this->fireMigrationEvent(new NoPendingMigrations('down'));
+
+            $this->write(Info::class, 'Nothing to rollback.');
+
+            return [];
+        }
+
+        return tap($this->rollbackMigrations($migrations, $paths, $options), function () {
+            if ($this->output) {
+                $this->output->writeln('');
+            }
+        });
+    }
+
+    /**
+     * Get the migrations for a rollback operation.
+     *
+     * @param  array  $options
+     * @return array
+     */
+    protected function getMigrationsForRollback(array $options)
+    {
+        if (($steps = $options['step'] ?? 0) > 0) {
+            return $this->repository->getMigrations($steps);
+        }
+
+        return $this->repository->getLast();
+    }
+
+    /**
+     * Rollback the given migrations.
+     *
+     * @param  array  $migrations
+     * @param  array|string  $paths
+     * @param  array  $options
+     * @return array
+     */
+    protected function rollbackMigrations(array $migrations, $paths, array $options)
+    {
+        $rolledBack = [];
+
+        $this->requireFiles($files = $this->getMigrationFiles($paths));
+
+        $this->fireMigrationEvent(new MigrationsStarted('down'));
+
+        $this->write(Info::class, 'Rolling back migrations.');
+
+        // Next we will run through all of the migrations and call the "down" method
+        // which will reverse each migration in order. This getLast method on the
+        // repository already returns these migration's names in reverse order.
+        foreach ($migrations as $migration) {
+            $migration = (object) $migration;
+
+            if (! $file = Arr::get($files, $migration->migration)) {
+                $this->write(TwoColumnDetail::class, $migration->migration, 'Migration not found');
+
+                continue;
+            }
+
+            $rolledBack[] = $file;
+
+            $this->runDown(
+                $file, $migration,
+                $options['pretend'] ?? false
+            );
+        }
+
+        $this->fireMigrationEvent(new MigrationsEnded('down'));
+
+        return $rolledBack;
+    }
+
+    /**
+     * Rolls all of the currently applied migrations back.
+     *
+     * @param  array|string  $paths
+     * @param  bool  $pretend
+     * @return array
+     */
+    public function reset($paths = [], $pretend = false)
+    {
+        // Next, we will reverse the migration list so we can run them back in the
+        // correct order for resetting this database. This will allow us to get
+        // the database back into its "empty" state ready for the migrations.
+        $migrations = array_reverse($this->repository->getRan());
+
+        if (count($migrations) === 0) {
+            $this->write(Info::class, 'Nothing to rollback.');
+
+            return [];
+        }
+
+        return tap($this->resetMigrations($migrations, $paths, $pretend), function () {
+            if ($this->output) {
+                $this->output->writeln('');
+            }
+        });
+    }
+
+    /**
+     * Reset the given migrations.
+     *
+     * @param  array  $migrations
+     * @param  array  $paths
+     * @param  bool  $pretend
+     * @return array
+     */
+    protected function resetMigrations(array $migrations, array $paths, $pretend = false)
+    {
+        // Since the getRan method that retrieves the migration name just gives us the
+        // migration name, we will format the names into objects with the name as a
+        // property on the objects so that we can pass it to the rollback method.
+        $migrations = collect($migrations)->map(function ($m) {
+            return (object) ['migration' => $m];
+        })->all();
+
+        return $this->rollbackMigrations(
+            $migrations, $paths, compact('pretend')
+        );
+    }
+
+    /**
+     * Run "down" a migration instance.
+     *
+     * @param  string  $file
+     * @param  object  $migration
+     * @param  bool  $pretend
+     * @return void
+     */
+    protected function runDown($file, $migration, $pretend)
+    {
+        // First we will get the file name of the migration so we can resolve out an
+        // instance of the migration. Once we get an instance we can either run a
+        // pretend execution of the migration or we can run the real migration.
+        $instance = $this->resolvePath($file);
+
+        $name = $this->getMigrationName($file);
+
+        if ($pretend) {
+            return $this->pretendToRun($instance, 'down');
+        }
+
+        $this->write(Task::class, $name, fn () => $this->runMigration($instance, 'down'));
+
+        // Once we have successfully run the migration "down" we will remove it from
+        // the migration repository so it will be considered to have not been run
+        // by the application then will be able to fire by any later operation.
+        $this->repository->delete($migration);
+    }
+
+    /**
+     * Run a migration inside a transaction if the database supports it.
+     *
+     * @param  object  $migration
+     * @param  string  $method
+     * @return void
+     */
+    protected function runMigration($migration, $method)
+    {
+        $connection = $this->resolveConnection(
+            $migration->getConnection()
+        );
+
+        $callback = function () use ($connection, $migration, $method) {
+            if (method_exists($migration, $method)) {
+                $this->fireMigrationEvent(new MigrationStarted($migration, $method));
+
+                $this->runMethod($connection, $migration, $method);
+
+                $this->fireMigrationEvent(new MigrationEnded($migration, $method));
+            }
+        };
+
+        $this->getSchemaGrammar($connection)->supportsSchemaTransactions()
+            && $migration->withinTransaction
+                    ? $connection->transaction($callback)
+                    : $callback();
+    }
+
+    /**
+     * Pretend to run the migrations.
+     *
+     * @param  object  $migration
+     * @param  string  $method
+     * @return void
+     */
+    protected function pretendToRun($migration, $method)
+    {
+        try {
+            $name = get_class($migration);
+
+            $reflectionClass = new ReflectionClass($migration);
+
+            if ($reflectionClass->isAnonymous()) {
+                $name = $this->getMigrationName($reflectionClass->getFileName());
+            }
+
+            $this->write(TwoColumnDetail::class, $name);
+            $this->write(BulletList::class, collect($this->getQueries($migration, $method))->map(function ($query) {
+                return $query['query'];
+            }));
+        } catch (SchemaException $e) {
+            $name = get_class($migration);
+
+            $this->write(Error::class, sprintf(
+                '[%s] failed to dump queries. This may be due to changing database columns using Doctrine, which is not supported while pretending to run migrations.',
+                $name,
+            ));
+        }
+    }
+
+    /**
+     * Get all of the queries that would be run for a migration.
+     *
+     * @param  object  $migration
+     * @param  string  $method
+     * @return array
+     */
+    protected function getQueries($migration, $method)
+    {
+        // Now that we have the connections we can resolve it and pretend to run the
+        // queries against the database returning the array of raw SQL statements
+        // that would get fired against the database system for this migration.
+        $db = $this->resolveConnection(
+            $migration->getConnection()
+        );
+
+        return $db->pretend(function () use ($db, $migration, $method) {
+            if (method_exists($migration, $method)) {
+                $this->runMethod($db, $migration, $method);
+            }
+        });
+    }
+
+    /**
+     * Run a migration method on the given connection.
+     *
+     * @param  \Illuminate\Database\Connection  $connection
+     * @param  object  $migration
+     * @param  string  $method
+     * @return void
+     */
+    protected function runMethod($connection, $migration, $method)
+    {
+        $previousConnection = $this->resolver->getDefaultConnection();
+
+        try {
+            $this->resolver->setDefaultConnection($connection->getName());
+
+            $migration->{$method}();
+        } finally {
+            $this->resolver->setDefaultConnection($previousConnection);
+        }
+    }
+
+    /**
+     * Resolve a migration instance from a file.
+     *
+     * @param  string  $file
+     * @return object
+     */
+    public function resolve($file)
+    {
+        $class = $this->getMigrationClass($file);
+
+        return new $class;
+    }
+
+    /**
+     * Resolve a migration instance from a migration path.
+     *
+     * @param  string  $path
+     * @return object
+     */
+    protected function resolvePath(string $path)
+    {
+        $class = $this->getMigrationClass($this->getMigrationName($path));
+
+        if (class_exists($class) && realpath($path) == (new ReflectionClass($class))->getFileName()) {
+            return new $class;
+        }
+
+        $migration = static::$requiredPathCache[$path] ??= $this->files->getRequire($path);
+
+        if (is_object($migration)) {
+            return method_exists($migration, '__construct')
+                    ? $this->files->getRequire($path)
+                    : clone $migration;
+        }
+
+        return new $class;
+    }
+
+    /**
+     * Generate a migration class name based on the migration file name.
+     *
+     * @param  string  $migrationName
+     * @return string
+     */
+    protected function getMigrationClass(string $migrationName): string
+    {
+        return Str::studly(implode('_', array_slice(explode('_', $migrationName), 4)));
+    }
+
+    /**
+     * Get all of the migration files in a given path.
+     *
+     * @param  string|array  $paths
+     * @return array
+     */
+    public function getMigrationFiles($paths)
+    {
+        return Collection::make($paths)->flatMap(function ($path) {
+            return str_ends_with($path, '.php') ? [$path] : $this->files->glob($path.'/*_*.php');
+        })->filter()->values()->keyBy(function ($file) {
+            return $this->getMigrationName($file);
+        })->sortBy(function ($file, $key) {
+            return $key;
+        })->all();
+    }
+
+    /**
+     * Require in all the migration files in a given path.
+     *
+     * @param  array  $files
+     * @return void
+     */
+    public function requireFiles(array $files)
+    {
+        foreach ($files as $file) {
+            $this->files->requireOnce($file);
+        }
+    }
+
+    /**
+     * Get the name of the migration.
+     *
+     * @param  string  $path
+     * @return string
+     */
+    public function getMigrationName($path)
+    {
+        return str_replace('.php', '', basename($path));
+    }
+
+    /**
+     * Register a custom migration path.
+     *
+     * @param  string  $path
+     * @return void
+     */
+    public function path($path)
+    {
+        $this->paths = array_unique(array_merge($this->paths, [$path]));
+    }
+
+    /**
+     * Get all of the custom migration paths.
+     *
+     * @return array
+     */
+    public function paths()
+    {
+        return $this->paths;
+    }
+
+    /**
+     * Get the default connection name.
+     *
+     * @return string
+     */
+    public function getConnection()
+    {
+        return $this->connection;
+    }
+
+    /**
+     * Execute the given callback using the given connection as the default connection.
+     *
+     * @param  string  $name
+     * @param  callable  $callback
+     * @return mixed
+     */
+    public function usingConnection($name, callable $callback)
+    {
+        $previousConnection = $this->resolver->getDefaultConnection();
+
+        $this->setConnection($name);
+
+        return tap($callback(), function () use ($previousConnection) {
+            $this->setConnection($previousConnection);
+        });
+    }
+
+    /**
+     * Set the default connection name.
+     *
+     * @param  string  $name
+     * @return void
+     */
+    public function setConnection($name)
+    {
+        if (! is_null($name)) {
+            $this->resolver->setDefaultConnection($name);
+        }
+
+        $this->repository->setSource($name);
+
+        $this->connection = $name;
+    }
+
+    /**
+     * Resolve the database connection instance.
+     *
+     * @param  string  $connection
+     * @return \Illuminate\Database\Connection
+     */
+    public function resolveConnection($connection)
+    {
+        return $this->resolver->connection($connection ?: $this->connection);
+    }
+
+    /**
+     * Get the schema grammar out of a migration connection.
+     *
+     * @param  \Illuminate\Database\Connection  $connection
+     * @return \Illuminate\Database\Schema\Grammars\Grammar
+     */
+    protected function getSchemaGrammar($connection)
+    {
+        if (is_null($grammar = $connection->getSchemaGrammar())) {
+            $connection->useDefaultSchemaGrammar();
+
+            $grammar = $connection->getSchemaGrammar();
+        }
+
+        return $grammar;
+    }
+
+    /**
+     * Get the migration repository instance.
+     *
+     * @return \Illuminate\Database\Migrations\MigrationRepositoryInterface
+     */
+    public function getRepository()
+    {
+        return $this->repository;
+    }
+
+    /**
+     * Determine if the migration repository exists.
+     *
+     * @return bool
+     */
+    public function repositoryExists()
+    {
+        return $this->repository->repositoryExists();
+    }
+
+    /**
+     * Determine if any migrations have been run.
+     *
+     * @return bool
+     */
+    public function hasRunAnyMigrations()
+    {
+        return $this->repositoryExists() && count($this->repository->getRan()) > 0;
+    }
+
+    /**
+     * Delete the migration repository data store.
+     *
+     * @return void
+     */
+    public function deleteRepository()
+    {
+        return $this->repository->deleteRepository();
+    }
+
+    /**
+     * Get the file system instance.
+     *
+     * @return \Illuminate\Filesystem\Filesystem
+     */
+    public function getFilesystem()
+    {
+        return $this->files;
+    }
+
+    /**
+     * Set the output implementation that should be used by the console.
+     *
+     * @param  \Symfony\Component\Console\Output\OutputInterface  $output
+     * @return $this
+     */
+    public function setOutput(OutputInterface $output)
+    {
+        $this->output = $output;
+
+        return $this;
+    }
+
+    /**
+     * Write to the console's output.
+     *
+     * @param  string  $component
+     * @param  array|string  ...$arguments
+     * @return void
+     */
+    protected function write($component, ...$arguments)
+    {
+        if ($this->output && class_exists($component)) {
+            (new $component($this->output))->render(...$arguments);
+        } else {
+            foreach ($arguments as $argument) {
+                if (is_callable($argument)) {
+                    $argument();
+                }
+            }
+        }
+    }
+
+    /**
+     * Fire the given event for the migration.
+     *
+     * @param  \Illuminate\Contracts\Database\Events\MigrationEvent  $event
+     * @return void
+     */
+    public function fireMigrationEvent($event)
+    {
+        if ($this->events) {
+            $this->events->dispatch($event);
+        }
+    }
+}
diff --git a/vendor/illuminate/database/Migrations/stubs/migration.create.stub b/vendor/illuminate/database/Migrations/stubs/migration.create.stub
new file mode 100755
index 0000000..0e0ec22
--- /dev/null
+++ b/vendor/illuminate/database/Migrations/stubs/migration.create.stub
@@ -0,0 +1,31 @@
+id();
+            $table->timestamps();
+        });
+    }
+
+    /**
+     * Reverse the migrations.
+     *
+     * @return void
+     */
+    public function down()
+    {
+        Schema::dropIfExists('{{ table }}');
+    }
+};
diff --git a/vendor/illuminate/database/Migrations/stubs/migration.stub b/vendor/illuminate/database/Migrations/stubs/migration.stub
new file mode 100755
index 0000000..41dd1c8
--- /dev/null
+++ b/vendor/illuminate/database/Migrations/stubs/migration.stub
@@ -0,0 +1,28 @@
+count = $count;
+
+        parent::__construct("$count records were found.", $code, $previous);
+    }
+
+    /**
+     * Get the number of records found.
+     *
+     * @return int
+     */
+    public function getCount()
+    {
+        return $this->count;
+    }
+}
diff --git a/vendor/illuminate/database/MySqlConnection.php b/vendor/illuminate/database/MySqlConnection.php
new file mode 100755
index 0000000..54e3d47
--- /dev/null
+++ b/vendor/illuminate/database/MySqlConnection.php
@@ -0,0 +1,91 @@
+getPdo()->getAttribute(PDO::ATTR_SERVER_VERSION), 'MariaDB');
+    }
+
+    /**
+     * Get the default query grammar instance.
+     *
+     * @return \Illuminate\Database\Query\Grammars\MySqlGrammar
+     */
+    protected function getDefaultQueryGrammar()
+    {
+        return $this->withTablePrefix(new QueryGrammar);
+    }
+
+    /**
+     * Get a schema builder instance for the connection.
+     *
+     * @return \Illuminate\Database\Schema\MySqlBuilder
+     */
+    public function getSchemaBuilder()
+    {
+        if (is_null($this->schemaGrammar)) {
+            $this->useDefaultSchemaGrammar();
+        }
+
+        return new MySqlBuilder($this);
+    }
+
+    /**
+     * Get the default schema grammar instance.
+     *
+     * @return \Illuminate\Database\Schema\Grammars\MySqlGrammar
+     */
+    protected function getDefaultSchemaGrammar()
+    {
+        return $this->withTablePrefix(new SchemaGrammar);
+    }
+
+    /**
+     * Get the schema state for the connection.
+     *
+     * @param  \Illuminate\Filesystem\Filesystem|null  $files
+     * @param  callable|null  $processFactory
+     * @return \Illuminate\Database\Schema\MySqlSchemaState
+     */
+    public function getSchemaState(Filesystem $files = null, callable $processFactory = null)
+    {
+        return new MySqlSchemaState($this, $files, $processFactory);
+    }
+
+    /**
+     * Get the default post processor instance.
+     *
+     * @return \Illuminate\Database\Query\Processors\MySqlProcessor
+     */
+    protected function getDefaultPostProcessor()
+    {
+        return new MySqlProcessor;
+    }
+
+    /**
+     * Get the Doctrine DBAL driver.
+     *
+     * @return \Illuminate\Database\PDO\MySqlDriver
+     */
+    protected function getDoctrineDriver()
+    {
+        return new MySqlDriver;
+    }
+}
diff --git a/vendor/illuminate/database/PDO/Concerns/ConnectsToDatabase.php b/vendor/illuminate/database/PDO/Concerns/ConnectsToDatabase.php
new file mode 100644
index 0000000..d2a8d60
--- /dev/null
+++ b/vendor/illuminate/database/PDO/Concerns/ConnectsToDatabase.php
@@ -0,0 +1,30 @@
+connection = $connection;
+    }
+
+    /**
+     * Execute an SQL statement.
+     *
+     * @param  string  $statement
+     * @return int
+     */
+    public function exec(string $statement): int
+    {
+        try {
+            $result = $this->connection->exec($statement);
+
+            \assert($result !== false);
+
+            return $result;
+        } catch (PDOException $exception) {
+            throw Exception::new($exception);
+        }
+    }
+
+    /**
+     * Prepare a new SQL statement.
+     *
+     * @param  string  $sql
+     * @return \Doctrine\DBAL\Driver\Statement
+     */
+    public function prepare(string $sql): StatementInterface
+    {
+        try {
+            return $this->createStatement(
+                $this->connection->prepare($sql)
+            );
+        } catch (PDOException $exception) {
+            throw Exception::new($exception);
+        }
+    }
+
+    /**
+     * Execute a new query against the connection.
+     *
+     * @param  string  $sql
+     * @return \Doctrine\DBAL\Driver\Result
+     */
+    public function query(string $sql): ResultInterface
+    {
+        try {
+            $stmt = $this->connection->query($sql);
+
+            \assert($stmt instanceof PDOStatement);
+
+            return new Result($stmt);
+        } catch (PDOException $exception) {
+            throw Exception::new($exception);
+        }
+    }
+
+    /**
+     * Get the last insert ID.
+     *
+     * @param  string|null  $name
+     * @return mixed
+     */
+    public function lastInsertId($name = null)
+    {
+        try {
+            if ($name === null) {
+                return $this->connection->lastInsertId();
+            }
+
+            return $this->connection->lastInsertId($name);
+        } catch (PDOException $exception) {
+            throw Exception::new($exception);
+        }
+    }
+
+    /**
+     * Create a new statement instance.
+     *
+     * @param  \PDOStatement  $stmt
+     * @return \Doctrine\DBAL\Driver\PDO\Statement
+     */
+    protected function createStatement(PDOStatement $stmt): Statement
+    {
+        return new Statement($stmt);
+    }
+
+    /**
+     * Begin a new database transaction.
+     *
+     * @return void
+     */
+    public function beginTransaction()
+    {
+        return $this->connection->beginTransaction();
+    }
+
+    /**
+     * Commit a database transaction.
+     *
+     * @return void
+     */
+    public function commit()
+    {
+        return $this->connection->commit();
+    }
+
+    /**
+     * Rollback a database transaction.
+     *
+     * @return void
+     */
+    public function rollBack()
+    {
+        return $this->connection->rollBack();
+    }
+
+    /**
+     * Wrap quotes around the given input.
+     *
+     * @param  string  $input
+     * @param  string  $type
+     * @return string
+     */
+    public function quote($input, $type = ParameterType::STRING)
+    {
+        return $this->connection->quote($input, $type);
+    }
+
+    /**
+     * Get the server version for the connection.
+     *
+     * @return string
+     */
+    public function getServerVersion()
+    {
+        return $this->connection->getAttribute(PDO::ATTR_SERVER_VERSION);
+    }
+
+    /**
+     * Get the wrapped PDO connection.
+     *
+     * @return \PDO
+     */
+    public function getWrappedConnection(): PDO
+    {
+        return $this->connection;
+    }
+}
diff --git a/vendor/illuminate/database/PDO/MySqlDriver.php b/vendor/illuminate/database/PDO/MySqlDriver.php
new file mode 100644
index 0000000..54ac375
--- /dev/null
+++ b/vendor/illuminate/database/PDO/MySqlDriver.php
@@ -0,0 +1,19 @@
+connection = $connection;
+    }
+
+    /**
+     * Prepare a new SQL statement.
+     *
+     * @param  string  $sql
+     * @return \Doctrine\DBAL\Driver\Statement
+     */
+    public function prepare(string $sql): StatementInterface
+    {
+        return new Statement(
+            $this->connection->prepare($sql)
+        );
+    }
+
+    /**
+     * Execute a new query against the connection.
+     *
+     * @param  string  $sql
+     * @return \Doctrine\DBAL\Driver\Result
+     */
+    public function query(string $sql): Result
+    {
+        return $this->connection->query($sql);
+    }
+
+    /**
+     * Execute an SQL statement.
+     *
+     * @param  string  $statement
+     * @return int
+     */
+    public function exec(string $statement): int
+    {
+        return $this->connection->exec($statement);
+    }
+
+    /**
+     * Get the last insert ID.
+     *
+     * @param  string|null  $name
+     * @return mixed
+     */
+    public function lastInsertId($name = null)
+    {
+        if ($name === null) {
+            return $this->connection->lastInsertId($name);
+        }
+
+        return $this->prepare('SELECT CONVERT(VARCHAR(MAX), current_value) FROM sys.sequences WHERE name = ?')
+            ->execute([$name])
+            ->fetchOne();
+    }
+
+    /**
+     * Begin a new database transaction.
+     *
+     * @return void
+     */
+    public function beginTransaction()
+    {
+        return $this->connection->beginTransaction();
+    }
+
+    /**
+     * Commit a database transaction.
+     *
+     * @return void
+     */
+    public function commit()
+    {
+        return $this->connection->commit();
+    }
+
+    /**
+     * Rollback a database transaction.
+     *
+     * @return void
+     */
+    public function rollBack()
+    {
+        return $this->connection->rollBack();
+    }
+
+    /**
+     * Wrap quotes around the given input.
+     *
+     * @param  string  $value
+     * @param  int  $type
+     * @return string
+     */
+    public function quote($value, $type = ParameterType::STRING)
+    {
+        $val = $this->connection->quote($value, $type);
+
+        // Fix for a driver version terminating all values with null byte...
+        if (\is_string($val) && str_contains($val, "\0")) {
+            $val = \substr($val, 0, -1);
+        }
+
+        return $val;
+    }
+
+    /**
+     * Get the server version for the connection.
+     *
+     * @return string
+     */
+    public function getServerVersion()
+    {
+        return $this->connection->getServerVersion();
+    }
+
+    /**
+     * Get the wrapped PDO connection.
+     *
+     * @return \PDO
+     */
+    public function getWrappedConnection(): PDO
+    {
+        return $this->connection->getWrappedConnection();
+    }
+}
diff --git a/vendor/illuminate/database/PDO/SqlServerDriver.php b/vendor/illuminate/database/PDO/SqlServerDriver.php
new file mode 100644
index 0000000..1b0d957
--- /dev/null
+++ b/vendor/illuminate/database/PDO/SqlServerDriver.php
@@ -0,0 +1,32 @@
+withTablePrefix(new QueryGrammar);
+    }
+
+    /**
+     * Get a schema builder instance for the connection.
+     *
+     * @return \Illuminate\Database\Schema\PostgresBuilder
+     */
+    public function getSchemaBuilder()
+    {
+        if (is_null($this->schemaGrammar)) {
+            $this->useDefaultSchemaGrammar();
+        }
+
+        return new PostgresBuilder($this);
+    }
+
+    /**
+     * Get the default schema grammar instance.
+     *
+     * @return \Illuminate\Database\Schema\Grammars\PostgresGrammar
+     */
+    protected function getDefaultSchemaGrammar()
+    {
+        return $this->withTablePrefix(new SchemaGrammar);
+    }
+
+    /**
+     * Get the schema state for the connection.
+     *
+     * @param  \Illuminate\Filesystem\Filesystem|null  $files
+     * @param  callable|null  $processFactory
+     * @return \Illuminate\Database\Schema\PostgresSchemaState
+     */
+    public function getSchemaState(Filesystem $files = null, callable $processFactory = null)
+    {
+        return new PostgresSchemaState($this, $files, $processFactory);
+    }
+
+    /**
+     * Get the default post processor instance.
+     *
+     * @return \Illuminate\Database\Query\Processors\PostgresProcessor
+     */
+    protected function getDefaultPostProcessor()
+    {
+        return new PostgresProcessor;
+    }
+
+    /**
+     * Get the Doctrine DBAL driver.
+     *
+     * @return \Illuminate\Database\PDO\PostgresDriver
+     */
+    protected function getDoctrineDriver()
+    {
+        return new PostgresDriver;
+    }
+}
diff --git a/vendor/illuminate/database/Query/Builder.php b/vendor/illuminate/database/Query/Builder.php
new file mode 100755
index 0000000..6f98a8c
--- /dev/null
+++ b/vendor/illuminate/database/Query/Builder.php
@@ -0,0 +1,3874 @@
+ [],
+        'from' => [],
+        'join' => [],
+        'where' => [],
+        'groupBy' => [],
+        'having' => [],
+        'order' => [],
+        'union' => [],
+        'unionOrder' => [],
+    ];
+
+    /**
+     * An aggregate function and column to be run.
+     *
+     * @var array
+     */
+    public $aggregate;
+
+    /**
+     * The columns that should be returned.
+     *
+     * @var array
+     */
+    public $columns;
+
+    /**
+     * Indicates if the query returns distinct results.
+     *
+     * Occasionally contains the columns that should be distinct.
+     *
+     * @var bool|array
+     */
+    public $distinct = false;
+
+    /**
+     * The table which the query is targeting.
+     *
+     * @var string
+     */
+    public $from;
+
+    /**
+     * The index hint for the query.
+     *
+     * @var \Illuminate\Database\Query\IndexHint
+     */
+    public $indexHint;
+
+    /**
+     * The table joins for the query.
+     *
+     * @var array
+     */
+    public $joins;
+
+    /**
+     * The where constraints for the query.
+     *
+     * @var array
+     */
+    public $wheres = [];
+
+    /**
+     * The groupings for the query.
+     *
+     * @var array
+     */
+    public $groups;
+
+    /**
+     * The having constraints for the query.
+     *
+     * @var array
+     */
+    public $havings;
+
+    /**
+     * The orderings for the query.
+     *
+     * @var array
+     */
+    public $orders;
+
+    /**
+     * The maximum number of records to return.
+     *
+     * @var int
+     */
+    public $limit;
+
+    /**
+     * The number of records to skip.
+     *
+     * @var int
+     */
+    public $offset;
+
+    /**
+     * The query union statements.
+     *
+     * @var array
+     */
+    public $unions;
+
+    /**
+     * The maximum number of union records to return.
+     *
+     * @var int
+     */
+    public $unionLimit;
+
+    /**
+     * The number of union records to skip.
+     *
+     * @var int
+     */
+    public $unionOffset;
+
+    /**
+     * The orderings for the union query.
+     *
+     * @var array
+     */
+    public $unionOrders;
+
+    /**
+     * Indicates whether row locking is being used.
+     *
+     * @var string|bool
+     */
+    public $lock;
+
+    /**
+     * The callbacks that should be invoked before the query is executed.
+     *
+     * @var array
+     */
+    public $beforeQueryCallbacks = [];
+
+    /**
+     * All of the available clause operators.
+     *
+     * @var string[]
+     */
+    public $operators = [
+        '=', '<', '>', '<=', '>=', '<>', '!=', '<=>',
+        'like', 'like binary', 'not like', 'ilike',
+        '&', '|', '^', '<<', '>>', '&~', 'is', 'is not',
+        'rlike', 'not rlike', 'regexp', 'not regexp',
+        '~', '~*', '!~', '!~*', 'similar to',
+        'not similar to', 'not ilike', '~~*', '!~~*',
+    ];
+
+    /**
+     * All of the available bitwise operators.
+     *
+     * @var string[]
+     */
+    public $bitwiseOperators = [
+        '&', '|', '^', '<<', '>>', '&~',
+    ];
+
+    /**
+     * Whether to use write pdo for the select.
+     *
+     * @var bool
+     */
+    public $useWritePdo = false;
+
+    /**
+     * Create a new query builder instance.
+     *
+     * @param  \Illuminate\Database\ConnectionInterface  $connection
+     * @param  \Illuminate\Database\Query\Grammars\Grammar|null  $grammar
+     * @param  \Illuminate\Database\Query\Processors\Processor|null  $processor
+     * @return void
+     */
+    public function __construct(ConnectionInterface $connection,
+                                Grammar $grammar = null,
+                                Processor $processor = null)
+    {
+        $this->connection = $connection;
+        $this->grammar = $grammar ?: $connection->getQueryGrammar();
+        $this->processor = $processor ?: $connection->getPostProcessor();
+    }
+
+    /**
+     * Set the columns to be selected.
+     *
+     * @param  array|mixed  $columns
+     * @return $this
+     */
+    public function select($columns = ['*'])
+    {
+        $this->columns = [];
+        $this->bindings['select'] = [];
+
+        $columns = is_array($columns) ? $columns : func_get_args();
+
+        foreach ($columns as $as => $column) {
+            if (is_string($as) && $this->isQueryable($column)) {
+                $this->selectSub($column, $as);
+            } else {
+                $this->columns[] = $column;
+            }
+        }
+
+        return $this;
+    }
+
+    /**
+     * Add a subselect expression to the query.
+     *
+     * @param  \Closure|\Illuminate\Database\Query\Builder|\Illuminate\Database\Eloquent\Builder|string  $query
+     * @param  string  $as
+     * @return $this
+     *
+     * @throws \InvalidArgumentException
+     */
+    public function selectSub($query, $as)
+    {
+        [$query, $bindings] = $this->createSub($query);
+
+        return $this->selectRaw(
+            '('.$query.') as '.$this->grammar->wrap($as), $bindings
+        );
+    }
+
+    /**
+     * Add a new "raw" select expression to the query.
+     *
+     * @param  string  $expression
+     * @param  array  $bindings
+     * @return $this
+     */
+    public function selectRaw($expression, array $bindings = [])
+    {
+        $this->addSelect(new Expression($expression));
+
+        if ($bindings) {
+            $this->addBinding($bindings, 'select');
+        }
+
+        return $this;
+    }
+
+    /**
+     * Makes "from" fetch from a subquery.
+     *
+     * @param  \Closure|\Illuminate\Database\Query\Builder|\Illuminate\Database\Eloquent\Builder|string  $query
+     * @param  string  $as
+     * @return $this
+     *
+     * @throws \InvalidArgumentException
+     */
+    public function fromSub($query, $as)
+    {
+        [$query, $bindings] = $this->createSub($query);
+
+        return $this->fromRaw('('.$query.') as '.$this->grammar->wrapTable($as), $bindings);
+    }
+
+    /**
+     * Add a raw from clause to the query.
+     *
+     * @param  string  $expression
+     * @param  mixed  $bindings
+     * @return $this
+     */
+    public function fromRaw($expression, $bindings = [])
+    {
+        $this->from = new Expression($expression);
+
+        $this->addBinding($bindings, 'from');
+
+        return $this;
+    }
+
+    /**
+     * Creates a subquery and parse it.
+     *
+     * @param  \Closure|\Illuminate\Database\Query\Builder|\Illuminate\Database\Eloquent\Builder|string  $query
+     * @return array
+     */
+    protected function createSub($query)
+    {
+        // If the given query is a Closure, we will execute it while passing in a new
+        // query instance to the Closure. This will give the developer a chance to
+        // format and work with the query before we cast it to a raw SQL string.
+        if ($query instanceof Closure) {
+            $callback = $query;
+
+            $callback($query = $this->forSubQuery());
+        }
+
+        return $this->parseSub($query);
+    }
+
+    /**
+     * Parse the subquery into SQL and bindings.
+     *
+     * @param  mixed  $query
+     * @return array
+     *
+     * @throws \InvalidArgumentException
+     */
+    protected function parseSub($query)
+    {
+        if ($query instanceof self || $query instanceof EloquentBuilder || $query instanceof Relation) {
+            $query = $this->prependDatabaseNameIfCrossDatabaseQuery($query);
+
+            return [$query->toSql(), $query->getBindings()];
+        } elseif (is_string($query)) {
+            return [$query, []];
+        } else {
+            throw new InvalidArgumentException(
+                'A subquery must be a query builder instance, a Closure, or a string.'
+            );
+        }
+    }
+
+    /**
+     * Prepend the database name if the given query is on another database.
+     *
+     * @param  mixed  $query
+     * @return mixed
+     */
+    protected function prependDatabaseNameIfCrossDatabaseQuery($query)
+    {
+        if ($query->getConnection()->getDatabaseName() !==
+            $this->getConnection()->getDatabaseName()) {
+            $databaseName = $query->getConnection()->getDatabaseName();
+
+            if (! str_starts_with($query->from, $databaseName) && ! str_contains($query->from, '.')) {
+                $query->from($databaseName.'.'.$query->from);
+            }
+        }
+
+        return $query;
+    }
+
+    /**
+     * Add a new select column to the query.
+     *
+     * @param  array|mixed  $column
+     * @return $this
+     */
+    public function addSelect($column)
+    {
+        $columns = is_array($column) ? $column : func_get_args();
+
+        foreach ($columns as $as => $column) {
+            if (is_string($as) && $this->isQueryable($column)) {
+                if (is_null($this->columns)) {
+                    $this->select($this->from.'.*');
+                }
+
+                $this->selectSub($column, $as);
+            } else {
+                if (is_array($this->columns) && in_array($column, $this->columns, true)) {
+                    continue;
+                }
+
+                $this->columns[] = $column;
+            }
+        }
+
+        return $this;
+    }
+
+    /**
+     * Force the query to only return distinct results.
+     *
+     * @return $this
+     */
+    public function distinct()
+    {
+        $columns = func_get_args();
+
+        if (count($columns) > 0) {
+            $this->distinct = is_array($columns[0]) || is_bool($columns[0]) ? $columns[0] : $columns;
+        } else {
+            $this->distinct = true;
+        }
+
+        return $this;
+    }
+
+    /**
+     * Set the table which the query is targeting.
+     *
+     * @param  \Closure|\Illuminate\Database\Query\Builder|\Illuminate\Database\Eloquent\Builder|string  $table
+     * @param  string|null  $as
+     * @return $this
+     */
+    public function from($table, $as = null)
+    {
+        if ($this->isQueryable($table)) {
+            return $this->fromSub($table, $as);
+        }
+
+        $this->from = $as ? "{$table} as {$as}" : $table;
+
+        return $this;
+    }
+
+    /**
+     * Add an index hint to suggest a query index.
+     *
+     * @param  string  $index
+     * @return $this
+     */
+    public function useIndex($index)
+    {
+        $this->indexHint = new IndexHint('hint', $index);
+
+        return $this;
+    }
+
+    /**
+     * Add an index hint to force a query index.
+     *
+     * @param  string  $index
+     * @return $this
+     */
+    public function forceIndex($index)
+    {
+        $this->indexHint = new IndexHint('force', $index);
+
+        return $this;
+    }
+
+    /**
+     * Add an index hint to ignore a query index.
+     *
+     * @param  string  $index
+     * @return $this
+     */
+    public function ignoreIndex($index)
+    {
+        $this->indexHint = new IndexHint('ignore', $index);
+
+        return $this;
+    }
+
+    /**
+     * Add a join clause to the query.
+     *
+     * @param  string  $table
+     * @param  \Closure|string  $first
+     * @param  string|null  $operator
+     * @param  string|null  $second
+     * @param  string  $type
+     * @param  bool  $where
+     * @return $this
+     */
+    public function join($table, $first, $operator = null, $second = null, $type = 'inner', $where = false)
+    {
+        $join = $this->newJoinClause($this, $type, $table);
+
+        // If the first "column" of the join is really a Closure instance the developer
+        // is trying to build a join with a complex "on" clause containing more than
+        // one condition, so we'll add the join and call a Closure with the query.
+        if ($first instanceof Closure) {
+            $first($join);
+
+            $this->joins[] = $join;
+
+            $this->addBinding($join->getBindings(), 'join');
+        }
+
+        // If the column is simply a string, we can assume the join simply has a basic
+        // "on" clause with a single condition. So we will just build the join with
+        // this simple join clauses attached to it. There is not a join callback.
+        else {
+            $method = $where ? 'where' : 'on';
+
+            $this->joins[] = $join->$method($first, $operator, $second);
+
+            $this->addBinding($join->getBindings(), 'join');
+        }
+
+        return $this;
+    }
+
+    /**
+     * Add a "join where" clause to the query.
+     *
+     * @param  string  $table
+     * @param  \Closure|string  $first
+     * @param  string  $operator
+     * @param  string  $second
+     * @param  string  $type
+     * @return $this
+     */
+    public function joinWhere($table, $first, $operator, $second, $type = 'inner')
+    {
+        return $this->join($table, $first, $operator, $second, $type, true);
+    }
+
+    /**
+     * Add a subquery join clause to the query.
+     *
+     * @param  \Closure|\Illuminate\Database\Query\Builder|\Illuminate\Database\Eloquent\Builder|string  $query
+     * @param  string  $as
+     * @param  \Closure|string  $first
+     * @param  string|null  $operator
+     * @param  string|null  $second
+     * @param  string  $type
+     * @param  bool  $where
+     * @return $this
+     *
+     * @throws \InvalidArgumentException
+     */
+    public function joinSub($query, $as, $first, $operator = null, $second = null, $type = 'inner', $where = false)
+    {
+        [$query, $bindings] = $this->createSub($query);
+
+        $expression = '('.$query.') as '.$this->grammar->wrapTable($as);
+
+        $this->addBinding($bindings, 'join');
+
+        return $this->join(new Expression($expression), $first, $operator, $second, $type, $where);
+    }
+
+    /**
+     * Add a left join to the query.
+     *
+     * @param  string  $table
+     * @param  \Closure|string  $first
+     * @param  string|null  $operator
+     * @param  string|null  $second
+     * @return $this
+     */
+    public function leftJoin($table, $first, $operator = null, $second = null)
+    {
+        return $this->join($table, $first, $operator, $second, 'left');
+    }
+
+    /**
+     * Add a "join where" clause to the query.
+     *
+     * @param  string  $table
+     * @param  \Closure|string  $first
+     * @param  string  $operator
+     * @param  string  $second
+     * @return $this
+     */
+    public function leftJoinWhere($table, $first, $operator, $second)
+    {
+        return $this->joinWhere($table, $first, $operator, $second, 'left');
+    }
+
+    /**
+     * Add a subquery left join to the query.
+     *
+     * @param  \Closure|\Illuminate\Database\Query\Builder|\Illuminate\Database\Eloquent\Builder|string  $query
+     * @param  string  $as
+     * @param  \Closure|string  $first
+     * @param  string|null  $operator
+     * @param  string|null  $second
+     * @return $this
+     */
+    public function leftJoinSub($query, $as, $first, $operator = null, $second = null)
+    {
+        return $this->joinSub($query, $as, $first, $operator, $second, 'left');
+    }
+
+    /**
+     * Add a right join to the query.
+     *
+     * @param  string  $table
+     * @param  \Closure|string  $first
+     * @param  string|null  $operator
+     * @param  string|null  $second
+     * @return $this
+     */
+    public function rightJoin($table, $first, $operator = null, $second = null)
+    {
+        return $this->join($table, $first, $operator, $second, 'right');
+    }
+
+    /**
+     * Add a "right join where" clause to the query.
+     *
+     * @param  string  $table
+     * @param  \Closure|string  $first
+     * @param  string  $operator
+     * @param  string  $second
+     * @return $this
+     */
+    public function rightJoinWhere($table, $first, $operator, $second)
+    {
+        return $this->joinWhere($table, $first, $operator, $second, 'right');
+    }
+
+    /**
+     * Add a subquery right join to the query.
+     *
+     * @param  \Closure|\Illuminate\Database\Query\Builder|\Illuminate\Database\Eloquent\Builder|string  $query
+     * @param  string  $as
+     * @param  \Closure|string  $first
+     * @param  string|null  $operator
+     * @param  string|null  $second
+     * @return $this
+     */
+    public function rightJoinSub($query, $as, $first, $operator = null, $second = null)
+    {
+        return $this->joinSub($query, $as, $first, $operator, $second, 'right');
+    }
+
+    /**
+     * Add a "cross join" clause to the query.
+     *
+     * @param  string  $table
+     * @param  \Closure|string|null  $first
+     * @param  string|null  $operator
+     * @param  string|null  $second
+     * @return $this
+     */
+    public function crossJoin($table, $first = null, $operator = null, $second = null)
+    {
+        if ($first) {
+            return $this->join($table, $first, $operator, $second, 'cross');
+        }
+
+        $this->joins[] = $this->newJoinClause($this, 'cross', $table);
+
+        return $this;
+    }
+
+    /**
+     * Add a subquery cross join to the query.
+     *
+     * @param  \Closure|\Illuminate\Database\Query\Builder|\Illuminate\Database\Eloquent\Builder|string  $query
+     * @param  string  $as
+     * @return $this
+     */
+    public function crossJoinSub($query, $as)
+    {
+        [$query, $bindings] = $this->createSub($query);
+
+        $expression = '('.$query.') as '.$this->grammar->wrapTable($as);
+
+        $this->addBinding($bindings, 'join');
+
+        $this->joins[] = $this->newJoinClause($this, 'cross', new Expression($expression));
+
+        return $this;
+    }
+
+    /**
+     * Get a new join clause.
+     *
+     * @param  \Illuminate\Database\Query\Builder  $parentQuery
+     * @param  string  $type
+     * @param  string  $table
+     * @return \Illuminate\Database\Query\JoinClause
+     */
+    protected function newJoinClause(self $parentQuery, $type, $table)
+    {
+        return new JoinClause($parentQuery, $type, $table);
+    }
+
+    /**
+     * Merge an array of where clauses and bindings.
+     *
+     * @param  array  $wheres
+     * @param  array  $bindings
+     * @return $this
+     */
+    public function mergeWheres($wheres, $bindings)
+    {
+        $this->wheres = array_merge($this->wheres, (array) $wheres);
+
+        $this->bindings['where'] = array_values(
+            array_merge($this->bindings['where'], (array) $bindings)
+        );
+
+        return $this;
+    }
+
+    /**
+     * Add a basic where clause to the query.
+     *
+     * @param  \Closure|string|array  $column
+     * @param  mixed  $operator
+     * @param  mixed  $value
+     * @param  string  $boolean
+     * @return $this
+     */
+    public function where($column, $operator = null, $value = null, $boolean = 'and')
+    {
+        // If the column is an array, we will assume it is an array of key-value pairs
+        // and can add them each as a where clause. We will maintain the boolean we
+        // received when the method was called and pass it into the nested where.
+        if (is_array($column)) {
+            return $this->addArrayOfWheres($column, $boolean);
+        }
+
+        // Here we will make some assumptions about the operator. If only 2 values are
+        // passed to the method, we will assume that the operator is an equals sign
+        // and keep going. Otherwise, we'll require the operator to be passed in.
+        [$value, $operator] = $this->prepareValueAndOperator(
+            $value, $operator, func_num_args() === 2
+        );
+
+        // If the column is actually a Closure instance, we will assume the developer
+        // wants to begin a nested where statement which is wrapped in parentheses.
+        // We will add that Closure to the query and return back out immediately.
+        if ($column instanceof Closure && is_null($operator)) {
+            return $this->whereNested($column, $boolean);
+        }
+
+        // If the column is a Closure instance and there is an operator value, we will
+        // assume the developer wants to run a subquery and then compare the result
+        // of that subquery with the given value that was provided to the method.
+        if ($this->isQueryable($column) && ! is_null($operator)) {
+            [$sub, $bindings] = $this->createSub($column);
+
+            return $this->addBinding($bindings, 'where')
+                ->where(new Expression('('.$sub.')'), $operator, $value, $boolean);
+        }
+
+        // If the given operator is not found in the list of valid operators we will
+        // assume that the developer is just short-cutting the '=' operators and
+        // we will set the operators to '=' and set the values appropriately.
+        if ($this->invalidOperator($operator)) {
+            [$value, $operator] = [$operator, '='];
+        }
+
+        // If the value is a Closure, it means the developer is performing an entire
+        // sub-select within the query and we will need to compile the sub-select
+        // within the where clause to get the appropriate query record results.
+        if ($value instanceof Closure) {
+            return $this->whereSub($column, $operator, $value, $boolean);
+        }
+
+        // If the value is "null", we will just assume the developer wants to add a
+        // where null clause to the query. So, we will allow a short-cut here to
+        // that method for convenience so the developer doesn't have to check.
+        if (is_null($value)) {
+            return $this->whereNull($column, $boolean, $operator !== '=');
+        }
+
+        $type = 'Basic';
+
+        // If the column is making a JSON reference we'll check to see if the value
+        // is a boolean. If it is, we'll add the raw boolean string as an actual
+        // value to the query to ensure this is properly handled by the query.
+        if (str_contains($column, '->') && is_bool($value)) {
+            $value = new Expression($value ? 'true' : 'false');
+
+            if (is_string($column)) {
+                $type = 'JsonBoolean';
+            }
+        }
+
+        if ($this->isBitwiseOperator($operator)) {
+            $type = 'Bitwise';
+        }
+
+        // Now that we are working with just a simple query we can put the elements
+        // in our array and add the query binding to our array of bindings that
+        // will be bound to each SQL statements when it is finally executed.
+        $this->wheres[] = compact(
+            'type', 'column', 'operator', 'value', 'boolean'
+        );
+
+        if (! $value instanceof Expression) {
+            $this->addBinding($this->flattenValue($value), 'where');
+        }
+
+        return $this;
+    }
+
+    /**
+     * Add an array of where clauses to the query.
+     *
+     * @param  array  $column
+     * @param  string  $boolean
+     * @param  string  $method
+     * @return $this
+     */
+    protected function addArrayOfWheres($column, $boolean, $method = 'where')
+    {
+        return $this->whereNested(function ($query) use ($column, $method, $boolean) {
+            foreach ($column as $key => $value) {
+                if (is_numeric($key) && is_array($value)) {
+                    $query->{$method}(...array_values($value));
+                } else {
+                    $query->{$method}($key, '=', $value, $boolean);
+                }
+            }
+        }, $boolean);
+    }
+
+    /**
+     * Prepare the value and operator for a where clause.
+     *
+     * @param  string  $value
+     * @param  string  $operator
+     * @param  bool  $useDefault
+     * @return array
+     *
+     * @throws \InvalidArgumentException
+     */
+    public function prepareValueAndOperator($value, $operator, $useDefault = false)
+    {
+        if ($useDefault) {
+            return [$operator, '='];
+        } elseif ($this->invalidOperatorAndValue($operator, $value)) {
+            throw new InvalidArgumentException('Illegal operator and value combination.');
+        }
+
+        return [$value, $operator];
+    }
+
+    /**
+     * Determine if the given operator and value combination is legal.
+     *
+     * Prevents using Null values with invalid operators.
+     *
+     * @param  string  $operator
+     * @param  mixed  $value
+     * @return bool
+     */
+    protected function invalidOperatorAndValue($operator, $value)
+    {
+        return is_null($value) && in_array($operator, $this->operators) &&
+             ! in_array($operator, ['=', '<>', '!=']);
+    }
+
+    /**
+     * Determine if the given operator is supported.
+     *
+     * @param  string  $operator
+     * @return bool
+     */
+    protected function invalidOperator($operator)
+    {
+        return ! is_string($operator) || (! in_array(strtolower($operator), $this->operators, true) &&
+               ! in_array(strtolower($operator), $this->grammar->getOperators(), true));
+    }
+
+    /**
+     * Determine if the operator is a bitwise operator.
+     *
+     * @param  string  $operator
+     * @return bool
+     */
+    protected function isBitwiseOperator($operator)
+    {
+        return in_array(strtolower($operator), $this->bitwiseOperators, true) ||
+               in_array(strtolower($operator), $this->grammar->getBitwiseOperators(), true);
+    }
+
+    /**
+     * Add an "or where" clause to the query.
+     *
+     * @param  \Closure|string|array  $column
+     * @param  mixed  $operator
+     * @param  mixed  $value
+     * @return $this
+     */
+    public function orWhere($column, $operator = null, $value = null)
+    {
+        [$value, $operator] = $this->prepareValueAndOperator(
+            $value, $operator, func_num_args() === 2
+        );
+
+        return $this->where($column, $operator, $value, 'or');
+    }
+
+    /**
+     * Add a basic "where not" clause to the query.
+     *
+     * @param  \Closure|string|array  $column
+     * @param  mixed  $operator
+     * @param  mixed  $value
+     * @param  string  $boolean
+     * @return $this
+     */
+    public function whereNot($column, $operator = null, $value = null, $boolean = 'and')
+    {
+        if (is_array($column)) {
+            return $this->whereNested(function ($query) use ($column, $operator, $value, $boolean) {
+                $query->where($column, $operator, $value, $boolean);
+            }, $boolean.' not');
+        }
+
+        return $this->where($column, $operator, $value, $boolean.' not');
+    }
+
+    /**
+     * Add an "or where not" clause to the query.
+     *
+     * @param  \Closure|string|array  $column
+     * @param  mixed  $operator
+     * @param  mixed  $value
+     * @return $this
+     */
+    public function orWhereNot($column, $operator = null, $value = null)
+    {
+        return $this->whereNot($column, $operator, $value, 'or');
+    }
+
+    /**
+     * Add a "where" clause comparing two columns to the query.
+     *
+     * @param  string|array  $first
+     * @param  string|null  $operator
+     * @param  string|null  $second
+     * @param  string|null  $boolean
+     * @return $this
+     */
+    public function whereColumn($first, $operator = null, $second = null, $boolean = 'and')
+    {
+        // If the column is an array, we will assume it is an array of key-value pairs
+        // and can add them each as a where clause. We will maintain the boolean we
+        // received when the method was called and pass it into the nested where.
+        if (is_array($first)) {
+            return $this->addArrayOfWheres($first, $boolean, 'whereColumn');
+        }
+
+        // If the given operator is not found in the list of valid operators we will
+        // assume that the developer is just short-cutting the '=' operators and
+        // we will set the operators to '=' and set the values appropriately.
+        if ($this->invalidOperator($operator)) {
+            [$second, $operator] = [$operator, '='];
+        }
+
+        // Finally, we will add this where clause into this array of clauses that we
+        // are building for the query. All of them will be compiled via a grammar
+        // once the query is about to be executed and run against the database.
+        $type = 'Column';
+
+        $this->wheres[] = compact(
+            'type', 'first', 'operator', 'second', 'boolean'
+        );
+
+        return $this;
+    }
+
+    /**
+     * Add an "or where" clause comparing two columns to the query.
+     *
+     * @param  string|array  $first
+     * @param  string|null  $operator
+     * @param  string|null  $second
+     * @return $this
+     */
+    public function orWhereColumn($first, $operator = null, $second = null)
+    {
+        return $this->whereColumn($first, $operator, $second, 'or');
+    }
+
+    /**
+     * Add a raw where clause to the query.
+     *
+     * @param  string  $sql
+     * @param  mixed  $bindings
+     * @param  string  $boolean
+     * @return $this
+     */
+    public function whereRaw($sql, $bindings = [], $boolean = 'and')
+    {
+        $this->wheres[] = ['type' => 'raw', 'sql' => $sql, 'boolean' => $boolean];
+
+        $this->addBinding((array) $bindings, 'where');
+
+        return $this;
+    }
+
+    /**
+     * Add a raw or where clause to the query.
+     *
+     * @param  string  $sql
+     * @param  mixed  $bindings
+     * @return $this
+     */
+    public function orWhereRaw($sql, $bindings = [])
+    {
+        return $this->whereRaw($sql, $bindings, 'or');
+    }
+
+    /**
+     * Add a "where in" clause to the query.
+     *
+     * @param  string  $column
+     * @param  mixed  $values
+     * @param  string  $boolean
+     * @param  bool  $not
+     * @return $this
+     */
+    public function whereIn($column, $values, $boolean = 'and', $not = false)
+    {
+        $type = $not ? 'NotIn' : 'In';
+
+        // If the value is a query builder instance we will assume the developer wants to
+        // look for any values that exist within this given query. So, we will add the
+        // query accordingly so that this query is properly executed when it is run.
+        if ($this->isQueryable($values)) {
+            [$query, $bindings] = $this->createSub($values);
+
+            $values = [new Expression($query)];
+
+            $this->addBinding($bindings, 'where');
+        }
+
+        // Next, if the value is Arrayable we need to cast it to its raw array form so we
+        // have the underlying array value instead of an Arrayable object which is not
+        // able to be added as a binding, etc. We will then add to the wheres array.
+        if ($values instanceof Arrayable) {
+            $values = $values->toArray();
+        }
+
+        $this->wheres[] = compact('type', 'column', 'values', 'boolean');
+
+        if (count($values) !== count(Arr::flatten($values, 1))) {
+            throw new InvalidArgumentException('Nested arrays may not be passed to whereIn method.');
+        }
+
+        // Finally, we'll add a binding for each value unless that value is an expression
+        // in which case we will just skip over it since it will be the query as a raw
+        // string and not as a parameterized place-holder to be replaced by the PDO.
+        $this->addBinding($this->cleanBindings($values), 'where');
+
+        return $this;
+    }
+
+    /**
+     * Add an "or where in" clause to the query.
+     *
+     * @param  string  $column
+     * @param  mixed  $values
+     * @return $this
+     */
+    public function orWhereIn($column, $values)
+    {
+        return $this->whereIn($column, $values, 'or');
+    }
+
+    /**
+     * Add a "where not in" clause to the query.
+     *
+     * @param  string  $column
+     * @param  mixed  $values
+     * @param  string  $boolean
+     * @return $this
+     */
+    public function whereNotIn($column, $values, $boolean = 'and')
+    {
+        return $this->whereIn($column, $values, $boolean, true);
+    }
+
+    /**
+     * Add an "or where not in" clause to the query.
+     *
+     * @param  string  $column
+     * @param  mixed  $values
+     * @return $this
+     */
+    public function orWhereNotIn($column, $values)
+    {
+        return $this->whereNotIn($column, $values, 'or');
+    }
+
+    /**
+     * Add a "where in raw" clause for integer values to the query.
+     *
+     * @param  string  $column
+     * @param  \Illuminate\Contracts\Support\Arrayable|array  $values
+     * @param  string  $boolean
+     * @param  bool  $not
+     * @return $this
+     */
+    public function whereIntegerInRaw($column, $values, $boolean = 'and', $not = false)
+    {
+        $type = $not ? 'NotInRaw' : 'InRaw';
+
+        if ($values instanceof Arrayable) {
+            $values = $values->toArray();
+        }
+
+        $values = Arr::flatten($values);
+
+        foreach ($values as &$value) {
+            $value = (int) $value;
+        }
+
+        $this->wheres[] = compact('type', 'column', 'values', 'boolean');
+
+        return $this;
+    }
+
+    /**
+     * Add an "or where in raw" clause for integer values to the query.
+     *
+     * @param  string  $column
+     * @param  \Illuminate\Contracts\Support\Arrayable|array  $values
+     * @return $this
+     */
+    public function orWhereIntegerInRaw($column, $values)
+    {
+        return $this->whereIntegerInRaw($column, $values, 'or');
+    }
+
+    /**
+     * Add a "where not in raw" clause for integer values to the query.
+     *
+     * @param  string  $column
+     * @param  \Illuminate\Contracts\Support\Arrayable|array  $values
+     * @param  string  $boolean
+     * @return $this
+     */
+    public function whereIntegerNotInRaw($column, $values, $boolean = 'and')
+    {
+        return $this->whereIntegerInRaw($column, $values, $boolean, true);
+    }
+
+    /**
+     * Add an "or where not in raw" clause for integer values to the query.
+     *
+     * @param  string  $column
+     * @param  \Illuminate\Contracts\Support\Arrayable|array  $values
+     * @return $this
+     */
+    public function orWhereIntegerNotInRaw($column, $values)
+    {
+        return $this->whereIntegerNotInRaw($column, $values, 'or');
+    }
+
+    /**
+     * Add a "where null" clause to the query.
+     *
+     * @param  string|array  $columns
+     * @param  string  $boolean
+     * @param  bool  $not
+     * @return $this
+     */
+    public function whereNull($columns, $boolean = 'and', $not = false)
+    {
+        $type = $not ? 'NotNull' : 'Null';
+
+        foreach (Arr::wrap($columns) as $column) {
+            $this->wheres[] = compact('type', 'column', 'boolean');
+        }
+
+        return $this;
+    }
+
+    /**
+     * Add an "or where null" clause to the query.
+     *
+     * @param  string|array  $column
+     * @return $this
+     */
+    public function orWhereNull($column)
+    {
+        return $this->whereNull($column, 'or');
+    }
+
+    /**
+     * Add a "where not null" clause to the query.
+     *
+     * @param  string|array  $columns
+     * @param  string  $boolean
+     * @return $this
+     */
+    public function whereNotNull($columns, $boolean = 'and')
+    {
+        return $this->whereNull($columns, $boolean, true);
+    }
+
+    /**
+     * Add a where between statement to the query.
+     *
+     * @param  string|\Illuminate\Database\Query\Expression  $column
+     * @param  iterable  $values
+     * @param  string  $boolean
+     * @param  bool  $not
+     * @return $this
+     */
+    public function whereBetween($column, iterable $values, $boolean = 'and', $not = false)
+    {
+        $type = 'between';
+
+        if ($values instanceof CarbonPeriod) {
+            $values = $values->toArray();
+        }
+
+        $this->wheres[] = compact('type', 'column', 'values', 'boolean', 'not');
+
+        $this->addBinding(array_slice($this->cleanBindings(Arr::flatten($values)), 0, 2), 'where');
+
+        return $this;
+    }
+
+    /**
+     * Add a where between statement using columns to the query.
+     *
+     * @param  string  $column
+     * @param  array  $values
+     * @param  string  $boolean
+     * @param  bool  $not
+     * @return $this
+     */
+    public function whereBetweenColumns($column, array $values, $boolean = 'and', $not = false)
+    {
+        $type = 'betweenColumns';
+
+        $this->wheres[] = compact('type', 'column', 'values', 'boolean', 'not');
+
+        return $this;
+    }
+
+    /**
+     * Add an or where between statement to the query.
+     *
+     * @param  string  $column
+     * @param  iterable  $values
+     * @return $this
+     */
+    public function orWhereBetween($column, iterable $values)
+    {
+        return $this->whereBetween($column, $values, 'or');
+    }
+
+    /**
+     * Add an or where between statement using columns to the query.
+     *
+     * @param  string  $column
+     * @param  array  $values
+     * @return $this
+     */
+    public function orWhereBetweenColumns($column, array $values)
+    {
+        return $this->whereBetweenColumns($column, $values, 'or');
+    }
+
+    /**
+     * Add a where not between statement to the query.
+     *
+     * @param  string  $column
+     * @param  iterable  $values
+     * @param  string  $boolean
+     * @return $this
+     */
+    public function whereNotBetween($column, iterable $values, $boolean = 'and')
+    {
+        return $this->whereBetween($column, $values, $boolean, true);
+    }
+
+    /**
+     * Add a where not between statement using columns to the query.
+     *
+     * @param  string  $column
+     * @param  array  $values
+     * @param  string  $boolean
+     * @return $this
+     */
+    public function whereNotBetweenColumns($column, array $values, $boolean = 'and')
+    {
+        return $this->whereBetweenColumns($column, $values, $boolean, true);
+    }
+
+    /**
+     * Add an or where not between statement to the query.
+     *
+     * @param  string  $column
+     * @param  iterable  $values
+     * @return $this
+     */
+    public function orWhereNotBetween($column, iterable $values)
+    {
+        return $this->whereNotBetween($column, $values, 'or');
+    }
+
+    /**
+     * Add an or where not between statement using columns to the query.
+     *
+     * @param  string  $column
+     * @param  array  $values
+     * @return $this
+     */
+    public function orWhereNotBetweenColumns($column, array $values)
+    {
+        return $this->whereNotBetweenColumns($column, $values, 'or');
+    }
+
+    /**
+     * Add an "or where not null" clause to the query.
+     *
+     * @param  string  $column
+     * @return $this
+     */
+    public function orWhereNotNull($column)
+    {
+        return $this->whereNotNull($column, 'or');
+    }
+
+    /**
+     * Add a "where date" statement to the query.
+     *
+     * @param  string  $column
+     * @param  string  $operator
+     * @param  \DateTimeInterface|string|null  $value
+     * @param  string  $boolean
+     * @return $this
+     */
+    public function whereDate($column, $operator, $value = null, $boolean = 'and')
+    {
+        [$value, $operator] = $this->prepareValueAndOperator(
+            $value, $operator, func_num_args() === 2
+        );
+
+        $value = $this->flattenValue($value);
+
+        if ($value instanceof DateTimeInterface) {
+            $value = $value->format('Y-m-d');
+        }
+
+        return $this->addDateBasedWhere('Date', $column, $operator, $value, $boolean);
+    }
+
+    /**
+     * Add an "or where date" statement to the query.
+     *
+     * @param  string  $column
+     * @param  string  $operator
+     * @param  \DateTimeInterface|string|null  $value
+     * @return $this
+     */
+    public function orWhereDate($column, $operator, $value = null)
+    {
+        [$value, $operator] = $this->prepareValueAndOperator(
+            $value, $operator, func_num_args() === 2
+        );
+
+        return $this->whereDate($column, $operator, $value, 'or');
+    }
+
+    /**
+     * Add a "where time" statement to the query.
+     *
+     * @param  string  $column
+     * @param  string  $operator
+     * @param  \DateTimeInterface|string|null  $value
+     * @param  string  $boolean
+     * @return $this
+     */
+    public function whereTime($column, $operator, $value = null, $boolean = 'and')
+    {
+        [$value, $operator] = $this->prepareValueAndOperator(
+            $value, $operator, func_num_args() === 2
+        );
+
+        $value = $this->flattenValue($value);
+
+        if ($value instanceof DateTimeInterface) {
+            $value = $value->format('H:i:s');
+        }
+
+        return $this->addDateBasedWhere('Time', $column, $operator, $value, $boolean);
+    }
+
+    /**
+     * Add an "or where time" statement to the query.
+     *
+     * @param  string  $column
+     * @param  string  $operator
+     * @param  \DateTimeInterface|string|null  $value
+     * @return $this
+     */
+    public function orWhereTime($column, $operator, $value = null)
+    {
+        [$value, $operator] = $this->prepareValueAndOperator(
+            $value, $operator, func_num_args() === 2
+        );
+
+        return $this->whereTime($column, $operator, $value, 'or');
+    }
+
+    /**
+     * Add a "where day" statement to the query.
+     *
+     * @param  string  $column
+     * @param  string  $operator
+     * @param  \DateTimeInterface|string|int|null  $value
+     * @param  string  $boolean
+     * @return $this
+     */
+    public function whereDay($column, $operator, $value = null, $boolean = 'and')
+    {
+        [$value, $operator] = $this->prepareValueAndOperator(
+            $value, $operator, func_num_args() === 2
+        );
+
+        $value = $this->flattenValue($value);
+
+        if ($value instanceof DateTimeInterface) {
+            $value = $value->format('d');
+        }
+
+        if (! $value instanceof Expression) {
+            $value = sprintf('%02d', $value);
+        }
+
+        return $this->addDateBasedWhere('Day', $column, $operator, $value, $boolean);
+    }
+
+    /**
+     * Add an "or where day" statement to the query.
+     *
+     * @param  string  $column
+     * @param  string  $operator
+     * @param  \DateTimeInterface|string|int|null  $value
+     * @return $this
+     */
+    public function orWhereDay($column, $operator, $value = null)
+    {
+        [$value, $operator] = $this->prepareValueAndOperator(
+            $value, $operator, func_num_args() === 2
+        );
+
+        return $this->whereDay($column, $operator, $value, 'or');
+    }
+
+    /**
+     * Add a "where month" statement to the query.
+     *
+     * @param  string  $column
+     * @param  string  $operator
+     * @param  \DateTimeInterface|string|int|null  $value
+     * @param  string  $boolean
+     * @return $this
+     */
+    public function whereMonth($column, $operator, $value = null, $boolean = 'and')
+    {
+        [$value, $operator] = $this->prepareValueAndOperator(
+            $value, $operator, func_num_args() === 2
+        );
+
+        $value = $this->flattenValue($value);
+
+        if ($value instanceof DateTimeInterface) {
+            $value = $value->format('m');
+        }
+
+        if (! $value instanceof Expression) {
+            $value = sprintf('%02d', $value);
+        }
+
+        return $this->addDateBasedWhere('Month', $column, $operator, $value, $boolean);
+    }
+
+    /**
+     * Add an "or where month" statement to the query.
+     *
+     * @param  string  $column
+     * @param  string  $operator
+     * @param  \DateTimeInterface|string|int|null  $value
+     * @return $this
+     */
+    public function orWhereMonth($column, $operator, $value = null)
+    {
+        [$value, $operator] = $this->prepareValueAndOperator(
+            $value, $operator, func_num_args() === 2
+        );
+
+        return $this->whereMonth($column, $operator, $value, 'or');
+    }
+
+    /**
+     * Add a "where year" statement to the query.
+     *
+     * @param  string  $column
+     * @param  string  $operator
+     * @param  \DateTimeInterface|string|int|null  $value
+     * @param  string  $boolean
+     * @return $this
+     */
+    public function whereYear($column, $operator, $value = null, $boolean = 'and')
+    {
+        [$value, $operator] = $this->prepareValueAndOperator(
+            $value, $operator, func_num_args() === 2
+        );
+
+        $value = $this->flattenValue($value);
+
+        if ($value instanceof DateTimeInterface) {
+            $value = $value->format('Y');
+        }
+
+        return $this->addDateBasedWhere('Year', $column, $operator, $value, $boolean);
+    }
+
+    /**
+     * Add an "or where year" statement to the query.
+     *
+     * @param  string  $column
+     * @param  string  $operator
+     * @param  \DateTimeInterface|string|int|null  $value
+     * @return $this
+     */
+    public function orWhereYear($column, $operator, $value = null)
+    {
+        [$value, $operator] = $this->prepareValueAndOperator(
+            $value, $operator, func_num_args() === 2
+        );
+
+        return $this->whereYear($column, $operator, $value, 'or');
+    }
+
+    /**
+     * Add a date based (year, month, day, time) statement to the query.
+     *
+     * @param  string  $type
+     * @param  string  $column
+     * @param  string  $operator
+     * @param  mixed  $value
+     * @param  string  $boolean
+     * @return $this
+     */
+    protected function addDateBasedWhere($type, $column, $operator, $value, $boolean = 'and')
+    {
+        $this->wheres[] = compact('column', 'type', 'boolean', 'operator', 'value');
+
+        if (! $value instanceof Expression) {
+            $this->addBinding($value, 'where');
+        }
+
+        return $this;
+    }
+
+    /**
+     * Add a nested where statement to the query.
+     *
+     * @param  \Closure  $callback
+     * @param  string  $boolean
+     * @return $this
+     */
+    public function whereNested(Closure $callback, $boolean = 'and')
+    {
+        $callback($query = $this->forNestedWhere());
+
+        return $this->addNestedWhereQuery($query, $boolean);
+    }
+
+    /**
+     * Create a new query instance for nested where condition.
+     *
+     * @return \Illuminate\Database\Query\Builder
+     */
+    public function forNestedWhere()
+    {
+        return $this->newQuery()->from($this->from);
+    }
+
+    /**
+     * Add another query builder as a nested where to the query builder.
+     *
+     * @param  \Illuminate\Database\Query\Builder  $query
+     * @param  string  $boolean
+     * @return $this
+     */
+    public function addNestedWhereQuery($query, $boolean = 'and')
+    {
+        if (count($query->wheres)) {
+            $type = 'Nested';
+
+            $this->wheres[] = compact('type', 'query', 'boolean');
+
+            $this->addBinding($query->getRawBindings()['where'], 'where');
+        }
+
+        return $this;
+    }
+
+    /**
+     * Add a full sub-select to the query.
+     *
+     * @param  string  $column
+     * @param  string  $operator
+     * @param  \Closure  $callback
+     * @param  string  $boolean
+     * @return $this
+     */
+    protected function whereSub($column, $operator, Closure $callback, $boolean)
+    {
+        $type = 'Sub';
+
+        // Once we have the query instance we can simply execute it so it can add all
+        // of the sub-select's conditions to itself, and then we can cache it off
+        // in the array of where clauses for the "main" parent query instance.
+        $callback($query = $this->forSubQuery());
+
+        $this->wheres[] = compact(
+            'type', 'column', 'operator', 'query', 'boolean'
+        );
+
+        $this->addBinding($query->getBindings(), 'where');
+
+        return $this;
+    }
+
+    /**
+     * Add an exists clause to the query.
+     *
+     * @param  \Closure  $callback
+     * @param  string  $boolean
+     * @param  bool  $not
+     * @return $this
+     */
+    public function whereExists(Closure $callback, $boolean = 'and', $not = false)
+    {
+        $query = $this->forSubQuery();
+
+        // Similar to the sub-select clause, we will create a new query instance so
+        // the developer may cleanly specify the entire exists query and we will
+        // compile the whole thing in the grammar and insert it into the SQL.
+        $callback($query);
+
+        return $this->addWhereExistsQuery($query, $boolean, $not);
+    }
+
+    /**
+     * Add an or exists clause to the query.
+     *
+     * @param  \Closure  $callback
+     * @param  bool  $not
+     * @return $this
+     */
+    public function orWhereExists(Closure $callback, $not = false)
+    {
+        return $this->whereExists($callback, 'or', $not);
+    }
+
+    /**
+     * Add a where not exists clause to the query.
+     *
+     * @param  \Closure  $callback
+     * @param  string  $boolean
+     * @return $this
+     */
+    public function whereNotExists(Closure $callback, $boolean = 'and')
+    {
+        return $this->whereExists($callback, $boolean, true);
+    }
+
+    /**
+     * Add a where not exists clause to the query.
+     *
+     * @param  \Closure  $callback
+     * @return $this
+     */
+    public function orWhereNotExists(Closure $callback)
+    {
+        return $this->orWhereExists($callback, true);
+    }
+
+    /**
+     * Add an exists clause to the query.
+     *
+     * @param  \Illuminate\Database\Query\Builder  $query
+     * @param  string  $boolean
+     * @param  bool  $not
+     * @return $this
+     */
+    public function addWhereExistsQuery(self $query, $boolean = 'and', $not = false)
+    {
+        $type = $not ? 'NotExists' : 'Exists';
+
+        $this->wheres[] = compact('type', 'query', 'boolean');
+
+        $this->addBinding($query->getBindings(), 'where');
+
+        return $this;
+    }
+
+    /**
+     * Adds a where condition using row values.
+     *
+     * @param  array  $columns
+     * @param  string  $operator
+     * @param  array  $values
+     * @param  string  $boolean
+     * @return $this
+     *
+     * @throws \InvalidArgumentException
+     */
+    public function whereRowValues($columns, $operator, $values, $boolean = 'and')
+    {
+        if (count($columns) !== count($values)) {
+            throw new InvalidArgumentException('The number of columns must match the number of values');
+        }
+
+        $type = 'RowValues';
+
+        $this->wheres[] = compact('type', 'columns', 'operator', 'values', 'boolean');
+
+        $this->addBinding($this->cleanBindings($values));
+
+        return $this;
+    }
+
+    /**
+     * Adds an or where condition using row values.
+     *
+     * @param  array  $columns
+     * @param  string  $operator
+     * @param  array  $values
+     * @return $this
+     */
+    public function orWhereRowValues($columns, $operator, $values)
+    {
+        return $this->whereRowValues($columns, $operator, $values, 'or');
+    }
+
+    /**
+     * Add a "where JSON contains" clause to the query.
+     *
+     * @param  string  $column
+     * @param  mixed  $value
+     * @param  string  $boolean
+     * @param  bool  $not
+     * @return $this
+     */
+    public function whereJsonContains($column, $value, $boolean = 'and', $not = false)
+    {
+        $type = 'JsonContains';
+
+        $this->wheres[] = compact('type', 'column', 'value', 'boolean', 'not');
+
+        if (! $value instanceof Expression) {
+            $this->addBinding($this->grammar->prepareBindingForJsonContains($value));
+        }
+
+        return $this;
+    }
+
+    /**
+     * Add an "or where JSON contains" clause to the query.
+     *
+     * @param  string  $column
+     * @param  mixed  $value
+     * @return $this
+     */
+    public function orWhereJsonContains($column, $value)
+    {
+        return $this->whereJsonContains($column, $value, 'or');
+    }
+
+    /**
+     * Add a "where JSON not contains" clause to the query.
+     *
+     * @param  string  $column
+     * @param  mixed  $value
+     * @param  string  $boolean
+     * @return $this
+     */
+    public function whereJsonDoesntContain($column, $value, $boolean = 'and')
+    {
+        return $this->whereJsonContains($column, $value, $boolean, true);
+    }
+
+    /**
+     * Add an "or where JSON not contains" clause to the query.
+     *
+     * @param  string  $column
+     * @param  mixed  $value
+     * @return $this
+     */
+    public function orWhereJsonDoesntContain($column, $value)
+    {
+        return $this->whereJsonDoesntContain($column, $value, 'or');
+    }
+
+    /**
+     * Add a clause that determines if a JSON path exists to the query.
+     *
+     * @param  string  $column
+     * @param  string  $boolean
+     * @param  bool  $not
+     * @return $this
+     */
+    public function whereJsonContainsKey($column, $boolean = 'and', $not = false)
+    {
+        $type = 'JsonContainsKey';
+
+        $this->wheres[] = compact('type', 'column', 'boolean', 'not');
+
+        return $this;
+    }
+
+    /**
+     * Add an "or" clause that determines if a JSON path exists to the query.
+     *
+     * @param  string  $column
+     * @return $this
+     */
+    public function orWhereJsonContainsKey($column)
+    {
+        return $this->whereJsonContainsKey($column, 'or');
+    }
+
+    /**
+     * Add a clause that determines if a JSON path does not exist to the query.
+     *
+     * @param  string  $column
+     * @param  string  $boolean
+     * @return $this
+     */
+    public function whereJsonDoesntContainKey($column, $boolean = 'and')
+    {
+        return $this->whereJsonContainsKey($column, $boolean, true);
+    }
+
+    /**
+     * Add an "or" clause that determines if a JSON path does not exist to the query.
+     *
+     * @param  string  $column
+     * @return $this
+     */
+    public function orWhereJsonDoesntContainKey($column)
+    {
+        return $this->whereJsonDoesntContainKey($column, 'or');
+    }
+
+    /**
+     * Add a "where JSON length" clause to the query.
+     *
+     * @param  string  $column
+     * @param  mixed  $operator
+     * @param  mixed  $value
+     * @param  string  $boolean
+     * @return $this
+     */
+    public function whereJsonLength($column, $operator, $value = null, $boolean = 'and')
+    {
+        $type = 'JsonLength';
+
+        [$value, $operator] = $this->prepareValueAndOperator(
+            $value, $operator, func_num_args() === 2
+        );
+
+        $this->wheres[] = compact('type', 'column', 'operator', 'value', 'boolean');
+
+        if (! $value instanceof Expression) {
+            $this->addBinding((int) $this->flattenValue($value));
+        }
+
+        return $this;
+    }
+
+    /**
+     * Add an "or where JSON length" clause to the query.
+     *
+     * @param  string  $column
+     * @param  mixed  $operator
+     * @param  mixed  $value
+     * @return $this
+     */
+    public function orWhereJsonLength($column, $operator, $value = null)
+    {
+        [$value, $operator] = $this->prepareValueAndOperator(
+            $value, $operator, func_num_args() === 2
+        );
+
+        return $this->whereJsonLength($column, $operator, $value, 'or');
+    }
+
+    /**
+     * Handles dynamic "where" clauses to the query.
+     *
+     * @param  string  $method
+     * @param  array  $parameters
+     * @return $this
+     */
+    public function dynamicWhere($method, $parameters)
+    {
+        $finder = substr($method, 5);
+
+        $segments = preg_split(
+            '/(And|Or)(?=[A-Z])/', $finder, -1, PREG_SPLIT_DELIM_CAPTURE
+        );
+
+        // The connector variable will determine which connector will be used for the
+        // query condition. We will change it as we come across new boolean values
+        // in the dynamic method strings, which could contain a number of these.
+        $connector = 'and';
+
+        $index = 0;
+
+        foreach ($segments as $segment) {
+            // If the segment is not a boolean connector, we can assume it is a column's name
+            // and we will add it to the query as a new constraint as a where clause, then
+            // we can keep iterating through the dynamic method string's segments again.
+            if ($segment !== 'And' && $segment !== 'Or') {
+                $this->addDynamic($segment, $connector, $parameters, $index);
+
+                $index++;
+            }
+
+            // Otherwise, we will store the connector so we know how the next where clause we
+            // find in the query should be connected to the previous ones, meaning we will
+            // have the proper boolean connector to connect the next where clause found.
+            else {
+                $connector = $segment;
+            }
+        }
+
+        return $this;
+    }
+
+    /**
+     * Add a single dynamic where clause statement to the query.
+     *
+     * @param  string  $segment
+     * @param  string  $connector
+     * @param  array  $parameters
+     * @param  int  $index
+     * @return void
+     */
+    protected function addDynamic($segment, $connector, $parameters, $index)
+    {
+        // Once we have parsed out the columns and formatted the boolean operators we
+        // are ready to add it to this query as a where clause just like any other
+        // clause on the query. Then we'll increment the parameter index values.
+        $bool = strtolower($connector);
+
+        $this->where(Str::snake($segment), '=', $parameters[$index], $bool);
+    }
+
+    /**
+     * Add a "where fulltext" clause to the query.
+     *
+     * @param  string|string[]  $columns
+     * @param  string  $value
+     * @param  string  $boolean
+     * @return $this
+     */
+    public function whereFullText($columns, $value, array $options = [], $boolean = 'and')
+    {
+        $type = 'Fulltext';
+
+        $columns = (array) $columns;
+
+        $this->wheres[] = compact('type', 'columns', 'value', 'options', 'boolean');
+
+        $this->addBinding($value);
+
+        return $this;
+    }
+
+    /**
+     * Add a "or where fulltext" clause to the query.
+     *
+     * @param  string|string[]  $columns
+     * @param  string  $value
+     * @return $this
+     */
+    public function orWhereFullText($columns, $value, array $options = [])
+    {
+        return $this->whereFulltext($columns, $value, $options, 'or');
+    }
+
+    /**
+     * Add a "group by" clause to the query.
+     *
+     * @param  array|string  ...$groups
+     * @return $this
+     */
+    public function groupBy(...$groups)
+    {
+        foreach ($groups as $group) {
+            $this->groups = array_merge(
+                (array) $this->groups,
+                Arr::wrap($group)
+            );
+        }
+
+        return $this;
+    }
+
+    /**
+     * Add a raw groupBy clause to the query.
+     *
+     * @param  string  $sql
+     * @param  array  $bindings
+     * @return $this
+     */
+    public function groupByRaw($sql, array $bindings = [])
+    {
+        $this->groups[] = new Expression($sql);
+
+        $this->addBinding($bindings, 'groupBy');
+
+        return $this;
+    }
+
+    /**
+     * Add a "having" clause to the query.
+     *
+     * @param  \Closure|string  $column
+     * @param  string|int|float|null  $operator
+     * @param  string|int|float|null  $value
+     * @param  string  $boolean
+     * @return $this
+     */
+    public function having($column, $operator = null, $value = null, $boolean = 'and')
+    {
+        $type = 'Basic';
+
+        // Here we will make some assumptions about the operator. If only 2 values are
+        // passed to the method, we will assume that the operator is an equals sign
+        // and keep going. Otherwise, we'll require the operator to be passed in.
+        [$value, $operator] = $this->prepareValueAndOperator(
+            $value, $operator, func_num_args() === 2
+        );
+
+        if ($column instanceof Closure && is_null($operator)) {
+            return $this->havingNested($column, $boolean);
+        }
+
+        // If the given operator is not found in the list of valid operators we will
+        // assume that the developer is just short-cutting the '=' operators and
+        // we will set the operators to '=' and set the values appropriately.
+        if ($this->invalidOperator($operator)) {
+            [$value, $operator] = [$operator, '='];
+        }
+
+        if ($this->isBitwiseOperator($operator)) {
+            $type = 'Bitwise';
+        }
+
+        $this->havings[] = compact('type', 'column', 'operator', 'value', 'boolean');
+
+        if (! $value instanceof Expression) {
+            $this->addBinding($this->flattenValue($value), 'having');
+        }
+
+        return $this;
+    }
+
+    /**
+     * Add an "or having" clause to the query.
+     *
+     * @param  \Closure|string  $column
+     * @param  string|int|float|null  $operator
+     * @param  string|int|float|null  $value
+     * @return $this
+     */
+    public function orHaving($column, $operator = null, $value = null)
+    {
+        [$value, $operator] = $this->prepareValueAndOperator(
+            $value, $operator, func_num_args() === 2
+        );
+
+        return $this->having($column, $operator, $value, 'or');
+    }
+
+    /**
+     * Add a nested having statement to the query.
+     *
+     * @param  \Closure  $callback
+     * @param  string  $boolean
+     * @return $this
+     */
+    public function havingNested(Closure $callback, $boolean = 'and')
+    {
+        $callback($query = $this->forNestedWhere());
+
+        return $this->addNestedHavingQuery($query, $boolean);
+    }
+
+    /**
+     * Add another query builder as a nested having to the query builder.
+     *
+     * @param  \Illuminate\Database\Query\Builder  $query
+     * @param  string  $boolean
+     * @return $this
+     */
+    public function addNestedHavingQuery($query, $boolean = 'and')
+    {
+        if (count($query->havings)) {
+            $type = 'Nested';
+
+            $this->havings[] = compact('type', 'query', 'boolean');
+
+            $this->addBinding($query->getRawBindings()['having'], 'having');
+        }
+
+        return $this;
+    }
+
+    /**
+     * Add a "having null" clause to the query.
+     *
+     * @param  string|array  $columns
+     * @param  string  $boolean
+     * @param  bool  $not
+     * @return $this
+     */
+    public function havingNull($columns, $boolean = 'and', $not = false)
+    {
+        $type = $not ? 'NotNull' : 'Null';
+
+        foreach (Arr::wrap($columns) as $column) {
+            $this->havings[] = compact('type', 'column', 'boolean');
+        }
+
+        return $this;
+    }
+
+    /**
+     * Add an "or having null" clause to the query.
+     *
+     * @param  string  $column
+     * @return $this
+     */
+    public function orHavingNull($column)
+    {
+        return $this->havingNull($column, 'or');
+    }
+
+    /**
+     * Add a "having not null" clause to the query.
+     *
+     * @param  string|array  $columns
+     * @param  string  $boolean
+     * @return $this
+     */
+    public function havingNotNull($columns, $boolean = 'and')
+    {
+        return $this->havingNull($columns, $boolean, true);
+    }
+
+    /**
+     * Add an "or having not null" clause to the query.
+     *
+     * @param  string  $column
+     * @return $this
+     */
+    public function orHavingNotNull($column)
+    {
+        return $this->havingNotNull($column, 'or');
+    }
+
+    /**
+     * Add a "having between " clause to the query.
+     *
+     * @param  string  $column
+     * @param  array  $values
+     * @param  string  $boolean
+     * @param  bool  $not
+     * @return $this
+     */
+    public function havingBetween($column, array $values, $boolean = 'and', $not = false)
+    {
+        $type = 'between';
+
+        $this->havings[] = compact('type', 'column', 'values', 'boolean', 'not');
+
+        $this->addBinding(array_slice($this->cleanBindings(Arr::flatten($values)), 0, 2), 'having');
+
+        return $this;
+    }
+
+    /**
+     * Add a raw having clause to the query.
+     *
+     * @param  string  $sql
+     * @param  array  $bindings
+     * @param  string  $boolean
+     * @return $this
+     */
+    public function havingRaw($sql, array $bindings = [], $boolean = 'and')
+    {
+        $type = 'Raw';
+
+        $this->havings[] = compact('type', 'sql', 'boolean');
+
+        $this->addBinding($bindings, 'having');
+
+        return $this;
+    }
+
+    /**
+     * Add a raw or having clause to the query.
+     *
+     * @param  string  $sql
+     * @param  array  $bindings
+     * @return $this
+     */
+    public function orHavingRaw($sql, array $bindings = [])
+    {
+        return $this->havingRaw($sql, $bindings, 'or');
+    }
+
+    /**
+     * Add an "order by" clause to the query.
+     *
+     * @param  \Closure|\Illuminate\Database\Query\Builder|\Illuminate\Database\Eloquent\Builder|\Illuminate\Database\Query\Expression|string  $column
+     * @param  string  $direction
+     * @return $this
+     *
+     * @throws \InvalidArgumentException
+     */
+    public function orderBy($column, $direction = 'asc')
+    {
+        if ($this->isQueryable($column)) {
+            [$query, $bindings] = $this->createSub($column);
+
+            $column = new Expression('('.$query.')');
+
+            $this->addBinding($bindings, $this->unions ? 'unionOrder' : 'order');
+        }
+
+        $direction = strtolower($direction);
+
+        if (! in_array($direction, ['asc', 'desc'], true)) {
+            throw new InvalidArgumentException('Order direction must be "asc" or "desc".');
+        }
+
+        $this->{$this->unions ? 'unionOrders' : 'orders'}[] = [
+            'column' => $column,
+            'direction' => $direction,
+        ];
+
+        return $this;
+    }
+
+    /**
+     * Add a descending "order by" clause to the query.
+     *
+     * @param  \Closure|\Illuminate\Database\Query\Builder|\Illuminate\Database\Eloquent\Builder|\Illuminate\Database\Query\Expression|string  $column
+     * @return $this
+     */
+    public function orderByDesc($column)
+    {
+        return $this->orderBy($column, 'desc');
+    }
+
+    /**
+     * Add an "order by" clause for a timestamp to the query.
+     *
+     * @param  \Closure|\Illuminate\Database\Query\Builder|\Illuminate\Database\Query\Expression|string  $column
+     * @return $this
+     */
+    public function latest($column = 'created_at')
+    {
+        return $this->orderBy($column, 'desc');
+    }
+
+    /**
+     * Add an "order by" clause for a timestamp to the query.
+     *
+     * @param  \Closure|\Illuminate\Database\Query\Builder|\Illuminate\Database\Query\Expression|string  $column
+     * @return $this
+     */
+    public function oldest($column = 'created_at')
+    {
+        return $this->orderBy($column, 'asc');
+    }
+
+    /**
+     * Put the query's results in random order.
+     *
+     * @param  string|int  $seed
+     * @return $this
+     */
+    public function inRandomOrder($seed = '')
+    {
+        return $this->orderByRaw($this->grammar->compileRandom($seed));
+    }
+
+    /**
+     * Add a raw "order by" clause to the query.
+     *
+     * @param  string  $sql
+     * @param  array  $bindings
+     * @return $this
+     */
+    public function orderByRaw($sql, $bindings = [])
+    {
+        $type = 'Raw';
+
+        $this->{$this->unions ? 'unionOrders' : 'orders'}[] = compact('type', 'sql');
+
+        $this->addBinding($bindings, $this->unions ? 'unionOrder' : 'order');
+
+        return $this;
+    }
+
+    /**
+     * Alias to set the "offset" value of the query.
+     *
+     * @param  int  $value
+     * @return $this
+     */
+    public function skip($value)
+    {
+        return $this->offset($value);
+    }
+
+    /**
+     * Set the "offset" value of the query.
+     *
+     * @param  int  $value
+     * @return $this
+     */
+    public function offset($value)
+    {
+        $property = $this->unions ? 'unionOffset' : 'offset';
+
+        $this->$property = max(0, (int) $value);
+
+        return $this;
+    }
+
+    /**
+     * Alias to set the "limit" value of the query.
+     *
+     * @param  int  $value
+     * @return $this
+     */
+    public function take($value)
+    {
+        return $this->limit($value);
+    }
+
+    /**
+     * Set the "limit" value of the query.
+     *
+     * @param  int  $value
+     * @return $this
+     */
+    public function limit($value)
+    {
+        $property = $this->unions ? 'unionLimit' : 'limit';
+
+        if ($value >= 0) {
+            $this->$property = ! is_null($value) ? (int) $value : null;
+        }
+
+        return $this;
+    }
+
+    /**
+     * Set the limit and offset for a given page.
+     *
+     * @param  int  $page
+     * @param  int  $perPage
+     * @return $this
+     */
+    public function forPage($page, $perPage = 15)
+    {
+        return $this->offset(($page - 1) * $perPage)->limit($perPage);
+    }
+
+    /**
+     * Constrain the query to the previous "page" of results before a given ID.
+     *
+     * @param  int  $perPage
+     * @param  int|null  $lastId
+     * @param  string  $column
+     * @return $this
+     */
+    public function forPageBeforeId($perPage = 15, $lastId = 0, $column = 'id')
+    {
+        $this->orders = $this->removeExistingOrdersFor($column);
+
+        if (! is_null($lastId)) {
+            $this->where($column, '<', $lastId);
+        }
+
+        return $this->orderBy($column, 'desc')
+                    ->limit($perPage);
+    }
+
+    /**
+     * Constrain the query to the next "page" of results after a given ID.
+     *
+     * @param  int  $perPage
+     * @param  int|null  $lastId
+     * @param  string  $column
+     * @return $this
+     */
+    public function forPageAfterId($perPage = 15, $lastId = 0, $column = 'id')
+    {
+        $this->orders = $this->removeExistingOrdersFor($column);
+
+        if (! is_null($lastId)) {
+            $this->where($column, '>', $lastId);
+        }
+
+        return $this->orderBy($column, 'asc')
+                    ->limit($perPage);
+    }
+
+    /**
+     * Remove all existing orders and optionally add a new order.
+     *
+     * @param  \Closure|\Illuminate\Database\Query\Builder|\Illuminate\Database\Query\Expression|string|null  $column
+     * @param  string  $direction
+     * @return $this
+     */
+    public function reorder($column = null, $direction = 'asc')
+    {
+        $this->orders = null;
+        $this->unionOrders = null;
+        $this->bindings['order'] = [];
+        $this->bindings['unionOrder'] = [];
+
+        if ($column) {
+            return $this->orderBy($column, $direction);
+        }
+
+        return $this;
+    }
+
+    /**
+     * Get an array with all orders with a given column removed.
+     *
+     * @param  string  $column
+     * @return array
+     */
+    protected function removeExistingOrdersFor($column)
+    {
+        return Collection::make($this->orders)
+                    ->reject(function ($order) use ($column) {
+                        return isset($order['column'])
+                               ? $order['column'] === $column : false;
+                    })->values()->all();
+    }
+
+    /**
+     * Add a union statement to the query.
+     *
+     * @param  \Closure|\Illuminate\Database\Query\Builder|\Illuminate\Database\Eloquent\Builder  $query
+     * @param  bool  $all
+     * @return $this
+     */
+    public function union($query, $all = false)
+    {
+        if ($query instanceof Closure) {
+            $query($query = $this->newQuery());
+        }
+
+        $this->unions[] = compact('query', 'all');
+
+        $this->addBinding($query->getBindings(), 'union');
+
+        return $this;
+    }
+
+    /**
+     * Add a union all statement to the query.
+     *
+     * @param  \Closure|\Illuminate\Database\Query\Builder|\Illuminate\Database\Eloquent\Builder  $query
+     * @return $this
+     */
+    public function unionAll($query)
+    {
+        return $this->union($query, true);
+    }
+
+    /**
+     * Lock the selected rows in the table.
+     *
+     * @param  string|bool  $value
+     * @return $this
+     */
+    public function lock($value = true)
+    {
+        $this->lock = $value;
+
+        if (! is_null($this->lock)) {
+            $this->useWritePdo();
+        }
+
+        return $this;
+    }
+
+    /**
+     * Lock the selected rows in the table for updating.
+     *
+     * @return $this
+     */
+    public function lockForUpdate()
+    {
+        return $this->lock(true);
+    }
+
+    /**
+     * Share lock the selected rows in the table.
+     *
+     * @return $this
+     */
+    public function sharedLock()
+    {
+        return $this->lock(false);
+    }
+
+    /**
+     * Register a closure to be invoked before the query is executed.
+     *
+     * @param  callable  $callback
+     * @return $this
+     */
+    public function beforeQuery(callable $callback)
+    {
+        $this->beforeQueryCallbacks[] = $callback;
+
+        return $this;
+    }
+
+    /**
+     * Invoke the "before query" modification callbacks.
+     *
+     * @return void
+     */
+    public function applyBeforeQueryCallbacks()
+    {
+        foreach ($this->beforeQueryCallbacks as $callback) {
+            $callback($this);
+        }
+
+        $this->beforeQueryCallbacks = [];
+    }
+
+    /**
+     * Get the SQL representation of the query.
+     *
+     * @return string
+     */
+    public function toSql()
+    {
+        $this->applyBeforeQueryCallbacks();
+
+        return $this->grammar->compileSelect($this);
+    }
+
+    /**
+     * Execute a query for a single record by ID.
+     *
+     * @param  int|string  $id
+     * @param  array|string  $columns
+     * @return mixed|static
+     */
+    public function find($id, $columns = ['*'])
+    {
+        return $this->where('id', '=', $id)->first($columns);
+    }
+
+    /**
+     * Execute a query for a single record by ID or call a callback.
+     *
+     * @param  mixed  $id
+     * @param  \Closure|array|string  $columns
+     * @param  \Closure|null  $callback
+     * @return mixed|static
+     */
+    public function findOr($id, $columns = ['*'], Closure $callback = null)
+    {
+        if ($columns instanceof Closure) {
+            $callback = $columns;
+
+            $columns = ['*'];
+        }
+
+        if (! is_null($data = $this->find($id, $columns))) {
+            return $data;
+        }
+
+        return $callback();
+    }
+
+    /**
+     * Get a single column's value from the first result of a query.
+     *
+     * @param  string  $column
+     * @return mixed
+     */
+    public function value($column)
+    {
+        $result = (array) $this->first([$column]);
+
+        return count($result) > 0 ? reset($result) : null;
+    }
+
+    /**
+     * Get a single expression value from the first result of a query.
+     *
+     * @param  string  $expression
+     * @param  array  $bindings
+     * @return mixed
+     */
+    public function rawValue(string $expression, array $bindings = [])
+    {
+        $result = (array) $this->selectRaw($expression, $bindings)->first();
+
+        return count($result) > 0 ? reset($result) : null;
+    }
+
+    /**
+     * Get a single column's value from the first result of a query if it's the sole matching record.
+     *
+     * @param  string  $column
+     * @return mixed
+     *
+     * @throws \Illuminate\Database\RecordsNotFoundException
+     * @throws \Illuminate\Database\MultipleRecordsFoundException
+     */
+    public function soleValue($column)
+    {
+        $result = (array) $this->sole([$column]);
+
+        return reset($result);
+    }
+
+    /**
+     * Execute the query as a "select" statement.
+     *
+     * @param  array|string  $columns
+     * @return \Illuminate\Support\Collection
+     */
+    public function get($columns = ['*'])
+    {
+        return collect($this->onceWithColumns(Arr::wrap($columns), function () {
+            return $this->processor->processSelect($this, $this->runSelect());
+        }));
+    }
+
+    /**
+     * Run the query as a "select" statement against the connection.
+     *
+     * @return array
+     */
+    protected function runSelect()
+    {
+        return $this->connection->select(
+            $this->toSql(), $this->getBindings(), ! $this->useWritePdo
+        );
+    }
+
+    /**
+     * Paginate the given query into a simple paginator.
+     *
+     * @param  int|\Closure  $perPage
+     * @param  array|string  $columns
+     * @param  string  $pageName
+     * @param  int|null  $page
+     * @return \Illuminate\Contracts\Pagination\LengthAwarePaginator
+     */
+    public function paginate($perPage = 15, $columns = ['*'], $pageName = 'page', $page = null)
+    {
+        $page = $page ?: Paginator::resolveCurrentPage($pageName);
+
+        $total = $this->getCountForPagination();
+
+        $perPage = $perPage instanceof Closure ? $perPage($total) : $perPage;
+
+        $results = $total ? $this->forPage($page, $perPage)->get($columns) : collect();
+
+        return $this->paginator($results, $total, $perPage, $page, [
+            'path' => Paginator::resolveCurrentPath(),
+            'pageName' => $pageName,
+        ]);
+    }
+
+    /**
+     * Get a paginator only supporting simple next and previous links.
+     *
+     * This is more efficient on larger data-sets, etc.
+     *
+     * @param  int  $perPage
+     * @param  array|string  $columns
+     * @param  string  $pageName
+     * @param  int|null  $page
+     * @return \Illuminate\Contracts\Pagination\Paginator
+     */
+    public function simplePaginate($perPage = 15, $columns = ['*'], $pageName = 'page', $page = null)
+    {
+        $page = $page ?: Paginator::resolveCurrentPage($pageName);
+
+        $this->offset(($page - 1) * $perPage)->limit($perPage + 1);
+
+        return $this->simplePaginator($this->get($columns), $perPage, $page, [
+            'path' => Paginator::resolveCurrentPath(),
+            'pageName' => $pageName,
+        ]);
+    }
+
+    /**
+     * Get a paginator only supporting simple next and previous links.
+     *
+     * This is more efficient on larger data-sets, etc.
+     *
+     * @param  int|null  $perPage
+     * @param  array|string  $columns
+     * @param  string  $cursorName
+     * @param  \Illuminate\Pagination\Cursor|string|null  $cursor
+     * @return \Illuminate\Contracts\Pagination\CursorPaginator
+     */
+    public function cursorPaginate($perPage = 15, $columns = ['*'], $cursorName = 'cursor', $cursor = null)
+    {
+        return $this->paginateUsingCursor($perPage, $columns, $cursorName, $cursor);
+    }
+
+    /**
+     * Ensure the proper order by required for cursor pagination.
+     *
+     * @param  bool  $shouldReverse
+     * @return \Illuminate\Support\Collection
+     */
+    protected function ensureOrderForCursorPagination($shouldReverse = false)
+    {
+        $this->enforceOrderBy();
+
+        return collect($this->orders ?? $this->unionOrders ?? [])->filter(function ($order) {
+            return Arr::has($order, 'direction');
+        })->when($shouldReverse, function (Collection $orders) {
+            return $orders->map(function ($order) {
+                $order['direction'] = $order['direction'] === 'asc' ? 'desc' : 'asc';
+
+                return $order;
+            });
+        })->values();
+    }
+
+    /**
+     * Get the count of the total records for the paginator.
+     *
+     * @param  array  $columns
+     * @return int
+     */
+    public function getCountForPagination($columns = ['*'])
+    {
+        $results = $this->runPaginationCountQuery($columns);
+
+        // Once we have run the pagination count query, we will get the resulting count and
+        // take into account what type of query it was. When there is a group by we will
+        // just return the count of the entire results set since that will be correct.
+        if (! isset($results[0])) {
+            return 0;
+        } elseif (is_object($results[0])) {
+            return (int) $results[0]->aggregate;
+        }
+
+        return (int) array_change_key_case((array) $results[0])['aggregate'];
+    }
+
+    /**
+     * Run a pagination count query.
+     *
+     * @param  array  $columns
+     * @return array
+     */
+    protected function runPaginationCountQuery($columns = ['*'])
+    {
+        if ($this->groups || $this->havings) {
+            $clone = $this->cloneForPaginationCount();
+
+            if (is_null($clone->columns) && ! empty($this->joins)) {
+                $clone->select($this->from.'.*');
+            }
+
+            return $this->newQuery()
+                ->from(new Expression('('.$clone->toSql().') as '.$this->grammar->wrap('aggregate_table')))
+                ->mergeBindings($clone)
+                ->setAggregate('count', $this->withoutSelectAliases($columns))
+                ->get()->all();
+        }
+
+        $without = $this->unions ? ['orders', 'limit', 'offset'] : ['columns', 'orders', 'limit', 'offset'];
+
+        return $this->cloneWithout($without)
+                    ->cloneWithoutBindings($this->unions ? ['order'] : ['select', 'order'])
+                    ->setAggregate('count', $this->withoutSelectAliases($columns))
+                    ->get()->all();
+    }
+
+    /**
+     * Clone the existing query instance for usage in a pagination subquery.
+     *
+     * @return self
+     */
+    protected function cloneForPaginationCount()
+    {
+        return $this->cloneWithout(['orders', 'limit', 'offset'])
+                    ->cloneWithoutBindings(['order']);
+    }
+
+    /**
+     * Remove the column aliases since they will break count queries.
+     *
+     * @param  array  $columns
+     * @return array
+     */
+    protected function withoutSelectAliases(array $columns)
+    {
+        return array_map(function ($column) {
+            return is_string($column) && ($aliasPosition = stripos($column, ' as ')) !== false
+                    ? substr($column, 0, $aliasPosition) : $column;
+        }, $columns);
+    }
+
+    /**
+     * Get a lazy collection for the given query.
+     *
+     * @return \Illuminate\Support\LazyCollection
+     */
+    public function cursor()
+    {
+        if (is_null($this->columns)) {
+            $this->columns = ['*'];
+        }
+
+        return new LazyCollection(function () {
+            yield from $this->connection->cursor(
+                $this->toSql(), $this->getBindings(), ! $this->useWritePdo
+            );
+        });
+    }
+
+    /**
+     * Throw an exception if the query doesn't have an orderBy clause.
+     *
+     * @return void
+     *
+     * @throws \RuntimeException
+     */
+    protected function enforceOrderBy()
+    {
+        if (empty($this->orders) && empty($this->unionOrders)) {
+            throw new RuntimeException('You must specify an orderBy clause when using this function.');
+        }
+    }
+
+    /**
+     * Get a collection instance containing the values of a given column.
+     *
+     * @param  string  $column
+     * @param  string|null  $key
+     * @return \Illuminate\Support\Collection
+     */
+    public function pluck($column, $key = null)
+    {
+        // First, we will need to select the results of the query accounting for the
+        // given columns / key. Once we have the results, we will be able to take
+        // the results and get the exact data that was requested for the query.
+        $queryResult = $this->onceWithColumns(
+            is_null($key) ? [$column] : [$column, $key],
+            function () {
+                return $this->processor->processSelect(
+                    $this, $this->runSelect()
+                );
+            }
+        );
+
+        if (empty($queryResult)) {
+            return collect();
+        }
+
+        // If the columns are qualified with a table or have an alias, we cannot use
+        // those directly in the "pluck" operations since the results from the DB
+        // are only keyed by the column itself. We'll strip the table out here.
+        $column = $this->stripTableForPluck($column);
+
+        $key = $this->stripTableForPluck($key);
+
+        return is_array($queryResult[0])
+                    ? $this->pluckFromArrayColumn($queryResult, $column, $key)
+                    : $this->pluckFromObjectColumn($queryResult, $column, $key);
+    }
+
+    /**
+     * Strip off the table name or alias from a column identifier.
+     *
+     * @param  string  $column
+     * @return string|null
+     */
+    protected function stripTableForPluck($column)
+    {
+        if (is_null($column)) {
+            return $column;
+        }
+
+        $separator = str_contains(strtolower($column), ' as ') ? ' as ' : '\.';
+
+        return last(preg_split('~'.$separator.'~i', $column));
+    }
+
+    /**
+     * Retrieve column values from rows represented as objects.
+     *
+     * @param  array  $queryResult
+     * @param  string  $column
+     * @param  string  $key
+     * @return \Illuminate\Support\Collection
+     */
+    protected function pluckFromObjectColumn($queryResult, $column, $key)
+    {
+        $results = [];
+
+        if (is_null($key)) {
+            foreach ($queryResult as $row) {
+                $results[] = $row->$column;
+            }
+        } else {
+            foreach ($queryResult as $row) {
+                $results[$row->$key] = $row->$column;
+            }
+        }
+
+        return collect($results);
+    }
+
+    /**
+     * Retrieve column values from rows represented as arrays.
+     *
+     * @param  array  $queryResult
+     * @param  string  $column
+     * @param  string  $key
+     * @return \Illuminate\Support\Collection
+     */
+    protected function pluckFromArrayColumn($queryResult, $column, $key)
+    {
+        $results = [];
+
+        if (is_null($key)) {
+            foreach ($queryResult as $row) {
+                $results[] = $row[$column];
+            }
+        } else {
+            foreach ($queryResult as $row) {
+                $results[$row[$key]] = $row[$column];
+            }
+        }
+
+        return collect($results);
+    }
+
+    /**
+     * Concatenate values of a given column as a string.
+     *
+     * @param  string  $column
+     * @param  string  $glue
+     * @return string
+     */
+    public function implode($column, $glue = '')
+    {
+        return $this->pluck($column)->implode($glue);
+    }
+
+    /**
+     * Determine if any rows exist for the current query.
+     *
+     * @return bool
+     */
+    public function exists()
+    {
+        $this->applyBeforeQueryCallbacks();
+
+        $results = $this->connection->select(
+            $this->grammar->compileExists($this), $this->getBindings(), ! $this->useWritePdo
+        );
+
+        // If the results have rows, we will get the row and see if the exists column is a
+        // boolean true. If there are no results for this query we will return false as
+        // there are no rows for this query at all, and we can return that info here.
+        if (isset($results[0])) {
+            $results = (array) $results[0];
+
+            return (bool) $results['exists'];
+        }
+
+        return false;
+    }
+
+    /**
+     * Determine if no rows exist for the current query.
+     *
+     * @return bool
+     */
+    public function doesntExist()
+    {
+        return ! $this->exists();
+    }
+
+    /**
+     * Execute the given callback if no rows exist for the current query.
+     *
+     * @param  \Closure  $callback
+     * @return mixed
+     */
+    public function existsOr(Closure $callback)
+    {
+        return $this->exists() ? true : $callback();
+    }
+
+    /**
+     * Execute the given callback if rows exist for the current query.
+     *
+     * @param  \Closure  $callback
+     * @return mixed
+     */
+    public function doesntExistOr(Closure $callback)
+    {
+        return $this->doesntExist() ? true : $callback();
+    }
+
+    /**
+     * Retrieve the "count" result of the query.
+     *
+     * @param  string  $columns
+     * @return int
+     */
+    public function count($columns = '*')
+    {
+        return (int) $this->aggregate(__FUNCTION__, Arr::wrap($columns));
+    }
+
+    /**
+     * Retrieve the minimum value of a given column.
+     *
+     * @param  string  $column
+     * @return mixed
+     */
+    public function min($column)
+    {
+        return $this->aggregate(__FUNCTION__, [$column]);
+    }
+
+    /**
+     * Retrieve the maximum value of a given column.
+     *
+     * @param  string  $column
+     * @return mixed
+     */
+    public function max($column)
+    {
+        return $this->aggregate(__FUNCTION__, [$column]);
+    }
+
+    /**
+     * Retrieve the sum of the values of a given column.
+     *
+     * @param  string  $column
+     * @return mixed
+     */
+    public function sum($column)
+    {
+        $result = $this->aggregate(__FUNCTION__, [$column]);
+
+        return $result ?: 0;
+    }
+
+    /**
+     * Retrieve the average of the values of a given column.
+     *
+     * @param  string  $column
+     * @return mixed
+     */
+    public function avg($column)
+    {
+        return $this->aggregate(__FUNCTION__, [$column]);
+    }
+
+    /**
+     * Alias for the "avg" method.
+     *
+     * @param  string  $column
+     * @return mixed
+     */
+    public function average($column)
+    {
+        return $this->avg($column);
+    }
+
+    /**
+     * Execute an aggregate function on the database.
+     *
+     * @param  string  $function
+     * @param  array  $columns
+     * @return mixed
+     */
+    public function aggregate($function, $columns = ['*'])
+    {
+        $results = $this->cloneWithout($this->unions || $this->havings ? [] : ['columns'])
+                        ->cloneWithoutBindings($this->unions || $this->havings ? [] : ['select'])
+                        ->setAggregate($function, $columns)
+                        ->get($columns);
+
+        if (! $results->isEmpty()) {
+            return array_change_key_case((array) $results[0])['aggregate'];
+        }
+    }
+
+    /**
+     * Execute a numeric aggregate function on the database.
+     *
+     * @param  string  $function
+     * @param  array  $columns
+     * @return float|int
+     */
+    public function numericAggregate($function, $columns = ['*'])
+    {
+        $result = $this->aggregate($function, $columns);
+
+        // If there is no result, we can obviously just return 0 here. Next, we will check
+        // if the result is an integer or float. If it is already one of these two data
+        // types we can just return the result as-is, otherwise we will convert this.
+        if (! $result) {
+            return 0;
+        }
+
+        if (is_int($result) || is_float($result)) {
+            return $result;
+        }
+
+        // If the result doesn't contain a decimal place, we will assume it is an int then
+        // cast it to one. When it does we will cast it to a float since it needs to be
+        // cast to the expected data type for the developers out of pure convenience.
+        return ! str_contains((string) $result, '.')
+                ? (int) $result : (float) $result;
+    }
+
+    /**
+     * Set the aggregate property without running the query.
+     *
+     * @param  string  $function
+     * @param  array  $columns
+     * @return $this
+     */
+    protected function setAggregate($function, $columns)
+    {
+        $this->aggregate = compact('function', 'columns');
+
+        if (empty($this->groups)) {
+            $this->orders = null;
+
+            $this->bindings['order'] = [];
+        }
+
+        return $this;
+    }
+
+    /**
+     * Execute the given callback while selecting the given columns.
+     *
+     * After running the callback, the columns are reset to the original value.
+     *
+     * @param  array  $columns
+     * @param  callable  $callback
+     * @return mixed
+     */
+    protected function onceWithColumns($columns, $callback)
+    {
+        $original = $this->columns;
+
+        if (is_null($original)) {
+            $this->columns = $columns;
+        }
+
+        $result = $callback();
+
+        $this->columns = $original;
+
+        return $result;
+    }
+
+    /**
+     * Insert new records into the database.
+     *
+     * @param  array  $values
+     * @return bool
+     */
+    public function insert(array $values)
+    {
+        // Since every insert gets treated like a batch insert, we will make sure the
+        // bindings are structured in a way that is convenient when building these
+        // inserts statements by verifying these elements are actually an array.
+        if (empty($values)) {
+            return true;
+        }
+
+        if (! is_array(reset($values))) {
+            $values = [$values];
+        }
+
+        // Here, we will sort the insert keys for every record so that each insert is
+        // in the same order for the record. We need to make sure this is the case
+        // so there are not any errors or problems when inserting these records.
+        else {
+            foreach ($values as $key => $value) {
+                ksort($value);
+
+                $values[$key] = $value;
+            }
+        }
+
+        $this->applyBeforeQueryCallbacks();
+
+        // Finally, we will run this query against the database connection and return
+        // the results. We will need to also flatten these bindings before running
+        // the query so they are all in one huge, flattened array for execution.
+        return $this->connection->insert(
+            $this->grammar->compileInsert($this, $values),
+            $this->cleanBindings(Arr::flatten($values, 1))
+        );
+    }
+
+    /**
+     * Insert new records into the database while ignoring errors.
+     *
+     * @param  array  $values
+     * @return int
+     */
+    public function insertOrIgnore(array $values)
+    {
+        if (empty($values)) {
+            return 0;
+        }
+
+        if (! is_array(reset($values))) {
+            $values = [$values];
+        } else {
+            foreach ($values as $key => $value) {
+                ksort($value);
+                $values[$key] = $value;
+            }
+        }
+
+        $this->applyBeforeQueryCallbacks();
+
+        return $this->connection->affectingStatement(
+            $this->grammar->compileInsertOrIgnore($this, $values),
+            $this->cleanBindings(Arr::flatten($values, 1))
+        );
+    }
+
+    /**
+     * Insert a new record and get the value of the primary key.
+     *
+     * @param  array  $values
+     * @param  string|null  $sequence
+     * @return int
+     */
+    public function insertGetId(array $values, $sequence = null)
+    {
+        $this->applyBeforeQueryCallbacks();
+
+        $sql = $this->grammar->compileInsertGetId($this, $values, $sequence);
+
+        $values = $this->cleanBindings($values);
+
+        return $this->processor->processInsertGetId($this, $sql, $values, $sequence);
+    }
+
+    /**
+     * Insert new records into the table using a subquery.
+     *
+     * @param  array  $columns
+     * @param  \Closure|\Illuminate\Database\Query\Builder|\Illuminate\Database\Eloquent\Builder|string  $query
+     * @return int
+     */
+    public function insertUsing(array $columns, $query)
+    {
+        $this->applyBeforeQueryCallbacks();
+
+        [$sql, $bindings] = $this->createSub($query);
+
+        return $this->connection->affectingStatement(
+            $this->grammar->compileInsertUsing($this, $columns, $sql),
+            $this->cleanBindings($bindings)
+        );
+    }
+
+    /**
+     * Update records in the database.
+     *
+     * @param  array  $values
+     * @return int
+     */
+    public function update(array $values)
+    {
+        $this->applyBeforeQueryCallbacks();
+
+        $sql = $this->grammar->compileUpdate($this, $values);
+
+        return $this->connection->update($sql, $this->cleanBindings(
+            $this->grammar->prepareBindingsForUpdate($this->bindings, $values)
+        ));
+    }
+
+    /**
+     * Update records in a PostgreSQL database using the update from syntax.
+     *
+     * @param  array  $values
+     * @return int
+     */
+    public function updateFrom(array $values)
+    {
+        if (! method_exists($this->grammar, 'compileUpdateFrom')) {
+            throw new LogicException('This database engine does not support the updateFrom method.');
+        }
+
+        $this->applyBeforeQueryCallbacks();
+
+        $sql = $this->grammar->compileUpdateFrom($this, $values);
+
+        return $this->connection->update($sql, $this->cleanBindings(
+            $this->grammar->prepareBindingsForUpdateFrom($this->bindings, $values)
+        ));
+    }
+
+    /**
+     * Insert or update a record matching the attributes, and fill it with values.
+     *
+     * @param  array  $attributes
+     * @param  array  $values
+     * @return bool
+     */
+    public function updateOrInsert(array $attributes, array $values = [])
+    {
+        if (! $this->where($attributes)->exists()) {
+            return $this->insert(array_merge($attributes, $values));
+        }
+
+        if (empty($values)) {
+            return true;
+        }
+
+        return (bool) $this->limit(1)->update($values);
+    }
+
+    /**
+     * Insert new records or update the existing ones.
+     *
+     * @param  array  $values
+     * @param  array|string  $uniqueBy
+     * @param  array|null  $update
+     * @return int
+     */
+    public function upsert(array $values, $uniqueBy, $update = null)
+    {
+        if (empty($values)) {
+            return 0;
+        } elseif ($update === []) {
+            return (int) $this->insert($values);
+        }
+
+        if (! is_array(reset($values))) {
+            $values = [$values];
+        } else {
+            foreach ($values as $key => $value) {
+                ksort($value);
+
+                $values[$key] = $value;
+            }
+        }
+
+        if (is_null($update)) {
+            $update = array_keys(reset($values));
+        }
+
+        $this->applyBeforeQueryCallbacks();
+
+        $bindings = $this->cleanBindings(array_merge(
+            Arr::flatten($values, 1),
+            collect($update)->reject(function ($value, $key) {
+                return is_int($key);
+            })->all()
+        ));
+
+        return $this->connection->affectingStatement(
+            $this->grammar->compileUpsert($this, $values, (array) $uniqueBy, $update),
+            $bindings
+        );
+    }
+
+    /**
+     * Increment a column's value by a given amount.
+     *
+     * @param  string  $column
+     * @param  float|int  $amount
+     * @param  array  $extra
+     * @return int
+     *
+     * @throws \InvalidArgumentException
+     */
+    public function increment($column, $amount = 1, array $extra = [])
+    {
+        if (! is_numeric($amount)) {
+            throw new InvalidArgumentException('Non-numeric value passed to increment method.');
+        }
+
+        return $this->incrementEach([$column => $amount], $extra);
+    }
+
+    /**
+     * Increment the given column's values by the given amounts.
+     *
+     * @param  array  $columns
+     * @param  array  $extra
+     * @return int
+     *
+     * @throws \InvalidArgumentException
+     */
+    public function incrementEach(array $columns, array $extra = [])
+    {
+        foreach ($columns as $column => $amount) {
+            if (! is_numeric($amount)) {
+                throw new InvalidArgumentException("Non-numeric value passed as increment amount for column: '$column'.");
+            } elseif (! is_string($column)) {
+                throw new InvalidArgumentException('Non-associative array passed to incrementEach method.');
+            }
+
+            $columns[$column] = $this->raw("{$this->grammar->wrap($column)} + $amount");
+        }
+
+        return $this->update(array_merge($columns, $extra));
+    }
+
+    /**
+     * Decrement a column's value by a given amount.
+     *
+     * @param  string  $column
+     * @param  float|int  $amount
+     * @param  array  $extra
+     * @return int
+     *
+     * @throws \InvalidArgumentException
+     */
+    public function decrement($column, $amount = 1, array $extra = [])
+    {
+        if (! is_numeric($amount)) {
+            throw new InvalidArgumentException('Non-numeric value passed to decrement method.');
+        }
+
+        return $this->decrementEach([$column => $amount], $extra);
+    }
+
+    /**
+     * Decrement the given column's values by the given amounts.
+     *
+     * @param  array  $columns
+     * @param  array  $extra
+     * @return int
+     *
+     * @throws \InvalidArgumentException
+     */
+    public function decrementEach(array $columns, array $extra = [])
+    {
+        foreach ($columns as $column => $amount) {
+            if (! is_numeric($amount)) {
+                throw new InvalidArgumentException("Non-numeric value passed as decrement amount for column: '$column'.");
+            } elseif (! is_string($column)) {
+                throw new InvalidArgumentException('Non-associative array passed to decrementEach method.');
+            }
+
+            $columns[$column] = $this->raw("{$this->grammar->wrap($column)} - $amount");
+        }
+
+        return $this->update(array_merge($columns, $extra));
+    }
+
+    /**
+     * Delete records from the database.
+     *
+     * @param  mixed  $id
+     * @return int
+     */
+    public function delete($id = null)
+    {
+        // If an ID is passed to the method, we will set the where clause to check the
+        // ID to let developers to simply and quickly remove a single row from this
+        // database without manually specifying the "where" clauses on the query.
+        if (! is_null($id)) {
+            $this->where($this->from.'.id', '=', $id);
+        }
+
+        $this->applyBeforeQueryCallbacks();
+
+        return $this->connection->delete(
+            $this->grammar->compileDelete($this), $this->cleanBindings(
+                $this->grammar->prepareBindingsForDelete($this->bindings)
+            )
+        );
+    }
+
+    /**
+     * Run a truncate statement on the table.
+     *
+     * @return void
+     */
+    public function truncate()
+    {
+        $this->applyBeforeQueryCallbacks();
+
+        foreach ($this->grammar->compileTruncate($this) as $sql => $bindings) {
+            $this->connection->statement($sql, $bindings);
+        }
+    }
+
+    /**
+     * Get a new instance of the query builder.
+     *
+     * @return \Illuminate\Database\Query\Builder
+     */
+    public function newQuery()
+    {
+        return new static($this->connection, $this->grammar, $this->processor);
+    }
+
+    /**
+     * Create a new query instance for a sub-query.
+     *
+     * @return \Illuminate\Database\Query\Builder
+     */
+    protected function forSubQuery()
+    {
+        return $this->newQuery();
+    }
+
+    /**
+     * Create a raw database expression.
+     *
+     * @param  mixed  $value
+     * @return \Illuminate\Database\Query\Expression
+     */
+    public function raw($value)
+    {
+        return $this->connection->raw($value);
+    }
+
+    /**
+     * Get the current query value bindings in a flattened array.
+     *
+     * @return array
+     */
+    public function getBindings()
+    {
+        return Arr::flatten($this->bindings);
+    }
+
+    /**
+     * Get the raw array of bindings.
+     *
+     * @return array
+     */
+    public function getRawBindings()
+    {
+        return $this->bindings;
+    }
+
+    /**
+     * Set the bindings on the query builder.
+     *
+     * @param  array  $bindings
+     * @param  string  $type
+     * @return $this
+     *
+     * @throws \InvalidArgumentException
+     */
+    public function setBindings(array $bindings, $type = 'where')
+    {
+        if (! array_key_exists($type, $this->bindings)) {
+            throw new InvalidArgumentException("Invalid binding type: {$type}.");
+        }
+
+        $this->bindings[$type] = $bindings;
+
+        return $this;
+    }
+
+    /**
+     * Add a binding to the query.
+     *
+     * @param  mixed  $value
+     * @param  string  $type
+     * @return $this
+     *
+     * @throws \InvalidArgumentException
+     */
+    public function addBinding($value, $type = 'where')
+    {
+        if (! array_key_exists($type, $this->bindings)) {
+            throw new InvalidArgumentException("Invalid binding type: {$type}.");
+        }
+
+        if (is_array($value)) {
+            $this->bindings[$type] = array_values(array_map(
+                [$this, 'castBinding'],
+                array_merge($this->bindings[$type], $value),
+            ));
+        } else {
+            $this->bindings[$type][] = $this->castBinding($value);
+        }
+
+        return $this;
+    }
+
+    /**
+     * Cast the given binding value.
+     *
+     * @param  mixed  $value
+     * @return mixed
+     */
+    public function castBinding($value)
+    {
+        if (function_exists('enum_exists') && $value instanceof BackedEnum) {
+            return $value->value;
+        }
+
+        return $value;
+    }
+
+    /**
+     * Merge an array of bindings into our bindings.
+     *
+     * @param  \Illuminate\Database\Query\Builder  $query
+     * @return $this
+     */
+    public function mergeBindings(self $query)
+    {
+        $this->bindings = array_merge_recursive($this->bindings, $query->bindings);
+
+        return $this;
+    }
+
+    /**
+     * Remove all of the expressions from a list of bindings.
+     *
+     * @param  array  $bindings
+     * @return array
+     */
+    public function cleanBindings(array $bindings)
+    {
+        return collect($bindings)
+                    ->reject(function ($binding) {
+                        return $binding instanceof Expression;
+                    })
+                    ->map([$this, 'castBinding'])
+                    ->values()
+                    ->all();
+    }
+
+    /**
+     * Get a scalar type value from an unknown type of input.
+     *
+     * @param  mixed  $value
+     * @return mixed
+     */
+    protected function flattenValue($value)
+    {
+        return is_array($value) ? head(Arr::flatten($value)) : $value;
+    }
+
+    /**
+     * Get the default key name of the table.
+     *
+     * @return string
+     */
+    protected function defaultKeyName()
+    {
+        return 'id';
+    }
+
+    /**
+     * Get the database connection instance.
+     *
+     * @return \Illuminate\Database\ConnectionInterface
+     */
+    public function getConnection()
+    {
+        return $this->connection;
+    }
+
+    /**
+     * Get the database query processor instance.
+     *
+     * @return \Illuminate\Database\Query\Processors\Processor
+     */
+    public function getProcessor()
+    {
+        return $this->processor;
+    }
+
+    /**
+     * Get the query grammar instance.
+     *
+     * @return \Illuminate\Database\Query\Grammars\Grammar
+     */
+    public function getGrammar()
+    {
+        return $this->grammar;
+    }
+
+    /**
+     * Use the "write" PDO connection when executing the query.
+     *
+     * @return $this
+     */
+    public function useWritePdo()
+    {
+        $this->useWritePdo = true;
+
+        return $this;
+    }
+
+    /**
+     * Determine if the value is a query builder instance or a Closure.
+     *
+     * @param  mixed  $value
+     * @return bool
+     */
+    protected function isQueryable($value)
+    {
+        return $value instanceof self ||
+               $value instanceof EloquentBuilder ||
+               $value instanceof Relation ||
+               $value instanceof Closure;
+    }
+
+    /**
+     * Clone the query.
+     *
+     * @return static
+     */
+    public function clone()
+    {
+        return clone $this;
+    }
+
+    /**
+     * Clone the query without the given properties.
+     *
+     * @param  array  $properties
+     * @return static
+     */
+    public function cloneWithout(array $properties)
+    {
+        return tap($this->clone(), function ($clone) use ($properties) {
+            foreach ($properties as $property) {
+                $clone->{$property} = null;
+            }
+        });
+    }
+
+    /**
+     * Clone the query without the given bindings.
+     *
+     * @param  array  $except
+     * @return static
+     */
+    public function cloneWithoutBindings(array $except)
+    {
+        return tap($this->clone(), function ($clone) use ($except) {
+            foreach ($except as $type) {
+                $clone->bindings[$type] = [];
+            }
+        });
+    }
+
+    /**
+     * Dump the current SQL and bindings.
+     *
+     * @return $this
+     */
+    public function dump()
+    {
+        dump($this->toSql(), $this->getBindings());
+
+        return $this;
+    }
+
+    /**
+     * Die and dump the current SQL and bindings.
+     *
+     * @return never
+     */
+    public function dd()
+    {
+        dd($this->toSql(), $this->getBindings());
+    }
+
+    /**
+     * Handle dynamic method calls into the method.
+     *
+     * @param  string  $method
+     * @param  array  $parameters
+     * @return mixed
+     *
+     * @throws \BadMethodCallException
+     */
+    public function __call($method, $parameters)
+    {
+        if (static::hasMacro($method)) {
+            return $this->macroCall($method, $parameters);
+        }
+
+        if (str_starts_with($method, 'where')) {
+            return $this->dynamicWhere($method, $parameters);
+        }
+
+        static::throwBadMethodCallException($method);
+    }
+}
diff --git a/vendor/illuminate/database/Query/Expression.php b/vendor/illuminate/database/Query/Expression.php
new file mode 100755
index 0000000..de69029
--- /dev/null
+++ b/vendor/illuminate/database/Query/Expression.php
@@ -0,0 +1,44 @@
+value = $value;
+    }
+
+    /**
+     * Get the value of the expression.
+     *
+     * @return mixed
+     */
+    public function getValue()
+    {
+        return $this->value;
+    }
+
+    /**
+     * Get the value of the expression.
+     *
+     * @return string
+     */
+    public function __toString()
+    {
+        return (string) $this->getValue();
+    }
+}
diff --git a/vendor/illuminate/database/Query/Grammars/Grammar.php b/vendor/illuminate/database/Query/Grammars/Grammar.php
new file mode 100755
index 0000000..cd3a0c0
--- /dev/null
+++ b/vendor/illuminate/database/Query/Grammars/Grammar.php
@@ -0,0 +1,1348 @@
+unions || $query->havings) && $query->aggregate) {
+            return $this->compileUnionAggregate($query);
+        }
+
+        // If the query does not have any columns set, we'll set the columns to the
+        // * character to just get all of the columns from the database. Then we
+        // can build the query and concatenate all the pieces together as one.
+        $original = $query->columns;
+
+        if (is_null($query->columns)) {
+            $query->columns = ['*'];
+        }
+
+        // To compile the query, we'll spin through each component of the query and
+        // see if that component exists. If it does we'll just call the compiler
+        // function for the component which is responsible for making the SQL.
+        $sql = trim($this->concatenate(
+            $this->compileComponents($query))
+        );
+
+        if ($query->unions) {
+            $sql = $this->wrapUnion($sql).' '.$this->compileUnions($query);
+        }
+
+        $query->columns = $original;
+
+        return $sql;
+    }
+
+    /**
+     * Compile the components necessary for a select clause.
+     *
+     * @param  \Illuminate\Database\Query\Builder  $query
+     * @return array
+     */
+    protected function compileComponents(Builder $query)
+    {
+        $sql = [];
+
+        foreach ($this->selectComponents as $component) {
+            if (isset($query->$component)) {
+                $method = 'compile'.ucfirst($component);
+
+                $sql[$component] = $this->$method($query, $query->$component);
+            }
+        }
+
+        return $sql;
+    }
+
+    /**
+     * Compile an aggregated select clause.
+     *
+     * @param  \Illuminate\Database\Query\Builder  $query
+     * @param  array  $aggregate
+     * @return string
+     */
+    protected function compileAggregate(Builder $query, $aggregate)
+    {
+        $column = $this->columnize($aggregate['columns']);
+
+        // If the query has a "distinct" constraint and we're not asking for all columns
+        // we need to prepend "distinct" onto the column name so that the query takes
+        // it into account when it performs the aggregating operations on the data.
+        if (is_array($query->distinct)) {
+            $column = 'distinct '.$this->columnize($query->distinct);
+        } elseif ($query->distinct && $column !== '*') {
+            $column = 'distinct '.$column;
+        }
+
+        return 'select '.$aggregate['function'].'('.$column.') as aggregate';
+    }
+
+    /**
+     * Compile the "select *" portion of the query.
+     *
+     * @param  \Illuminate\Database\Query\Builder  $query
+     * @param  array  $columns
+     * @return string|null
+     */
+    protected function compileColumns(Builder $query, $columns)
+    {
+        // If the query is actually performing an aggregating select, we will let that
+        // compiler handle the building of the select clauses, as it will need some
+        // more syntax that is best handled by that function to keep things neat.
+        if (! is_null($query->aggregate)) {
+            return;
+        }
+
+        if ($query->distinct) {
+            $select = 'select distinct ';
+        } else {
+            $select = 'select ';
+        }
+
+        return $select.$this->columnize($columns);
+    }
+
+    /**
+     * Compile the "from" portion of the query.
+     *
+     * @param  \Illuminate\Database\Query\Builder  $query
+     * @param  string  $table
+     * @return string
+     */
+    protected function compileFrom(Builder $query, $table)
+    {
+        return 'from '.$this->wrapTable($table);
+    }
+
+    /**
+     * Compile the "join" portions of the query.
+     *
+     * @param  \Illuminate\Database\Query\Builder  $query
+     * @param  array  $joins
+     * @return string
+     */
+    protected function compileJoins(Builder $query, $joins)
+    {
+        return collect($joins)->map(function ($join) use ($query) {
+            $table = $this->wrapTable($join->table);
+
+            $nestedJoins = is_null($join->joins) ? '' : ' '.$this->compileJoins($query, $join->joins);
+
+            $tableAndNestedJoins = is_null($join->joins) ? $table : '('.$table.$nestedJoins.')';
+
+            return trim("{$join->type} join {$tableAndNestedJoins} {$this->compileWheres($join)}");
+        })->implode(' ');
+    }
+
+    /**
+     * Compile the "where" portions of the query.
+     *
+     * @param  \Illuminate\Database\Query\Builder  $query
+     * @return string
+     */
+    public function compileWheres(Builder $query)
+    {
+        // Each type of where clause has its own compiler function, which is responsible
+        // for actually creating the where clauses SQL. This helps keep the code nice
+        // and maintainable since each clause has a very small method that it uses.
+        if (is_null($query->wheres)) {
+            return '';
+        }
+
+        // If we actually have some where clauses, we will strip off the first boolean
+        // operator, which is added by the query builders for convenience so we can
+        // avoid checking for the first clauses in each of the compilers methods.
+        if (count($sql = $this->compileWheresToArray($query)) > 0) {
+            return $this->concatenateWhereClauses($query, $sql);
+        }
+
+        return '';
+    }
+
+    /**
+     * Get an array of all the where clauses for the query.
+     *
+     * @param  \Illuminate\Database\Query\Builder  $query
+     * @return array
+     */
+    protected function compileWheresToArray($query)
+    {
+        return collect($query->wheres)->map(function ($where) use ($query) {
+            return $where['boolean'].' '.$this->{"where{$where['type']}"}($query, $where);
+        })->all();
+    }
+
+    /**
+     * Format the where clause statements into one string.
+     *
+     * @param  \Illuminate\Database\Query\Builder  $query
+     * @param  array  $sql
+     * @return string
+     */
+    protected function concatenateWhereClauses($query, $sql)
+    {
+        $conjunction = $query instanceof JoinClause ? 'on' : 'where';
+
+        return $conjunction.' '.$this->removeLeadingBoolean(implode(' ', $sql));
+    }
+
+    /**
+     * Compile a raw where clause.
+     *
+     * @param  \Illuminate\Database\Query\Builder  $query
+     * @param  array  $where
+     * @return string
+     */
+    protected function whereRaw(Builder $query, $where)
+    {
+        return $where['sql'];
+    }
+
+    /**
+     * Compile a basic where clause.
+     *
+     * @param  \Illuminate\Database\Query\Builder  $query
+     * @param  array  $where
+     * @return string
+     */
+    protected function whereBasic(Builder $query, $where)
+    {
+        $value = $this->parameter($where['value']);
+
+        $operator = str_replace('?', '??', $where['operator']);
+
+        return $this->wrap($where['column']).' '.$operator.' '.$value;
+    }
+
+    /**
+     * Compile a bitwise operator where clause.
+     *
+     * @param  \Illuminate\Database\Query\Builder  $query
+     * @param  array  $where
+     * @return string
+     */
+    protected function whereBitwise(Builder $query, $where)
+    {
+        return $this->whereBasic($query, $where);
+    }
+
+    /**
+     * Compile a "where in" clause.
+     *
+     * @param  \Illuminate\Database\Query\Builder  $query
+     * @param  array  $where
+     * @return string
+     */
+    protected function whereIn(Builder $query, $where)
+    {
+        if (! empty($where['values'])) {
+            return $this->wrap($where['column']).' in ('.$this->parameterize($where['values']).')';
+        }
+
+        return '0 = 1';
+    }
+
+    /**
+     * Compile a "where not in" clause.
+     *
+     * @param  \Illuminate\Database\Query\Builder  $query
+     * @param  array  $where
+     * @return string
+     */
+    protected function whereNotIn(Builder $query, $where)
+    {
+        if (! empty($where['values'])) {
+            return $this->wrap($where['column']).' not in ('.$this->parameterize($where['values']).')';
+        }
+
+        return '1 = 1';
+    }
+
+    /**
+     * Compile a "where not in raw" clause.
+     *
+     * For safety, whereIntegerInRaw ensures this method is only used with integer values.
+     *
+     * @param  \Illuminate\Database\Query\Builder  $query
+     * @param  array  $where
+     * @return string
+     */
+    protected function whereNotInRaw(Builder $query, $where)
+    {
+        if (! empty($where['values'])) {
+            return $this->wrap($where['column']).' not in ('.implode(', ', $where['values']).')';
+        }
+
+        return '1 = 1';
+    }
+
+    /**
+     * Compile a "where in raw" clause.
+     *
+     * For safety, whereIntegerInRaw ensures this method is only used with integer values.
+     *
+     * @param  \Illuminate\Database\Query\Builder  $query
+     * @param  array  $where
+     * @return string
+     */
+    protected function whereInRaw(Builder $query, $where)
+    {
+        if (! empty($where['values'])) {
+            return $this->wrap($where['column']).' in ('.implode(', ', $where['values']).')';
+        }
+
+        return '0 = 1';
+    }
+
+    /**
+     * Compile a "where null" clause.
+     *
+     * @param  \Illuminate\Database\Query\Builder  $query
+     * @param  array  $where
+     * @return string
+     */
+    protected function whereNull(Builder $query, $where)
+    {
+        return $this->wrap($where['column']).' is null';
+    }
+
+    /**
+     * Compile a "where not null" clause.
+     *
+     * @param  \Illuminate\Database\Query\Builder  $query
+     * @param  array  $where
+     * @return string
+     */
+    protected function whereNotNull(Builder $query, $where)
+    {
+        return $this->wrap($where['column']).' is not null';
+    }
+
+    /**
+     * Compile a "between" where clause.
+     *
+     * @param  \Illuminate\Database\Query\Builder  $query
+     * @param  array  $where
+     * @return string
+     */
+    protected function whereBetween(Builder $query, $where)
+    {
+        $between = $where['not'] ? 'not between' : 'between';
+
+        $min = $this->parameter(is_array($where['values']) ? reset($where['values']) : $where['values'][0]);
+
+        $max = $this->parameter(is_array($where['values']) ? end($where['values']) : $where['values'][1]);
+
+        return $this->wrap($where['column']).' '.$between.' '.$min.' and '.$max;
+    }
+
+    /**
+     * Compile a "between" where clause.
+     *
+     * @param  \Illuminate\Database\Query\Builder  $query
+     * @param  array  $where
+     * @return string
+     */
+    protected function whereBetweenColumns(Builder $query, $where)
+    {
+        $between = $where['not'] ? 'not between' : 'between';
+
+        $min = $this->wrap(is_array($where['values']) ? reset($where['values']) : $where['values'][0]);
+
+        $max = $this->wrap(is_array($where['values']) ? end($where['values']) : $where['values'][1]);
+
+        return $this->wrap($where['column']).' '.$between.' '.$min.' and '.$max;
+    }
+
+    /**
+     * Compile a "where date" clause.
+     *
+     * @param  \Illuminate\Database\Query\Builder  $query
+     * @param  array  $where
+     * @return string
+     */
+    protected function whereDate(Builder $query, $where)
+    {
+        return $this->dateBasedWhere('date', $query, $where);
+    }
+
+    /**
+     * Compile a "where time" clause.
+     *
+     * @param  \Illuminate\Database\Query\Builder  $query
+     * @param  array  $where
+     * @return string
+     */
+    protected function whereTime(Builder $query, $where)
+    {
+        return $this->dateBasedWhere('time', $query, $where);
+    }
+
+    /**
+     * Compile a "where day" clause.
+     *
+     * @param  \Illuminate\Database\Query\Builder  $query
+     * @param  array  $where
+     * @return string
+     */
+    protected function whereDay(Builder $query, $where)
+    {
+        return $this->dateBasedWhere('day', $query, $where);
+    }
+
+    /**
+     * Compile a "where month" clause.
+     *
+     * @param  \Illuminate\Database\Query\Builder  $query
+     * @param  array  $where
+     * @return string
+     */
+    protected function whereMonth(Builder $query, $where)
+    {
+        return $this->dateBasedWhere('month', $query, $where);
+    }
+
+    /**
+     * Compile a "where year" clause.
+     *
+     * @param  \Illuminate\Database\Query\Builder  $query
+     * @param  array  $where
+     * @return string
+     */
+    protected function whereYear(Builder $query, $where)
+    {
+        return $this->dateBasedWhere('year', $query, $where);
+    }
+
+    /**
+     * Compile a date based where clause.
+     *
+     * @param  string  $type
+     * @param  \Illuminate\Database\Query\Builder  $query
+     * @param  array  $where
+     * @return string
+     */
+    protected function dateBasedWhere($type, Builder $query, $where)
+    {
+        $value = $this->parameter($where['value']);
+
+        return $type.'('.$this->wrap($where['column']).') '.$where['operator'].' '.$value;
+    }
+
+    /**
+     * Compile a where clause comparing two columns.
+     *
+     * @param  \Illuminate\Database\Query\Builder  $query
+     * @param  array  $where
+     * @return string
+     */
+    protected function whereColumn(Builder $query, $where)
+    {
+        return $this->wrap($where['first']).' '.$where['operator'].' '.$this->wrap($where['second']);
+    }
+
+    /**
+     * Compile a nested where clause.
+     *
+     * @param  \Illuminate\Database\Query\Builder  $query
+     * @param  array  $where
+     * @return string
+     */
+    protected function whereNested(Builder $query, $where)
+    {
+        // Here we will calculate what portion of the string we need to remove. If this
+        // is a join clause query, we need to remove the "on" portion of the SQL and
+        // if it is a normal query we need to take the leading "where" of queries.
+        $offset = $query instanceof JoinClause ? 3 : 6;
+
+        return '('.substr($this->compileWheres($where['query']), $offset).')';
+    }
+
+    /**
+     * Compile a where condition with a sub-select.
+     *
+     * @param  \Illuminate\Database\Query\Builder  $query
+     * @param  array  $where
+     * @return string
+     */
+    protected function whereSub(Builder $query, $where)
+    {
+        $select = $this->compileSelect($where['query']);
+
+        return $this->wrap($where['column']).' '.$where['operator']." ($select)";
+    }
+
+    /**
+     * Compile a where exists clause.
+     *
+     * @param  \Illuminate\Database\Query\Builder  $query
+     * @param  array  $where
+     * @return string
+     */
+    protected function whereExists(Builder $query, $where)
+    {
+        return 'exists ('.$this->compileSelect($where['query']).')';
+    }
+
+    /**
+     * Compile a where exists clause.
+     *
+     * @param  \Illuminate\Database\Query\Builder  $query
+     * @param  array  $where
+     * @return string
+     */
+    protected function whereNotExists(Builder $query, $where)
+    {
+        return 'not exists ('.$this->compileSelect($where['query']).')';
+    }
+
+    /**
+     * Compile a where row values condition.
+     *
+     * @param  \Illuminate\Database\Query\Builder  $query
+     * @param  array  $where
+     * @return string
+     */
+    protected function whereRowValues(Builder $query, $where)
+    {
+        $columns = $this->columnize($where['columns']);
+
+        $values = $this->parameterize($where['values']);
+
+        return '('.$columns.') '.$where['operator'].' ('.$values.')';
+    }
+
+    /**
+     * Compile a "where JSON boolean" clause.
+     *
+     * @param  \Illuminate\Database\Query\Builder  $query
+     * @param  array  $where
+     * @return string
+     */
+    protected function whereJsonBoolean(Builder $query, $where)
+    {
+        $column = $this->wrapJsonBooleanSelector($where['column']);
+
+        $value = $this->wrapJsonBooleanValue(
+            $this->parameter($where['value'])
+        );
+
+        return $column.' '.$where['operator'].' '.$value;
+    }
+
+    /**
+     * Compile a "where JSON contains" clause.
+     *
+     * @param  \Illuminate\Database\Query\Builder  $query
+     * @param  array  $where
+     * @return string
+     */
+    protected function whereJsonContains(Builder $query, $where)
+    {
+        $not = $where['not'] ? 'not ' : '';
+
+        return $not.$this->compileJsonContains(
+            $where['column'],
+            $this->parameter($where['value'])
+        );
+    }
+
+    /**
+     * Compile a "JSON contains" statement into SQL.
+     *
+     * @param  string  $column
+     * @param  string  $value
+     * @return string
+     *
+     * @throws \RuntimeException
+     */
+    protected function compileJsonContains($column, $value)
+    {
+        throw new RuntimeException('This database engine does not support JSON contains operations.');
+    }
+
+    /**
+     * Prepare the binding for a "JSON contains" statement.
+     *
+     * @param  mixed  $binding
+     * @return string
+     */
+    public function prepareBindingForJsonContains($binding)
+    {
+        return json_encode($binding, JSON_UNESCAPED_UNICODE);
+    }
+
+    /**
+     * Compile a "where JSON contains key" clause.
+     *
+     * @param  \Illuminate\Database\Query\Builder  $query
+     * @param  array  $where
+     * @return string
+     */
+    protected function whereJsonContainsKey(Builder $query, $where)
+    {
+        $not = $where['not'] ? 'not ' : '';
+
+        return $not.$this->compileJsonContainsKey(
+            $where['column']
+        );
+    }
+
+    /**
+     * Compile a "JSON contains key" statement into SQL.
+     *
+     * @param  string  $column
+     * @return string
+     *
+     * @throws \RuntimeException
+     */
+    protected function compileJsonContainsKey($column)
+    {
+        throw new RuntimeException('This database engine does not support JSON contains key operations.');
+    }
+
+    /**
+     * Compile a "where JSON length" clause.
+     *
+     * @param  \Illuminate\Database\Query\Builder  $query
+     * @param  array  $where
+     * @return string
+     */
+    protected function whereJsonLength(Builder $query, $where)
+    {
+        return $this->compileJsonLength(
+            $where['column'],
+            $where['operator'],
+            $this->parameter($where['value'])
+        );
+    }
+
+    /**
+     * Compile a "JSON length" statement into SQL.
+     *
+     * @param  string  $column
+     * @param  string  $operator
+     * @param  string  $value
+     * @return string
+     *
+     * @throws \RuntimeException
+     */
+    protected function compileJsonLength($column, $operator, $value)
+    {
+        throw new RuntimeException('This database engine does not support JSON length operations.');
+    }
+
+    /**
+     * Compile a "JSON value cast" statement into SQL.
+     *
+     * @param  string  $value
+     * @return string
+     */
+    public function compileJsonValueCast($value)
+    {
+        return $value;
+    }
+
+    /**
+     * Compile a "where fulltext" clause.
+     *
+     * @param  \Illuminate\Database\Query\Builder  $query
+     * @param  array  $where
+     * @return string
+     */
+    public function whereFullText(Builder $query, $where)
+    {
+        throw new RuntimeException('This database engine does not support fulltext search operations.');
+    }
+
+    /**
+     * Compile the "group by" portions of the query.
+     *
+     * @param  \Illuminate\Database\Query\Builder  $query
+     * @param  array  $groups
+     * @return string
+     */
+    protected function compileGroups(Builder $query, $groups)
+    {
+        return 'group by '.$this->columnize($groups);
+    }
+
+    /**
+     * Compile the "having" portions of the query.
+     *
+     * @param  \Illuminate\Database\Query\Builder  $query
+     * @return string
+     */
+    protected function compileHavings(Builder $query)
+    {
+        return 'having '.$this->removeLeadingBoolean(collect($query->havings)->map(function ($having) {
+            return $having['boolean'].' '.$this->compileHaving($having);
+        })->implode(' '));
+    }
+
+    /**
+     * Compile a single having clause.
+     *
+     * @param  array  $having
+     * @return string
+     */
+    protected function compileHaving(array $having)
+    {
+        // If the having clause is "raw", we can just return the clause straight away
+        // without doing any more processing on it. Otherwise, we will compile the
+        // clause into SQL based on the components that make it up from builder.
+        if ($having['type'] === 'Raw') {
+            return $having['sql'];
+        } elseif ($having['type'] === 'between') {
+            return $this->compileHavingBetween($having);
+        } elseif ($having['type'] === 'Null') {
+            return $this->compileHavingNull($having);
+        } elseif ($having['type'] === 'NotNull') {
+            return $this->compileHavingNotNull($having);
+        } elseif ($having['type'] === 'bit') {
+            return $this->compileHavingBit($having);
+        } elseif ($having['type'] === 'Nested') {
+            return $this->compileNestedHavings($having);
+        }
+
+        return $this->compileBasicHaving($having);
+    }
+
+    /**
+     * Compile a basic having clause.
+     *
+     * @param  array  $having
+     * @return string
+     */
+    protected function compileBasicHaving($having)
+    {
+        $column = $this->wrap($having['column']);
+
+        $parameter = $this->parameter($having['value']);
+
+        return $column.' '.$having['operator'].' '.$parameter;
+    }
+
+    /**
+     * Compile a "between" having clause.
+     *
+     * @param  array  $having
+     * @return string
+     */
+    protected function compileHavingBetween($having)
+    {
+        $between = $having['not'] ? 'not between' : 'between';
+
+        $column = $this->wrap($having['column']);
+
+        $min = $this->parameter(head($having['values']));
+
+        $max = $this->parameter(last($having['values']));
+
+        return $column.' '.$between.' '.$min.' and '.$max;
+    }
+
+    /**
+     * Compile a having null clause.
+     *
+     * @param  array  $having
+     * @return string
+     */
+    protected function compileHavingNull($having)
+    {
+        $column = $this->wrap($having['column']);
+
+        return $column.' is null';
+    }
+
+    /**
+     * Compile a having not null clause.
+     *
+     * @param  array  $having
+     * @return string
+     */
+    protected function compileHavingNotNull($having)
+    {
+        $column = $this->wrap($having['column']);
+
+        return $column.' is not null';
+    }
+
+    /**
+     * Compile a having clause involving a bit operator.
+     *
+     * @param  array  $having
+     * @return string
+     */
+    protected function compileHavingBit($having)
+    {
+        $column = $this->wrap($having['column']);
+
+        $parameter = $this->parameter($having['value']);
+
+        return '('.$column.' '.$having['operator'].' '.$parameter.') != 0';
+    }
+
+    /**
+     * Compile a nested having clause.
+     *
+     * @param  array  $having
+     * @return string
+     */
+    protected function compileNestedHavings($having)
+    {
+        return '('.substr($this->compileHavings($having['query']), 7).')';
+    }
+
+    /**
+     * Compile the "order by" portions of the query.
+     *
+     * @param  \Illuminate\Database\Query\Builder  $query
+     * @param  array  $orders
+     * @return string
+     */
+    protected function compileOrders(Builder $query, $orders)
+    {
+        if (! empty($orders)) {
+            return 'order by '.implode(', ', $this->compileOrdersToArray($query, $orders));
+        }
+
+        return '';
+    }
+
+    /**
+     * Compile the query orders to an array.
+     *
+     * @param  \Illuminate\Database\Query\Builder  $query
+     * @param  array  $orders
+     * @return array
+     */
+    protected function compileOrdersToArray(Builder $query, $orders)
+    {
+        return array_map(function ($order) {
+            return $order['sql'] ?? $this->wrap($order['column']).' '.$order['direction'];
+        }, $orders);
+    }
+
+    /**
+     * Compile the random statement into SQL.
+     *
+     * @param  string|int  $seed
+     * @return string
+     */
+    public function compileRandom($seed)
+    {
+        return 'RANDOM()';
+    }
+
+    /**
+     * Compile the "limit" portions of the query.
+     *
+     * @param  \Illuminate\Database\Query\Builder  $query
+     * @param  int  $limit
+     * @return string
+     */
+    protected function compileLimit(Builder $query, $limit)
+    {
+        return 'limit '.(int) $limit;
+    }
+
+    /**
+     * Compile the "offset" portions of the query.
+     *
+     * @param  \Illuminate\Database\Query\Builder  $query
+     * @param  int  $offset
+     * @return string
+     */
+    protected function compileOffset(Builder $query, $offset)
+    {
+        return 'offset '.(int) $offset;
+    }
+
+    /**
+     * Compile the "union" queries attached to the main query.
+     *
+     * @param  \Illuminate\Database\Query\Builder  $query
+     * @return string
+     */
+    protected function compileUnions(Builder $query)
+    {
+        $sql = '';
+
+        foreach ($query->unions as $union) {
+            $sql .= $this->compileUnion($union);
+        }
+
+        if (! empty($query->unionOrders)) {
+            $sql .= ' '.$this->compileOrders($query, $query->unionOrders);
+        }
+
+        if (isset($query->unionLimit)) {
+            $sql .= ' '.$this->compileLimit($query, $query->unionLimit);
+        }
+
+        if (isset($query->unionOffset)) {
+            $sql .= ' '.$this->compileOffset($query, $query->unionOffset);
+        }
+
+        return ltrim($sql);
+    }
+
+    /**
+     * Compile a single union statement.
+     *
+     * @param  array  $union
+     * @return string
+     */
+    protected function compileUnion(array $union)
+    {
+        $conjunction = $union['all'] ? ' union all ' : ' union ';
+
+        return $conjunction.$this->wrapUnion($union['query']->toSql());
+    }
+
+    /**
+     * Wrap a union subquery in parentheses.
+     *
+     * @param  string  $sql
+     * @return string
+     */
+    protected function wrapUnion($sql)
+    {
+        return '('.$sql.')';
+    }
+
+    /**
+     * Compile a union aggregate query into SQL.
+     *
+     * @param  \Illuminate\Database\Query\Builder  $query
+     * @return string
+     */
+    protected function compileUnionAggregate(Builder $query)
+    {
+        $sql = $this->compileAggregate($query, $query->aggregate);
+
+        $query->aggregate = null;
+
+        return $sql.' from ('.$this->compileSelect($query).') as '.$this->wrapTable('temp_table');
+    }
+
+    /**
+     * Compile an exists statement into SQL.
+     *
+     * @param  \Illuminate\Database\Query\Builder  $query
+     * @return string
+     */
+    public function compileExists(Builder $query)
+    {
+        $select = $this->compileSelect($query);
+
+        return "select exists({$select}) as {$this->wrap('exists')}";
+    }
+
+    /**
+     * Compile an insert statement into SQL.
+     *
+     * @param  \Illuminate\Database\Query\Builder  $query
+     * @param  array  $values
+     * @return string
+     */
+    public function compileInsert(Builder $query, array $values)
+    {
+        // Essentially we will force every insert to be treated as a batch insert which
+        // simply makes creating the SQL easier for us since we can utilize the same
+        // basic routine regardless of an amount of records given to us to insert.
+        $table = $this->wrapTable($query->from);
+
+        if (empty($values)) {
+            return "insert into {$table} default values";
+        }
+
+        if (! is_array(reset($values))) {
+            $values = [$values];
+        }
+
+        $columns = $this->columnize(array_keys(reset($values)));
+
+        // We need to build a list of parameter place-holders of values that are bound
+        // to the query. Each insert should have the exact same number of parameter
+        // bindings so we will loop through the record and parameterize them all.
+        $parameters = collect($values)->map(function ($record) {
+            return '('.$this->parameterize($record).')';
+        })->implode(', ');
+
+        return "insert into $table ($columns) values $parameters";
+    }
+
+    /**
+     * Compile an insert ignore statement into SQL.
+     *
+     * @param  \Illuminate\Database\Query\Builder  $query
+     * @param  array  $values
+     * @return string
+     *
+     * @throws \RuntimeException
+     */
+    public function compileInsertOrIgnore(Builder $query, array $values)
+    {
+        throw new RuntimeException('This database engine does not support inserting while ignoring errors.');
+    }
+
+    /**
+     * Compile an insert and get ID statement into SQL.
+     *
+     * @param  \Illuminate\Database\Query\Builder  $query
+     * @param  array  $values
+     * @param  string  $sequence
+     * @return string
+     */
+    public function compileInsertGetId(Builder $query, $values, $sequence)
+    {
+        return $this->compileInsert($query, $values);
+    }
+
+    /**
+     * Compile an insert statement using a subquery into SQL.
+     *
+     * @param  \Illuminate\Database\Query\Builder  $query
+     * @param  array  $columns
+     * @param  string  $sql
+     * @return string
+     */
+    public function compileInsertUsing(Builder $query, array $columns, string $sql)
+    {
+        return "insert into {$this->wrapTable($query->from)} ({$this->columnize($columns)}) $sql";
+    }
+
+    /**
+     * Compile an update statement into SQL.
+     *
+     * @param  \Illuminate\Database\Query\Builder  $query
+     * @param  array  $values
+     * @return string
+     */
+    public function compileUpdate(Builder $query, array $values)
+    {
+        $table = $this->wrapTable($query->from);
+
+        $columns = $this->compileUpdateColumns($query, $values);
+
+        $where = $this->compileWheres($query);
+
+        return trim(
+            isset($query->joins)
+                ? $this->compileUpdateWithJoins($query, $table, $columns, $where)
+                : $this->compileUpdateWithoutJoins($query, $table, $columns, $where)
+        );
+    }
+
+    /**
+     * Compile the columns for an update statement.
+     *
+     * @param  \Illuminate\Database\Query\Builder  $query
+     * @param  array  $values
+     * @return string
+     */
+    protected function compileUpdateColumns(Builder $query, array $values)
+    {
+        return collect($values)->map(function ($value, $key) {
+            return $this->wrap($key).' = '.$this->parameter($value);
+        })->implode(', ');
+    }
+
+    /**
+     * Compile an update statement without joins into SQL.
+     *
+     * @param  \Illuminate\Database\Query\Builder  $query
+     * @param  string  $table
+     * @param  string  $columns
+     * @param  string  $where
+     * @return string
+     */
+    protected function compileUpdateWithoutJoins(Builder $query, $table, $columns, $where)
+    {
+        return "update {$table} set {$columns} {$where}";
+    }
+
+    /**
+     * Compile an update statement with joins into SQL.
+     *
+     * @param  \Illuminate\Database\Query\Builder  $query
+     * @param  string  $table
+     * @param  string  $columns
+     * @param  string  $where
+     * @return string
+     */
+    protected function compileUpdateWithJoins(Builder $query, $table, $columns, $where)
+    {
+        $joins = $this->compileJoins($query, $query->joins);
+
+        return "update {$table} {$joins} set {$columns} {$where}";
+    }
+
+    /**
+     * Compile an "upsert" statement into SQL.
+     *
+     * @param  \Illuminate\Database\Query\Builder  $query
+     * @param  array  $values
+     * @param  array  $uniqueBy
+     * @param  array  $update
+     * @return string
+     *
+     * @throws \RuntimeException
+     */
+    public function compileUpsert(Builder $query, array $values, array $uniqueBy, array $update)
+    {
+        throw new RuntimeException('This database engine does not support upserts.');
+    }
+
+    /**
+     * Prepare the bindings for an update statement.
+     *
+     * @param  array  $bindings
+     * @param  array  $values
+     * @return array
+     */
+    public function prepareBindingsForUpdate(array $bindings, array $values)
+    {
+        $cleanBindings = Arr::except($bindings, ['select', 'join']);
+
+        return array_values(
+            array_merge($bindings['join'], $values, Arr::flatten($cleanBindings))
+        );
+    }
+
+    /**
+     * Compile a delete statement into SQL.
+     *
+     * @param  \Illuminate\Database\Query\Builder  $query
+     * @return string
+     */
+    public function compileDelete(Builder $query)
+    {
+        $table = $this->wrapTable($query->from);
+
+        $where = $this->compileWheres($query);
+
+        return trim(
+            isset($query->joins)
+                ? $this->compileDeleteWithJoins($query, $table, $where)
+                : $this->compileDeleteWithoutJoins($query, $table, $where)
+        );
+    }
+
+    /**
+     * Compile a delete statement without joins into SQL.
+     *
+     * @param  \Illuminate\Database\Query\Builder  $query
+     * @param  string  $table
+     * @param  string  $where
+     * @return string
+     */
+    protected function compileDeleteWithoutJoins(Builder $query, $table, $where)
+    {
+        return "delete from {$table} {$where}";
+    }
+
+    /**
+     * Compile a delete statement with joins into SQL.
+     *
+     * @param  \Illuminate\Database\Query\Builder  $query
+     * @param  string  $table
+     * @param  string  $where
+     * @return string
+     */
+    protected function compileDeleteWithJoins(Builder $query, $table, $where)
+    {
+        $alias = last(explode(' as ', $table));
+
+        $joins = $this->compileJoins($query, $query->joins);
+
+        return "delete {$alias} from {$table} {$joins} {$where}";
+    }
+
+    /**
+     * Prepare the bindings for a delete statement.
+     *
+     * @param  array  $bindings
+     * @return array
+     */
+    public function prepareBindingsForDelete(array $bindings)
+    {
+        return Arr::flatten(
+            Arr::except($bindings, 'select')
+        );
+    }
+
+    /**
+     * Compile a truncate table statement into SQL.
+     *
+     * @param  \Illuminate\Database\Query\Builder  $query
+     * @return array
+     */
+    public function compileTruncate(Builder $query)
+    {
+        return ['truncate table '.$this->wrapTable($query->from) => []];
+    }
+
+    /**
+     * Compile the lock into SQL.
+     *
+     * @param  \Illuminate\Database\Query\Builder  $query
+     * @param  bool|string  $value
+     * @return string
+     */
+    protected function compileLock(Builder $query, $value)
+    {
+        return is_string($value) ? $value : '';
+    }
+
+    /**
+     * Determine if the grammar supports savepoints.
+     *
+     * @return bool
+     */
+    public function supportsSavepoints()
+    {
+        return true;
+    }
+
+    /**
+     * Compile the SQL statement to define a savepoint.
+     *
+     * @param  string  $name
+     * @return string
+     */
+    public function compileSavepoint($name)
+    {
+        return 'SAVEPOINT '.$name;
+    }
+
+    /**
+     * Compile the SQL statement to execute a savepoint rollback.
+     *
+     * @param  string  $name
+     * @return string
+     */
+    public function compileSavepointRollBack($name)
+    {
+        return 'ROLLBACK TO SAVEPOINT '.$name;
+    }
+
+    /**
+     * Wrap the given JSON selector for boolean values.
+     *
+     * @param  string  $value
+     * @return string
+     */
+    protected function wrapJsonBooleanSelector($value)
+    {
+        return $this->wrapJsonSelector($value);
+    }
+
+    /**
+     * Wrap the given JSON boolean value.
+     *
+     * @param  string  $value
+     * @return string
+     */
+    protected function wrapJsonBooleanValue($value)
+    {
+        return $value;
+    }
+
+    /**
+     * Concatenate an array of segments, removing empties.
+     *
+     * @param  array  $segments
+     * @return string
+     */
+    protected function concatenate($segments)
+    {
+        return implode(' ', array_filter($segments, function ($value) {
+            return (string) $value !== '';
+        }));
+    }
+
+    /**
+     * Remove the leading boolean from a statement.
+     *
+     * @param  string  $value
+     * @return string
+     */
+    protected function removeLeadingBoolean($value)
+    {
+        return preg_replace('/and |or /i', '', $value, 1);
+    }
+
+    /**
+     * Get the grammar specific operators.
+     *
+     * @return array
+     */
+    public function getOperators()
+    {
+        return $this->operators;
+    }
+
+    /**
+     * Get the grammar specific bitwise operators.
+     *
+     * @return array
+     */
+    public function getBitwiseOperators()
+    {
+        return $this->bitwiseOperators;
+    }
+}
diff --git a/vendor/illuminate/database/Query/Grammars/MySqlGrammar.php b/vendor/illuminate/database/Query/Grammars/MySqlGrammar.php
new file mode 100755
index 0000000..131f8af
--- /dev/null
+++ b/vendor/illuminate/database/Query/Grammars/MySqlGrammar.php
@@ -0,0 +1,381 @@
+isJsonSelector($where['column'])) {
+            [$field, $path] = $this->wrapJsonFieldAndPath($where['column']);
+
+            return '(json_extract('.$field.$path.') is null OR json_type(json_extract('.$field.$path.')) = \'NULL\')';
+        }
+
+        return parent::whereNull($query, $where);
+    }
+
+    /**
+     * Add a "where not null" clause to the query.
+     *
+     * @param  \Illuminate\Database\Query\Builder  $query
+     * @param  array  $where
+     * @return string
+     */
+    protected function whereNotNull(Builder $query, $where)
+    {
+        if ($this->isJsonSelector($where['column'])) {
+            [$field, $path] = $this->wrapJsonFieldAndPath($where['column']);
+
+            return '(json_extract('.$field.$path.') is not null AND json_type(json_extract('.$field.$path.')) != \'NULL\')';
+        }
+
+        return parent::whereNotNull($query, $where);
+    }
+
+    /**
+     * Compile a "where fulltext" clause.
+     *
+     * @param  \Illuminate\Database\Query\Builder  $query
+     * @param  array  $where
+     * @return string
+     */
+    public function whereFullText(Builder $query, $where)
+    {
+        $columns = $this->columnize($where['columns']);
+
+        $value = $this->parameter($where['value']);
+
+        $mode = ($where['options']['mode'] ?? []) === 'boolean'
+            ? ' in boolean mode'
+            : ' in natural language mode';
+
+        $expanded = ($where['options']['expanded'] ?? []) && ($where['options']['mode'] ?? []) !== 'boolean'
+            ? ' with query expansion'
+            : '';
+
+        return "match ({$columns}) against (".$value."{$mode}{$expanded})";
+    }
+
+    /**
+     * Compile the index hints for the query.
+     *
+     * @param  \Illuminate\Database\Query\Builder  $query
+     * @param  \Illuminate\Database\Query\IndexHint  $indexHint
+     * @return string
+     */
+    protected function compileIndexHint(Builder $query, $indexHint)
+    {
+        return match ($indexHint->type) {
+            'hint' => "use index ({$indexHint->index})",
+            'force' => "force index ({$indexHint->index})",
+            default => "ignore index ({$indexHint->index})",
+        };
+    }
+
+    /**
+     * Compile an insert ignore statement into SQL.
+     *
+     * @param  \Illuminate\Database\Query\Builder  $query
+     * @param  array  $values
+     * @return string
+     */
+    public function compileInsertOrIgnore(Builder $query, array $values)
+    {
+        return Str::replaceFirst('insert', 'insert ignore', $this->compileInsert($query, $values));
+    }
+
+    /**
+     * Compile a "JSON contains" statement into SQL.
+     *
+     * @param  string  $column
+     * @param  string  $value
+     * @return string
+     */
+    protected function compileJsonContains($column, $value)
+    {
+        [$field, $path] = $this->wrapJsonFieldAndPath($column);
+
+        return 'json_contains('.$field.', '.$value.$path.')';
+    }
+
+    /**
+     * Compile a "JSON contains key" statement into SQL.
+     *
+     * @param  string  $column
+     * @return string
+     */
+    protected function compileJsonContainsKey($column)
+    {
+        [$field, $path] = $this->wrapJsonFieldAndPath($column);
+
+        return 'ifnull(json_contains_path('.$field.', \'one\''.$path.'), 0)';
+    }
+
+    /**
+     * Compile a "JSON length" statement into SQL.
+     *
+     * @param  string  $column
+     * @param  string  $operator
+     * @param  string  $value
+     * @return string
+     */
+    protected function compileJsonLength($column, $operator, $value)
+    {
+        [$field, $path] = $this->wrapJsonFieldAndPath($column);
+
+        return 'json_length('.$field.$path.') '.$operator.' '.$value;
+    }
+
+    /**
+     * Compile a "JSON value cast" statement into SQL.
+     *
+     * @param  string  $value
+     * @return string
+     */
+    public function compileJsonValueCast($value)
+    {
+        return 'cast('.$value.' as json)';
+    }
+
+    /**
+     * Compile the random statement into SQL.
+     *
+     * @param  string|int  $seed
+     * @return string
+     */
+    public function compileRandom($seed)
+    {
+        return 'RAND('.$seed.')';
+    }
+
+    /**
+     * Compile the lock into SQL.
+     *
+     * @param  \Illuminate\Database\Query\Builder  $query
+     * @param  bool|string  $value
+     * @return string
+     */
+    protected function compileLock(Builder $query, $value)
+    {
+        if (! is_string($value)) {
+            return $value ? 'for update' : 'lock in share mode';
+        }
+
+        return $value;
+    }
+
+    /**
+     * Compile an insert statement into SQL.
+     *
+     * @param  \Illuminate\Database\Query\Builder  $query
+     * @param  array  $values
+     * @return string
+     */
+    public function compileInsert(Builder $query, array $values)
+    {
+        if (empty($values)) {
+            $values = [[]];
+        }
+
+        return parent::compileInsert($query, $values);
+    }
+
+    /**
+     * Compile the columns for an update statement.
+     *
+     * @param  \Illuminate\Database\Query\Builder  $query
+     * @param  array  $values
+     * @return string
+     */
+    protected function compileUpdateColumns(Builder $query, array $values)
+    {
+        return collect($values)->map(function ($value, $key) {
+            if ($this->isJsonSelector($key)) {
+                return $this->compileJsonUpdateColumn($key, $value);
+            }
+
+            return $this->wrap($key).' = '.$this->parameter($value);
+        })->implode(', ');
+    }
+
+    /**
+     * Compile an "upsert" statement into SQL.
+     *
+     * @param  \Illuminate\Database\Query\Builder  $query
+     * @param  array  $values
+     * @param  array  $uniqueBy
+     * @param  array  $update
+     * @return string
+     */
+    public function compileUpsert(Builder $query, array $values, array $uniqueBy, array $update)
+    {
+        $useUpsertAlias = $query->connection->getConfig('use_upsert_alias');
+
+        $sql = $this->compileInsert($query, $values);
+
+        if ($useUpsertAlias) {
+            $sql .= ' as laravel_upsert_alias';
+        }
+
+        $sql .= ' on duplicate key update ';
+
+        $columns = collect($update)->map(function ($value, $key) use ($useUpsertAlias) {
+            if (! is_numeric($key)) {
+                return $this->wrap($key).' = '.$this->parameter($value);
+            }
+
+            return $useUpsertAlias
+                ? $this->wrap($value).' = '.$this->wrap('laravel_upsert_alias').'.'.$this->wrap($value)
+                : $this->wrap($value).' = values('.$this->wrap($value).')';
+        })->implode(', ');
+
+        return $sql.$columns;
+    }
+
+    /**
+     * Prepare a JSON column being updated using the JSON_SET function.
+     *
+     * @param  string  $key
+     * @param  mixed  $value
+     * @return string
+     */
+    protected function compileJsonUpdateColumn($key, $value)
+    {
+        if (is_bool($value)) {
+            $value = $value ? 'true' : 'false';
+        } elseif (is_array($value)) {
+            $value = 'cast(? as json)';
+        } else {
+            $value = $this->parameter($value);
+        }
+
+        [$field, $path] = $this->wrapJsonFieldAndPath($key);
+
+        return "{$field} = json_set({$field}{$path}, {$value})";
+    }
+
+    /**
+     * Compile an update statement without joins into SQL.
+     *
+     * @param  \Illuminate\Database\Query\Builder  $query
+     * @param  string  $table
+     * @param  string  $columns
+     * @param  string  $where
+     * @return string
+     */
+    protected function compileUpdateWithoutJoins(Builder $query, $table, $columns, $where)
+    {
+        $sql = parent::compileUpdateWithoutJoins($query, $table, $columns, $where);
+
+        if (! empty($query->orders)) {
+            $sql .= ' '.$this->compileOrders($query, $query->orders);
+        }
+
+        if (isset($query->limit)) {
+            $sql .= ' '.$this->compileLimit($query, $query->limit);
+        }
+
+        return $sql;
+    }
+
+    /**
+     * Prepare the bindings for an update statement.
+     *
+     * Booleans, integers, and doubles are inserted into JSON updates as raw values.
+     *
+     * @param  array  $bindings
+     * @param  array  $values
+     * @return array
+     */
+    public function prepareBindingsForUpdate(array $bindings, array $values)
+    {
+        $values = collect($values)->reject(function ($value, $column) {
+            return $this->isJsonSelector($column) && is_bool($value);
+        })->map(function ($value) {
+            return is_array($value) ? json_encode($value) : $value;
+        })->all();
+
+        return parent::prepareBindingsForUpdate($bindings, $values);
+    }
+
+    /**
+     * Compile a delete query that does not use joins.
+     *
+     * @param  \Illuminate\Database\Query\Builder  $query
+     * @param  string  $table
+     * @param  string  $where
+     * @return string
+     */
+    protected function compileDeleteWithoutJoins(Builder $query, $table, $where)
+    {
+        $sql = parent::compileDeleteWithoutJoins($query, $table, $where);
+
+        // When using MySQL, delete statements may contain order by statements and limits
+        // so we will compile both of those here. Once we have finished compiling this
+        // we will return the completed SQL statement so it will be executed for us.
+        if (! empty($query->orders)) {
+            $sql .= ' '.$this->compileOrders($query, $query->orders);
+        }
+
+        if (isset($query->limit)) {
+            $sql .= ' '.$this->compileLimit($query, $query->limit);
+        }
+
+        return $sql;
+    }
+
+    /**
+     * Wrap a single string in keyword identifiers.
+     *
+     * @param  string  $value
+     * @return string
+     */
+    protected function wrapValue($value)
+    {
+        return $value === '*' ? $value : '`'.str_replace('`', '``', $value).'`';
+    }
+
+    /**
+     * Wrap the given JSON selector.
+     *
+     * @param  string  $value
+     * @return string
+     */
+    protected function wrapJsonSelector($value)
+    {
+        [$field, $path] = $this->wrapJsonFieldAndPath($value);
+
+        return 'json_unquote(json_extract('.$field.$path.'))';
+    }
+
+    /**
+     * Wrap the given JSON selector for boolean values.
+     *
+     * @param  string  $value
+     * @return string
+     */
+    protected function wrapJsonBooleanSelector($value)
+    {
+        [$field, $path] = $this->wrapJsonFieldAndPath($value);
+
+        return 'json_extract('.$field.$path.')';
+    }
+}
diff --git a/vendor/illuminate/database/Query/Grammars/PostgresGrammar.php b/vendor/illuminate/database/Query/Grammars/PostgresGrammar.php
new file mode 100755
index 0000000..ad4678b
--- /dev/null
+++ b/vendor/illuminate/database/Query/Grammars/PostgresGrammar.php
@@ -0,0 +1,701 @@
+', '<=', '>=', '<>', '!=',
+        'like', 'not like', 'between', 'ilike', 'not ilike',
+        '~', '&', '|', '#', '<<', '>>', '<<=', '>>=',
+        '&&', '@>', '<@', '?', '?|', '?&', '||', '-', '@?', '@@', '#-',
+        'is distinct from', 'is not distinct from',
+    ];
+
+    /**
+     * The grammar specific bitwise operators.
+     *
+     * @var array
+     */
+    protected $bitwiseOperators = [
+        '~', '&', '|', '#', '<<', '>>', '<<=', '>>=',
+    ];
+
+    /**
+     * Compile a basic where clause.
+     *
+     * @param  \Illuminate\Database\Query\Builder  $query
+     * @param  array  $where
+     * @return string
+     */
+    protected function whereBasic(Builder $query, $where)
+    {
+        if (str_contains(strtolower($where['operator']), 'like')) {
+            return sprintf(
+                '%s::text %s %s',
+                $this->wrap($where['column']),
+                $where['operator'],
+                $this->parameter($where['value'])
+            );
+        }
+
+        return parent::whereBasic($query, $where);
+    }
+
+    /**
+     * Compile a bitwise operator where clause.
+     *
+     * @param  \Illuminate\Database\Query\Builder  $query
+     * @param  array  $where
+     * @return string
+     */
+    protected function whereBitwise(Builder $query, $where)
+    {
+        $value = $this->parameter($where['value']);
+
+        $operator = str_replace('?', '??', $where['operator']);
+
+        return '('.$this->wrap($where['column']).' '.$operator.' '.$value.')::bool';
+    }
+
+    /**
+     * Compile a "where date" clause.
+     *
+     * @param  \Illuminate\Database\Query\Builder  $query
+     * @param  array  $where
+     * @return string
+     */
+    protected function whereDate(Builder $query, $where)
+    {
+        $value = $this->parameter($where['value']);
+
+        return $this->wrap($where['column']).'::date '.$where['operator'].' '.$value;
+    }
+
+    /**
+     * Compile a "where time" clause.
+     *
+     * @param  \Illuminate\Database\Query\Builder  $query
+     * @param  array  $where
+     * @return string
+     */
+    protected function whereTime(Builder $query, $where)
+    {
+        $value = $this->parameter($where['value']);
+
+        return $this->wrap($where['column']).'::time '.$where['operator'].' '.$value;
+    }
+
+    /**
+     * Compile a date based where clause.
+     *
+     * @param  string  $type
+     * @param  \Illuminate\Database\Query\Builder  $query
+     * @param  array  $where
+     * @return string
+     */
+    protected function dateBasedWhere($type, Builder $query, $where)
+    {
+        $value = $this->parameter($where['value']);
+
+        return 'extract('.$type.' from '.$this->wrap($where['column']).') '.$where['operator'].' '.$value;
+    }
+
+    /**
+     * Compile a "where fulltext" clause.
+     *
+     * @param  \Illuminate\Database\Query\Builder  $query
+     * @param  array  $where
+     * @return string
+     */
+    public function whereFullText(Builder $query, $where)
+    {
+        $language = $where['options']['language'] ?? 'english';
+
+        if (! in_array($language, $this->validFullTextLanguages())) {
+            $language = 'english';
+        }
+
+        $columns = collect($where['columns'])->map(function ($column) use ($language) {
+            return "to_tsvector('{$language}', {$this->wrap($column)})";
+        })->implode(' || ');
+
+        $mode = 'plainto_tsquery';
+
+        if (($where['options']['mode'] ?? []) === 'phrase') {
+            $mode = 'phraseto_tsquery';
+        }
+
+        if (($where['options']['mode'] ?? []) === 'websearch') {
+            $mode = 'websearch_to_tsquery';
+        }
+
+        return "({$columns}) @@ {$mode}('{$language}', {$this->parameter($where['value'])})";
+    }
+
+    /**
+     * Get an array of valid full text languages.
+     *
+     * @return array
+     */
+    protected function validFullTextLanguages()
+    {
+        return [
+            'simple',
+            'arabic',
+            'danish',
+            'dutch',
+            'english',
+            'finnish',
+            'french',
+            'german',
+            'hungarian',
+            'indonesian',
+            'irish',
+            'italian',
+            'lithuanian',
+            'nepali',
+            'norwegian',
+            'portuguese',
+            'romanian',
+            'russian',
+            'spanish',
+            'swedish',
+            'tamil',
+            'turkish',
+        ];
+    }
+
+    /**
+     * Compile the "select *" portion of the query.
+     *
+     * @param  \Illuminate\Database\Query\Builder  $query
+     * @param  array  $columns
+     * @return string|null
+     */
+    protected function compileColumns(Builder $query, $columns)
+    {
+        // If the query is actually performing an aggregating select, we will let that
+        // compiler handle the building of the select clauses, as it will need some
+        // more syntax that is best handled by that function to keep things neat.
+        if (! is_null($query->aggregate)) {
+            return;
+        }
+
+        if (is_array($query->distinct)) {
+            $select = 'select distinct on ('.$this->columnize($query->distinct).') ';
+        } elseif ($query->distinct) {
+            $select = 'select distinct ';
+        } else {
+            $select = 'select ';
+        }
+
+        return $select.$this->columnize($columns);
+    }
+
+    /**
+     * Compile a "JSON contains" statement into SQL.
+     *
+     * @param  string  $column
+     * @param  string  $value
+     * @return string
+     */
+    protected function compileJsonContains($column, $value)
+    {
+        $column = str_replace('->>', '->', $this->wrap($column));
+
+        return '('.$column.')::jsonb @> '.$value;
+    }
+
+    /**
+     * Compile a "JSON contains key" statement into SQL.
+     *
+     * @param  string  $column
+     * @return string
+     */
+    protected function compileJsonContainsKey($column)
+    {
+        $segments = explode('->', $column);
+
+        $lastSegment = array_pop($segments);
+
+        if (filter_var($lastSegment, FILTER_VALIDATE_INT) !== false) {
+            $i = $lastSegment;
+        } elseif (preg_match('/\[(-?[0-9]+)\]$/', $lastSegment, $matches)) {
+            $segments[] = Str::beforeLast($lastSegment, $matches[0]);
+
+            $i = $matches[1];
+        }
+
+        $column = str_replace('->>', '->', $this->wrap(implode('->', $segments)));
+
+        if (isset($i)) {
+            return vsprintf('case when %s then %s else false end', [
+                'jsonb_typeof(('.$column.")::jsonb) = 'array'",
+                'jsonb_array_length(('.$column.')::jsonb) >= '.($i < 0 ? abs($i) : $i + 1),
+            ]);
+        }
+
+        $key = "'".str_replace("'", "''", $lastSegment)."'";
+
+        return 'coalesce(('.$column.')::jsonb ?? '.$key.', false)';
+    }
+
+    /**
+     * Compile a "JSON length" statement into SQL.
+     *
+     * @param  string  $column
+     * @param  string  $operator
+     * @param  string  $value
+     * @return string
+     */
+    protected function compileJsonLength($column, $operator, $value)
+    {
+        $column = str_replace('->>', '->', $this->wrap($column));
+
+        return 'jsonb_array_length(('.$column.')::jsonb) '.$operator.' '.$value;
+    }
+
+    /**
+     * Compile a single having clause.
+     *
+     * @param  array  $having
+     * @return string
+     */
+    protected function compileHaving(array $having)
+    {
+        if ($having['type'] === 'Bitwise') {
+            return $this->compileHavingBitwise($having);
+        }
+
+        return parent::compileHaving($having);
+    }
+
+    /**
+     * Compile a having clause involving a bitwise operator.
+     *
+     * @param  array  $having
+     * @return string
+     */
+    protected function compileHavingBitwise($having)
+    {
+        $column = $this->wrap($having['column']);
+
+        $parameter = $this->parameter($having['value']);
+
+        return '('.$column.' '.$having['operator'].' '.$parameter.')::bool';
+    }
+
+    /**
+     * Compile the lock into SQL.
+     *
+     * @param  \Illuminate\Database\Query\Builder  $query
+     * @param  bool|string  $value
+     * @return string
+     */
+    protected function compileLock(Builder $query, $value)
+    {
+        if (! is_string($value)) {
+            return $value ? 'for update' : 'for share';
+        }
+
+        return $value;
+    }
+
+    /**
+     * Compile an insert ignore statement into SQL.
+     *
+     * @param  \Illuminate\Database\Query\Builder  $query
+     * @param  array  $values
+     * @return string
+     */
+    public function compileInsertOrIgnore(Builder $query, array $values)
+    {
+        return $this->compileInsert($query, $values).' on conflict do nothing';
+    }
+
+    /**
+     * Compile an insert and get ID statement into SQL.
+     *
+     * @param  \Illuminate\Database\Query\Builder  $query
+     * @param  array  $values
+     * @param  string  $sequence
+     * @return string
+     */
+    public function compileInsertGetId(Builder $query, $values, $sequence)
+    {
+        return $this->compileInsert($query, $values).' returning '.$this->wrap($sequence ?: 'id');
+    }
+
+    /**
+     * Compile an update statement into SQL.
+     *
+     * @param  \Illuminate\Database\Query\Builder  $query
+     * @param  array  $values
+     * @return string
+     */
+    public function compileUpdate(Builder $query, array $values)
+    {
+        if (isset($query->joins) || isset($query->limit)) {
+            return $this->compileUpdateWithJoinsOrLimit($query, $values);
+        }
+
+        return parent::compileUpdate($query, $values);
+    }
+
+    /**
+     * Compile the columns for an update statement.
+     *
+     * @param  \Illuminate\Database\Query\Builder  $query
+     * @param  array  $values
+     * @return string
+     */
+    protected function compileUpdateColumns(Builder $query, array $values)
+    {
+        return collect($values)->map(function ($value, $key) {
+            $column = last(explode('.', $key));
+
+            if ($this->isJsonSelector($key)) {
+                return $this->compileJsonUpdateColumn($column, $value);
+            }
+
+            return $this->wrap($column).' = '.$this->parameter($value);
+        })->implode(', ');
+    }
+
+    /**
+     * Compile an "upsert" statement into SQL.
+     *
+     * @param  \Illuminate\Database\Query\Builder  $query
+     * @param  array  $values
+     * @param  array  $uniqueBy
+     * @param  array  $update
+     * @return string
+     */
+    public function compileUpsert(Builder $query, array $values, array $uniqueBy, array $update)
+    {
+        $sql = $this->compileInsert($query, $values);
+
+        $sql .= ' on conflict ('.$this->columnize($uniqueBy).') do update set ';
+
+        $columns = collect($update)->map(function ($value, $key) {
+            return is_numeric($key)
+                ? $this->wrap($value).' = '.$this->wrapValue('excluded').'.'.$this->wrap($value)
+                : $this->wrap($key).' = '.$this->parameter($value);
+        })->implode(', ');
+
+        return $sql.$columns;
+    }
+
+    /**
+     * Prepares a JSON column being updated using the JSONB_SET function.
+     *
+     * @param  string  $key
+     * @param  mixed  $value
+     * @return string
+     */
+    protected function compileJsonUpdateColumn($key, $value)
+    {
+        $segments = explode('->', $key);
+
+        $field = $this->wrap(array_shift($segments));
+
+        $path = "'{".implode(',', $this->wrapJsonPathAttributes($segments, '"'))."}'";
+
+        return "{$field} = jsonb_set({$field}::jsonb, {$path}, {$this->parameter($value)})";
+    }
+
+    /**
+     * Compile an update from statement into SQL.
+     *
+     * @param  \Illuminate\Database\Query\Builder  $query
+     * @param  array  $values
+     * @return string
+     */
+    public function compileUpdateFrom(Builder $query, $values)
+    {
+        $table = $this->wrapTable($query->from);
+
+        // Each one of the columns in the update statements needs to be wrapped in the
+        // keyword identifiers, also a place-holder needs to be created for each of
+        // the values in the list of bindings so we can make the sets statements.
+        $columns = $this->compileUpdateColumns($query, $values);
+
+        $from = '';
+
+        if (isset($query->joins)) {
+            // When using Postgres, updates with joins list the joined tables in the from
+            // clause, which is different than other systems like MySQL. Here, we will
+            // compile out the tables that are joined and add them to a from clause.
+            $froms = collect($query->joins)->map(function ($join) {
+                return $this->wrapTable($join->table);
+            })->all();
+
+            if (count($froms) > 0) {
+                $from = ' from '.implode(', ', $froms);
+            }
+        }
+
+        $where = $this->compileUpdateWheres($query);
+
+        return trim("update {$table} set {$columns}{$from} {$where}");
+    }
+
+    /**
+     * Compile the additional where clauses for updates with joins.
+     *
+     * @param  \Illuminate\Database\Query\Builder  $query
+     * @return string
+     */
+    protected function compileUpdateWheres(Builder $query)
+    {
+        $baseWheres = $this->compileWheres($query);
+
+        if (! isset($query->joins)) {
+            return $baseWheres;
+        }
+
+        // Once we compile the join constraints, we will either use them as the where
+        // clause or append them to the existing base where clauses. If we need to
+        // strip the leading boolean we will do so when using as the only where.
+        $joinWheres = $this->compileUpdateJoinWheres($query);
+
+        if (trim($baseWheres) == '') {
+            return 'where '.$this->removeLeadingBoolean($joinWheres);
+        }
+
+        return $baseWheres.' '.$joinWheres;
+    }
+
+    /**
+     * Compile the "join" clause where clauses for an update.
+     *
+     * @param  \Illuminate\Database\Query\Builder  $query
+     * @return string
+     */
+    protected function compileUpdateJoinWheres(Builder $query)
+    {
+        $joinWheres = [];
+
+        // Here we will just loop through all of the join constraints and compile them
+        // all out then implode them. This should give us "where" like syntax after
+        // everything has been built and then we will join it to the real wheres.
+        foreach ($query->joins as $join) {
+            foreach ($join->wheres as $where) {
+                $method = "where{$where['type']}";
+
+                $joinWheres[] = $where['boolean'].' '.$this->$method($query, $where);
+            }
+        }
+
+        return implode(' ', $joinWheres);
+    }
+
+    /**
+     * Prepare the bindings for an update statement.
+     *
+     * @param  array  $bindings
+     * @param  array  $values
+     * @return array
+     */
+    public function prepareBindingsForUpdateFrom(array $bindings, array $values)
+    {
+        $values = collect($values)->map(function ($value, $column) {
+            return is_array($value) || ($this->isJsonSelector($column) && ! $this->isExpression($value))
+                ? json_encode($value)
+                : $value;
+        })->all();
+
+        $bindingsWithoutWhere = Arr::except($bindings, ['select', 'where']);
+
+        return array_values(
+            array_merge($values, $bindings['where'], Arr::flatten($bindingsWithoutWhere))
+        );
+    }
+
+    /**
+     * Compile an update statement with joins or limit into SQL.
+     *
+     * @param  \Illuminate\Database\Query\Builder  $query
+     * @param  array  $values
+     * @return string
+     */
+    protected function compileUpdateWithJoinsOrLimit(Builder $query, array $values)
+    {
+        $table = $this->wrapTable($query->from);
+
+        $columns = $this->compileUpdateColumns($query, $values);
+
+        $alias = last(preg_split('/\s+as\s+/i', $query->from));
+
+        $selectSql = $this->compileSelect($query->select($alias.'.ctid'));
+
+        return "update {$table} set {$columns} where {$this->wrap('ctid')} in ({$selectSql})";
+    }
+
+    /**
+     * Prepare the bindings for an update statement.
+     *
+     * @param  array  $bindings
+     * @param  array  $values
+     * @return array
+     */
+    public function prepareBindingsForUpdate(array $bindings, array $values)
+    {
+        $values = collect($values)->map(function ($value, $column) {
+            return is_array($value) || ($this->isJsonSelector($column) && ! $this->isExpression($value))
+                ? json_encode($value)
+                : $value;
+        })->all();
+
+        $cleanBindings = Arr::except($bindings, 'select');
+
+        return array_values(
+            array_merge($values, Arr::flatten($cleanBindings))
+        );
+    }
+
+    /**
+     * Compile a delete statement into SQL.
+     *
+     * @param  \Illuminate\Database\Query\Builder  $query
+     * @return string
+     */
+    public function compileDelete(Builder $query)
+    {
+        if (isset($query->joins) || isset($query->limit)) {
+            return $this->compileDeleteWithJoinsOrLimit($query);
+        }
+
+        return parent::compileDelete($query);
+    }
+
+    /**
+     * Compile a delete statement with joins or limit into SQL.
+     *
+     * @param  \Illuminate\Database\Query\Builder  $query
+     * @return string
+     */
+    protected function compileDeleteWithJoinsOrLimit(Builder $query)
+    {
+        $table = $this->wrapTable($query->from);
+
+        $alias = last(preg_split('/\s+as\s+/i', $query->from));
+
+        $selectSql = $this->compileSelect($query->select($alias.'.ctid'));
+
+        return "delete from {$table} where {$this->wrap('ctid')} in ({$selectSql})";
+    }
+
+    /**
+     * Compile a truncate table statement into SQL.
+     *
+     * @param  \Illuminate\Database\Query\Builder  $query
+     * @return array
+     */
+    public function compileTruncate(Builder $query)
+    {
+        return ['truncate '.$this->wrapTable($query->from).' restart identity cascade' => []];
+    }
+
+    /**
+     * Wrap the given JSON selector.
+     *
+     * @param  string  $value
+     * @return string
+     */
+    protected function wrapJsonSelector($value)
+    {
+        $path = explode('->', $value);
+
+        $field = $this->wrapSegments(explode('.', array_shift($path)));
+
+        $wrappedPath = $this->wrapJsonPathAttributes($path);
+
+        $attribute = array_pop($wrappedPath);
+
+        if (! empty($wrappedPath)) {
+            return $field.'->'.implode('->', $wrappedPath).'->>'.$attribute;
+        }
+
+        return $field.'->>'.$attribute;
+    }
+
+    /**
+     * Wrap the given JSON selector for boolean values.
+     *
+     * @param  string  $value
+     * @return string
+     */
+    protected function wrapJsonBooleanSelector($value)
+    {
+        $selector = str_replace(
+            '->>', '->',
+            $this->wrapJsonSelector($value)
+        );
+
+        return '('.$selector.')::jsonb';
+    }
+
+    /**
+     * Wrap the given JSON boolean value.
+     *
+     * @param  string  $value
+     * @return string
+     */
+    protected function wrapJsonBooleanValue($value)
+    {
+        return "'".$value."'::jsonb";
+    }
+
+    /**
+     * Wrap the attributes of the given JSON path.
+     *
+     * @param  array  $path
+     * @return array
+     */
+    protected function wrapJsonPathAttributes($path)
+    {
+        $quote = func_num_args() === 2 ? func_get_arg(1) : "'";
+
+        return collect($path)->map(function ($attribute) {
+            return $this->parseJsonPathArrayKeys($attribute);
+        })->collapse()->map(function ($attribute) use ($quote) {
+            return filter_var($attribute, FILTER_VALIDATE_INT) !== false
+                        ? $attribute
+                        : $quote.$attribute.$quote;
+        })->all();
+    }
+
+    /**
+     * Parse the given JSON path attribute for array keys.
+     *
+     * @param  string  $attribute
+     * @return array
+     */
+    protected function parseJsonPathArrayKeys($attribute)
+    {
+        if (preg_match('/(\[[^\]]+\])+$/', $attribute, $parts)) {
+            $key = Str::beforeLast($attribute, $parts[0]);
+
+            preg_match_all('/\[([^\]]+)\]/', $parts[0], $keys);
+
+            return collect([$key])
+                ->merge($keys[1])
+                ->diff('')
+                ->values()
+                ->all();
+        }
+
+        return [$attribute];
+    }
+}
diff --git a/vendor/illuminate/database/Query/Grammars/SQLiteGrammar.php b/vendor/illuminate/database/Query/Grammars/SQLiteGrammar.php
new file mode 100755
index 0000000..8bf7d39
--- /dev/null
+++ b/vendor/illuminate/database/Query/Grammars/SQLiteGrammar.php
@@ -0,0 +1,369 @@
+', '<=', '>=', '<>', '!=',
+        'like', 'not like', 'ilike',
+        '&', '|', '<<', '>>',
+    ];
+
+    /**
+     * Compile the lock into SQL.
+     *
+     * @param  \Illuminate\Database\Query\Builder  $query
+     * @param  bool|string  $value
+     * @return string
+     */
+    protected function compileLock(Builder $query, $value)
+    {
+        return '';
+    }
+
+    /**
+     * Wrap a union subquery in parentheses.
+     *
+     * @param  string  $sql
+     * @return string
+     */
+    protected function wrapUnion($sql)
+    {
+        return 'select * from ('.$sql.')';
+    }
+
+    /**
+     * Compile a "where date" clause.
+     *
+     * @param  \Illuminate\Database\Query\Builder  $query
+     * @param  array  $where
+     * @return string
+     */
+    protected function whereDate(Builder $query, $where)
+    {
+        return $this->dateBasedWhere('%Y-%m-%d', $query, $where);
+    }
+
+    /**
+     * Compile a "where day" clause.
+     *
+     * @param  \Illuminate\Database\Query\Builder  $query
+     * @param  array  $where
+     * @return string
+     */
+    protected function whereDay(Builder $query, $where)
+    {
+        return $this->dateBasedWhere('%d', $query, $where);
+    }
+
+    /**
+     * Compile a "where month" clause.
+     *
+     * @param  \Illuminate\Database\Query\Builder  $query
+     * @param  array  $where
+     * @return string
+     */
+    protected function whereMonth(Builder $query, $where)
+    {
+        return $this->dateBasedWhere('%m', $query, $where);
+    }
+
+    /**
+     * Compile a "where year" clause.
+     *
+     * @param  \Illuminate\Database\Query\Builder  $query
+     * @param  array  $where
+     * @return string
+     */
+    protected function whereYear(Builder $query, $where)
+    {
+        return $this->dateBasedWhere('%Y', $query, $where);
+    }
+
+    /**
+     * Compile a "where time" clause.
+     *
+     * @param  \Illuminate\Database\Query\Builder  $query
+     * @param  array  $where
+     * @return string
+     */
+    protected function whereTime(Builder $query, $where)
+    {
+        return $this->dateBasedWhere('%H:%M:%S', $query, $where);
+    }
+
+    /**
+     * Compile a date based where clause.
+     *
+     * @param  string  $type
+     * @param  \Illuminate\Database\Query\Builder  $query
+     * @param  array  $where
+     * @return string
+     */
+    protected function dateBasedWhere($type, Builder $query, $where)
+    {
+        $value = $this->parameter($where['value']);
+
+        return "strftime('{$type}', {$this->wrap($where['column'])}) {$where['operator']} cast({$value} as text)";
+    }
+
+    /**
+     * Compile the index hints for the query.
+     *
+     * @param  \Illuminate\Database\Query\Builder  $query
+     * @param  \Illuminate\Database\Query\IndexHint  $indexHint
+     * @return string
+     */
+    protected function compileIndexHint(Builder $query, $indexHint)
+    {
+        return $indexHint->type === 'force'
+                ? "indexed by {$indexHint->index}"
+                : '';
+    }
+
+    /**
+     * Compile a "JSON length" statement into SQL.
+     *
+     * @param  string  $column
+     * @param  string  $operator
+     * @param  string  $value
+     * @return string
+     */
+    protected function compileJsonLength($column, $operator, $value)
+    {
+        [$field, $path] = $this->wrapJsonFieldAndPath($column);
+
+        return 'json_array_length('.$field.$path.') '.$operator.' '.$value;
+    }
+
+    /**
+     * Compile a "JSON contains key" statement into SQL.
+     *
+     * @param  string  $column
+     * @return string
+     */
+    protected function compileJsonContainsKey($column)
+    {
+        [$field, $path] = $this->wrapJsonFieldAndPath($column);
+
+        return 'json_type('.$field.$path.') is not null';
+    }
+
+    /**
+     * Compile an update statement into SQL.
+     *
+     * @param  \Illuminate\Database\Query\Builder  $query
+     * @param  array  $values
+     * @return string
+     */
+    public function compileUpdate(Builder $query, array $values)
+    {
+        if (isset($query->joins) || isset($query->limit)) {
+            return $this->compileUpdateWithJoinsOrLimit($query, $values);
+        }
+
+        return parent::compileUpdate($query, $values);
+    }
+
+    /**
+     * Compile an insert ignore statement into SQL.
+     *
+     * @param  \Illuminate\Database\Query\Builder  $query
+     * @param  array  $values
+     * @return string
+     */
+    public function compileInsertOrIgnore(Builder $query, array $values)
+    {
+        return Str::replaceFirst('insert', 'insert or ignore', $this->compileInsert($query, $values));
+    }
+
+    /**
+     * Compile the columns for an update statement.
+     *
+     * @param  \Illuminate\Database\Query\Builder  $query
+     * @param  array  $values
+     * @return string
+     */
+    protected function compileUpdateColumns(Builder $query, array $values)
+    {
+        $jsonGroups = $this->groupJsonColumnsForUpdate($values);
+
+        return collect($values)->reject(function ($value, $key) {
+            return $this->isJsonSelector($key);
+        })->merge($jsonGroups)->map(function ($value, $key) use ($jsonGroups) {
+            $column = last(explode('.', $key));
+
+            $value = isset($jsonGroups[$key]) ? $this->compileJsonPatch($column, $value) : $this->parameter($value);
+
+            return $this->wrap($column).' = '.$value;
+        })->implode(', ');
+    }
+
+    /**
+     * Compile an "upsert" statement into SQL.
+     *
+     * @param  \Illuminate\Database\Query\Builder  $query
+     * @param  array  $values
+     * @param  array  $uniqueBy
+     * @param  array  $update
+     * @return string
+     */
+    public function compileUpsert(Builder $query, array $values, array $uniqueBy, array $update)
+    {
+        $sql = $this->compileInsert($query, $values);
+
+        $sql .= ' on conflict ('.$this->columnize($uniqueBy).') do update set ';
+
+        $columns = collect($update)->map(function ($value, $key) {
+            return is_numeric($key)
+                ? $this->wrap($value).' = '.$this->wrapValue('excluded').'.'.$this->wrap($value)
+                : $this->wrap($key).' = '.$this->parameter($value);
+        })->implode(', ');
+
+        return $sql.$columns;
+    }
+
+    /**
+     * Group the nested JSON columns.
+     *
+     * @param  array  $values
+     * @return array
+     */
+    protected function groupJsonColumnsForUpdate(array $values)
+    {
+        $groups = [];
+
+        foreach ($values as $key => $value) {
+            if ($this->isJsonSelector($key)) {
+                Arr::set($groups, str_replace('->', '.', Str::after($key, '.')), $value);
+            }
+        }
+
+        return $groups;
+    }
+
+    /**
+     * Compile a "JSON" patch statement into SQL.
+     *
+     * @param  string  $column
+     * @param  mixed  $value
+     * @return string
+     */
+    protected function compileJsonPatch($column, $value)
+    {
+        return "json_patch(ifnull({$this->wrap($column)}, json('{}')), json({$this->parameter($value)}))";
+    }
+
+    /**
+     * Compile an update statement with joins or limit into SQL.
+     *
+     * @param  \Illuminate\Database\Query\Builder  $query
+     * @param  array  $values
+     * @return string
+     */
+    protected function compileUpdateWithJoinsOrLimit(Builder $query, array $values)
+    {
+        $table = $this->wrapTable($query->from);
+
+        $columns = $this->compileUpdateColumns($query, $values);
+
+        $alias = last(preg_split('/\s+as\s+/i', $query->from));
+
+        $selectSql = $this->compileSelect($query->select($alias.'.rowid'));
+
+        return "update {$table} set {$columns} where {$this->wrap('rowid')} in ({$selectSql})";
+    }
+
+    /**
+     * Prepare the bindings for an update statement.
+     *
+     * @param  array  $bindings
+     * @param  array  $values
+     * @return array
+     */
+    public function prepareBindingsForUpdate(array $bindings, array $values)
+    {
+        $groups = $this->groupJsonColumnsForUpdate($values);
+
+        $values = collect($values)->reject(function ($value, $key) {
+            return $this->isJsonSelector($key);
+        })->merge($groups)->map(function ($value) {
+            return is_array($value) ? json_encode($value) : $value;
+        })->all();
+
+        $cleanBindings = Arr::except($bindings, 'select');
+
+        return array_values(
+            array_merge($values, Arr::flatten($cleanBindings))
+        );
+    }
+
+    /**
+     * Compile a delete statement into SQL.
+     *
+     * @param  \Illuminate\Database\Query\Builder  $query
+     * @return string
+     */
+    public function compileDelete(Builder $query)
+    {
+        if (isset($query->joins) || isset($query->limit)) {
+            return $this->compileDeleteWithJoinsOrLimit($query);
+        }
+
+        return parent::compileDelete($query);
+    }
+
+    /**
+     * Compile a delete statement with joins or limit into SQL.
+     *
+     * @param  \Illuminate\Database\Query\Builder  $query
+     * @return string
+     */
+    protected function compileDeleteWithJoinsOrLimit(Builder $query)
+    {
+        $table = $this->wrapTable($query->from);
+
+        $alias = last(preg_split('/\s+as\s+/i', $query->from));
+
+        $selectSql = $this->compileSelect($query->select($alias.'.rowid'));
+
+        return "delete from {$table} where {$this->wrap('rowid')} in ({$selectSql})";
+    }
+
+    /**
+     * Compile a truncate table statement into SQL.
+     *
+     * @param  \Illuminate\Database\Query\Builder  $query
+     * @return array
+     */
+    public function compileTruncate(Builder $query)
+    {
+        return [
+            'delete from sqlite_sequence where name = ?' => [$query->from],
+            'delete from '.$this->wrapTable($query->from) => [],
+        ];
+    }
+
+    /**
+     * Wrap the given JSON selector.
+     *
+     * @param  string  $value
+     * @return string
+     */
+    protected function wrapJsonSelector($value)
+    {
+        [$field, $path] = $this->wrapJsonFieldAndPath($value);
+
+        return 'json_extract('.$field.$path.')';
+    }
+}
diff --git a/vendor/illuminate/database/Query/Grammars/SqlServerGrammar.php b/vendor/illuminate/database/Query/Grammars/SqlServerGrammar.php
new file mode 100755
index 0000000..baebb93
--- /dev/null
+++ b/vendor/illuminate/database/Query/Grammars/SqlServerGrammar.php
@@ -0,0 +1,634 @@
+', '<=', '>=', '!<', '!>', '<>', '!=',
+        'like', 'not like', 'ilike',
+        '&', '&=', '|', '|=', '^', '^=',
+    ];
+
+    /**
+     * Compile a select query into SQL.
+     *
+     * @param  \Illuminate\Database\Query\Builder  $query
+     * @return string
+     */
+    public function compileSelect(Builder $query)
+    {
+        if (! $query->offset) {
+            return parent::compileSelect($query);
+        }
+
+        if (is_null($query->columns)) {
+            $query->columns = ['*'];
+        }
+
+        $components = $this->compileComponents($query);
+
+        if (! empty($components['orders'])) {
+            return parent::compileSelect($query)." offset {$query->offset} rows fetch next {$query->limit} rows only";
+        }
+
+        // If an offset is present on the query, we will need to wrap the query in
+        // a big "ANSI" offset syntax block. This is very nasty compared to the
+        // other database systems but is necessary for implementing features.
+        return $this->compileAnsiOffset(
+            $query, $components
+        );
+    }
+
+    /**
+     * Compile the "select *" portion of the query.
+     *
+     * @param  \Illuminate\Database\Query\Builder  $query
+     * @param  array  $columns
+     * @return string|null
+     */
+    protected function compileColumns(Builder $query, $columns)
+    {
+        if (! is_null($query->aggregate)) {
+            return;
+        }
+
+        $select = $query->distinct ? 'select distinct ' : 'select ';
+
+        // If there is a limit on the query, but not an offset, we will add the top
+        // clause to the query, which serves as a "limit" type clause within the
+        // SQL Server system similar to the limit keywords available in MySQL.
+        if (is_numeric($query->limit) && $query->limit > 0 && $query->offset <= 0) {
+            $select .= 'top '.((int) $query->limit).' ';
+        }
+
+        return $select.$this->columnize($columns);
+    }
+
+    /**
+     * Compile the "from" portion of the query.
+     *
+     * @param  \Illuminate\Database\Query\Builder  $query
+     * @param  string  $table
+     * @return string
+     */
+    protected function compileFrom(Builder $query, $table)
+    {
+        $from = parent::compileFrom($query, $table);
+
+        if (is_string($query->lock)) {
+            return $from.' '.$query->lock;
+        }
+
+        if (! is_null($query->lock)) {
+            return $from.' with(rowlock,'.($query->lock ? 'updlock,' : '').'holdlock)';
+        }
+
+        return $from;
+    }
+
+    /**
+     * Compile the index hints for the query.
+     *
+     * @param  \Illuminate\Database\Query\Builder  $query
+     * @param  \Illuminate\Database\Query\IndexHint  $indexHint
+     * @return string
+     */
+    protected function compileIndexHint(Builder $query, $indexHint)
+    {
+        return $indexHint->type === 'force'
+                    ? "with (index({$indexHint->index}))"
+                    : '';
+    }
+
+    /**
+     * {@inheritdoc}
+     *
+     * @param  \Illuminate\Database\Query\Builder  $query
+     * @param  array  $where
+     * @return string
+     */
+    protected function whereBitwise(Builder $query, $where)
+    {
+        $value = $this->parameter($where['value']);
+
+        $operator = str_replace('?', '??', $where['operator']);
+
+        return '('.$this->wrap($where['column']).' '.$operator.' '.$value.') != 0';
+    }
+
+    /**
+     * Compile a "where date" clause.
+     *
+     * @param  \Illuminate\Database\Query\Builder  $query
+     * @param  array  $where
+     * @return string
+     */
+    protected function whereDate(Builder $query, $where)
+    {
+        $value = $this->parameter($where['value']);
+
+        return 'cast('.$this->wrap($where['column']).' as date) '.$where['operator'].' '.$value;
+    }
+
+    /**
+     * Compile a "where time" clause.
+     *
+     * @param  \Illuminate\Database\Query\Builder  $query
+     * @param  array  $where
+     * @return string
+     */
+    protected function whereTime(Builder $query, $where)
+    {
+        $value = $this->parameter($where['value']);
+
+        return 'cast('.$this->wrap($where['column']).' as time) '.$where['operator'].' '.$value;
+    }
+
+    /**
+     * Compile a "JSON contains" statement into SQL.
+     *
+     * @param  string  $column
+     * @param  string  $value
+     * @return string
+     */
+    protected function compileJsonContains($column, $value)
+    {
+        [$field, $path] = $this->wrapJsonFieldAndPath($column);
+
+        return $value.' in (select [value] from openjson('.$field.$path.'))';
+    }
+
+    /**
+     * Prepare the binding for a "JSON contains" statement.
+     *
+     * @param  mixed  $binding
+     * @return string
+     */
+    public function prepareBindingForJsonContains($binding)
+    {
+        return is_bool($binding) ? json_encode($binding) : $binding;
+    }
+
+    /**
+     * Compile a "JSON contains key" statement into SQL.
+     *
+     * @param  string  $column
+     * @return string
+     */
+    protected function compileJsonContainsKey($column)
+    {
+        $segments = explode('->', $column);
+
+        $lastSegment = array_pop($segments);
+
+        if (preg_match('/\[([0-9]+)\]$/', $lastSegment, $matches)) {
+            $segments[] = Str::beforeLast($lastSegment, $matches[0]);
+
+            $key = $matches[1];
+        } else {
+            $key = "'".str_replace("'", "''", $lastSegment)."'";
+        }
+
+        [$field, $path] = $this->wrapJsonFieldAndPath(implode('->', $segments));
+
+        return $key.' in (select [key] from openjson('.$field.$path.'))';
+    }
+
+    /**
+     * Compile a "JSON length" statement into SQL.
+     *
+     * @param  string  $column
+     * @param  string  $operator
+     * @param  string  $value
+     * @return string
+     */
+    protected function compileJsonLength($column, $operator, $value)
+    {
+        [$field, $path] = $this->wrapJsonFieldAndPath($column);
+
+        return '(select count(*) from openjson('.$field.$path.')) '.$operator.' '.$value;
+    }
+
+    /**
+     * Compile a "JSON value cast" statement into SQL.
+     *
+     * @param  string  $value
+     * @return string
+     */
+    public function compileJsonValueCast($value)
+    {
+        return 'json_query('.$value.')';
+    }
+
+    /**
+     * Compile a single having clause.
+     *
+     * @param  array  $having
+     * @return string
+     */
+    protected function compileHaving(array $having)
+    {
+        if ($having['type'] === 'Bitwise') {
+            return $this->compileHavingBitwise($having);
+        }
+
+        return parent::compileHaving($having);
+    }
+
+    /**
+     * Compile a having clause involving a bitwise operator.
+     *
+     * @param  array  $having
+     * @return string
+     */
+    protected function compileHavingBitwise($having)
+    {
+        $column = $this->wrap($having['column']);
+
+        $parameter = $this->parameter($having['value']);
+
+        return '('.$column.' '.$having['operator'].' '.$parameter.') != 0';
+    }
+
+    /**
+     * Create a full ANSI offset clause for the query.
+     *
+     * @param  \Illuminate\Database\Query\Builder  $query
+     * @param  array  $components
+     * @return string
+     */
+    protected function compileAnsiOffset(Builder $query, $components)
+    {
+        // An ORDER BY clause is required to make this offset query work, so if one does
+        // not exist we'll just create a dummy clause to trick the database and so it
+        // does not complain about the queries for not having an "order by" clause.
+        if (empty($components['orders'])) {
+            $components['orders'] = 'order by (select 0)';
+        }
+
+        // We need to add the row number to the query so we can compare it to the offset
+        // and limit values given for the statements. So we will add an expression to
+        // the "select" that will give back the row numbers on each of the records.
+        $components['columns'] .= $this->compileOver($components['orders']);
+
+        unset($components['orders']);
+
+        if ($this->queryOrderContainsSubquery($query)) {
+            $query->bindings = $this->sortBindingsForSubqueryOrderBy($query);
+        }
+
+        // Next we need to calculate the constraints that should be placed on the query
+        // to get the right offset and limit from our query but if there is no limit
+        // set we will just handle the offset only since that is all that matters.
+        $sql = $this->concatenate($components);
+
+        return $this->compileTableExpression($sql, $query);
+    }
+
+    /**
+     * Compile the over statement for a table expression.
+     *
+     * @param  string  $orderings
+     * @return string
+     */
+    protected function compileOver($orderings)
+    {
+        return ", row_number() over ({$orderings}) as row_num";
+    }
+
+    /**
+     * Determine if the query's order by clauses contain a subquery.
+     *
+     * @param  \Illuminate\Database\Query\Builder  $query
+     * @return bool
+     */
+    protected function queryOrderContainsSubquery($query)
+    {
+        if (! is_array($query->orders)) {
+            return false;
+        }
+
+        return Arr::first($query->orders, function ($value) {
+            return $this->isExpression($value['column'] ?? null);
+        }, false) !== false;
+    }
+
+    /**
+     * Move the order bindings to be after the "select" statement to account for an order by subquery.
+     *
+     * @param  \Illuminate\Database\Query\Builder  $query
+     * @return array
+     */
+    protected function sortBindingsForSubqueryOrderBy($query)
+    {
+        return Arr::sort($query->bindings, function ($bindings, $key) {
+            return array_search($key, ['select', 'order', 'from', 'join', 'where', 'groupBy', 'having', 'union', 'unionOrder']);
+        });
+    }
+
+    /**
+     * Compile a common table expression for a query.
+     *
+     * @param  string  $sql
+     * @param  \Illuminate\Database\Query\Builder  $query
+     * @return string
+     */
+    protected function compileTableExpression($sql, $query)
+    {
+        $constraint = $this->compileRowConstraint($query);
+
+        return "select * from ({$sql}) as temp_table where row_num {$constraint} order by row_num";
+    }
+
+    /**
+     * Compile the limit / offset row constraint for a query.
+     *
+     * @param  \Illuminate\Database\Query\Builder  $query
+     * @return string
+     */
+    protected function compileRowConstraint($query)
+    {
+        $start = (int) $query->offset + 1;
+
+        if ($query->limit > 0) {
+            $finish = (int) $query->offset + (int) $query->limit;
+
+            return "between {$start} and {$finish}";
+        }
+
+        return ">= {$start}";
+    }
+
+    /**
+     * Compile a delete statement without joins into SQL.
+     *
+     * @param  \Illuminate\Database\Query\Builder  $query
+     * @param  string  $table
+     * @param  string  $where
+     * @return string
+     */
+    protected function compileDeleteWithoutJoins(Builder $query, $table, $where)
+    {
+        $sql = parent::compileDeleteWithoutJoins($query, $table, $where);
+
+        return ! is_null($query->limit) && $query->limit > 0 && $query->offset <= 0
+                        ? Str::replaceFirst('delete', 'delete top ('.$query->limit.')', $sql)
+                        : $sql;
+    }
+
+    /**
+     * Compile the random statement into SQL.
+     *
+     * @param  string|int  $seed
+     * @return string
+     */
+    public function compileRandom($seed)
+    {
+        return 'NEWID()';
+    }
+
+    /**
+     * Compile the "limit" portions of the query.
+     *
+     * @param  \Illuminate\Database\Query\Builder  $query
+     * @param  int  $limit
+     * @return string
+     */
+    protected function compileLimit(Builder $query, $limit)
+    {
+        return '';
+    }
+
+    /**
+     * Compile the "offset" portions of the query.
+     *
+     * @param  \Illuminate\Database\Query\Builder  $query
+     * @param  int  $offset
+     * @return string
+     */
+    protected function compileOffset(Builder $query, $offset)
+    {
+        return '';
+    }
+
+    /**
+     * Compile the lock into SQL.
+     *
+     * @param  \Illuminate\Database\Query\Builder  $query
+     * @param  bool|string  $value
+     * @return string
+     */
+    protected function compileLock(Builder $query, $value)
+    {
+        return '';
+    }
+
+    /**
+     * Wrap a union subquery in parentheses.
+     *
+     * @param  string  $sql
+     * @return string
+     */
+    protected function wrapUnion($sql)
+    {
+        return 'select * from ('.$sql.') as '.$this->wrapTable('temp_table');
+    }
+
+    /**
+     * Compile an exists statement into SQL.
+     *
+     * @param  \Illuminate\Database\Query\Builder  $query
+     * @return string
+     */
+    public function compileExists(Builder $query)
+    {
+        $existsQuery = clone $query;
+
+        $existsQuery->columns = [];
+
+        return $this->compileSelect($existsQuery->selectRaw('1 [exists]')->limit(1));
+    }
+
+    /**
+     * Compile an update statement with joins into SQL.
+     *
+     * @param  \Illuminate\Database\Query\Builder  $query
+     * @param  string  $table
+     * @param  string  $columns
+     * @param  string  $where
+     * @return string
+     */
+    protected function compileUpdateWithJoins(Builder $query, $table, $columns, $where)
+    {
+        $alias = last(explode(' as ', $table));
+
+        $joins = $this->compileJoins($query, $query->joins);
+
+        return "update {$alias} set {$columns} from {$table} {$joins} {$where}";
+    }
+
+    /**
+     * Compile an "upsert" statement into SQL.
+     *
+     * @param  \Illuminate\Database\Query\Builder  $query
+     * @param  array  $values
+     * @param  array  $uniqueBy
+     * @param  array  $update
+     * @return string
+     */
+    public function compileUpsert(Builder $query, array $values, array $uniqueBy, array $update)
+    {
+        $columns = $this->columnize(array_keys(reset($values)));
+
+        $sql = 'merge '.$this->wrapTable($query->from).' ';
+
+        $parameters = collect($values)->map(function ($record) {
+            return '('.$this->parameterize($record).')';
+        })->implode(', ');
+
+        $sql .= 'using (values '.$parameters.') '.$this->wrapTable('laravel_source').' ('.$columns.') ';
+
+        $on = collect($uniqueBy)->map(function ($column) use ($query) {
+            return $this->wrap('laravel_source.'.$column).' = '.$this->wrap($query->from.'.'.$column);
+        })->implode(' and ');
+
+        $sql .= 'on '.$on.' ';
+
+        if ($update) {
+            $update = collect($update)->map(function ($value, $key) {
+                return is_numeric($key)
+                    ? $this->wrap($value).' = '.$this->wrap('laravel_source.'.$value)
+                    : $this->wrap($key).' = '.$this->parameter($value);
+            })->implode(', ');
+
+            $sql .= 'when matched then update set '.$update.' ';
+        }
+
+        $sql .= 'when not matched then insert ('.$columns.') values ('.$columns.');';
+
+        return $sql;
+    }
+
+    /**
+     * Prepare the bindings for an update statement.
+     *
+     * @param  array  $bindings
+     * @param  array  $values
+     * @return array
+     */
+    public function prepareBindingsForUpdate(array $bindings, array $values)
+    {
+        $cleanBindings = Arr::except($bindings, 'select');
+
+        return array_values(
+            array_merge($values, Arr::flatten($cleanBindings))
+        );
+    }
+
+    /**
+     * Compile the SQL statement to define a savepoint.
+     *
+     * @param  string  $name
+     * @return string
+     */
+    public function compileSavepoint($name)
+    {
+        return 'SAVE TRANSACTION '.$name;
+    }
+
+    /**
+     * Compile the SQL statement to execute a savepoint rollback.
+     *
+     * @param  string  $name
+     * @return string
+     */
+    public function compileSavepointRollBack($name)
+    {
+        return 'ROLLBACK TRANSACTION '.$name;
+    }
+
+    /**
+     * Get the format for database stored dates.
+     *
+     * @return string
+     */
+    public function getDateFormat()
+    {
+        return 'Y-m-d H:i:s.v';
+    }
+
+    /**
+     * Wrap a single string in keyword identifiers.
+     *
+     * @param  string  $value
+     * @return string
+     */
+    protected function wrapValue($value)
+    {
+        return $value === '*' ? $value : '['.str_replace(']', ']]', $value).']';
+    }
+
+    /**
+     * Wrap the given JSON selector.
+     *
+     * @param  string  $value
+     * @return string
+     */
+    protected function wrapJsonSelector($value)
+    {
+        [$field, $path] = $this->wrapJsonFieldAndPath($value);
+
+        return 'json_value('.$field.$path.')';
+    }
+
+    /**
+     * Wrap the given JSON boolean value.
+     *
+     * @param  string  $value
+     * @return string
+     */
+    protected function wrapJsonBooleanValue($value)
+    {
+        return "'".$value."'";
+    }
+
+    /**
+     * Wrap a table in keyword identifiers.
+     *
+     * @param  \Illuminate\Database\Query\Expression|string  $table
+     * @return string
+     */
+    public function wrapTable($table)
+    {
+        if (! $this->isExpression($table)) {
+            return $this->wrapTableValuedFunction(parent::wrapTable($table));
+        }
+
+        return $this->getValue($table);
+    }
+
+    /**
+     * Wrap a table in keyword identifiers.
+     *
+     * @param  string  $table
+     * @return string
+     */
+    protected function wrapTableValuedFunction($table)
+    {
+        if (preg_match('/^(.+?)(\(.*?\))]$/', $table, $matches) === 1) {
+            $table = $matches[1].']'.$matches[2];
+        }
+
+        return $table;
+    }
+}
diff --git a/vendor/illuminate/database/Query/IndexHint.php b/vendor/illuminate/database/Query/IndexHint.php
new file mode 100755
index 0000000..2a720a2
--- /dev/null
+++ b/vendor/illuminate/database/Query/IndexHint.php
@@ -0,0 +1,33 @@
+type = $type;
+        $this->index = $index;
+    }
+}
diff --git a/vendor/illuminate/database/Query/JoinClause.php b/vendor/illuminate/database/Query/JoinClause.php
new file mode 100755
index 0000000..57d650a
--- /dev/null
+++ b/vendor/illuminate/database/Query/JoinClause.php
@@ -0,0 +1,146 @@
+type = $type;
+        $this->table = $table;
+        $this->parentClass = get_class($parentQuery);
+        $this->parentGrammar = $parentQuery->getGrammar();
+        $this->parentProcessor = $parentQuery->getProcessor();
+        $this->parentConnection = $parentQuery->getConnection();
+
+        parent::__construct(
+            $this->parentConnection, $this->parentGrammar, $this->parentProcessor
+        );
+    }
+
+    /**
+     * Add an "on" clause to the join.
+     *
+     * On clauses can be chained, e.g.
+     *
+     *  $join->on('contacts.user_id', '=', 'users.id')
+     *       ->on('contacts.info_id', '=', 'info.id')
+     *
+     * will produce the following SQL:
+     *
+     * on `contacts`.`user_id` = `users`.`id` and `contacts`.`info_id` = `info`.`id`
+     *
+     * @param  \Closure|string  $first
+     * @param  string|null  $operator
+     * @param  \Illuminate\Database\Query\Expression|string|null  $second
+     * @param  string  $boolean
+     * @return $this
+     *
+     * @throws \InvalidArgumentException
+     */
+    public function on($first, $operator = null, $second = null, $boolean = 'and')
+    {
+        if ($first instanceof Closure) {
+            return $this->whereNested($first, $boolean);
+        }
+
+        return $this->whereColumn($first, $operator, $second, $boolean);
+    }
+
+    /**
+     * Add an "or on" clause to the join.
+     *
+     * @param  \Closure|string  $first
+     * @param  string|null  $operator
+     * @param  \Illuminate\Database\Query\Expression|string|null  $second
+     * @return \Illuminate\Database\Query\JoinClause
+     */
+    public function orOn($first, $operator = null, $second = null)
+    {
+        return $this->on($first, $operator, $second, 'or');
+    }
+
+    /**
+     * Get a new instance of the join clause builder.
+     *
+     * @return \Illuminate\Database\Query\JoinClause
+     */
+    public function newQuery()
+    {
+        return new static($this->newParentQuery(), $this->type, $this->table);
+    }
+
+    /**
+     * Create a new query instance for sub-query.
+     *
+     * @return \Illuminate\Database\Query\Builder
+     */
+    protected function forSubQuery()
+    {
+        return $this->newParentQuery()->newQuery();
+    }
+
+    /**
+     * Create a new parent query instance.
+     *
+     * @return \Illuminate\Database\Query\Builder
+     */
+    protected function newParentQuery()
+    {
+        $class = $this->parentClass;
+
+        return new $class($this->parentConnection, $this->parentGrammar, $this->parentProcessor);
+    }
+}
diff --git a/vendor/illuminate/database/Query/Processors/MySqlProcessor.php b/vendor/illuminate/database/Query/Processors/MySqlProcessor.php
new file mode 100644
index 0000000..ce91838
--- /dev/null
+++ b/vendor/illuminate/database/Query/Processors/MySqlProcessor.php
@@ -0,0 +1,19 @@
+column_name;
+        }, $results);
+    }
+}
diff --git a/vendor/illuminate/database/Query/Processors/PostgresProcessor.php b/vendor/illuminate/database/Query/Processors/PostgresProcessor.php
new file mode 100755
index 0000000..5956a8f
--- /dev/null
+++ b/vendor/illuminate/database/Query/Processors/PostgresProcessor.php
@@ -0,0 +1,45 @@
+getConnection();
+
+        $connection->recordsHaveBeenModified();
+
+        $result = $connection->selectFromWriteConnection($sql, $values)[0];
+
+        $sequence = $sequence ?: 'id';
+
+        $id = is_object($result) ? $result->{$sequence} : $result[$sequence];
+
+        return is_numeric($id) ? (int) $id : $id;
+    }
+
+    /**
+     * Process the results of a column listing query.
+     *
+     * @param  array  $results
+     * @return array
+     */
+    public function processColumnListing($results)
+    {
+        return array_map(function ($result) {
+            return ((object) $result)->column_name;
+        }, $results);
+    }
+}
diff --git a/vendor/illuminate/database/Query/Processors/Processor.php b/vendor/illuminate/database/Query/Processors/Processor.php
new file mode 100755
index 0000000..0069b43
--- /dev/null
+++ b/vendor/illuminate/database/Query/Processors/Processor.php
@@ -0,0 +1,49 @@
+getConnection()->insert($sql, $values);
+
+        $id = $query->getConnection()->getPdo()->lastInsertId($sequence);
+
+        return is_numeric($id) ? (int) $id : $id;
+    }
+
+    /**
+     * Process the results of a column listing query.
+     *
+     * @param  array  $results
+     * @return array
+     */
+    public function processColumnListing($results)
+    {
+        return $results;
+    }
+}
diff --git a/vendor/illuminate/database/Query/Processors/SQLiteProcessor.php b/vendor/illuminate/database/Query/Processors/SQLiteProcessor.php
new file mode 100644
index 0000000..65da1df
--- /dev/null
+++ b/vendor/illuminate/database/Query/Processors/SQLiteProcessor.php
@@ -0,0 +1,19 @@
+name;
+        }, $results);
+    }
+}
diff --git a/vendor/illuminate/database/Query/Processors/SqlServerProcessor.php b/vendor/illuminate/database/Query/Processors/SqlServerProcessor.php
new file mode 100755
index 0000000..49476f0
--- /dev/null
+++ b/vendor/illuminate/database/Query/Processors/SqlServerProcessor.php
@@ -0,0 +1,70 @@
+getConnection();
+
+        $connection->insert($sql, $values);
+
+        if ($connection->getConfig('odbc') === true) {
+            $id = $this->processInsertGetIdForOdbc($connection);
+        } else {
+            $id = $connection->getPdo()->lastInsertId();
+        }
+
+        return is_numeric($id) ? (int) $id : $id;
+    }
+
+    /**
+     * Process an "insert get ID" query for ODBC.
+     *
+     * @param  \Illuminate\Database\Connection  $connection
+     * @return int
+     *
+     * @throws \Exception
+     */
+    protected function processInsertGetIdForOdbc(Connection $connection)
+    {
+        $result = $connection->selectFromWriteConnection(
+            'SELECT CAST(COALESCE(SCOPE_IDENTITY(), @@IDENTITY) AS int) AS insertid'
+        );
+
+        if (! $result) {
+            throw new Exception('Unable to retrieve lastInsertID for ODBC.');
+        }
+
+        $row = $result[0];
+
+        return is_object($row) ? $row->insertid : $row['insertid'];
+    }
+
+    /**
+     * Process the results of a column listing query.
+     *
+     * @param  array  $results
+     * @return array
+     */
+    public function processColumnListing($results)
+    {
+        return array_map(function ($result) {
+            return ((object) $result)->name;
+        }, $results);
+    }
+}
diff --git a/vendor/illuminate/database/QueryException.php b/vendor/illuminate/database/QueryException.php
new file mode 100644
index 0000000..74e5a31
--- /dev/null
+++ b/vendor/illuminate/database/QueryException.php
@@ -0,0 +1,79 @@
+sql = $sql;
+        $this->bindings = $bindings;
+        $this->code = $previous->getCode();
+        $this->message = $this->formatMessage($sql, $bindings, $previous);
+
+        if ($previous instanceof PDOException) {
+            $this->errorInfo = $previous->errorInfo;
+        }
+    }
+
+    /**
+     * Format the SQL error message.
+     *
+     * @param  string  $sql
+     * @param  array  $bindings
+     * @param  \Throwable  $previous
+     * @return string
+     */
+    protected function formatMessage($sql, $bindings, Throwable $previous)
+    {
+        return $previous->getMessage().' (SQL: '.Str::replaceArray('?', $bindings, $sql).')';
+    }
+
+    /**
+     * Get the SQL for the query.
+     *
+     * @return string
+     */
+    public function getSql()
+    {
+        return $this->sql;
+    }
+
+    /**
+     * Get the bindings for the query.
+     *
+     * @return array
+     */
+    public function getBindings()
+    {
+        return $this->bindings;
+    }
+}
diff --git a/vendor/illuminate/database/README.md b/vendor/illuminate/database/README.md
new file mode 100755
index 0000000..9019936
--- /dev/null
+++ b/vendor/illuminate/database/README.md
@@ -0,0 +1,69 @@
+## Illuminate Database
+
+The Illuminate Database component is a full database toolkit for PHP, providing an expressive query builder, ActiveRecord style ORM, and schema builder. It currently supports MySQL, Postgres, SQL Server, and SQLite. It also serves as the database layer of the Laravel PHP framework.
+
+### Usage Instructions
+
+First, create a new "Capsule" manager instance. Capsule aims to make configuring the library for usage outside of the Laravel framework as easy as possible.
+
+```PHP
+use Illuminate\Database\Capsule\Manager as Capsule;
+
+$capsule = new Capsule;
+
+$capsule->addConnection([
+    'driver' => 'mysql',
+    'host' => 'localhost',
+    'database' => 'database',
+    'username' => 'root',
+    'password' => 'password',
+    'charset' => 'utf8',
+    'collation' => 'utf8_unicode_ci',
+    'prefix' => '',
+]);
+
+// Set the event dispatcher used by Eloquent models... (optional)
+use Illuminate\Events\Dispatcher;
+use Illuminate\Container\Container;
+$capsule->setEventDispatcher(new Dispatcher(new Container));
+
+// Make this Capsule instance available globally via static methods... (optional)
+$capsule->setAsGlobal();
+
+// Setup the Eloquent ORM... (optional; unless you've used setEventDispatcher())
+$capsule->bootEloquent();
+```
+
+> `composer require "illuminate/events"` required when you need to use observers with Eloquent.
+
+Once the Capsule instance has been registered. You may use it like so:
+
+**Using The Query Builder**
+
+```PHP
+$users = Capsule::table('users')->where('votes', '>', 100)->get();
+```
+Other core methods may be accessed directly from the Capsule in the same manner as from the DB facade:
+```PHP
+$results = Capsule::select('select * from users where id = ?', [1]);
+```
+
+**Using The Schema Builder**
+
+```PHP
+Capsule::schema()->create('users', function ($table) {
+    $table->increments('id');
+    $table->string('email')->unique();
+    $table->timestamps();
+});
+```
+
+**Using The Eloquent ORM**
+
+```PHP
+class User extends Illuminate\Database\Eloquent\Model {}
+
+$users = User::where('votes', '>', 1)->get();
+```
+
+For further documentation on using the various database facilities this library provides, consult the [Laravel framework documentation](https://laravel.com/docs).
diff --git a/vendor/illuminate/database/RecordsNotFoundException.php b/vendor/illuminate/database/RecordsNotFoundException.php
new file mode 100755
index 0000000..3e0d955
--- /dev/null
+++ b/vendor/illuminate/database/RecordsNotFoundException.php
@@ -0,0 +1,10 @@
+getForeignKeyConstraintsConfigurationValue();
+
+        if ($enableForeignKeyConstraints === null) {
+            return;
+        }
+
+        $enableForeignKeyConstraints
+            ? $this->getSchemaBuilder()->enableForeignKeyConstraints()
+            : $this->getSchemaBuilder()->disableForeignKeyConstraints();
+    }
+
+    /**
+     * Get the default query grammar instance.
+     *
+     * @return \Illuminate\Database\Query\Grammars\SQLiteGrammar
+     */
+    protected function getDefaultQueryGrammar()
+    {
+        return $this->withTablePrefix(new QueryGrammar);
+    }
+
+    /**
+     * Get a schema builder instance for the connection.
+     *
+     * @return \Illuminate\Database\Schema\SQLiteBuilder
+     */
+    public function getSchemaBuilder()
+    {
+        if (is_null($this->schemaGrammar)) {
+            $this->useDefaultSchemaGrammar();
+        }
+
+        return new SQLiteBuilder($this);
+    }
+
+    /**
+     * Get the default schema grammar instance.
+     *
+     * @return \Illuminate\Database\Schema\Grammars\SQLiteGrammar
+     */
+    protected function getDefaultSchemaGrammar()
+    {
+        return $this->withTablePrefix(new SchemaGrammar);
+    }
+
+    /**
+     * Get the schema state for the connection.
+     *
+     * @param  \Illuminate\Filesystem\Filesystem|null  $files
+     * @param  callable|null  $processFactory
+     *
+     * @throws \RuntimeException
+     */
+    public function getSchemaState(Filesystem $files = null, callable $processFactory = null)
+    {
+        return new SqliteSchemaState($this, $files, $processFactory);
+    }
+
+    /**
+     * Get the default post processor instance.
+     *
+     * @return \Illuminate\Database\Query\Processors\SQLiteProcessor
+     */
+    protected function getDefaultPostProcessor()
+    {
+        return new SQLiteProcessor;
+    }
+
+    /**
+     * Get the Doctrine DBAL driver.
+     *
+     * @return \Illuminate\Database\PDO\SQLiteDriver
+     */
+    protected function getDoctrineDriver()
+    {
+        return new SQLiteDriver;
+    }
+
+    /**
+     * Get the database connection foreign key constraints configuration option.
+     *
+     * @return bool|null
+     */
+    protected function getForeignKeyConstraintsConfigurationValue()
+    {
+        return $this->getConfig('foreign_key_constraints');
+    }
+}
diff --git a/vendor/illuminate/database/SQLiteDatabaseDoesNotExistException.php b/vendor/illuminate/database/SQLiteDatabaseDoesNotExistException.php
new file mode 100644
index 0000000..f93cfe4
--- /dev/null
+++ b/vendor/illuminate/database/SQLiteDatabaseDoesNotExistException.php
@@ -0,0 +1,28 @@
+path = $path;
+    }
+}
diff --git a/vendor/illuminate/database/Schema/Blueprint.php b/vendor/illuminate/database/Schema/Blueprint.php
new file mode 100755
index 0000000..3ea7d15
--- /dev/null
+++ b/vendor/illuminate/database/Schema/Blueprint.php
@@ -0,0 +1,1829 @@
+table = $table;
+        $this->prefix = $prefix;
+
+        if (! is_null($callback)) {
+            $callback($this);
+        }
+    }
+
+    /**
+     * Execute the blueprint against the database.
+     *
+     * @param  \Illuminate\Database\Connection  $connection
+     * @param  \Illuminate\Database\Schema\Grammars\Grammar  $grammar
+     * @return void
+     */
+    public function build(Connection $connection, Grammar $grammar)
+    {
+        foreach ($this->toSql($connection, $grammar) as $statement) {
+            $connection->statement($statement);
+        }
+    }
+
+    /**
+     * Get the raw SQL statements for the blueprint.
+     *
+     * @param  \Illuminate\Database\Connection  $connection
+     * @param  \Illuminate\Database\Schema\Grammars\Grammar  $grammar
+     * @return array
+     */
+    public function toSql(Connection $connection, Grammar $grammar)
+    {
+        $this->addImpliedCommands($grammar);
+
+        $statements = [];
+
+        // Each type of command has a corresponding compiler function on the schema
+        // grammar which is used to build the necessary SQL statements to build
+        // the blueprint element, so we'll just call that compilers function.
+        $this->ensureCommandsAreValid($connection);
+
+        foreach ($this->commands as $command) {
+            $method = 'compile'.ucfirst($command->name);
+
+            if (method_exists($grammar, $method) || $grammar::hasMacro($method)) {
+                if (! is_null($sql = $grammar->$method($this, $command, $connection))) {
+                    $statements = array_merge($statements, (array) $sql);
+                }
+            }
+        }
+
+        return $statements;
+    }
+
+    /**
+     * Ensure the commands on the blueprint are valid for the connection type.
+     *
+     * @param  \Illuminate\Database\Connection  $connection
+     * @return void
+     *
+     * @throws \BadMethodCallException
+     */
+    protected function ensureCommandsAreValid(Connection $connection)
+    {
+        if ($connection instanceof SQLiteConnection) {
+            if ($this->commandsNamed(['dropColumn', 'renameColumn'])->count() > 1
+                && ! $connection->usingNativeSchemaOperations()) {
+                throw new BadMethodCallException(
+                    "SQLite doesn't support multiple calls to dropColumn / renameColumn in a single modification."
+                );
+            }
+
+            if ($this->commandsNamed(['dropForeign'])->count() > 0) {
+                throw new BadMethodCallException(
+                    "SQLite doesn't support dropping foreign keys (you would need to re-create the table)."
+                );
+            }
+        }
+    }
+
+    /**
+     * Get all of the commands matching the given names.
+     *
+     * @param  array  $names
+     * @return \Illuminate\Support\Collection
+     */
+    protected function commandsNamed(array $names)
+    {
+        return collect($this->commands)->filter(function ($command) use ($names) {
+            return in_array($command->name, $names);
+        });
+    }
+
+    /**
+     * Add the commands that are implied by the blueprint's state.
+     *
+     * @param  \Illuminate\Database\Schema\Grammars\Grammar  $grammar
+     * @return void
+     */
+    protected function addImpliedCommands(Grammar $grammar)
+    {
+        if (count($this->getAddedColumns()) > 0 && ! $this->creating()) {
+            array_unshift($this->commands, $this->createCommand('add'));
+        }
+
+        if (count($this->getChangedColumns()) > 0 && ! $this->creating()) {
+            array_unshift($this->commands, $this->createCommand('change'));
+        }
+
+        $this->addFluentIndexes();
+
+        $this->addFluentCommands($grammar);
+    }
+
+    /**
+     * Add the index commands fluently specified on columns.
+     *
+     * @return void
+     */
+    protected function addFluentIndexes()
+    {
+        foreach ($this->columns as $column) {
+            foreach (['primary', 'unique', 'index', 'fulltext', 'fullText', 'spatialIndex'] as $index) {
+                // If the index has been specified on the given column, but is simply equal
+                // to "true" (boolean), no name has been specified for this index so the
+                // index method can be called without a name and it will generate one.
+                if ($column->{$index} === true) {
+                    $this->{$index}($column->name);
+                    $column->{$index} = null;
+
+                    continue 2;
+                }
+
+                // If the index has been specified on the given column, but it equals false
+                // and the column is supposed to be changed, we will call the drop index
+                // method with an array of column to drop it by its conventional name.
+                elseif ($column->{$index} === false && $column->change) {
+                    $this->{'drop'.ucfirst($index)}([$column->name]);
+                    $column->{$index} = null;
+
+                    continue 2;
+                }
+
+                // If the index has been specified on the given column, and it has a string
+                // value, we'll go ahead and call the index method and pass the name for
+                // the index since the developer specified the explicit name for this.
+                elseif (isset($column->{$index})) {
+                    $this->{$index}($column->name, $column->{$index});
+                    $column->{$index} = null;
+
+                    continue 2;
+                }
+            }
+        }
+    }
+
+    /**
+     * Add the fluent commands specified on any columns.
+     *
+     * @param  \Illuminate\Database\Schema\Grammars\Grammar  $grammar
+     * @return void
+     */
+    public function addFluentCommands(Grammar $grammar)
+    {
+        foreach ($this->columns as $column) {
+            foreach ($grammar->getFluentCommands() as $commandName) {
+                $attributeName = lcfirst($commandName);
+
+                if (! isset($column->{$attributeName})) {
+                    continue;
+                }
+
+                $value = $column->{$attributeName};
+
+                $this->addCommand(
+                    $commandName, compact('value', 'column')
+                );
+            }
+        }
+    }
+
+    /**
+     * Determine if the blueprint has a create command.
+     *
+     * @return bool
+     */
+    public function creating()
+    {
+        return collect($this->commands)->contains(function ($command) {
+            return $command->name === 'create';
+        });
+    }
+
+    /**
+     * Indicate that the table needs to be created.
+     *
+     * @return \Illuminate\Support\Fluent
+     */
+    public function create()
+    {
+        return $this->addCommand('create');
+    }
+
+    /**
+     * Indicate that the table needs to be temporary.
+     *
+     * @return void
+     */
+    public function temporary()
+    {
+        $this->temporary = true;
+    }
+
+    /**
+     * Indicate that the table should be dropped.
+     *
+     * @return \Illuminate\Support\Fluent
+     */
+    public function drop()
+    {
+        return $this->addCommand('drop');
+    }
+
+    /**
+     * Indicate that the table should be dropped if it exists.
+     *
+     * @return \Illuminate\Support\Fluent
+     */
+    public function dropIfExists()
+    {
+        return $this->addCommand('dropIfExists');
+    }
+
+    /**
+     * Indicate that the given columns should be dropped.
+     *
+     * @param  array|mixed  $columns
+     * @return \Illuminate\Support\Fluent
+     */
+    public function dropColumn($columns)
+    {
+        $columns = is_array($columns) ? $columns : func_get_args();
+
+        return $this->addCommand('dropColumn', compact('columns'));
+    }
+
+    /**
+     * Indicate that the given columns should be renamed.
+     *
+     * @param  string  $from
+     * @param  string  $to
+     * @return \Illuminate\Support\Fluent
+     */
+    public function renameColumn($from, $to)
+    {
+        return $this->addCommand('renameColumn', compact('from', 'to'));
+    }
+
+    /**
+     * Indicate that the given primary key should be dropped.
+     *
+     * @param  string|array|null  $index
+     * @return \Illuminate\Support\Fluent
+     */
+    public function dropPrimary($index = null)
+    {
+        return $this->dropIndexCommand('dropPrimary', 'primary', $index);
+    }
+
+    /**
+     * Indicate that the given unique key should be dropped.
+     *
+     * @param  string|array  $index
+     * @return \Illuminate\Support\Fluent
+     */
+    public function dropUnique($index)
+    {
+        return $this->dropIndexCommand('dropUnique', 'unique', $index);
+    }
+
+    /**
+     * Indicate that the given index should be dropped.
+     *
+     * @param  string|array  $index
+     * @return \Illuminate\Support\Fluent
+     */
+    public function dropIndex($index)
+    {
+        return $this->dropIndexCommand('dropIndex', 'index', $index);
+    }
+
+    /**
+     * Indicate that the given fulltext index should be dropped.
+     *
+     * @param  string|array  $index
+     * @return \Illuminate\Support\Fluent
+     */
+    public function dropFullText($index)
+    {
+        return $this->dropIndexCommand('dropFullText', 'fulltext', $index);
+    }
+
+    /**
+     * Indicate that the given spatial index should be dropped.
+     *
+     * @param  string|array  $index
+     * @return \Illuminate\Support\Fluent
+     */
+    public function dropSpatialIndex($index)
+    {
+        return $this->dropIndexCommand('dropSpatialIndex', 'spatialIndex', $index);
+    }
+
+    /**
+     * Indicate that the given foreign key should be dropped.
+     *
+     * @param  string|array  $index
+     * @return \Illuminate\Support\Fluent
+     */
+    public function dropForeign($index)
+    {
+        return $this->dropIndexCommand('dropForeign', 'foreign', $index);
+    }
+
+    /**
+     * Indicate that the given column and foreign key should be dropped.
+     *
+     * @param  string  $column
+     * @return \Illuminate\Support\Fluent
+     */
+    public function dropConstrainedForeignId($column)
+    {
+        $this->dropForeign([$column]);
+
+        return $this->dropColumn($column);
+    }
+
+    /**
+     * Indicate that the given foreign key should be dropped.
+     *
+     * @param  \Illuminate\Database\Eloquent\Model|string  $model
+     * @param  string|null  $column
+     * @return \Illuminate\Support\Fluent
+     */
+    public function dropForeignIdFor($model, $column = null)
+    {
+        if (is_string($model)) {
+            $model = new $model;
+        }
+
+        return $this->dropForeign([$column ?: $model->getForeignKey()]);
+    }
+
+    /**
+     * Indicate that the given foreign key should be dropped.
+     *
+     * @param  \Illuminate\Database\Eloquent\Model|string  $model
+     * @param  string|null  $column
+     * @return \Illuminate\Support\Fluent
+     */
+    public function dropConstrainedForeignIdFor($model, $column = null)
+    {
+        if (is_string($model)) {
+            $model = new $model;
+        }
+
+        return $this->dropConstrainedForeignId($column ?: $model->getForeignKey());
+    }
+
+    /**
+     * Indicate that the given indexes should be renamed.
+     *
+     * @param  string  $from
+     * @param  string  $to
+     * @return \Illuminate\Support\Fluent
+     */
+    public function renameIndex($from, $to)
+    {
+        return $this->addCommand('renameIndex', compact('from', 'to'));
+    }
+
+    /**
+     * Indicate that the timestamp columns should be dropped.
+     *
+     * @return void
+     */
+    public function dropTimestamps()
+    {
+        $this->dropColumn('created_at', 'updated_at');
+    }
+
+    /**
+     * Indicate that the timestamp columns should be dropped.
+     *
+     * @return void
+     */
+    public function dropTimestampsTz()
+    {
+        $this->dropTimestamps();
+    }
+
+    /**
+     * Indicate that the soft delete column should be dropped.
+     *
+     * @param  string  $column
+     * @return void
+     */
+    public function dropSoftDeletes($column = 'deleted_at')
+    {
+        $this->dropColumn($column);
+    }
+
+    /**
+     * Indicate that the soft delete column should be dropped.
+     *
+     * @param  string  $column
+     * @return void
+     */
+    public function dropSoftDeletesTz($column = 'deleted_at')
+    {
+        $this->dropSoftDeletes($column);
+    }
+
+    /**
+     * Indicate that the remember token column should be dropped.
+     *
+     * @return void
+     */
+    public function dropRememberToken()
+    {
+        $this->dropColumn('remember_token');
+    }
+
+    /**
+     * Indicate that the polymorphic columns should be dropped.
+     *
+     * @param  string  $name
+     * @param  string|null  $indexName
+     * @return void
+     */
+    public function dropMorphs($name, $indexName = null)
+    {
+        $this->dropIndex($indexName ?: $this->createIndexName('index', ["{$name}_type", "{$name}_id"]));
+
+        $this->dropColumn("{$name}_type", "{$name}_id");
+    }
+
+    /**
+     * Rename the table to a given name.
+     *
+     * @param  string  $to
+     * @return \Illuminate\Support\Fluent
+     */
+    public function rename($to)
+    {
+        return $this->addCommand('rename', compact('to'));
+    }
+
+    /**
+     * Specify the primary key(s) for the table.
+     *
+     * @param  string|array  $columns
+     * @param  string|null  $name
+     * @param  string|null  $algorithm
+     * @return \Illuminate\Database\Schema\IndexDefinition
+     */
+    public function primary($columns, $name = null, $algorithm = null)
+    {
+        return $this->indexCommand('primary', $columns, $name, $algorithm);
+    }
+
+    /**
+     * Specify a unique index for the table.
+     *
+     * @param  string|array  $columns
+     * @param  string|null  $name
+     * @param  string|null  $algorithm
+     * @return \Illuminate\Database\Schema\IndexDefinition
+     */
+    public function unique($columns, $name = null, $algorithm = null)
+    {
+        return $this->indexCommand('unique', $columns, $name, $algorithm);
+    }
+
+    /**
+     * Specify an index for the table.
+     *
+     * @param  string|array  $columns
+     * @param  string|null  $name
+     * @param  string|null  $algorithm
+     * @return \Illuminate\Database\Schema\IndexDefinition
+     */
+    public function index($columns, $name = null, $algorithm = null)
+    {
+        return $this->indexCommand('index', $columns, $name, $algorithm);
+    }
+
+    /**
+     * Specify an fulltext for the table.
+     *
+     * @param  string|array  $columns
+     * @param  string|null  $name
+     * @param  string|null  $algorithm
+     * @return \Illuminate\Database\Schema\IndexDefinition
+     */
+    public function fullText($columns, $name = null, $algorithm = null)
+    {
+        return $this->indexCommand('fulltext', $columns, $name, $algorithm);
+    }
+
+    /**
+     * Specify a spatial index for the table.
+     *
+     * @param  string|array  $columns
+     * @param  string|null  $name
+     * @return \Illuminate\Database\Schema\IndexDefinition
+     */
+    public function spatialIndex($columns, $name = null)
+    {
+        return $this->indexCommand('spatialIndex', $columns, $name);
+    }
+
+    /**
+     * Specify a raw index for the table.
+     *
+     * @param  string  $expression
+     * @param  string  $name
+     * @return \Illuminate\Database\Schema\IndexDefinition
+     */
+    public function rawIndex($expression, $name)
+    {
+        return $this->index([new Expression($expression)], $name);
+    }
+
+    /**
+     * Specify a foreign key for the table.
+     *
+     * @param  string|array  $columns
+     * @param  string|null  $name
+     * @return \Illuminate\Database\Schema\ForeignKeyDefinition
+     */
+    public function foreign($columns, $name = null)
+    {
+        $command = new ForeignKeyDefinition(
+            $this->indexCommand('foreign', $columns, $name)->getAttributes()
+        );
+
+        $this->commands[count($this->commands) - 1] = $command;
+
+        return $command;
+    }
+
+    /**
+     * Create a new auto-incrementing big integer (8-byte) column on the table.
+     *
+     * @param  string  $column
+     * @return \Illuminate\Database\Schema\ColumnDefinition
+     */
+    public function id($column = 'id')
+    {
+        return $this->bigIncrements($column);
+    }
+
+    /**
+     * Create a new auto-incrementing integer (4-byte) column on the table.
+     *
+     * @param  string  $column
+     * @return \Illuminate\Database\Schema\ColumnDefinition
+     */
+    public function increments($column)
+    {
+        return $this->unsignedInteger($column, true);
+    }
+
+    /**
+     * Create a new auto-incrementing integer (4-byte) column on the table.
+     *
+     * @param  string  $column
+     * @return \Illuminate\Database\Schema\ColumnDefinition
+     */
+    public function integerIncrements($column)
+    {
+        return $this->unsignedInteger($column, true);
+    }
+
+    /**
+     * Create a new auto-incrementing tiny integer (1-byte) column on the table.
+     *
+     * @param  string  $column
+     * @return \Illuminate\Database\Schema\ColumnDefinition
+     */
+    public function tinyIncrements($column)
+    {
+        return $this->unsignedTinyInteger($column, true);
+    }
+
+    /**
+     * Create a new auto-incrementing small integer (2-byte) column on the table.
+     *
+     * @param  string  $column
+     * @return \Illuminate\Database\Schema\ColumnDefinition
+     */
+    public function smallIncrements($column)
+    {
+        return $this->unsignedSmallInteger($column, true);
+    }
+
+    /**
+     * Create a new auto-incrementing medium integer (3-byte) column on the table.
+     *
+     * @param  string  $column
+     * @return \Illuminate\Database\Schema\ColumnDefinition
+     */
+    public function mediumIncrements($column)
+    {
+        return $this->unsignedMediumInteger($column, true);
+    }
+
+    /**
+     * Create a new auto-incrementing big integer (8-byte) column on the table.
+     *
+     * @param  string  $column
+     * @return \Illuminate\Database\Schema\ColumnDefinition
+     */
+    public function bigIncrements($column)
+    {
+        return $this->unsignedBigInteger($column, true);
+    }
+
+    /**
+     * Create a new char column on the table.
+     *
+     * @param  string  $column
+     * @param  int|null  $length
+     * @return \Illuminate\Database\Schema\ColumnDefinition
+     */
+    public function char($column, $length = null)
+    {
+        $length = ! is_null($length) ? $length : Builder::$defaultStringLength;
+
+        return $this->addColumn('char', $column, compact('length'));
+    }
+
+    /**
+     * Create a new string column on the table.
+     *
+     * @param  string  $column
+     * @param  int|null  $length
+     * @return \Illuminate\Database\Schema\ColumnDefinition
+     */
+    public function string($column, $length = null)
+    {
+        $length = $length ?: Builder::$defaultStringLength;
+
+        return $this->addColumn('string', $column, compact('length'));
+    }
+
+    /**
+     * Create a new tiny text column on the table.
+     *
+     * @param  string  $column
+     * @return \Illuminate\Database\Schema\ColumnDefinition
+     */
+    public function tinyText($column)
+    {
+        return $this->addColumn('tinyText', $column);
+    }
+
+    /**
+     * Create a new text column on the table.
+     *
+     * @param  string  $column
+     * @return \Illuminate\Database\Schema\ColumnDefinition
+     */
+    public function text($column)
+    {
+        return $this->addColumn('text', $column);
+    }
+
+    /**
+     * Create a new medium text column on the table.
+     *
+     * @param  string  $column
+     * @return \Illuminate\Database\Schema\ColumnDefinition
+     */
+    public function mediumText($column)
+    {
+        return $this->addColumn('mediumText', $column);
+    }
+
+    /**
+     * Create a new long text column on the table.
+     *
+     * @param  string  $column
+     * @return \Illuminate\Database\Schema\ColumnDefinition
+     */
+    public function longText($column)
+    {
+        return $this->addColumn('longText', $column);
+    }
+
+    /**
+     * Create a new integer (4-byte) column on the table.
+     *
+     * @param  string  $column
+     * @param  bool  $autoIncrement
+     * @param  bool  $unsigned
+     * @return \Illuminate\Database\Schema\ColumnDefinition
+     */
+    public function integer($column, $autoIncrement = false, $unsigned = false)
+    {
+        return $this->addColumn('integer', $column, compact('autoIncrement', 'unsigned'));
+    }
+
+    /**
+     * Create a new tiny integer (1-byte) column on the table.
+     *
+     * @param  string  $column
+     * @param  bool  $autoIncrement
+     * @param  bool  $unsigned
+     * @return \Illuminate\Database\Schema\ColumnDefinition
+     */
+    public function tinyInteger($column, $autoIncrement = false, $unsigned = false)
+    {
+        return $this->addColumn('tinyInteger', $column, compact('autoIncrement', 'unsigned'));
+    }
+
+    /**
+     * Create a new small integer (2-byte) column on the table.
+     *
+     * @param  string  $column
+     * @param  bool  $autoIncrement
+     * @param  bool  $unsigned
+     * @return \Illuminate\Database\Schema\ColumnDefinition
+     */
+    public function smallInteger($column, $autoIncrement = false, $unsigned = false)
+    {
+        return $this->addColumn('smallInteger', $column, compact('autoIncrement', 'unsigned'));
+    }
+
+    /**
+     * Create a new medium integer (3-byte) column on the table.
+     *
+     * @param  string  $column
+     * @param  bool  $autoIncrement
+     * @param  bool  $unsigned
+     * @return \Illuminate\Database\Schema\ColumnDefinition
+     */
+    public function mediumInteger($column, $autoIncrement = false, $unsigned = false)
+    {
+        return $this->addColumn('mediumInteger', $column, compact('autoIncrement', 'unsigned'));
+    }
+
+    /**
+     * Create a new big integer (8-byte) column on the table.
+     *
+     * @param  string  $column
+     * @param  bool  $autoIncrement
+     * @param  bool  $unsigned
+     * @return \Illuminate\Database\Schema\ColumnDefinition
+     */
+    public function bigInteger($column, $autoIncrement = false, $unsigned = false)
+    {
+        return $this->addColumn('bigInteger', $column, compact('autoIncrement', 'unsigned'));
+    }
+
+    /**
+     * Create a new unsigned integer (4-byte) column on the table.
+     *
+     * @param  string  $column
+     * @param  bool  $autoIncrement
+     * @return \Illuminate\Database\Schema\ColumnDefinition
+     */
+    public function unsignedInteger($column, $autoIncrement = false)
+    {
+        return $this->integer($column, $autoIncrement, true);
+    }
+
+    /**
+     * Create a new unsigned tiny integer (1-byte) column on the table.
+     *
+     * @param  string  $column
+     * @param  bool  $autoIncrement
+     * @return \Illuminate\Database\Schema\ColumnDefinition
+     */
+    public function unsignedTinyInteger($column, $autoIncrement = false)
+    {
+        return $this->tinyInteger($column, $autoIncrement, true);
+    }
+
+    /**
+     * Create a new unsigned small integer (2-byte) column on the table.
+     *
+     * @param  string  $column
+     * @param  bool  $autoIncrement
+     * @return \Illuminate\Database\Schema\ColumnDefinition
+     */
+    public function unsignedSmallInteger($column, $autoIncrement = false)
+    {
+        return $this->smallInteger($column, $autoIncrement, true);
+    }
+
+    /**
+     * Create a new unsigned medium integer (3-byte) column on the table.
+     *
+     * @param  string  $column
+     * @param  bool  $autoIncrement
+     * @return \Illuminate\Database\Schema\ColumnDefinition
+     */
+    public function unsignedMediumInteger($column, $autoIncrement = false)
+    {
+        return $this->mediumInteger($column, $autoIncrement, true);
+    }
+
+    /**
+     * Create a new unsigned big integer (8-byte) column on the table.
+     *
+     * @param  string  $column
+     * @param  bool  $autoIncrement
+     * @return \Illuminate\Database\Schema\ColumnDefinition
+     */
+    public function unsignedBigInteger($column, $autoIncrement = false)
+    {
+        return $this->bigInteger($column, $autoIncrement, true);
+    }
+
+    /**
+     * Create a new unsigned big integer (8-byte) column on the table.
+     *
+     * @param  string  $column
+     * @return \Illuminate\Database\Schema\ForeignIdColumnDefinition
+     */
+    public function foreignId($column)
+    {
+        return $this->addColumnDefinition(new ForeignIdColumnDefinition($this, [
+            'type' => 'bigInteger',
+            'name' => $column,
+            'autoIncrement' => false,
+            'unsigned' => true,
+        ]));
+    }
+
+    /**
+     * Create a foreign ID column for the given model.
+     *
+     * @param  \Illuminate\Database\Eloquent\Model|string  $model
+     * @param  string|null  $column
+     * @return \Illuminate\Database\Schema\ForeignIdColumnDefinition
+     */
+    public function foreignIdFor($model, $column = null)
+    {
+        if (is_string($model)) {
+            $model = new $model;
+        }
+
+        return $model->getKeyType() === 'int' && $model->getIncrementing()
+                    ? $this->foreignId($column ?: $model->getForeignKey())
+                    : $this->foreignUuid($column ?: $model->getForeignKey());
+    }
+
+    /**
+     * Create a new float column on the table.
+     *
+     * @param  string  $column
+     * @param  int  $total
+     * @param  int  $places
+     * @param  bool  $unsigned
+     * @return \Illuminate\Database\Schema\ColumnDefinition
+     */
+    public function float($column, $total = 8, $places = 2, $unsigned = false)
+    {
+        return $this->addColumn('float', $column, compact('total', 'places', 'unsigned'));
+    }
+
+    /**
+     * Create a new double column on the table.
+     *
+     * @param  string  $column
+     * @param  int|null  $total
+     * @param  int|null  $places
+     * @param  bool  $unsigned
+     * @return \Illuminate\Database\Schema\ColumnDefinition
+     */
+    public function double($column, $total = null, $places = null, $unsigned = false)
+    {
+        return $this->addColumn('double', $column, compact('total', 'places', 'unsigned'));
+    }
+
+    /**
+     * Create a new decimal column on the table.
+     *
+     * @param  string  $column
+     * @param  int  $total
+     * @param  int  $places
+     * @param  bool  $unsigned
+     * @return \Illuminate\Database\Schema\ColumnDefinition
+     */
+    public function decimal($column, $total = 8, $places = 2, $unsigned = false)
+    {
+        return $this->addColumn('decimal', $column, compact('total', 'places', 'unsigned'));
+    }
+
+    /**
+     * Create a new unsigned float column on the table.
+     *
+     * @param  string  $column
+     * @param  int  $total
+     * @param  int  $places
+     * @return \Illuminate\Database\Schema\ColumnDefinition
+     */
+    public function unsignedFloat($column, $total = 8, $places = 2)
+    {
+        return $this->float($column, $total, $places, true);
+    }
+
+    /**
+     * Create a new unsigned double column on the table.
+     *
+     * @param  string  $column
+     * @param  int  $total
+     * @param  int  $places
+     * @return \Illuminate\Database\Schema\ColumnDefinition
+     */
+    public function unsignedDouble($column, $total = null, $places = null)
+    {
+        return $this->double($column, $total, $places, true);
+    }
+
+    /**
+     * Create a new unsigned decimal column on the table.
+     *
+     * @param  string  $column
+     * @param  int  $total
+     * @param  int  $places
+     * @return \Illuminate\Database\Schema\ColumnDefinition
+     */
+    public function unsignedDecimal($column, $total = 8, $places = 2)
+    {
+        return $this->decimal($column, $total, $places, true);
+    }
+
+    /**
+     * Create a new boolean column on the table.
+     *
+     * @param  string  $column
+     * @return \Illuminate\Database\Schema\ColumnDefinition
+     */
+    public function boolean($column)
+    {
+        return $this->addColumn('boolean', $column);
+    }
+
+    /**
+     * Create a new enum column on the table.
+     *
+     * @param  string  $column
+     * @param  array  $allowed
+     * @return \Illuminate\Database\Schema\ColumnDefinition
+     */
+    public function enum($column, array $allowed)
+    {
+        return $this->addColumn('enum', $column, compact('allowed'));
+    }
+
+    /**
+     * Create a new set column on the table.
+     *
+     * @param  string  $column
+     * @param  array  $allowed
+     * @return \Illuminate\Database\Schema\ColumnDefinition
+     */
+    public function set($column, array $allowed)
+    {
+        return $this->addColumn('set', $column, compact('allowed'));
+    }
+
+    /**
+     * Create a new json column on the table.
+     *
+     * @param  string  $column
+     * @return \Illuminate\Database\Schema\ColumnDefinition
+     */
+    public function json($column)
+    {
+        return $this->addColumn('json', $column);
+    }
+
+    /**
+     * Create a new jsonb column on the table.
+     *
+     * @param  string  $column
+     * @return \Illuminate\Database\Schema\ColumnDefinition
+     */
+    public function jsonb($column)
+    {
+        return $this->addColumn('jsonb', $column);
+    }
+
+    /**
+     * Create a new date column on the table.
+     *
+     * @param  string  $column
+     * @return \Illuminate\Database\Schema\ColumnDefinition
+     */
+    public function date($column)
+    {
+        return $this->addColumn('date', $column);
+    }
+
+    /**
+     * Create a new date-time column on the table.
+     *
+     * @param  string  $column
+     * @param  int|null  $precision
+     * @return \Illuminate\Database\Schema\ColumnDefinition
+     */
+    public function dateTime($column, $precision = 0)
+    {
+        return $this->addColumn('dateTime', $column, compact('precision'));
+    }
+
+    /**
+     * Create a new date-time column (with time zone) on the table.
+     *
+     * @param  string  $column
+     * @param  int|null  $precision
+     * @return \Illuminate\Database\Schema\ColumnDefinition
+     */
+    public function dateTimeTz($column, $precision = 0)
+    {
+        return $this->addColumn('dateTimeTz', $column, compact('precision'));
+    }
+
+    /**
+     * Create a new time column on the table.
+     *
+     * @param  string  $column
+     * @param  int|null  $precision
+     * @return \Illuminate\Database\Schema\ColumnDefinition
+     */
+    public function time($column, $precision = 0)
+    {
+        return $this->addColumn('time', $column, compact('precision'));
+    }
+
+    /**
+     * Create a new time column (with time zone) on the table.
+     *
+     * @param  string  $column
+     * @param  int|null  $precision
+     * @return \Illuminate\Database\Schema\ColumnDefinition
+     */
+    public function timeTz($column, $precision = 0)
+    {
+        return $this->addColumn('timeTz', $column, compact('precision'));
+    }
+
+    /**
+     * Create a new timestamp column on the table.
+     *
+     * @param  string  $column
+     * @param  int|null  $precision
+     * @return \Illuminate\Database\Schema\ColumnDefinition
+     */
+    public function timestamp($column, $precision = 0)
+    {
+        return $this->addColumn('timestamp', $column, compact('precision'));
+    }
+
+    /**
+     * Create a new timestamp (with time zone) column on the table.
+     *
+     * @param  string  $column
+     * @param  int|null  $precision
+     * @return \Illuminate\Database\Schema\ColumnDefinition
+     */
+    public function timestampTz($column, $precision = 0)
+    {
+        return $this->addColumn('timestampTz', $column, compact('precision'));
+    }
+
+    /**
+     * Add nullable creation and update timestamps to the table.
+     *
+     * @param  int|null  $precision
+     * @return void
+     */
+    public function timestamps($precision = 0)
+    {
+        $this->timestamp('created_at', $precision)->nullable();
+
+        $this->timestamp('updated_at', $precision)->nullable();
+    }
+
+    /**
+     * Add nullable creation and update timestamps to the table.
+     *
+     * Alias for self::timestamps().
+     *
+     * @param  int|null  $precision
+     * @return void
+     */
+    public function nullableTimestamps($precision = 0)
+    {
+        $this->timestamps($precision);
+    }
+
+    /**
+     * Add creation and update timestampTz columns to the table.
+     *
+     * @param  int|null  $precision
+     * @return void
+     */
+    public function timestampsTz($precision = 0)
+    {
+        $this->timestampTz('created_at', $precision)->nullable();
+
+        $this->timestampTz('updated_at', $precision)->nullable();
+    }
+
+    /**
+     * Add a "deleted at" timestamp for the table.
+     *
+     * @param  string  $column
+     * @param  int|null  $precision
+     * @return \Illuminate\Database\Schema\ColumnDefinition
+     */
+    public function softDeletes($column = 'deleted_at', $precision = 0)
+    {
+        return $this->timestamp($column, $precision)->nullable();
+    }
+
+    /**
+     * Add a "deleted at" timestampTz for the table.
+     *
+     * @param  string  $column
+     * @param  int|null  $precision
+     * @return \Illuminate\Database\Schema\ColumnDefinition
+     */
+    public function softDeletesTz($column = 'deleted_at', $precision = 0)
+    {
+        return $this->timestampTz($column, $precision)->nullable();
+    }
+
+    /**
+     * Create a new year column on the table.
+     *
+     * @param  string  $column
+     * @return \Illuminate\Database\Schema\ColumnDefinition
+     */
+    public function year($column)
+    {
+        return $this->addColumn('year', $column);
+    }
+
+    /**
+     * Create a new binary column on the table.
+     *
+     * @param  string  $column
+     * @return \Illuminate\Database\Schema\ColumnDefinition
+     */
+    public function binary($column)
+    {
+        return $this->addColumn('binary', $column);
+    }
+
+    /**
+     * Create a new UUID column on the table.
+     *
+     * @param  string  $column
+     * @return \Illuminate\Database\Schema\ColumnDefinition
+     */
+    public function uuid($column = 'uuid')
+    {
+        return $this->addColumn('uuid', $column);
+    }
+
+    /**
+     * Create a new UUID column on the table with a foreign key constraint.
+     *
+     * @param  string  $column
+     * @return \Illuminate\Database\Schema\ForeignIdColumnDefinition
+     */
+    public function foreignUuid($column)
+    {
+        return $this->addColumnDefinition(new ForeignIdColumnDefinition($this, [
+            'type' => 'uuid',
+            'name' => $column,
+        ]));
+    }
+
+    /**
+     * Create a new ULID column on the table.
+     *
+     * @param  string  $column
+     * @param  int|null  $length
+     * @return \Illuminate\Database\Schema\ColumnDefinition
+     */
+    public function ulid($column = 'uuid', $length = 26)
+    {
+        return $this->char($column, $length);
+    }
+
+    /**
+     * Create a new ULID column on the table with a foreign key constraint.
+     *
+     * @param  string  $column
+     * @param  int|null  $length
+     * @return \Illuminate\Database\Schema\ForeignIdColumnDefinition
+     */
+    public function foreignUlid($column, $length = 26)
+    {
+        return $this->addColumnDefinition(new ForeignIdColumnDefinition($this, [
+            'type' => 'char',
+            'name' => $column,
+            'length' => $length,
+        ]));
+    }
+
+    /**
+     * Create a new IP address column on the table.
+     *
+     * @param  string  $column
+     * @return \Illuminate\Database\Schema\ColumnDefinition
+     */
+    public function ipAddress($column = 'ip_address')
+    {
+        return $this->addColumn('ipAddress', $column);
+    }
+
+    /**
+     * Create a new MAC address column on the table.
+     *
+     * @param  string  $column
+     * @return \Illuminate\Database\Schema\ColumnDefinition
+     */
+    public function macAddress($column = 'mac_address')
+    {
+        return $this->addColumn('macAddress', $column);
+    }
+
+    /**
+     * Create a new geometry column on the table.
+     *
+     * @param  string  $column
+     * @return \Illuminate\Database\Schema\ColumnDefinition
+     */
+    public function geometry($column)
+    {
+        return $this->addColumn('geometry', $column);
+    }
+
+    /**
+     * Create a new point column on the table.
+     *
+     * @param  string  $column
+     * @param  int|null  $srid
+     * @return \Illuminate\Database\Schema\ColumnDefinition
+     */
+    public function point($column, $srid = null)
+    {
+        return $this->addColumn('point', $column, compact('srid'));
+    }
+
+    /**
+     * Create a new linestring column on the table.
+     *
+     * @param  string  $column
+     * @return \Illuminate\Database\Schema\ColumnDefinition
+     */
+    public function lineString($column)
+    {
+        return $this->addColumn('linestring', $column);
+    }
+
+    /**
+     * Create a new polygon column on the table.
+     *
+     * @param  string  $column
+     * @return \Illuminate\Database\Schema\ColumnDefinition
+     */
+    public function polygon($column)
+    {
+        return $this->addColumn('polygon', $column);
+    }
+
+    /**
+     * Create a new geometrycollection column on the table.
+     *
+     * @param  string  $column
+     * @return \Illuminate\Database\Schema\ColumnDefinition
+     */
+    public function geometryCollection($column)
+    {
+        return $this->addColumn('geometrycollection', $column);
+    }
+
+    /**
+     * Create a new multipoint column on the table.
+     *
+     * @param  string  $column
+     * @return \Illuminate\Database\Schema\ColumnDefinition
+     */
+    public function multiPoint($column)
+    {
+        return $this->addColumn('multipoint', $column);
+    }
+
+    /**
+     * Create a new multilinestring column on the table.
+     *
+     * @param  string  $column
+     * @return \Illuminate\Database\Schema\ColumnDefinition
+     */
+    public function multiLineString($column)
+    {
+        return $this->addColumn('multilinestring', $column);
+    }
+
+    /**
+     * Create a new multipolygon column on the table.
+     *
+     * @param  string  $column
+     * @return \Illuminate\Database\Schema\ColumnDefinition
+     */
+    public function multiPolygon($column)
+    {
+        return $this->addColumn('multipolygon', $column);
+    }
+
+    /**
+     * Create a new multipolygon column on the table.
+     *
+     * @param  string  $column
+     * @return \Illuminate\Database\Schema\ColumnDefinition
+     */
+    public function multiPolygonZ($column)
+    {
+        return $this->addColumn('multipolygonz', $column);
+    }
+
+    /**
+     * Create a new generated, computed column on the table.
+     *
+     * @param  string  $column
+     * @param  string  $expression
+     * @return \Illuminate\Database\Schema\ColumnDefinition
+     */
+    public function computed($column, $expression)
+    {
+        return $this->addColumn('computed', $column, compact('expression'));
+    }
+
+    /**
+     * Add the proper columns for a polymorphic table.
+     *
+     * @param  string  $name
+     * @param  string|null  $indexName
+     * @return void
+     */
+    public function morphs($name, $indexName = null)
+    {
+        if (Builder::$defaultMorphKeyType === 'uuid') {
+            $this->uuidMorphs($name, $indexName);
+        } elseif (Builder::$defaultMorphKeyType === 'ulid') {
+            $this->ulidMorphs($name, $indexName);
+        } else {
+            $this->numericMorphs($name, $indexName);
+        }
+    }
+
+    /**
+     * Add nullable columns for a polymorphic table.
+     *
+     * @param  string  $name
+     * @param  string|null  $indexName
+     * @return void
+     */
+    public function nullableMorphs($name, $indexName = null)
+    {
+        if (Builder::$defaultMorphKeyType === 'uuid') {
+            $this->nullableUuidMorphs($name, $indexName);
+        } elseif (Builder::$defaultMorphKeyType === 'ulid') {
+            $this->nullableUlidMorphs($name, $indexName);
+        } else {
+            $this->nullableNumericMorphs($name, $indexName);
+        }
+    }
+
+    /**
+     * Add the proper columns for a polymorphic table using numeric IDs (incremental).
+     *
+     * @param  string  $name
+     * @param  string|null  $indexName
+     * @return void
+     */
+    public function numericMorphs($name, $indexName = null)
+    {
+        $this->string("{$name}_type");
+
+        $this->unsignedBigInteger("{$name}_id");
+
+        $this->index(["{$name}_type", "{$name}_id"], $indexName);
+    }
+
+    /**
+     * Add nullable columns for a polymorphic table using numeric IDs (incremental).
+     *
+     * @param  string  $name
+     * @param  string|null  $indexName
+     * @return void
+     */
+    public function nullableNumericMorphs($name, $indexName = null)
+    {
+        $this->string("{$name}_type")->nullable();
+
+        $this->unsignedBigInteger("{$name}_id")->nullable();
+
+        $this->index(["{$name}_type", "{$name}_id"], $indexName);
+    }
+
+    /**
+     * Add the proper columns for a polymorphic table using UUIDs.
+     *
+     * @param  string  $name
+     * @param  string|null  $indexName
+     * @return void
+     */
+    public function uuidMorphs($name, $indexName = null)
+    {
+        $this->string("{$name}_type");
+
+        $this->uuid("{$name}_id");
+
+        $this->index(["{$name}_type", "{$name}_id"], $indexName);
+    }
+
+    /**
+     * Add nullable columns for a polymorphic table using UUIDs.
+     *
+     * @param  string  $name
+     * @param  string|null  $indexName
+     * @return void
+     */
+    public function nullableUuidMorphs($name, $indexName = null)
+    {
+        $this->string("{$name}_type")->nullable();
+
+        $this->uuid("{$name}_id")->nullable();
+
+        $this->index(["{$name}_type", "{$name}_id"], $indexName);
+    }
+
+    /**
+     * Add the proper columns for a polymorphic table using ULIDs.
+     *
+     * @param  string  $name
+     * @param  string|null  $indexName
+     * @return void
+     */
+    public function ulidMorphs($name, $indexName = null)
+    {
+        $this->string("{$name}_type");
+
+        $this->ulid("{$name}_id");
+
+        $this->index(["{$name}_type", "{$name}_id"], $indexName);
+    }
+
+    /**
+     * Add nullable columns for a polymorphic table using ULIDs.
+     *
+     * @param  string  $name
+     * @param  string|null  $indexName
+     * @return void
+     */
+    public function nullableUlidMorphs($name, $indexName = null)
+    {
+        $this->string("{$name}_type")->nullable();
+
+        $this->ulid("{$name}_id")->nullable();
+
+        $this->index(["{$name}_type", "{$name}_id"], $indexName);
+    }
+
+    /**
+     * Adds the `remember_token` column to the table.
+     *
+     * @return \Illuminate\Database\Schema\ColumnDefinition
+     */
+    public function rememberToken()
+    {
+        return $this->string('remember_token', 100)->nullable();
+    }
+
+    /**
+     * Add a comment to the table.
+     *
+     * @param  string  $comment
+     * @return \Illuminate\Support\Fluent
+     */
+    public function comment($comment)
+    {
+        return $this->addCommand('tableComment', compact('comment'));
+    }
+
+    /**
+     * Add a new index command to the blueprint.
+     *
+     * @param  string  $type
+     * @param  string|array  $columns
+     * @param  string  $index
+     * @param  string|null  $algorithm
+     * @return \Illuminate\Support\Fluent
+     */
+    protected function indexCommand($type, $columns, $index, $algorithm = null)
+    {
+        $columns = (array) $columns;
+
+        // If no name was specified for this index, we will create one using a basic
+        // convention of the table name, followed by the columns, followed by an
+        // index type, such as primary or index, which makes the index unique.
+        $index = $index ?: $this->createIndexName($type, $columns);
+
+        return $this->addCommand(
+            $type, compact('index', 'columns', 'algorithm')
+        );
+    }
+
+    /**
+     * Create a new drop index command on the blueprint.
+     *
+     * @param  string  $command
+     * @param  string  $type
+     * @param  string|array  $index
+     * @return \Illuminate\Support\Fluent
+     */
+    protected function dropIndexCommand($command, $type, $index)
+    {
+        $columns = [];
+
+        // If the given "index" is actually an array of columns, the developer means
+        // to drop an index merely by specifying the columns involved without the
+        // conventional name, so we will build the index name from the columns.
+        if (is_array($index)) {
+            $index = $this->createIndexName($type, $columns = $index);
+        }
+
+        return $this->indexCommand($command, $columns, $index);
+    }
+
+    /**
+     * Create a default index name for the table.
+     *
+     * @param  string  $type
+     * @param  array  $columns
+     * @return string
+     */
+    protected function createIndexName($type, array $columns)
+    {
+        $index = strtolower($this->prefix.$this->table.'_'.implode('_', $columns).'_'.$type);
+
+        return str_replace(['-', '.'], '_', $index);
+    }
+
+    /**
+     * Add a new column to the blueprint.
+     *
+     * @param  string  $type
+     * @param  string  $name
+     * @param  array  $parameters
+     * @return \Illuminate\Database\Schema\ColumnDefinition
+     */
+    public function addColumn($type, $name, array $parameters = [])
+    {
+        return $this->addColumnDefinition(new ColumnDefinition(
+            array_merge(compact('type', 'name'), $parameters)
+        ));
+    }
+
+    /**
+     * Add a new column definition to the blueprint.
+     *
+     * @param  \Illuminate\Database\Schema\ColumnDefinition  $definition
+     * @return \Illuminate\Database\Schema\ColumnDefinition
+     */
+    protected function addColumnDefinition($definition)
+    {
+        $this->columns[] = $definition;
+
+        if ($this->after) {
+            $definition->after($this->after);
+
+            $this->after = $definition->name;
+        }
+
+        return $definition;
+    }
+
+    /**
+     * Add the columns from the callback after the given column.
+     *
+     * @param  string  $column
+     * @param  \Closure  $callback
+     * @return void
+     */
+    public function after($column, Closure $callback)
+    {
+        $this->after = $column;
+
+        $callback($this);
+
+        $this->after = null;
+    }
+
+    /**
+     * Remove a column from the schema blueprint.
+     *
+     * @param  string  $name
+     * @return $this
+     */
+    public function removeColumn($name)
+    {
+        $this->columns = array_values(array_filter($this->columns, function ($c) use ($name) {
+            return $c['name'] != $name;
+        }));
+
+        return $this;
+    }
+
+    /**
+     * Add a new command to the blueprint.
+     *
+     * @param  string  $name
+     * @param  array  $parameters
+     * @return \Illuminate\Support\Fluent
+     */
+    protected function addCommand($name, array $parameters = [])
+    {
+        $this->commands[] = $command = $this->createCommand($name, $parameters);
+
+        return $command;
+    }
+
+    /**
+     * Create a new Fluent command.
+     *
+     * @param  string  $name
+     * @param  array  $parameters
+     * @return \Illuminate\Support\Fluent
+     */
+    protected function createCommand($name, array $parameters = [])
+    {
+        return new Fluent(array_merge(compact('name'), $parameters));
+    }
+
+    /**
+     * Get the table the blueprint describes.
+     *
+     * @return string
+     */
+    public function getTable()
+    {
+        return $this->table;
+    }
+
+    /**
+     * Get the columns on the blueprint.
+     *
+     * @return \Illuminate\Database\Schema\ColumnDefinition[]
+     */
+    public function getColumns()
+    {
+        return $this->columns;
+    }
+
+    /**
+     * Get the commands on the blueprint.
+     *
+     * @return \Illuminate\Support\Fluent[]
+     */
+    public function getCommands()
+    {
+        return $this->commands;
+    }
+
+    /**
+     * Get the columns on the blueprint that should be added.
+     *
+     * @return \Illuminate\Database\Schema\ColumnDefinition[]
+     */
+    public function getAddedColumns()
+    {
+        return array_filter($this->columns, function ($column) {
+            return ! $column->change;
+        });
+    }
+
+    /**
+     * Get the columns on the blueprint that should be changed.
+     *
+     * @return \Illuminate\Database\Schema\ColumnDefinition[]
+     */
+    public function getChangedColumns()
+    {
+        return array_filter($this->columns, function ($column) {
+            return (bool) $column->change;
+        });
+    }
+
+    /**
+     * Determine if the blueprint has auto-increment columns.
+     *
+     * @return bool
+     */
+    public function hasAutoIncrementColumn()
+    {
+        return ! is_null(collect($this->getAddedColumns())->first(function ($column) {
+            return $column->autoIncrement === true;
+        }));
+    }
+
+    /**
+     * Get the auto-increment column starting values.
+     *
+     * @return array
+     */
+    public function autoIncrementingStartingValues()
+    {
+        if (! $this->hasAutoIncrementColumn()) {
+            return [];
+        }
+
+        return collect($this->getAddedColumns())->mapWithKeys(function ($column) {
+            return $column->autoIncrement === true
+                        ? [$column->name => $column->get('startingValue', $column->get('from'))]
+                        : [$column->name => null];
+        })->filter()->all();
+    }
+}
diff --git a/vendor/illuminate/database/Schema/Builder.php b/vendor/illuminate/database/Schema/Builder.php
new file mode 100755
index 0000000..88cd965
--- /dev/null
+++ b/vendor/illuminate/database/Schema/Builder.php
@@ -0,0 +1,495 @@
+connection = $connection;
+        $this->grammar = $connection->getSchemaGrammar();
+    }
+
+    /**
+     * Set the default string length for migrations.
+     *
+     * @param  int  $length
+     * @return void
+     */
+    public static function defaultStringLength($length)
+    {
+        static::$defaultStringLength = $length;
+    }
+
+    /**
+     * Set the default morph key type for migrations.
+     *
+     * @param  string  $type
+     * @return void
+     *
+     * @throws \InvalidArgumentException
+     */
+    public static function defaultMorphKeyType(string $type)
+    {
+        if (! in_array($type, ['int', 'uuid', 'ulid'])) {
+            throw new InvalidArgumentException("Morph key type must be 'int', 'uuid', or 'ulid'.");
+        }
+
+        static::$defaultMorphKeyType = $type;
+    }
+
+    /**
+     * Set the default morph key type for migrations to UUIDs.
+     *
+     * @return void
+     */
+    public static function morphUsingUuids()
+    {
+        return static::defaultMorphKeyType('uuid');
+    }
+
+    /**
+     * Set the default morph key type for migrations to ULIDs.
+     *
+     * @return void
+     */
+    public static function morphUsingUlids()
+    {
+        return static::defaultMorphKeyType('ulid');
+    }
+
+    /**
+     * Attempt to use native schema operations for dropping and renaming columns, even if Doctrine DBAL is installed.
+     *
+     * @param  bool  $value
+     * @return void
+     */
+    public static function useNativeSchemaOperationsIfPossible(bool $value = true)
+    {
+        static::$alwaysUsesNativeSchemaOperationsIfPossible = $value;
+    }
+
+    /**
+     * Create a database in the schema.
+     *
+     * @param  string  $name
+     * @return bool
+     *
+     * @throws \LogicException
+     */
+    public function createDatabase($name)
+    {
+        throw new LogicException('This database driver does not support creating databases.');
+    }
+
+    /**
+     * Drop a database from the schema if the database exists.
+     *
+     * @param  string  $name
+     * @return bool
+     *
+     * @throws \LogicException
+     */
+    public function dropDatabaseIfExists($name)
+    {
+        throw new LogicException('This database driver does not support dropping databases.');
+    }
+
+    /**
+     * Determine if the given table exists.
+     *
+     * @param  string  $table
+     * @return bool
+     */
+    public function hasTable($table)
+    {
+        $table = $this->connection->getTablePrefix().$table;
+
+        return count($this->connection->selectFromWriteConnection(
+            $this->grammar->compileTableExists(), [$table]
+        )) > 0;
+    }
+
+    /**
+     * Determine if the given table has a given column.
+     *
+     * @param  string  $table
+     * @param  string  $column
+     * @return bool
+     */
+    public function hasColumn($table, $column)
+    {
+        return in_array(
+            strtolower($column), array_map('strtolower', $this->getColumnListing($table))
+        );
+    }
+
+    /**
+     * Determine if the given table has given columns.
+     *
+     * @param  string  $table
+     * @param  array  $columns
+     * @return bool
+     */
+    public function hasColumns($table, array $columns)
+    {
+        $tableColumns = array_map('strtolower', $this->getColumnListing($table));
+
+        foreach ($columns as $column) {
+            if (! in_array(strtolower($column), $tableColumns)) {
+                return false;
+            }
+        }
+
+        return true;
+    }
+
+    /**
+     * Execute a table builder callback if the given table has a given column.
+     *
+     * @param  string  $table
+     * @param  string  $column
+     * @param  \Closure  $callback
+     * @return void
+     */
+    public function whenTableHasColumn(string $table, string $column, Closure $callback)
+    {
+        if ($this->hasColumn($table, $column)) {
+            $this->table($table, fn (Blueprint $table) => $callback($table));
+        }
+    }
+
+    /**
+     * Execute a table builder callback if the given table doesn't have a given column.
+     *
+     * @param  string  $table
+     * @param  string  $column
+     * @param  \Closure  $callback
+     * @return void
+     */
+    public function whenTableDoesntHaveColumn(string $table, string $column, Closure $callback)
+    {
+        if (! $this->hasColumn($table, $column)) {
+            $this->table($table, fn (Blueprint $table) => $callback($table));
+        }
+    }
+
+    /**
+     * Get the data type for the given column name.
+     *
+     * @param  string  $table
+     * @param  string  $column
+     * @return string
+     */
+    public function getColumnType($table, $column)
+    {
+        $table = $this->connection->getTablePrefix().$table;
+
+        return $this->connection->getDoctrineColumn($table, $column)->getType()->getName();
+    }
+
+    /**
+     * Get the column listing for a given table.
+     *
+     * @param  string  $table
+     * @return array
+     */
+    public function getColumnListing($table)
+    {
+        $results = $this->connection->selectFromWriteConnection($this->grammar->compileColumnListing(
+            $this->connection->getTablePrefix().$table
+        ));
+
+        return $this->connection->getPostProcessor()->processColumnListing($results);
+    }
+
+    /**
+     * Modify a table on the schema.
+     *
+     * @param  string  $table
+     * @param  \Closure  $callback
+     * @return void
+     */
+    public function table($table, Closure $callback)
+    {
+        $this->build($this->createBlueprint($table, $callback));
+    }
+
+    /**
+     * Create a new table on the schema.
+     *
+     * @param  string  $table
+     * @param  \Closure  $callback
+     * @return void
+     */
+    public function create($table, Closure $callback)
+    {
+        $this->build(tap($this->createBlueprint($table), function ($blueprint) use ($callback) {
+            $blueprint->create();
+
+            $callback($blueprint);
+        }));
+    }
+
+    /**
+     * Drop a table from the schema.
+     *
+     * @param  string  $table
+     * @return void
+     */
+    public function drop($table)
+    {
+        $this->build(tap($this->createBlueprint($table), function ($blueprint) {
+            $blueprint->drop();
+        }));
+    }
+
+    /**
+     * Drop a table from the schema if it exists.
+     *
+     * @param  string  $table
+     * @return void
+     */
+    public function dropIfExists($table)
+    {
+        $this->build(tap($this->createBlueprint($table), function ($blueprint) {
+            $blueprint->dropIfExists();
+        }));
+    }
+
+    /**
+     * Drop columns from a table schema.
+     *
+     * @param  string  $table
+     * @param  string|array  $columns
+     * @return void
+     */
+    public function dropColumns($table, $columns)
+    {
+        $this->table($table, function (Blueprint $blueprint) use ($columns) {
+            $blueprint->dropColumn($columns);
+        });
+    }
+
+    /**
+     * Drop all tables from the database.
+     *
+     * @return void
+     *
+     * @throws \LogicException
+     */
+    public function dropAllTables()
+    {
+        throw new LogicException('This database driver does not support dropping all tables.');
+    }
+
+    /**
+     * Drop all views from the database.
+     *
+     * @return void
+     *
+     * @throws \LogicException
+     */
+    public function dropAllViews()
+    {
+        throw new LogicException('This database driver does not support dropping all views.');
+    }
+
+    /**
+     * Drop all types from the database.
+     *
+     * @return void
+     *
+     * @throws \LogicException
+     */
+    public function dropAllTypes()
+    {
+        throw new LogicException('This database driver does not support dropping all types.');
+    }
+
+    /**
+     * Get all of the table names for the database.
+     *
+     * @return void
+     *
+     * @throws \LogicException
+     */
+    public function getAllTables()
+    {
+        throw new LogicException('This database driver does not support getting all tables.');
+    }
+
+    /**
+     * Rename a table on the schema.
+     *
+     * @param  string  $from
+     * @param  string  $to
+     * @return void
+     */
+    public function rename($from, $to)
+    {
+        $this->build(tap($this->createBlueprint($from), function ($blueprint) use ($to) {
+            $blueprint->rename($to);
+        }));
+    }
+
+    /**
+     * Enable foreign key constraints.
+     *
+     * @return bool
+     */
+    public function enableForeignKeyConstraints()
+    {
+        return $this->connection->statement(
+            $this->grammar->compileEnableForeignKeyConstraints()
+        );
+    }
+
+    /**
+     * Disable foreign key constraints.
+     *
+     * @return bool
+     */
+    public function disableForeignKeyConstraints()
+    {
+        return $this->connection->statement(
+            $this->grammar->compileDisableForeignKeyConstraints()
+        );
+    }
+
+    /**
+     * Disable foreign key constraints during the execution of a callback.
+     *
+     * @param  \Closure  $callback
+     * @return mixed
+     */
+    public function withoutForeignKeyConstraints(Closure $callback)
+    {
+        $this->disableForeignKeyConstraints();
+
+        $result = $callback();
+
+        $this->enableForeignKeyConstraints();
+
+        return $result;
+    }
+
+    /**
+     * Execute the blueprint to build / modify the table.
+     *
+     * @param  \Illuminate\Database\Schema\Blueprint  $blueprint
+     * @return void
+     */
+    protected function build(Blueprint $blueprint)
+    {
+        $blueprint->build($this->connection, $this->grammar);
+    }
+
+    /**
+     * Create a new command set with a Closure.
+     *
+     * @param  string  $table
+     * @param  \Closure|null  $callback
+     * @return \Illuminate\Database\Schema\Blueprint
+     */
+    protected function createBlueprint($table, Closure $callback = null)
+    {
+        $prefix = $this->connection->getConfig('prefix_indexes')
+                    ? $this->connection->getConfig('prefix')
+                    : '';
+
+        if (isset($this->resolver)) {
+            return call_user_func($this->resolver, $table, $callback, $prefix);
+        }
+
+        return Container::getInstance()->make(Blueprint::class, compact('table', 'callback', 'prefix'));
+    }
+
+    /**
+     * Get the database connection instance.
+     *
+     * @return \Illuminate\Database\Connection
+     */
+    public function getConnection()
+    {
+        return $this->connection;
+    }
+
+    /**
+     * Set the database connection instance.
+     *
+     * @param  \Illuminate\Database\Connection  $connection
+     * @return $this
+     */
+    public function setConnection(Connection $connection)
+    {
+        $this->connection = $connection;
+
+        return $this;
+    }
+
+    /**
+     * Set the Schema Blueprint resolver callback.
+     *
+     * @param  \Closure  $resolver
+     * @return void
+     */
+    public function blueprintResolver(Closure $resolver)
+    {
+        $this->resolver = $resolver;
+    }
+}
diff --git a/vendor/illuminate/database/Schema/ColumnDefinition.php b/vendor/illuminate/database/Schema/ColumnDefinition.php
new file mode 100644
index 0000000..51265ac
--- /dev/null
+++ b/vendor/illuminate/database/Schema/ColumnDefinition.php
@@ -0,0 +1,38 @@
+blueprint = $blueprint;
+    }
+
+    /**
+     * Create a foreign key constraint on this column referencing the "id" column of the conventionally related table.
+     *
+     * @param  string|null  $table
+     * @param  string  $column
+     * @return \Illuminate\Database\Schema\ForeignKeyDefinition
+     */
+    public function constrained($table = null, $column = 'id')
+    {
+        return $this->references($column)->on($table ?? Str::of($this->name)->beforeLast('_'.$column)->plural());
+    }
+
+    /**
+     * Specify which column this foreign ID references on another table.
+     *
+     * @param  string  $column
+     * @return \Illuminate\Database\Schema\ForeignKeyDefinition
+     */
+    public function references($column)
+    {
+        return $this->blueprint->foreign($this->name)->references($column);
+    }
+}
diff --git a/vendor/illuminate/database/Schema/ForeignKeyDefinition.php b/vendor/illuminate/database/Schema/ForeignKeyDefinition.php
new file mode 100644
index 0000000..3bb8b71
--- /dev/null
+++ b/vendor/illuminate/database/Schema/ForeignKeyDefinition.php
@@ -0,0 +1,76 @@
+onUpdate('cascade');
+    }
+
+    /**
+     * Indicate that updates should be restricted.
+     *
+     * @return $this
+     */
+    public function restrictOnUpdate()
+    {
+        return $this->onUpdate('restrict');
+    }
+
+    /**
+     * Indicate that deletes should cascade.
+     *
+     * @return $this
+     */
+    public function cascadeOnDelete()
+    {
+        return $this->onDelete('cascade');
+    }
+
+    /**
+     * Indicate that deletes should be restricted.
+     *
+     * @return $this
+     */
+    public function restrictOnDelete()
+    {
+        return $this->onDelete('restrict');
+    }
+
+    /**
+     * Indicate that deletes should set the foreign key value to null.
+     *
+     * @return $this
+     */
+    public function nullOnDelete()
+    {
+        return $this->onDelete('set null');
+    }
+
+    /**
+     * Indicate that deletes should have "no action".
+     *
+     * @return $this
+     */
+    public function noActionOnDelete()
+    {
+        return $this->onDelete('no action');
+    }
+}
diff --git a/vendor/illuminate/database/Schema/Grammars/ChangeColumn.php b/vendor/illuminate/database/Schema/Grammars/ChangeColumn.php
new file mode 100644
index 0000000..9579222
--- /dev/null
+++ b/vendor/illuminate/database/Schema/Grammars/ChangeColumn.php
@@ -0,0 +1,235 @@
+isDoctrineAvailable()) {
+            throw new RuntimeException(sprintf(
+                'Changing columns for table "%s" requires Doctrine DBAL. Please install the doctrine/dbal package.',
+                $blueprint->getTable()
+            ));
+        }
+
+        $schema = $connection->getDoctrineSchemaManager();
+        $databasePlatform = $schema->getDatabasePlatform();
+        $databasePlatform->registerDoctrineTypeMapping('enum', 'string');
+
+        $tableDiff = static::getChangedDiff(
+            $grammar, $blueprint, $schema
+        );
+
+        if ($tableDiff !== false) {
+            return (array) $databasePlatform->getAlterTableSQL($tableDiff);
+        }
+
+        return [];
+    }
+
+    /**
+     * Get the Doctrine table difference for the given changes.
+     *
+     * @param  \Illuminate\Database\Schema\Grammars\Grammar  $grammar
+     * @param  \Illuminate\Database\Schema\Blueprint  $blueprint
+     * @param  \Doctrine\DBAL\Schema\AbstractSchemaManager  $schema
+     * @return \Doctrine\DBAL\Schema\TableDiff|bool
+     */
+    protected static function getChangedDiff($grammar, Blueprint $blueprint, SchemaManager $schema)
+    {
+        $current = $schema->listTableDetails($grammar->getTablePrefix().$blueprint->getTable());
+
+        return (new Comparator)->diffTable(
+            $current, static::getTableWithColumnChanges($blueprint, $current)
+        );
+    }
+
+    /**
+     * Get a copy of the given Doctrine table after making the column changes.
+     *
+     * @param  \Illuminate\Database\Schema\Blueprint  $blueprint
+     * @param  \Doctrine\DBAL\Schema\Table  $table
+     * @return \Doctrine\DBAL\Schema\Table
+     */
+    protected static function getTableWithColumnChanges(Blueprint $blueprint, Table $table)
+    {
+        $table = clone $table;
+
+        foreach ($blueprint->getChangedColumns() as $fluent) {
+            $column = static::getDoctrineColumn($table, $fluent);
+
+            // Here we will spin through each fluent column definition and map it to the proper
+            // Doctrine column definitions - which is necessary because Laravel and Doctrine
+            // use some different terminology for various column attributes on the tables.
+            foreach ($fluent->getAttributes() as $key => $value) {
+                if (! is_null($option = static::mapFluentOptionToDoctrine($key))) {
+                    if (method_exists($column, $method = 'set'.ucfirst($option))) {
+                        $column->{$method}(static::mapFluentValueToDoctrine($option, $value));
+                        continue;
+                    }
+
+                    $column->setCustomSchemaOption($option, static::mapFluentValueToDoctrine($option, $value));
+                }
+            }
+        }
+
+        return $table;
+    }
+
+    /**
+     * Get the Doctrine column instance for a column change.
+     *
+     * @param  \Doctrine\DBAL\Schema\Table  $table
+     * @param  \Illuminate\Support\Fluent  $fluent
+     * @return \Doctrine\DBAL\Schema\Column
+     */
+    protected static function getDoctrineColumn(Table $table, Fluent $fluent)
+    {
+        return $table->changeColumn(
+            $fluent['name'], static::getDoctrineColumnChangeOptions($fluent)
+        )->getColumn($fluent['name']);
+    }
+
+    /**
+     * Get the Doctrine column change options.
+     *
+     * @param  \Illuminate\Support\Fluent  $fluent
+     * @return array
+     */
+    protected static function getDoctrineColumnChangeOptions(Fluent $fluent)
+    {
+        $options = ['type' => static::getDoctrineColumnType($fluent['type'])];
+
+        if (in_array($fluent['type'], ['tinyText', 'text', 'mediumText', 'longText'])) {
+            $options['length'] = static::calculateDoctrineTextLength($fluent['type']);
+        }
+
+        if ($fluent['type'] === 'char') {
+            $options['fixed'] = true;
+        }
+
+        if (static::doesntNeedCharacterOptions($fluent['type'])) {
+            $options['customSchemaOptions'] = [
+                'collation' => '',
+                'charset' => '',
+            ];
+        }
+
+        return $options;
+    }
+
+    /**
+     * Get the doctrine column type.
+     *
+     * @param  string  $type
+     * @return \Doctrine\DBAL\Types\Type
+     */
+    protected static function getDoctrineColumnType($type)
+    {
+        $type = strtolower($type);
+
+        return Type::getType(match ($type) {
+            'biginteger' => 'bigint',
+            'smallinteger' => 'smallint',
+            'tinytext', 'mediumtext', 'longtext' => 'text',
+            'binary' => 'blob',
+            'uuid' => 'guid',
+            'char' => 'string',
+            'double' => 'float',
+            default => $type,
+        });
+    }
+
+    /**
+     * Calculate the proper column length to force the Doctrine text type.
+     *
+     * @param  string  $type
+     * @return int
+     */
+    protected static function calculateDoctrineTextLength($type)
+    {
+        return match ($type) {
+            'tinyText' => 1,
+            'mediumText' => 65535 + 1,
+            'longText' => 16777215 + 1,
+            default => 255 + 1,
+        };
+    }
+
+    /**
+     * Determine if the given type does not need character / collation options.
+     *
+     * @param  string  $type
+     * @return bool
+     */
+    protected static function doesntNeedCharacterOptions($type)
+    {
+        return in_array($type, [
+            'bigInteger',
+            'binary',
+            'boolean',
+            'date',
+            'dateTime',
+            'decimal',
+            'double',
+            'float',
+            'integer',
+            'json',
+            'mediumInteger',
+            'smallInteger',
+            'time',
+            'timestamp',
+            'tinyInteger',
+        ]);
+    }
+
+    /**
+     * Get the matching Doctrine option for a given Fluent attribute name.
+     *
+     * @param  string  $attribute
+     * @return string|null
+     */
+    protected static function mapFluentOptionToDoctrine($attribute)
+    {
+        return match ($attribute) {
+            'type', 'name' => null,
+            'nullable' => 'notnull',
+            'total' => 'precision',
+            'places' => 'scale',
+            default => $attribute,
+        };
+    }
+
+    /**
+     * Get the matching Doctrine value for a given Fluent attribute.
+     *
+     * @param  string  $option
+     * @param  mixed  $value
+     * @return mixed
+     */
+    protected static function mapFluentValueToDoctrine($option, $value)
+    {
+        return $option === 'notnull' ? ! $value : $value;
+    }
+}
diff --git a/vendor/illuminate/database/Schema/Grammars/Grammar.php b/vendor/illuminate/database/Schema/Grammars/Grammar.php
new file mode 100755
index 0000000..ea8333e
--- /dev/null
+++ b/vendor/illuminate/database/Schema/Grammars/Grammar.php
@@ -0,0 +1,345 @@
+wrapTable($blueprint),
+            $this->wrap($command->index)
+        );
+
+        // Once we have the initial portion of the SQL statement we will add on the
+        // key name, table name, and referenced columns. These will complete the
+        // main portion of the SQL statement and this SQL will almost be done.
+        $sql .= sprintf('foreign key (%s) references %s (%s)',
+            $this->columnize($command->columns),
+            $this->wrapTable($command->on),
+            $this->columnize((array) $command->references)
+        );
+
+        // Once we have the basic foreign key creation statement constructed we can
+        // build out the syntax for what should happen on an update or delete of
+        // the affected columns, which will get something like "cascade", etc.
+        if (! is_null($command->onDelete)) {
+            $sql .= " on delete {$command->onDelete}";
+        }
+
+        if (! is_null($command->onUpdate)) {
+            $sql .= " on update {$command->onUpdate}";
+        }
+
+        return $sql;
+    }
+
+    /**
+     * Compile the blueprint's column definitions.
+     *
+     * @param  \Illuminate\Database\Schema\Blueprint  $blueprint
+     * @return array
+     */
+    protected function getColumns(Blueprint $blueprint)
+    {
+        $columns = [];
+
+        foreach ($blueprint->getAddedColumns() as $column) {
+            // Each of the column types has their own compiler functions, which are tasked
+            // with turning the column definition into its SQL format for this platform
+            // used by the connection. The column's modifiers are compiled and added.
+            $sql = $this->wrap($column).' '.$this->getType($column);
+
+            $columns[] = $this->addModifiers($sql, $blueprint, $column);
+        }
+
+        return $columns;
+    }
+
+    /**
+     * Get the SQL for the column data type.
+     *
+     * @param  \Illuminate\Support\Fluent  $column
+     * @return string
+     */
+    protected function getType(Fluent $column)
+    {
+        return $this->{'type'.ucfirst($column->type)}($column);
+    }
+
+    /**
+     * Create the column definition for a generated, computed column type.
+     *
+     * @param  \Illuminate\Support\Fluent  $column
+     * @return void
+     *
+     * @throws \RuntimeException
+     */
+    protected function typeComputed(Fluent $column)
+    {
+        throw new RuntimeException('This database driver does not support the computed type.');
+    }
+
+    /**
+     * Add the column modifiers to the definition.
+     *
+     * @param  string  $sql
+     * @param  \Illuminate\Database\Schema\Blueprint  $blueprint
+     * @param  \Illuminate\Support\Fluent  $column
+     * @return string
+     */
+    protected function addModifiers($sql, Blueprint $blueprint, Fluent $column)
+    {
+        foreach ($this->modifiers as $modifier) {
+            if (method_exists($this, $method = "modify{$modifier}")) {
+                $sql .= $this->{$method}($blueprint, $column);
+            }
+        }
+
+        return $sql;
+    }
+
+    /**
+     * Get the primary key command if it exists on the blueprint.
+     *
+     * @param  \Illuminate\Database\Schema\Blueprint  $blueprint
+     * @param  string  $name
+     * @return \Illuminate\Support\Fluent|null
+     */
+    protected function getCommandByName(Blueprint $blueprint, $name)
+    {
+        $commands = $this->getCommandsByName($blueprint, $name);
+
+        if (count($commands) > 0) {
+            return reset($commands);
+        }
+    }
+
+    /**
+     * Get all of the commands with a given name.
+     *
+     * @param  \Illuminate\Database\Schema\Blueprint  $blueprint
+     * @param  string  $name
+     * @return array
+     */
+    protected function getCommandsByName(Blueprint $blueprint, $name)
+    {
+        return array_filter($blueprint->getCommands(), function ($value) use ($name) {
+            return $value->name == $name;
+        });
+    }
+
+    /**
+     * Add a prefix to an array of values.
+     *
+     * @param  string  $prefix
+     * @param  array  $values
+     * @return array
+     */
+    public function prefixArray($prefix, array $values)
+    {
+        return array_map(function ($value) use ($prefix) {
+            return $prefix.' '.$value;
+        }, $values);
+    }
+
+    /**
+     * Wrap a table in keyword identifiers.
+     *
+     * @param  mixed  $table
+     * @return string
+     */
+    public function wrapTable($table)
+    {
+        return parent::wrapTable(
+            $table instanceof Blueprint ? $table->getTable() : $table
+        );
+    }
+
+    /**
+     * Wrap a value in keyword identifiers.
+     *
+     * @param  \Illuminate\Database\Query\Expression|string  $value
+     * @param  bool  $prefixAlias
+     * @return string
+     */
+    public function wrap($value, $prefixAlias = false)
+    {
+        return parent::wrap(
+            $value instanceof Fluent ? $value->name : $value, $prefixAlias
+        );
+    }
+
+    /**
+     * Format a value so that it can be used in "default" clauses.
+     *
+     * @param  mixed  $value
+     * @return string
+     */
+    protected function getDefaultValue($value)
+    {
+        if ($value instanceof Expression) {
+            return $value;
+        }
+
+        return is_bool($value)
+                    ? "'".(int) $value."'"
+                    : "'".(string) $value."'";
+    }
+
+    /**
+     * Create an empty Doctrine DBAL TableDiff from the Blueprint.
+     *
+     * @param  \Illuminate\Database\Schema\Blueprint  $blueprint
+     * @param  \Doctrine\DBAL\Schema\AbstractSchemaManager  $schema
+     * @return \Doctrine\DBAL\Schema\TableDiff
+     */
+    public function getDoctrineTableDiff(Blueprint $blueprint, SchemaManager $schema)
+    {
+        $table = $this->getTablePrefix().$blueprint->getTable();
+
+        return tap(new TableDiff($table), function ($tableDiff) use ($schema, $table) {
+            $tableDiff->fromTable = $schema->listTableDetails($table);
+        });
+    }
+
+    /**
+     * Get the fluent commands for the grammar.
+     *
+     * @return array
+     */
+    public function getFluentCommands()
+    {
+        return $this->fluentCommands;
+    }
+
+    /**
+     * Check if this Grammar supports schema changes wrapped in a transaction.
+     *
+     * @return bool
+     */
+    public function supportsSchemaTransactions()
+    {
+        return $this->transactions;
+    }
+}
diff --git a/vendor/illuminate/database/Schema/Grammars/MySqlGrammar.php b/vendor/illuminate/database/Schema/Grammars/MySqlGrammar.php
new file mode 100755
index 0000000..f87acfd
--- /dev/null
+++ b/vendor/illuminate/database/Schema/Grammars/MySqlGrammar.php
@@ -0,0 +1,1221 @@
+wrapValue($name),
+            $this->wrapValue($connection->getConfig('charset')),
+            $this->wrapValue($connection->getConfig('collation')),
+        );
+    }
+
+    /**
+     * Compile a drop database if exists command.
+     *
+     * @param  string  $name
+     * @return string
+     */
+    public function compileDropDatabaseIfExists($name)
+    {
+        return sprintf(
+            'drop database if exists %s',
+            $this->wrapValue($name)
+        );
+    }
+
+    /**
+     * Compile the query to determine the list of tables.
+     *
+     * @return string
+     */
+    public function compileTableExists()
+    {
+        return "select * from information_schema.tables where table_schema = ? and table_name = ? and table_type = 'BASE TABLE'";
+    }
+
+    /**
+     * Compile the query to determine the list of columns.
+     *
+     * @return string
+     */
+    public function compileColumnListing()
+    {
+        return 'select column_name as `column_name` from information_schema.columns where table_schema = ? and table_name = ?';
+    }
+
+    /**
+     * Compile a create table command.
+     *
+     * @param  \Illuminate\Database\Schema\Blueprint  $blueprint
+     * @param  \Illuminate\Support\Fluent  $command
+     * @param  \Illuminate\Database\Connection  $connection
+     * @return array
+     */
+    public function compileCreate(Blueprint $blueprint, Fluent $command, Connection $connection)
+    {
+        $sql = $this->compileCreateTable(
+            $blueprint, $command, $connection
+        );
+
+        // Once we have the primary SQL, we can add the encoding option to the SQL for
+        // the table.  Then, we can check if a storage engine has been supplied for
+        // the table. If so, we will add the engine declaration to the SQL query.
+        $sql = $this->compileCreateEncoding(
+            $sql, $connection, $blueprint
+        );
+
+        // Finally, we will append the engine configuration onto this SQL statement as
+        // the final thing we do before returning this finished SQL. Once this gets
+        // added the query will be ready to execute against the real connections.
+        return array_values(array_filter(array_merge([$this->compileCreateEngine(
+            $sql, $connection, $blueprint
+        )], $this->compileAutoIncrementStartingValues($blueprint))));
+    }
+
+    /**
+     * Create the main create table clause.
+     *
+     * @param  \Illuminate\Database\Schema\Blueprint  $blueprint
+     * @param  \Illuminate\Support\Fluent  $command
+     * @param  \Illuminate\Database\Connection  $connection
+     * @return array
+     */
+    protected function compileCreateTable($blueprint, $command, $connection)
+    {
+        return trim(sprintf('%s table %s (%s)',
+            $blueprint->temporary ? 'create temporary' : 'create',
+            $this->wrapTable($blueprint),
+            implode(', ', $this->getColumns($blueprint))
+        ));
+    }
+
+    /**
+     * Append the character set specifications to a command.
+     *
+     * @param  string  $sql
+     * @param  \Illuminate\Database\Connection  $connection
+     * @param  \Illuminate\Database\Schema\Blueprint  $blueprint
+     * @return string
+     */
+    protected function compileCreateEncoding($sql, Connection $connection, Blueprint $blueprint)
+    {
+        // First we will set the character set if one has been set on either the create
+        // blueprint itself or on the root configuration for the connection that the
+        // table is being created on. We will add these to the create table query.
+        if (isset($blueprint->charset)) {
+            $sql .= ' default character set '.$blueprint->charset;
+        } elseif (! is_null($charset = $connection->getConfig('charset'))) {
+            $sql .= ' default character set '.$charset;
+        }
+
+        // Next we will add the collation to the create table statement if one has been
+        // added to either this create table blueprint or the configuration for this
+        // connection that the query is targeting. We'll add it to this SQL query.
+        if (isset($blueprint->collation)) {
+            $sql .= " collate '{$blueprint->collation}'";
+        } elseif (! is_null($collation = $connection->getConfig('collation'))) {
+            $sql .= " collate '{$collation}'";
+        }
+
+        return $sql;
+    }
+
+    /**
+     * Append the engine specifications to a command.
+     *
+     * @param  string  $sql
+     * @param  \Illuminate\Database\Connection  $connection
+     * @param  \Illuminate\Database\Schema\Blueprint  $blueprint
+     * @return string
+     */
+    protected function compileCreateEngine($sql, Connection $connection, Blueprint $blueprint)
+    {
+        if (isset($blueprint->engine)) {
+            return $sql.' engine = '.$blueprint->engine;
+        } elseif (! is_null($engine = $connection->getConfig('engine'))) {
+            return $sql.' engine = '.$engine;
+        }
+
+        return $sql;
+    }
+
+    /**
+     * Compile an add column command.
+     *
+     * @param  \Illuminate\Database\Schema\Blueprint  $blueprint
+     * @param  \Illuminate\Support\Fluent  $command
+     * @return array
+     */
+    public function compileAdd(Blueprint $blueprint, Fluent $command)
+    {
+        $columns = $this->prefixArray('add', $this->getColumns($blueprint));
+
+        return array_values(array_merge(
+            ['alter table '.$this->wrapTable($blueprint).' '.implode(', ', $columns)],
+            $this->compileAutoIncrementStartingValues($blueprint)
+        ));
+    }
+
+    /**
+     * Compile the auto-incrementing column starting values.
+     *
+     * @param  \Illuminate\Database\Schema\Blueprint  $blueprint
+     * @return array
+     */
+    public function compileAutoIncrementStartingValues(Blueprint $blueprint)
+    {
+        return collect($blueprint->autoIncrementingStartingValues())->map(function ($value, $column) use ($blueprint) {
+            return 'alter table '.$this->wrapTable($blueprint->getTable()).' auto_increment = '.$value;
+        })->all();
+    }
+
+    /**
+     * Compile a rename column command.
+     *
+     * @param  \Illuminate\Database\Schema\Blueprint  $blueprint
+     * @param  \Illuminate\Support\Fluent  $command
+     * @param  \Illuminate\Database\Connection  $connection
+     * @return array|string
+     */
+    public function compileRenameColumn(Blueprint $blueprint, Fluent $command, Connection $connection)
+    {
+        return $connection->usingNativeSchemaOperations()
+            ? sprintf('alter table %s rename column %s to %s',
+                $this->wrapTable($blueprint),
+                $this->wrap($command->from),
+                $this->wrap($command->to)
+            )
+            : parent::compileRenameColumn($blueprint, $command, $connection);
+    }
+
+    /**
+     * Compile a primary key command.
+     *
+     * @param  \Illuminate\Database\Schema\Blueprint  $blueprint
+     * @param  \Illuminate\Support\Fluent  $command
+     * @return string
+     */
+    public function compilePrimary(Blueprint $blueprint, Fluent $command)
+    {
+        return sprintf('alter table %s add primary key %s(%s)',
+            $this->wrapTable($blueprint),
+            $command->algorithm ? 'using '.$command->algorithm : '',
+            $this->columnize($command->columns)
+        );
+    }
+
+    /**
+     * Compile a unique key command.
+     *
+     * @param  \Illuminate\Database\Schema\Blueprint  $blueprint
+     * @param  \Illuminate\Support\Fluent  $command
+     * @return string
+     */
+    public function compileUnique(Blueprint $blueprint, Fluent $command)
+    {
+        return $this->compileKey($blueprint, $command, 'unique');
+    }
+
+    /**
+     * Compile a plain index key command.
+     *
+     * @param  \Illuminate\Database\Schema\Blueprint  $blueprint
+     * @param  \Illuminate\Support\Fluent  $command
+     * @return string
+     */
+    public function compileIndex(Blueprint $blueprint, Fluent $command)
+    {
+        return $this->compileKey($blueprint, $command, 'index');
+    }
+
+    /**
+     * Compile a fulltext index key command.
+     *
+     * @param  \Illuminate\Database\Schema\Blueprint  $blueprint
+     * @param  \Illuminate\Support\Fluent  $command
+     * @return string
+     */
+    public function compileFullText(Blueprint $blueprint, Fluent $command)
+    {
+        return $this->compileKey($blueprint, $command, 'fulltext');
+    }
+
+    /**
+     * Compile a spatial index key command.
+     *
+     * @param  \Illuminate\Database\Schema\Blueprint  $blueprint
+     * @param  \Illuminate\Support\Fluent  $command
+     * @return string
+     */
+    public function compileSpatialIndex(Blueprint $blueprint, Fluent $command)
+    {
+        return $this->compileKey($blueprint, $command, 'spatial index');
+    }
+
+    /**
+     * Compile an index creation command.
+     *
+     * @param  \Illuminate\Database\Schema\Blueprint  $blueprint
+     * @param  \Illuminate\Support\Fluent  $command
+     * @param  string  $type
+     * @return string
+     */
+    protected function compileKey(Blueprint $blueprint, Fluent $command, $type)
+    {
+        return sprintf('alter table %s add %s %s%s(%s)',
+            $this->wrapTable($blueprint),
+            $type,
+            $this->wrap($command->index),
+            $command->algorithm ? ' using '.$command->algorithm : '',
+            $this->columnize($command->columns)
+        );
+    }
+
+    /**
+     * Compile a drop table command.
+     *
+     * @param  \Illuminate\Database\Schema\Blueprint  $blueprint
+     * @param  \Illuminate\Support\Fluent  $command
+     * @return string
+     */
+    public function compileDrop(Blueprint $blueprint, Fluent $command)
+    {
+        return 'drop table '.$this->wrapTable($blueprint);
+    }
+
+    /**
+     * Compile a drop table (if exists) command.
+     *
+     * @param  \Illuminate\Database\Schema\Blueprint  $blueprint
+     * @param  \Illuminate\Support\Fluent  $command
+     * @return string
+     */
+    public function compileDropIfExists(Blueprint $blueprint, Fluent $command)
+    {
+        return 'drop table if exists '.$this->wrapTable($blueprint);
+    }
+
+    /**
+     * Compile a drop column command.
+     *
+     * @param  \Illuminate\Database\Schema\Blueprint  $blueprint
+     * @param  \Illuminate\Support\Fluent  $command
+     * @return string
+     */
+    public function compileDropColumn(Blueprint $blueprint, Fluent $command)
+    {
+        $columns = $this->prefixArray('drop', $this->wrapArray($command->columns));
+
+        return 'alter table '.$this->wrapTable($blueprint).' '.implode(', ', $columns);
+    }
+
+    /**
+     * Compile a drop primary key command.
+     *
+     * @param  \Illuminate\Database\Schema\Blueprint  $blueprint
+     * @param  \Illuminate\Support\Fluent  $command
+     * @return string
+     */
+    public function compileDropPrimary(Blueprint $blueprint, Fluent $command)
+    {
+        return 'alter table '.$this->wrapTable($blueprint).' drop primary key';
+    }
+
+    /**
+     * Compile a drop unique key command.
+     *
+     * @param  \Illuminate\Database\Schema\Blueprint  $blueprint
+     * @param  \Illuminate\Support\Fluent  $command
+     * @return string
+     */
+    public function compileDropUnique(Blueprint $blueprint, Fluent $command)
+    {
+        $index = $this->wrap($command->index);
+
+        return "alter table {$this->wrapTable($blueprint)} drop index {$index}";
+    }
+
+    /**
+     * Compile a drop index command.
+     *
+     * @param  \Illuminate\Database\Schema\Blueprint  $blueprint
+     * @param  \Illuminate\Support\Fluent  $command
+     * @return string
+     */
+    public function compileDropIndex(Blueprint $blueprint, Fluent $command)
+    {
+        $index = $this->wrap($command->index);
+
+        return "alter table {$this->wrapTable($blueprint)} drop index {$index}";
+    }
+
+    /**
+     * Compile a drop fulltext index command.
+     *
+     * @param  \Illuminate\Database\Schema\Blueprint  $blueprint
+     * @param  \Illuminate\Support\Fluent  $command
+     * @return string
+     */
+    public function compileDropFullText(Blueprint $blueprint, Fluent $command)
+    {
+        return $this->compileDropIndex($blueprint, $command);
+    }
+
+    /**
+     * Compile a drop spatial index command.
+     *
+     * @param  \Illuminate\Database\Schema\Blueprint  $blueprint
+     * @param  \Illuminate\Support\Fluent  $command
+     * @return string
+     */
+    public function compileDropSpatialIndex(Blueprint $blueprint, Fluent $command)
+    {
+        return $this->compileDropIndex($blueprint, $command);
+    }
+
+    /**
+     * Compile a drop foreign key command.
+     *
+     * @param  \Illuminate\Database\Schema\Blueprint  $blueprint
+     * @param  \Illuminate\Support\Fluent  $command
+     * @return string
+     */
+    public function compileDropForeign(Blueprint $blueprint, Fluent $command)
+    {
+        $index = $this->wrap($command->index);
+
+        return "alter table {$this->wrapTable($blueprint)} drop foreign key {$index}";
+    }
+
+    /**
+     * Compile a rename table command.
+     *
+     * @param  \Illuminate\Database\Schema\Blueprint  $blueprint
+     * @param  \Illuminate\Support\Fluent  $command
+     * @return string
+     */
+    public function compileRename(Blueprint $blueprint, Fluent $command)
+    {
+        $from = $this->wrapTable($blueprint);
+
+        return "rename table {$from} to ".$this->wrapTable($command->to);
+    }
+
+    /**
+     * Compile a rename index command.
+     *
+     * @param  \Illuminate\Database\Schema\Blueprint  $blueprint
+     * @param  \Illuminate\Support\Fluent  $command
+     * @return string
+     */
+    public function compileRenameIndex(Blueprint $blueprint, Fluent $command)
+    {
+        return sprintf('alter table %s rename index %s to %s',
+            $this->wrapTable($blueprint),
+            $this->wrap($command->from),
+            $this->wrap($command->to)
+        );
+    }
+
+    /**
+     * Compile the SQL needed to drop all tables.
+     *
+     * @param  array  $tables
+     * @return string
+     */
+    public function compileDropAllTables($tables)
+    {
+        return 'drop table '.implode(',', $this->wrapArray($tables));
+    }
+
+    /**
+     * Compile the SQL needed to drop all views.
+     *
+     * @param  array  $views
+     * @return string
+     */
+    public function compileDropAllViews($views)
+    {
+        return 'drop view '.implode(',', $this->wrapArray($views));
+    }
+
+    /**
+     * Compile the SQL needed to retrieve all table names.
+     *
+     * @return string
+     */
+    public function compileGetAllTables()
+    {
+        return 'SHOW FULL TABLES WHERE table_type = \'BASE TABLE\'';
+    }
+
+    /**
+     * Compile the SQL needed to retrieve all view names.
+     *
+     * @return string
+     */
+    public function compileGetAllViews()
+    {
+        return 'SHOW FULL TABLES WHERE table_type = \'VIEW\'';
+    }
+
+    /**
+     * Compile the command to enable foreign key constraints.
+     *
+     * @return string
+     */
+    public function compileEnableForeignKeyConstraints()
+    {
+        return 'SET FOREIGN_KEY_CHECKS=1;';
+    }
+
+    /**
+     * Compile the command to disable foreign key constraints.
+     *
+     * @return string
+     */
+    public function compileDisableForeignKeyConstraints()
+    {
+        return 'SET FOREIGN_KEY_CHECKS=0;';
+    }
+
+    /**
+     * Compile a table comment command.
+     *
+     * @param  \Illuminate\Database\Schema\Blueprint  $blueprint
+     * @param  \Illuminate\Support\Fluent  $command
+     * @return string
+     */
+    public function compileTableComment(Blueprint $blueprint, Fluent $command)
+    {
+        return sprintf('alter table %s comment = %s',
+            $this->wrapTable($blueprint),
+            "'".str_replace("'", "''", $command->comment)."'"
+        );
+    }
+
+    /**
+     * Create the column definition for a char type.
+     *
+     * @param  \Illuminate\Support\Fluent  $column
+     * @return string
+     */
+    protected function typeChar(Fluent $column)
+    {
+        return "char({$column->length})";
+    }
+
+    /**
+     * Create the column definition for a string type.
+     *
+     * @param  \Illuminate\Support\Fluent  $column
+     * @return string
+     */
+    protected function typeString(Fluent $column)
+    {
+        return "varchar({$column->length})";
+    }
+
+    /**
+     * Create the column definition for a tiny text type.
+     *
+     * @param  \Illuminate\Support\Fluent  $column
+     * @return string
+     */
+    protected function typeTinyText(Fluent $column)
+    {
+        return 'tinytext';
+    }
+
+    /**
+     * Create the column definition for a text type.
+     *
+     * @param  \Illuminate\Support\Fluent  $column
+     * @return string
+     */
+    protected function typeText(Fluent $column)
+    {
+        return 'text';
+    }
+
+    /**
+     * Create the column definition for a medium text type.
+     *
+     * @param  \Illuminate\Support\Fluent  $column
+     * @return string
+     */
+    protected function typeMediumText(Fluent $column)
+    {
+        return 'mediumtext';
+    }
+
+    /**
+     * Create the column definition for a long text type.
+     *
+     * @param  \Illuminate\Support\Fluent  $column
+     * @return string
+     */
+    protected function typeLongText(Fluent $column)
+    {
+        return 'longtext';
+    }
+
+    /**
+     * Create the column definition for a big integer type.
+     *
+     * @param  \Illuminate\Support\Fluent  $column
+     * @return string
+     */
+    protected function typeBigInteger(Fluent $column)
+    {
+        return 'bigint';
+    }
+
+    /**
+     * Create the column definition for an integer type.
+     *
+     * @param  \Illuminate\Support\Fluent  $column
+     * @return string
+     */
+    protected function typeInteger(Fluent $column)
+    {
+        return 'int';
+    }
+
+    /**
+     * Create the column definition for a medium integer type.
+     *
+     * @param  \Illuminate\Support\Fluent  $column
+     * @return string
+     */
+    protected function typeMediumInteger(Fluent $column)
+    {
+        return 'mediumint';
+    }
+
+    /**
+     * Create the column definition for a tiny integer type.
+     *
+     * @param  \Illuminate\Support\Fluent  $column
+     * @return string
+     */
+    protected function typeTinyInteger(Fluent $column)
+    {
+        return 'tinyint';
+    }
+
+    /**
+     * Create the column definition for a small integer type.
+     *
+     * @param  \Illuminate\Support\Fluent  $column
+     * @return string
+     */
+    protected function typeSmallInteger(Fluent $column)
+    {
+        return 'smallint';
+    }
+
+    /**
+     * Create the column definition for a float type.
+     *
+     * @param  \Illuminate\Support\Fluent  $column
+     * @return string
+     */
+    protected function typeFloat(Fluent $column)
+    {
+        return $this->typeDouble($column);
+    }
+
+    /**
+     * Create the column definition for a double type.
+     *
+     * @param  \Illuminate\Support\Fluent  $column
+     * @return string
+     */
+    protected function typeDouble(Fluent $column)
+    {
+        if ($column->total && $column->places) {
+            return "double({$column->total}, {$column->places})";
+        }
+
+        return 'double';
+    }
+
+    /**
+     * Create the column definition for a decimal type.
+     *
+     * @param  \Illuminate\Support\Fluent  $column
+     * @return string
+     */
+    protected function typeDecimal(Fluent $column)
+    {
+        return "decimal({$column->total}, {$column->places})";
+    }
+
+    /**
+     * Create the column definition for a boolean type.
+     *
+     * @param  \Illuminate\Support\Fluent  $column
+     * @return string
+     */
+    protected function typeBoolean(Fluent $column)
+    {
+        return 'tinyint(1)';
+    }
+
+    /**
+     * Create the column definition for an enumeration type.
+     *
+     * @param  \Illuminate\Support\Fluent  $column
+     * @return string
+     */
+    protected function typeEnum(Fluent $column)
+    {
+        return sprintf('enum(%s)', $this->quoteString($column->allowed));
+    }
+
+    /**
+     * Create the column definition for a set enumeration type.
+     *
+     * @param  \Illuminate\Support\Fluent  $column
+     * @return string
+     */
+    protected function typeSet(Fluent $column)
+    {
+        return sprintf('set(%s)', $this->quoteString($column->allowed));
+    }
+
+    /**
+     * Create the column definition for a json type.
+     *
+     * @param  \Illuminate\Support\Fluent  $column
+     * @return string
+     */
+    protected function typeJson(Fluent $column)
+    {
+        return 'json';
+    }
+
+    /**
+     * Create the column definition for a jsonb type.
+     *
+     * @param  \Illuminate\Support\Fluent  $column
+     * @return string
+     */
+    protected function typeJsonb(Fluent $column)
+    {
+        return 'json';
+    }
+
+    /**
+     * Create the column definition for a date type.
+     *
+     * @param  \Illuminate\Support\Fluent  $column
+     * @return string
+     */
+    protected function typeDate(Fluent $column)
+    {
+        return 'date';
+    }
+
+    /**
+     * Create the column definition for a date-time type.
+     *
+     * @param  \Illuminate\Support\Fluent  $column
+     * @return string
+     */
+    protected function typeDateTime(Fluent $column)
+    {
+        $columnType = $column->precision ? "datetime($column->precision)" : 'datetime';
+
+        $current = $column->precision ? "CURRENT_TIMESTAMP($column->precision)" : 'CURRENT_TIMESTAMP';
+
+        $columnType = $column->useCurrent ? "$columnType default $current" : $columnType;
+
+        return $column->useCurrentOnUpdate ? "$columnType on update $current" : $columnType;
+    }
+
+    /**
+     * Create the column definition for a date-time (with time zone) type.
+     *
+     * @param  \Illuminate\Support\Fluent  $column
+     * @return string
+     */
+    protected function typeDateTimeTz(Fluent $column)
+    {
+        return $this->typeDateTime($column);
+    }
+
+    /**
+     * Create the column definition for a time type.
+     *
+     * @param  \Illuminate\Support\Fluent  $column
+     * @return string
+     */
+    protected function typeTime(Fluent $column)
+    {
+        return $column->precision ? "time($column->precision)" : 'time';
+    }
+
+    /**
+     * Create the column definition for a time (with time zone) type.
+     *
+     * @param  \Illuminate\Support\Fluent  $column
+     * @return string
+     */
+    protected function typeTimeTz(Fluent $column)
+    {
+        return $this->typeTime($column);
+    }
+
+    /**
+     * Create the column definition for a timestamp type.
+     *
+     * @param  \Illuminate\Support\Fluent  $column
+     * @return string
+     */
+    protected function typeTimestamp(Fluent $column)
+    {
+        $columnType = $column->precision ? "timestamp($column->precision)" : 'timestamp';
+
+        $current = $column->precision ? "CURRENT_TIMESTAMP($column->precision)" : 'CURRENT_TIMESTAMP';
+
+        $columnType = $column->useCurrent ? "$columnType default $current" : $columnType;
+
+        return $column->useCurrentOnUpdate ? "$columnType on update $current" : $columnType;
+    }
+
+    /**
+     * Create the column definition for a timestamp (with time zone) type.
+     *
+     * @param  \Illuminate\Support\Fluent  $column
+     * @return string
+     */
+    protected function typeTimestampTz(Fluent $column)
+    {
+        return $this->typeTimestamp($column);
+    }
+
+    /**
+     * Create the column definition for a year type.
+     *
+     * @param  \Illuminate\Support\Fluent  $column
+     * @return string
+     */
+    protected function typeYear(Fluent $column)
+    {
+        return 'year';
+    }
+
+    /**
+     * Create the column definition for a binary type.
+     *
+     * @param  \Illuminate\Support\Fluent  $column
+     * @return string
+     */
+    protected function typeBinary(Fluent $column)
+    {
+        return 'blob';
+    }
+
+    /**
+     * Create the column definition for a uuid type.
+     *
+     * @param  \Illuminate\Support\Fluent  $column
+     * @return string
+     */
+    protected function typeUuid(Fluent $column)
+    {
+        return 'char(36)';
+    }
+
+    /**
+     * Create the column definition for an IP address type.
+     *
+     * @param  \Illuminate\Support\Fluent  $column
+     * @return string
+     */
+    protected function typeIpAddress(Fluent $column)
+    {
+        return 'varchar(45)';
+    }
+
+    /**
+     * Create the column definition for a MAC address type.
+     *
+     * @param  \Illuminate\Support\Fluent  $column
+     * @return string
+     */
+    protected function typeMacAddress(Fluent $column)
+    {
+        return 'varchar(17)';
+    }
+
+    /**
+     * Create the column definition for a spatial Geometry type.
+     *
+     * @param  \Illuminate\Support\Fluent  $column
+     * @return string
+     */
+    public function typeGeometry(Fluent $column)
+    {
+        return 'geometry';
+    }
+
+    /**
+     * Create the column definition for a spatial Point type.
+     *
+     * @param  \Illuminate\Support\Fluent  $column
+     * @return string
+     */
+    public function typePoint(Fluent $column)
+    {
+        return 'point';
+    }
+
+    /**
+     * Create the column definition for a spatial LineString type.
+     *
+     * @param  \Illuminate\Support\Fluent  $column
+     * @return string
+     */
+    public function typeLineString(Fluent $column)
+    {
+        return 'linestring';
+    }
+
+    /**
+     * Create the column definition for a spatial Polygon type.
+     *
+     * @param  \Illuminate\Support\Fluent  $column
+     * @return string
+     */
+    public function typePolygon(Fluent $column)
+    {
+        return 'polygon';
+    }
+
+    /**
+     * Create the column definition for a spatial GeometryCollection type.
+     *
+     * @param  \Illuminate\Support\Fluent  $column
+     * @return string
+     */
+    public function typeGeometryCollection(Fluent $column)
+    {
+        return 'geometrycollection';
+    }
+
+    /**
+     * Create the column definition for a spatial MultiPoint type.
+     *
+     * @param  \Illuminate\Support\Fluent  $column
+     * @return string
+     */
+    public function typeMultiPoint(Fluent $column)
+    {
+        return 'multipoint';
+    }
+
+    /**
+     * Create the column definition for a spatial MultiLineString type.
+     *
+     * @param  \Illuminate\Support\Fluent  $column
+     * @return string
+     */
+    public function typeMultiLineString(Fluent $column)
+    {
+        return 'multilinestring';
+    }
+
+    /**
+     * Create the column definition for a spatial MultiPolygon type.
+     *
+     * @param  \Illuminate\Support\Fluent  $column
+     * @return string
+     */
+    public function typeMultiPolygon(Fluent $column)
+    {
+        return 'multipolygon';
+    }
+
+    /**
+     * Create the column definition for a generated, computed column type.
+     *
+     * @param  \Illuminate\Support\Fluent  $column
+     * @return void
+     *
+     * @throws \RuntimeException
+     */
+    protected function typeComputed(Fluent $column)
+    {
+        throw new RuntimeException('This database driver requires a type, see the virtualAs / storedAs modifiers.');
+    }
+
+    /**
+     * Get the SQL for a generated virtual column modifier.
+     *
+     * @param  \Illuminate\Database\Schema\Blueprint  $blueprint
+     * @param  \Illuminate\Support\Fluent  $column
+     * @return string|null
+     */
+    protected function modifyVirtualAs(Blueprint $blueprint, Fluent $column)
+    {
+        if (! is_null($virtualAs = $column->virtualAsJson)) {
+            if ($this->isJsonSelector($virtualAs)) {
+                $virtualAs = $this->wrapJsonSelector($virtualAs);
+            }
+
+            return " as ({$virtualAs})";
+        }
+
+        if (! is_null($virtualAs = $column->virtualAs)) {
+            return " as ({$virtualAs})";
+        }
+    }
+
+    /**
+     * Get the SQL for a generated stored column modifier.
+     *
+     * @param  \Illuminate\Database\Schema\Blueprint  $blueprint
+     * @param  \Illuminate\Support\Fluent  $column
+     * @return string|null
+     */
+    protected function modifyStoredAs(Blueprint $blueprint, Fluent $column)
+    {
+        if (! is_null($storedAs = $column->storedAsJson)) {
+            if ($this->isJsonSelector($storedAs)) {
+                $storedAs = $this->wrapJsonSelector($storedAs);
+            }
+
+            return " as ({$storedAs}) stored";
+        }
+
+        if (! is_null($storedAs = $column->storedAs)) {
+            return " as ({$storedAs}) stored";
+        }
+    }
+
+    /**
+     * Get the SQL for an unsigned column modifier.
+     *
+     * @param  \Illuminate\Database\Schema\Blueprint  $blueprint
+     * @param  \Illuminate\Support\Fluent  $column
+     * @return string|null
+     */
+    protected function modifyUnsigned(Blueprint $blueprint, Fluent $column)
+    {
+        if ($column->unsigned) {
+            return ' unsigned';
+        }
+    }
+
+    /**
+     * Get the SQL for a character set column modifier.
+     *
+     * @param  \Illuminate\Database\Schema\Blueprint  $blueprint
+     * @param  \Illuminate\Support\Fluent  $column
+     * @return string|null
+     */
+    protected function modifyCharset(Blueprint $blueprint, Fluent $column)
+    {
+        if (! is_null($column->charset)) {
+            return ' character set '.$column->charset;
+        }
+    }
+
+    /**
+     * Get the SQL for a collation column modifier.
+     *
+     * @param  \Illuminate\Database\Schema\Blueprint  $blueprint
+     * @param  \Illuminate\Support\Fluent  $column
+     * @return string|null
+     */
+    protected function modifyCollate(Blueprint $blueprint, Fluent $column)
+    {
+        if (! is_null($column->collation)) {
+            return " collate '{$column->collation}'";
+        }
+    }
+
+    /**
+     * Get the SQL for a nullable column modifier.
+     *
+     * @param  \Illuminate\Database\Schema\Blueprint  $blueprint
+     * @param  \Illuminate\Support\Fluent  $column
+     * @return string|null
+     */
+    protected function modifyNullable(Blueprint $blueprint, Fluent $column)
+    {
+        if (is_null($column->virtualAs) &&
+            is_null($column->virtualAsJson) &&
+            is_null($column->storedAs) &&
+            is_null($column->storedAsJson)) {
+            return $column->nullable ? ' null' : ' not null';
+        }
+
+        if ($column->nullable === false) {
+            return ' not null';
+        }
+    }
+
+    /**
+     * Get the SQL for an invisible column modifier.
+     *
+     * @param  \Illuminate\Database\Schema\Blueprint  $blueprint
+     * @param  \Illuminate\Support\Fluent  $column
+     * @return string|null
+     */
+    protected function modifyInvisible(Blueprint $blueprint, Fluent $column)
+    {
+        if (! is_null($column->invisible)) {
+            return ' invisible';
+        }
+    }
+
+    /**
+     * Get the SQL for a default column modifier.
+     *
+     * @param  \Illuminate\Database\Schema\Blueprint  $blueprint
+     * @param  \Illuminate\Support\Fluent  $column
+     * @return string|null
+     */
+    protected function modifyDefault(Blueprint $blueprint, Fluent $column)
+    {
+        if (! is_null($column->default)) {
+            return ' default '.$this->getDefaultValue($column->default);
+        }
+    }
+
+    /**
+     * Get the SQL for an auto-increment column modifier.
+     *
+     * @param  \Illuminate\Database\Schema\Blueprint  $blueprint
+     * @param  \Illuminate\Support\Fluent  $column
+     * @return string|null
+     */
+    protected function modifyIncrement(Blueprint $blueprint, Fluent $column)
+    {
+        if (in_array($column->type, $this->serials) && $column->autoIncrement) {
+            return ' auto_increment primary key';
+        }
+    }
+
+    /**
+     * Get the SQL for a "first" column modifier.
+     *
+     * @param  \Illuminate\Database\Schema\Blueprint  $blueprint
+     * @param  \Illuminate\Support\Fluent  $column
+     * @return string|null
+     */
+    protected function modifyFirst(Blueprint $blueprint, Fluent $column)
+    {
+        if (! is_null($column->first)) {
+            return ' first';
+        }
+    }
+
+    /**
+     * Get the SQL for an "after" column modifier.
+     *
+     * @param  \Illuminate\Database\Schema\Blueprint  $blueprint
+     * @param  \Illuminate\Support\Fluent  $column
+     * @return string|null
+     */
+    protected function modifyAfter(Blueprint $blueprint, Fluent $column)
+    {
+        if (! is_null($column->after)) {
+            return ' after '.$this->wrap($column->after);
+        }
+    }
+
+    /**
+     * Get the SQL for a "comment" column modifier.
+     *
+     * @param  \Illuminate\Database\Schema\Blueprint  $blueprint
+     * @param  \Illuminate\Support\Fluent  $column
+     * @return string|null
+     */
+    protected function modifyComment(Blueprint $blueprint, Fluent $column)
+    {
+        if (! is_null($column->comment)) {
+            return " comment '".addslashes($column->comment)."'";
+        }
+    }
+
+    /**
+     * Get the SQL for a SRID column modifier.
+     *
+     * @param  \Illuminate\Database\Schema\Blueprint  $blueprint
+     * @param  \Illuminate\Support\Fluent  $column
+     * @return string|null
+     */
+    protected function modifySrid(Blueprint $blueprint, Fluent $column)
+    {
+        if (is_int($column->srid) && $column->srid > 0) {
+            return ' srid '.$column->srid;
+        }
+    }
+
+    /**
+     * Wrap a single string in keyword identifiers.
+     *
+     * @param  string  $value
+     * @return string
+     */
+    protected function wrapValue($value)
+    {
+        if ($value !== '*') {
+            return '`'.str_replace('`', '``', $value).'`';
+        }
+
+        return $value;
+    }
+
+    /**
+     * Wrap the given JSON selector.
+     *
+     * @param  string  $value
+     * @return string
+     */
+    protected function wrapJsonSelector($value)
+    {
+        [$field, $path] = $this->wrapJsonFieldAndPath($value);
+
+        return 'json_unquote(json_extract('.$field.$path.'))';
+    }
+}
diff --git a/vendor/illuminate/database/Schema/Grammars/PostgresGrammar.php b/vendor/illuminate/database/Schema/Grammars/PostgresGrammar.php
new file mode 100755
index 0000000..ef60d0f
--- /dev/null
+++ b/vendor/illuminate/database/Schema/Grammars/PostgresGrammar.php
@@ -0,0 +1,1141 @@
+wrapValue($name),
+            $this->wrapValue($connection->getConfig('charset')),
+        );
+    }
+
+    /**
+     * Compile a drop database if exists command.
+     *
+     * @param  string  $name
+     * @return string
+     */
+    public function compileDropDatabaseIfExists($name)
+    {
+        return sprintf(
+            'drop database if exists %s',
+            $this->wrapValue($name)
+        );
+    }
+
+    /**
+     * Compile the query to determine if a table exists.
+     *
+     * @return string
+     */
+    public function compileTableExists()
+    {
+        return "select * from information_schema.tables where table_catalog = ? and table_schema = ? and table_name = ? and table_type = 'BASE TABLE'";
+    }
+
+    /**
+     * Compile the query to determine the list of columns.
+     *
+     * @return string
+     */
+    public function compileColumnListing()
+    {
+        return 'select column_name from information_schema.columns where table_catalog = ? and table_schema = ? and table_name = ?';
+    }
+
+    /**
+     * Compile a create table command.
+     *
+     * @param  \Illuminate\Database\Schema\Blueprint  $blueprint
+     * @param  \Illuminate\Support\Fluent  $command
+     * @return array
+     */
+    public function compileCreate(Blueprint $blueprint, Fluent $command)
+    {
+        return array_values(array_filter(array_merge([sprintf('%s table %s (%s)',
+            $blueprint->temporary ? 'create temporary' : 'create',
+            $this->wrapTable($blueprint),
+            implode(', ', $this->getColumns($blueprint))
+        )], $this->compileAutoIncrementStartingValues($blueprint))));
+    }
+
+    /**
+     * Compile a column addition command.
+     *
+     * @param  \Illuminate\Database\Schema\Blueprint  $blueprint
+     * @param  \Illuminate\Support\Fluent  $command
+     * @return string
+     */
+    public function compileAdd(Blueprint $blueprint, Fluent $command)
+    {
+        return array_values(array_filter(array_merge([sprintf('alter table %s %s',
+            $this->wrapTable($blueprint),
+            implode(', ', $this->prefixArray('add column', $this->getColumns($blueprint)))
+        )], $this->compileAutoIncrementStartingValues($blueprint))));
+    }
+
+    /**
+     * Compile the auto-incrementing column starting values.
+     *
+     * @param  \Illuminate\Database\Schema\Blueprint  $blueprint
+     * @return array
+     */
+    public function compileAutoIncrementStartingValues(Blueprint $blueprint)
+    {
+        return collect($blueprint->autoIncrementingStartingValues())->map(function ($value, $column) use ($blueprint) {
+            return 'alter sequence '.$blueprint->getTable().'_'.$column.'_seq restart with '.$value;
+        })->all();
+    }
+
+    /**
+     * Compile a rename column command.
+     *
+     * @param  \Illuminate\Database\Schema\Blueprint  $blueprint
+     * @param  \Illuminate\Support\Fluent  $command
+     * @param  \Illuminate\Database\Connection  $connection
+     * @return array|string
+     */
+    public function compileRenameColumn(Blueprint $blueprint, Fluent $command, Connection $connection)
+    {
+        return $connection->usingNativeSchemaOperations()
+            ? sprintf('alter table %s rename column %s to %s',
+                $this->wrapTable($blueprint),
+                $this->wrap($command->from),
+                $this->wrap($command->to)
+            )
+            : parent::compileRenameColumn($blueprint, $command, $connection);
+    }
+
+    /**
+     * Compile a primary key command.
+     *
+     * @param  \Illuminate\Database\Schema\Blueprint  $blueprint
+     * @param  \Illuminate\Support\Fluent  $command
+     * @return string
+     */
+    public function compilePrimary(Blueprint $blueprint, Fluent $command)
+    {
+        $columns = $this->columnize($command->columns);
+
+        return 'alter table '.$this->wrapTable($blueprint)." add primary key ({$columns})";
+    }
+
+    /**
+     * Compile a unique key command.
+     *
+     * @param  \Illuminate\Database\Schema\Blueprint  $blueprint
+     * @param  \Illuminate\Support\Fluent  $command
+     * @return string
+     */
+    public function compileUnique(Blueprint $blueprint, Fluent $command)
+    {
+        $sql = sprintf('alter table %s add constraint %s unique (%s)',
+            $this->wrapTable($blueprint),
+            $this->wrap($command->index),
+            $this->columnize($command->columns)
+        );
+
+        if (! is_null($command->deferrable)) {
+            $sql .= $command->deferrable ? ' deferrable' : ' not deferrable';
+        }
+
+        if ($command->deferrable && ! is_null($command->initiallyImmediate)) {
+            $sql .= $command->initiallyImmediate ? ' initially immediate' : ' initially deferred';
+        }
+
+        return $sql;
+    }
+
+    /**
+     * Compile a plain index key command.
+     *
+     * @param  \Illuminate\Database\Schema\Blueprint  $blueprint
+     * @param  \Illuminate\Support\Fluent  $command
+     * @return string
+     */
+    public function compileIndex(Blueprint $blueprint, Fluent $command)
+    {
+        return sprintf('create index %s on %s%s (%s)',
+            $this->wrap($command->index),
+            $this->wrapTable($blueprint),
+            $command->algorithm ? ' using '.$command->algorithm : '',
+            $this->columnize($command->columns)
+        );
+    }
+
+    /**
+     * Compile a fulltext index key command.
+     *
+     * @param  \Illuminate\Database\Schema\Blueprint  $blueprint
+     * @param  \Illuminate\Support\Fluent  $command
+     * @return string
+     *
+     * @throws \RuntimeException
+     */
+    public function compileFulltext(Blueprint $blueprint, Fluent $command)
+    {
+        $language = $command->language ?: 'english';
+
+        $columns = array_map(function ($column) use ($language) {
+            return "to_tsvector({$this->quoteString($language)}, {$this->wrap($column)})";
+        }, $command->columns);
+
+        return sprintf('create index %s on %s using gin ((%s))',
+            $this->wrap($command->index),
+            $this->wrapTable($blueprint),
+            implode(' || ', $columns)
+        );
+    }
+
+    /**
+     * Compile a spatial index key command.
+     *
+     * @param  \Illuminate\Database\Schema\Blueprint  $blueprint
+     * @param  \Illuminate\Support\Fluent  $command
+     * @return string
+     */
+    public function compileSpatialIndex(Blueprint $blueprint, Fluent $command)
+    {
+        $command->algorithm = 'gist';
+
+        return $this->compileIndex($blueprint, $command);
+    }
+
+    /**
+     * Compile a foreign key command.
+     *
+     * @param  \Illuminate\Database\Schema\Blueprint  $blueprint
+     * @param  \Illuminate\Support\Fluent  $command
+     * @return string
+     */
+    public function compileForeign(Blueprint $blueprint, Fluent $command)
+    {
+        $sql = parent::compileForeign($blueprint, $command);
+
+        if (! is_null($command->deferrable)) {
+            $sql .= $command->deferrable ? ' deferrable' : ' not deferrable';
+        }
+
+        if ($command->deferrable && ! is_null($command->initiallyImmediate)) {
+            $sql .= $command->initiallyImmediate ? ' initially immediate' : ' initially deferred';
+        }
+
+        if (! is_null($command->notValid)) {
+            $sql .= ' not valid';
+        }
+
+        return $sql;
+    }
+
+    /**
+     * Compile a drop table command.
+     *
+     * @param  \Illuminate\Database\Schema\Blueprint  $blueprint
+     * @param  \Illuminate\Support\Fluent  $command
+     * @return string
+     */
+    public function compileDrop(Blueprint $blueprint, Fluent $command)
+    {
+        return 'drop table '.$this->wrapTable($blueprint);
+    }
+
+    /**
+     * Compile a drop table (if exists) command.
+     *
+     * @param  \Illuminate\Database\Schema\Blueprint  $blueprint
+     * @param  \Illuminate\Support\Fluent  $command
+     * @return string
+     */
+    public function compileDropIfExists(Blueprint $blueprint, Fluent $command)
+    {
+        return 'drop table if exists '.$this->wrapTable($blueprint);
+    }
+
+    /**
+     * Compile the SQL needed to drop all tables.
+     *
+     * @param  array  $tables
+     * @return string
+     */
+    public function compileDropAllTables($tables)
+    {
+        return 'drop table '.implode(',', $this->escapeNames($tables)).' cascade';
+    }
+
+    /**
+     * Compile the SQL needed to drop all views.
+     *
+     * @param  array  $views
+     * @return string
+     */
+    public function compileDropAllViews($views)
+    {
+        return 'drop view '.implode(',', $this->escapeNames($views)).' cascade';
+    }
+
+    /**
+     * Compile the SQL needed to drop all types.
+     *
+     * @param  array  $types
+     * @return string
+     */
+    public function compileDropAllTypes($types)
+    {
+        return 'drop type '.implode(',', $this->escapeNames($types)).' cascade';
+    }
+
+    /**
+     * Compile the SQL needed to retrieve all table names.
+     *
+     * @param  string|array  $searchPath
+     * @return string
+     */
+    public function compileGetAllTables($searchPath)
+    {
+        return "select tablename, concat('\"', schemaname, '\".\"', tablename, '\"') as qualifiedname from pg_catalog.pg_tables where schemaname in ('".implode("','", (array) $searchPath)."')";
+    }
+
+    /**
+     * Compile the SQL needed to retrieve all view names.
+     *
+     * @param  string|array  $searchPath
+     * @return string
+     */
+    public function compileGetAllViews($searchPath)
+    {
+        return "select viewname, concat('\"', schemaname, '\".\"', viewname, '\"') as qualifiedname from pg_catalog.pg_views where schemaname in ('".implode("','", (array) $searchPath)."')";
+    }
+
+    /**
+     * Compile the SQL needed to retrieve all type names.
+     *
+     * @return string
+     */
+    public function compileGetAllTypes()
+    {
+        return 'select distinct pg_type.typname from pg_type inner join pg_enum on pg_enum.enumtypid = pg_type.oid';
+    }
+
+    /**
+     * Compile a drop column command.
+     *
+     * @param  \Illuminate\Database\Schema\Blueprint  $blueprint
+     * @param  \Illuminate\Support\Fluent  $command
+     * @return string
+     */
+    public function compileDropColumn(Blueprint $blueprint, Fluent $command)
+    {
+        $columns = $this->prefixArray('drop column', $this->wrapArray($command->columns));
+
+        return 'alter table '.$this->wrapTable($blueprint).' '.implode(', ', $columns);
+    }
+
+    /**
+     * Compile a drop primary key command.
+     *
+     * @param  \Illuminate\Database\Schema\Blueprint  $blueprint
+     * @param  \Illuminate\Support\Fluent  $command
+     * @return string
+     */
+    public function compileDropPrimary(Blueprint $blueprint, Fluent $command)
+    {
+        $index = $this->wrap("{$blueprint->getTable()}_pkey");
+
+        return 'alter table '.$this->wrapTable($blueprint)." drop constraint {$index}";
+    }
+
+    /**
+     * Compile a drop unique key command.
+     *
+     * @param  \Illuminate\Database\Schema\Blueprint  $blueprint
+     * @param  \Illuminate\Support\Fluent  $command
+     * @return string
+     */
+    public function compileDropUnique(Blueprint $blueprint, Fluent $command)
+    {
+        $index = $this->wrap($command->index);
+
+        return "alter table {$this->wrapTable($blueprint)} drop constraint {$index}";
+    }
+
+    /**
+     * Compile a drop index command.
+     *
+     * @param  \Illuminate\Database\Schema\Blueprint  $blueprint
+     * @param  \Illuminate\Support\Fluent  $command
+     * @return string
+     */
+    public function compileDropIndex(Blueprint $blueprint, Fluent $command)
+    {
+        return "drop index {$this->wrap($command->index)}";
+    }
+
+    /**
+     * Compile a drop fulltext index command.
+     *
+     * @param  \Illuminate\Database\Schema\Blueprint  $blueprint
+     * @param  \Illuminate\Support\Fluent  $command
+     * @return string
+     */
+    public function compileDropFullText(Blueprint $blueprint, Fluent $command)
+    {
+        return $this->compileDropIndex($blueprint, $command);
+    }
+
+    /**
+     * Compile a drop spatial index command.
+     *
+     * @param  \Illuminate\Database\Schema\Blueprint  $blueprint
+     * @param  \Illuminate\Support\Fluent  $command
+     * @return string
+     */
+    public function compileDropSpatialIndex(Blueprint $blueprint, Fluent $command)
+    {
+        return $this->compileDropIndex($blueprint, $command);
+    }
+
+    /**
+     * Compile a drop foreign key command.
+     *
+     * @param  \Illuminate\Database\Schema\Blueprint  $blueprint
+     * @param  \Illuminate\Support\Fluent  $command
+     * @return string
+     */
+    public function compileDropForeign(Blueprint $blueprint, Fluent $command)
+    {
+        $index = $this->wrap($command->index);
+
+        return "alter table {$this->wrapTable($blueprint)} drop constraint {$index}";
+    }
+
+    /**
+     * Compile a rename table command.
+     *
+     * @param  \Illuminate\Database\Schema\Blueprint  $blueprint
+     * @param  \Illuminate\Support\Fluent  $command
+     * @return string
+     */
+    public function compileRename(Blueprint $blueprint, Fluent $command)
+    {
+        $from = $this->wrapTable($blueprint);
+
+        return "alter table {$from} rename to ".$this->wrapTable($command->to);
+    }
+
+    /**
+     * Compile a rename index command.
+     *
+     * @param  \Illuminate\Database\Schema\Blueprint  $blueprint
+     * @param  \Illuminate\Support\Fluent  $command
+     * @return string
+     */
+    public function compileRenameIndex(Blueprint $blueprint, Fluent $command)
+    {
+        return sprintf('alter index %s rename to %s',
+            $this->wrap($command->from),
+            $this->wrap($command->to)
+        );
+    }
+
+    /**
+     * Compile the command to enable foreign key constraints.
+     *
+     * @return string
+     */
+    public function compileEnableForeignKeyConstraints()
+    {
+        return 'SET CONSTRAINTS ALL IMMEDIATE;';
+    }
+
+    /**
+     * Compile the command to disable foreign key constraints.
+     *
+     * @return string
+     */
+    public function compileDisableForeignKeyConstraints()
+    {
+        return 'SET CONSTRAINTS ALL DEFERRED;';
+    }
+
+    /**
+     * Compile a comment command.
+     *
+     * @param  \Illuminate\Database\Schema\Blueprint  $blueprint
+     * @param  \Illuminate\Support\Fluent  $command
+     * @return string
+     */
+    public function compileComment(Blueprint $blueprint, Fluent $command)
+    {
+        return sprintf('comment on column %s.%s is %s',
+            $this->wrapTable($blueprint),
+            $this->wrap($command->column->name),
+            "'".str_replace("'", "''", $command->value)."'"
+        );
+    }
+
+    /**
+     * Compile a table comment command.
+     *
+     * @param  \Illuminate\Database\Schema\Blueprint  $blueprint
+     * @param  \Illuminate\Support\Fluent  $command
+     * @return string
+     */
+    public function compileTableComment(Blueprint $blueprint, Fluent $command)
+    {
+        return sprintf('comment on table %s is %s',
+            $this->wrapTable($blueprint),
+            "'".str_replace("'", "''", $command->comment)."'"
+        );
+    }
+
+    /**
+     * Quote-escape the given tables, views, or types.
+     *
+     * @param  array  $names
+     * @return array
+     */
+    public function escapeNames($names)
+    {
+        return array_map(static function ($name) {
+            return '"'.collect(explode('.', $name))
+                ->map(fn ($segment) => trim($segment, '\'"'))
+                ->implode('"."').'"';
+        }, $names);
+    }
+
+    /**
+     * Create the column definition for a char type.
+     *
+     * @param  \Illuminate\Support\Fluent  $column
+     * @return string
+     */
+    protected function typeChar(Fluent $column)
+    {
+        if ($column->length) {
+            return "char({$column->length})";
+        }
+
+        return 'char';
+    }
+
+    /**
+     * Create the column definition for a string type.
+     *
+     * @param  \Illuminate\Support\Fluent  $column
+     * @return string
+     */
+    protected function typeString(Fluent $column)
+    {
+        if ($column->length) {
+            return "varchar({$column->length})";
+        }
+
+        return 'varchar';
+    }
+
+    /**
+     * Create the column definition for a tiny text type.
+     *
+     * @param  \Illuminate\Support\Fluent  $column
+     * @return string
+     */
+    protected function typeTinyText(Fluent $column)
+    {
+        return 'varchar(255)';
+    }
+
+    /**
+     * Create the column definition for a text type.
+     *
+     * @param  \Illuminate\Support\Fluent  $column
+     * @return string
+     */
+    protected function typeText(Fluent $column)
+    {
+        return 'text';
+    }
+
+    /**
+     * Create the column definition for a medium text type.
+     *
+     * @param  \Illuminate\Support\Fluent  $column
+     * @return string
+     */
+    protected function typeMediumText(Fluent $column)
+    {
+        return 'text';
+    }
+
+    /**
+     * Create the column definition for a long text type.
+     *
+     * @param  \Illuminate\Support\Fluent  $column
+     * @return string
+     */
+    protected function typeLongText(Fluent $column)
+    {
+        return 'text';
+    }
+
+    /**
+     * Create the column definition for an integer type.
+     *
+     * @param  \Illuminate\Support\Fluent  $column
+     * @return string
+     */
+    protected function typeInteger(Fluent $column)
+    {
+        return $this->generatableColumn('integer', $column);
+    }
+
+    /**
+     * Create the column definition for a big integer type.
+     *
+     * @param  \Illuminate\Support\Fluent  $column
+     * @return string
+     */
+    protected function typeBigInteger(Fluent $column)
+    {
+        return $this->generatableColumn('bigint', $column);
+    }
+
+    /**
+     * Create the column definition for a medium integer type.
+     *
+     * @param  \Illuminate\Support\Fluent  $column
+     * @return string
+     */
+    protected function typeMediumInteger(Fluent $column)
+    {
+        return $this->generatableColumn('integer', $column);
+    }
+
+    /**
+     * Create the column definition for a tiny integer type.
+     *
+     * @param  \Illuminate\Support\Fluent  $column
+     * @return string
+     */
+    protected function typeTinyInteger(Fluent $column)
+    {
+        return $this->generatableColumn('smallint', $column);
+    }
+
+    /**
+     * Create the column definition for a small integer type.
+     *
+     * @param  \Illuminate\Support\Fluent  $column
+     * @return string
+     */
+    protected function typeSmallInteger(Fluent $column)
+    {
+        return $this->generatableColumn('smallint', $column);
+    }
+
+    /**
+     * Create the column definition for a generatable column.
+     *
+     * @param  string  $type
+     * @param  \Illuminate\Support\Fluent  $column
+     * @return string
+     */
+    protected function generatableColumn($type, Fluent $column)
+    {
+        if (! $column->autoIncrement && is_null($column->generatedAs)) {
+            return $type;
+        }
+
+        if ($column->autoIncrement && is_null($column->generatedAs)) {
+            return with([
+                'integer' => 'serial',
+                'bigint' => 'bigserial',
+                'smallint' => 'smallserial',
+            ])[$type];
+        }
+
+        $options = '';
+
+        if (! is_bool($column->generatedAs) && ! empty($column->generatedAs)) {
+            $options = sprintf(' (%s)', $column->generatedAs);
+        }
+
+        return sprintf(
+            '%s generated %s as identity%s',
+            $type,
+            $column->always ? 'always' : 'by default',
+            $options
+        );
+    }
+
+    /**
+     * Create the column definition for a float type.
+     *
+     * @param  \Illuminate\Support\Fluent  $column
+     * @return string
+     */
+    protected function typeFloat(Fluent $column)
+    {
+        return $this->typeDouble($column);
+    }
+
+    /**
+     * Create the column definition for a double type.
+     *
+     * @param  \Illuminate\Support\Fluent  $column
+     * @return string
+     */
+    protected function typeDouble(Fluent $column)
+    {
+        return 'double precision';
+    }
+
+    /**
+     * Create the column definition for a real type.
+     *
+     * @param  \Illuminate\Support\Fluent  $column
+     * @return string
+     */
+    protected function typeReal(Fluent $column)
+    {
+        return 'real';
+    }
+
+    /**
+     * Create the column definition for a decimal type.
+     *
+     * @param  \Illuminate\Support\Fluent  $column
+     * @return string
+     */
+    protected function typeDecimal(Fluent $column)
+    {
+        return "decimal({$column->total}, {$column->places})";
+    }
+
+    /**
+     * Create the column definition for a boolean type.
+     *
+     * @param  \Illuminate\Support\Fluent  $column
+     * @return string
+     */
+    protected function typeBoolean(Fluent $column)
+    {
+        return 'boolean';
+    }
+
+    /**
+     * Create the column definition for an enumeration type.
+     *
+     * @param  \Illuminate\Support\Fluent  $column
+     * @return string
+     */
+    protected function typeEnum(Fluent $column)
+    {
+        return sprintf(
+            'varchar(255) check ("%s" in (%s))',
+            $column->name,
+            $this->quoteString($column->allowed)
+        );
+    }
+
+    /**
+     * Create the column definition for a json type.
+     *
+     * @param  \Illuminate\Support\Fluent  $column
+     * @return string
+     */
+    protected function typeJson(Fluent $column)
+    {
+        return 'json';
+    }
+
+    /**
+     * Create the column definition for a jsonb type.
+     *
+     * @param  \Illuminate\Support\Fluent  $column
+     * @return string
+     */
+    protected function typeJsonb(Fluent $column)
+    {
+        return 'jsonb';
+    }
+
+    /**
+     * Create the column definition for a date type.
+     *
+     * @param  \Illuminate\Support\Fluent  $column
+     * @return string
+     */
+    protected function typeDate(Fluent $column)
+    {
+        return 'date';
+    }
+
+    /**
+     * Create the column definition for a date-time type.
+     *
+     * @param  \Illuminate\Support\Fluent  $column
+     * @return string
+     */
+    protected function typeDateTime(Fluent $column)
+    {
+        return $this->typeTimestamp($column);
+    }
+
+    /**
+     * Create the column definition for a date-time (with time zone) type.
+     *
+     * @param  \Illuminate\Support\Fluent  $column
+     * @return string
+     */
+    protected function typeDateTimeTz(Fluent $column)
+    {
+        return $this->typeTimestampTz($column);
+    }
+
+    /**
+     * Create the column definition for a time type.
+     *
+     * @param  \Illuminate\Support\Fluent  $column
+     * @return string
+     */
+    protected function typeTime(Fluent $column)
+    {
+        return 'time'.(is_null($column->precision) ? '' : "($column->precision)").' without time zone';
+    }
+
+    /**
+     * Create the column definition for a time (with time zone) type.
+     *
+     * @param  \Illuminate\Support\Fluent  $column
+     * @return string
+     */
+    protected function typeTimeTz(Fluent $column)
+    {
+        return 'time'.(is_null($column->precision) ? '' : "($column->precision)").' with time zone';
+    }
+
+    /**
+     * Create the column definition for a timestamp type.
+     *
+     * @param  \Illuminate\Support\Fluent  $column
+     * @return string
+     */
+    protected function typeTimestamp(Fluent $column)
+    {
+        $columnType = 'timestamp'.(is_null($column->precision) ? '' : "($column->precision)").' without time zone';
+
+        return $column->useCurrent ? "$columnType default CURRENT_TIMESTAMP" : $columnType;
+    }
+
+    /**
+     * Create the column definition for a timestamp (with time zone) type.
+     *
+     * @param  \Illuminate\Support\Fluent  $column
+     * @return string
+     */
+    protected function typeTimestampTz(Fluent $column)
+    {
+        $columnType = 'timestamp'.(is_null($column->precision) ? '' : "($column->precision)").' with time zone';
+
+        return $column->useCurrent ? "$columnType default CURRENT_TIMESTAMP" : $columnType;
+    }
+
+    /**
+     * Create the column definition for a year type.
+     *
+     * @param  \Illuminate\Support\Fluent  $column
+     * @return string
+     */
+    protected function typeYear(Fluent $column)
+    {
+        return $this->typeInteger($column);
+    }
+
+    /**
+     * Create the column definition for a binary type.
+     *
+     * @param  \Illuminate\Support\Fluent  $column
+     * @return string
+     */
+    protected function typeBinary(Fluent $column)
+    {
+        return 'bytea';
+    }
+
+    /**
+     * Create the column definition for a uuid type.
+     *
+     * @param  \Illuminate\Support\Fluent  $column
+     * @return string
+     */
+    protected function typeUuid(Fluent $column)
+    {
+        return 'uuid';
+    }
+
+    /**
+     * Create the column definition for an IP address type.
+     *
+     * @param  \Illuminate\Support\Fluent  $column
+     * @return string
+     */
+    protected function typeIpAddress(Fluent $column)
+    {
+        return 'inet';
+    }
+
+    /**
+     * Create the column definition for a MAC address type.
+     *
+     * @param  \Illuminate\Support\Fluent  $column
+     * @return string
+     */
+    protected function typeMacAddress(Fluent $column)
+    {
+        return 'macaddr';
+    }
+
+    /**
+     * Create the column definition for a spatial Geometry type.
+     *
+     * @param  \Illuminate\Support\Fluent  $column
+     * @return string
+     */
+    protected function typeGeometry(Fluent $column)
+    {
+        return $this->formatPostGisType('geometry', $column);
+    }
+
+    /**
+     * Create the column definition for a spatial Point type.
+     *
+     * @param  \Illuminate\Support\Fluent  $column
+     * @return string
+     */
+    protected function typePoint(Fluent $column)
+    {
+        return $this->formatPostGisType('point', $column);
+    }
+
+    /**
+     * Create the column definition for a spatial LineString type.
+     *
+     * @param  \Illuminate\Support\Fluent  $column
+     * @return string
+     */
+    protected function typeLineString(Fluent $column)
+    {
+        return $this->formatPostGisType('linestring', $column);
+    }
+
+    /**
+     * Create the column definition for a spatial Polygon type.
+     *
+     * @param  \Illuminate\Support\Fluent  $column
+     * @return string
+     */
+    protected function typePolygon(Fluent $column)
+    {
+        return $this->formatPostGisType('polygon', $column);
+    }
+
+    /**
+     * Create the column definition for a spatial GeometryCollection type.
+     *
+     * @param  \Illuminate\Support\Fluent  $column
+     * @return string
+     */
+    protected function typeGeometryCollection(Fluent $column)
+    {
+        return $this->formatPostGisType('geometrycollection', $column);
+    }
+
+    /**
+     * Create the column definition for a spatial MultiPoint type.
+     *
+     * @param  \Illuminate\Support\Fluent  $column
+     * @return string
+     */
+    protected function typeMultiPoint(Fluent $column)
+    {
+        return $this->formatPostGisType('multipoint', $column);
+    }
+
+    /**
+     * Create the column definition for a spatial MultiLineString type.
+     *
+     * @param  \Illuminate\Support\Fluent  $column
+     * @return string
+     */
+    public function typeMultiLineString(Fluent $column)
+    {
+        return $this->formatPostGisType('multilinestring', $column);
+    }
+
+    /**
+     * Create the column definition for a spatial MultiPolygon type.
+     *
+     * @param  \Illuminate\Support\Fluent  $column
+     * @return string
+     */
+    protected function typeMultiPolygon(Fluent $column)
+    {
+        return $this->formatPostGisType('multipolygon', $column);
+    }
+
+    /**
+     * Create the column definition for a spatial MultiPolygonZ type.
+     *
+     * @param  \Illuminate\Support\Fluent  $column
+     * @return string
+     */
+    protected function typeMultiPolygonZ(Fluent $column)
+    {
+        return $this->formatPostGisType('multipolygonz', $column);
+    }
+
+    /**
+     * Format the column definition for a PostGIS spatial type.
+     *
+     * @param  string  $type
+     * @param  \Illuminate\Support\Fluent  $column
+     * @return string
+     */
+    private function formatPostGisType($type, Fluent $column)
+    {
+        if ($column->isGeometry === null) {
+            return sprintf('geography(%s, %s)', $type, $column->projection ?? '4326');
+        }
+
+        if ($column->projection !== null) {
+            return sprintf('geometry(%s, %s)', $type, $column->projection);
+        }
+
+        return "geometry({$type})";
+    }
+
+    /**
+     * Get the SQL for a collation column modifier.
+     *
+     * @param  \Illuminate\Database\Schema\Blueprint  $blueprint
+     * @param  \Illuminate\Support\Fluent  $column
+     * @return string|null
+     */
+    protected function modifyCollate(Blueprint $blueprint, Fluent $column)
+    {
+        if (! is_null($column->collation)) {
+            return ' collate '.$this->wrapValue($column->collation);
+        }
+    }
+
+    /**
+     * Get the SQL for a nullable column modifier.
+     *
+     * @param  \Illuminate\Database\Schema\Blueprint  $blueprint
+     * @param  \Illuminate\Support\Fluent  $column
+     * @return string|null
+     */
+    protected function modifyNullable(Blueprint $blueprint, Fluent $column)
+    {
+        return $column->nullable ? ' null' : ' not null';
+    }
+
+    /**
+     * Get the SQL for a default column modifier.
+     *
+     * @param  \Illuminate\Database\Schema\Blueprint  $blueprint
+     * @param  \Illuminate\Support\Fluent  $column
+     * @return string|null
+     */
+    protected function modifyDefault(Blueprint $blueprint, Fluent $column)
+    {
+        if (! is_null($column->default)) {
+            return ' default '.$this->getDefaultValue($column->default);
+        }
+    }
+
+    /**
+     * Get the SQL for an auto-increment column modifier.
+     *
+     * @param  \Illuminate\Database\Schema\Blueprint  $blueprint
+     * @param  \Illuminate\Support\Fluent  $column
+     * @return string|null
+     */
+    protected function modifyIncrement(Blueprint $blueprint, Fluent $column)
+    {
+        if ((in_array($column->type, $this->serials) || ($column->generatedAs !== null)) && $column->autoIncrement) {
+            return ' primary key';
+        }
+    }
+
+    /**
+     * Get the SQL for a generated virtual column modifier.
+     *
+     * @param  \Illuminate\Database\Schema\Blueprint  $blueprint
+     * @param  \Illuminate\Support\Fluent  $column
+     * @return string|null
+     */
+    protected function modifyVirtualAs(Blueprint $blueprint, Fluent $column)
+    {
+        if ($column->virtualAs !== null) {
+            return " generated always as ({$column->virtualAs})";
+        }
+    }
+
+    /**
+     * Get the SQL for a generated stored column modifier.
+     *
+     * @param  \Illuminate\Database\Schema\Blueprint  $blueprint
+     * @param  \Illuminate\Support\Fluent  $column
+     * @return string|null
+     */
+    protected function modifyStoredAs(Blueprint $blueprint, Fluent $column)
+    {
+        if ($column->storedAs !== null) {
+            return " generated always as ({$column->storedAs}) stored";
+        }
+    }
+}
diff --git a/vendor/illuminate/database/Schema/Grammars/RenameColumn.php b/vendor/illuminate/database/Schema/Grammars/RenameColumn.php
new file mode 100644
index 0000000..0db0c50
--- /dev/null
+++ b/vendor/illuminate/database/Schema/Grammars/RenameColumn.php
@@ -0,0 +1,84 @@
+getDoctrineSchemaManager();
+        $databasePlatform = $schema->getDatabasePlatform();
+        $databasePlatform->registerDoctrineTypeMapping('enum', 'string');
+
+        $column = $connection->getDoctrineColumn(
+            $grammar->getTablePrefix().$blueprint->getTable(), $command->from
+        );
+
+        return (array) $databasePlatform->getAlterTableSQL(static::getRenamedDiff(
+            $grammar, $blueprint, $command, $column, $schema
+        ));
+    }
+
+    /**
+     * Get a new column instance with the new column name.
+     *
+     * @param  \Illuminate\Database\Schema\Grammars\Grammar  $grammar
+     * @param  \Illuminate\Database\Schema\Blueprint  $blueprint
+     * @param  \Illuminate\Support\Fluent  $command
+     * @param  \Doctrine\DBAL\Schema\Column  $column
+     * @param  \Doctrine\DBAL\Schema\AbstractSchemaManager  $schema
+     * @return \Doctrine\DBAL\Schema\TableDiff
+     */
+    protected static function getRenamedDiff(Grammar $grammar, Blueprint $blueprint, Fluent $command, Column $column, SchemaManager $schema)
+    {
+        return static::setRenamedColumns(
+            $grammar->getDoctrineTableDiff($blueprint, $schema), $command, $column
+        );
+    }
+
+    /**
+     * Set the renamed columns on the table diff.
+     *
+     * @param  \Doctrine\DBAL\Schema\TableDiff  $tableDiff
+     * @param  \Illuminate\Support\Fluent  $command
+     * @param  \Doctrine\DBAL\Schema\Column  $column
+     * @return \Doctrine\DBAL\Schema\TableDiff
+     */
+    protected static function setRenamedColumns(TableDiff $tableDiff, Fluent $command, Column $column)
+    {
+        $tableDiff->renamedColumns = [
+            $command->from => new Column($command->to, $column->getType(), self::getWritableColumnOptions($column)),
+        ];
+
+        return $tableDiff;
+    }
+
+    /**
+     * Get the writable column options.
+     *
+     * @param  \Doctrine\DBAL\Schema\Column  $column
+     * @return array
+     */
+    private static function getWritableColumnOptions(Column $column)
+    {
+        return array_filter($column->toArray(), function (string $name) use ($column) {
+            return method_exists($column, 'set'.$name);
+        }, ARRAY_FILTER_USE_KEY);
+    }
+}
diff --git a/vendor/illuminate/database/Schema/Grammars/SQLiteGrammar.php b/vendor/illuminate/database/Schema/Grammars/SQLiteGrammar.php
new file mode 100755
index 0000000..c9d1c55
--- /dev/null
+++ b/vendor/illuminate/database/Schema/Grammars/SQLiteGrammar.php
@@ -0,0 +1,1005 @@
+wrap(str_replace('.', '__', $table)).')';
+    }
+
+    /**
+     * Compile a create table command.
+     *
+     * @param  \Illuminate\Database\Schema\Blueprint  $blueprint
+     * @param  \Illuminate\Support\Fluent  $command
+     * @return string
+     */
+    public function compileCreate(Blueprint $blueprint, Fluent $command)
+    {
+        return sprintf('%s table %s (%s%s%s)',
+            $blueprint->temporary ? 'create temporary' : 'create',
+            $this->wrapTable($blueprint),
+            implode(', ', $this->getColumns($blueprint)),
+            (string) $this->addForeignKeys($blueprint),
+            (string) $this->addPrimaryKeys($blueprint)
+        );
+    }
+
+    /**
+     * Get the foreign key syntax for a table creation statement.
+     *
+     * @param  \Illuminate\Database\Schema\Blueprint  $blueprint
+     * @return string|null
+     */
+    protected function addForeignKeys(Blueprint $blueprint)
+    {
+        $foreigns = $this->getCommandsByName($blueprint, 'foreign');
+
+        return collect($foreigns)->reduce(function ($sql, $foreign) {
+            // Once we have all the foreign key commands for the table creation statement
+            // we'll loop through each of them and add them to the create table SQL we
+            // are building, since SQLite needs foreign keys on the tables creation.
+            $sql .= $this->getForeignKey($foreign);
+
+            if (! is_null($foreign->onDelete)) {
+                $sql .= " on delete {$foreign->onDelete}";
+            }
+
+            // If this foreign key specifies the action to be taken on update we will add
+            // that to the statement here. We'll append it to this SQL and then return
+            // the SQL so we can keep adding any other foreign constraints onto this.
+            if (! is_null($foreign->onUpdate)) {
+                $sql .= " on update {$foreign->onUpdate}";
+            }
+
+            return $sql;
+        }, '');
+    }
+
+    /**
+     * Get the SQL for the foreign key.
+     *
+     * @param  \Illuminate\Support\Fluent  $foreign
+     * @return string
+     */
+    protected function getForeignKey($foreign)
+    {
+        // We need to columnize the columns that the foreign key is being defined for
+        // so that it is a properly formatted list. Once we have done this, we can
+        // return the foreign key SQL declaration to the calling method for use.
+        return sprintf(', foreign key(%s) references %s(%s)',
+            $this->columnize($foreign->columns),
+            $this->wrapTable($foreign->on),
+            $this->columnize((array) $foreign->references)
+        );
+    }
+
+    /**
+     * Get the primary key syntax for a table creation statement.
+     *
+     * @param  \Illuminate\Database\Schema\Blueprint  $blueprint
+     * @return string|null
+     */
+    protected function addPrimaryKeys(Blueprint $blueprint)
+    {
+        if (! is_null($primary = $this->getCommandByName($blueprint, 'primary'))) {
+            return ", primary key ({$this->columnize($primary->columns)})";
+        }
+    }
+
+    /**
+     * Compile alter table commands for adding columns.
+     *
+     * @param  \Illuminate\Database\Schema\Blueprint  $blueprint
+     * @param  \Illuminate\Support\Fluent  $command
+     * @return array
+     */
+    public function compileAdd(Blueprint $blueprint, Fluent $command)
+    {
+        $columns = $this->prefixArray('add column', $this->getColumns($blueprint));
+
+        return collect($columns)->reject(function ($column) {
+            return preg_match('/as \(.*\) stored/', $column) > 0;
+        })->map(function ($column) use ($blueprint) {
+            return 'alter table '.$this->wrapTable($blueprint).' '.$column;
+        })->all();
+    }
+
+    /**
+     * Compile a rename column command.
+     *
+     * @param  \Illuminate\Database\Schema\Blueprint  $blueprint
+     * @param  \Illuminate\Support\Fluent  $command
+     * @param  \Illuminate\Database\Connection  $connection
+     * @return array|string
+     */
+    public function compileRenameColumn(Blueprint $blueprint, Fluent $command, Connection $connection)
+    {
+        return $connection->usingNativeSchemaOperations()
+            ? sprintf('alter table %s rename column %s to %s',
+                $this->wrapTable($blueprint),
+                $this->wrap($command->from),
+                $this->wrap($command->to)
+            )
+            : parent::compileRenameColumn($blueprint, $command, $connection);
+    }
+
+    /**
+     * Compile a unique key command.
+     *
+     * @param  \Illuminate\Database\Schema\Blueprint  $blueprint
+     * @param  \Illuminate\Support\Fluent  $command
+     * @return string
+     */
+    public function compileUnique(Blueprint $blueprint, Fluent $command)
+    {
+        return sprintf('create unique index %s on %s (%s)',
+            $this->wrap($command->index),
+            $this->wrapTable($blueprint),
+            $this->columnize($command->columns)
+        );
+    }
+
+    /**
+     * Compile a plain index key command.
+     *
+     * @param  \Illuminate\Database\Schema\Blueprint  $blueprint
+     * @param  \Illuminate\Support\Fluent  $command
+     * @return string
+     */
+    public function compileIndex(Blueprint $blueprint, Fluent $command)
+    {
+        return sprintf('create index %s on %s (%s)',
+            $this->wrap($command->index),
+            $this->wrapTable($blueprint),
+            $this->columnize($command->columns)
+        );
+    }
+
+    /**
+     * Compile a spatial index key command.
+     *
+     * @param  \Illuminate\Database\Schema\Blueprint  $blueprint
+     * @param  \Illuminate\Support\Fluent  $command
+     * @return void
+     *
+     * @throws \RuntimeException
+     */
+    public function compileSpatialIndex(Blueprint $blueprint, Fluent $command)
+    {
+        throw new RuntimeException('The database driver in use does not support spatial indexes.');
+    }
+
+    /**
+     * Compile a foreign key command.
+     *
+     * @param  \Illuminate\Database\Schema\Blueprint  $blueprint
+     * @param  \Illuminate\Support\Fluent  $command
+     * @return string
+     */
+    public function compileForeign(Blueprint $blueprint, Fluent $command)
+    {
+        // Handled on table creation...
+    }
+
+    /**
+     * Compile a drop table command.
+     *
+     * @param  \Illuminate\Database\Schema\Blueprint  $blueprint
+     * @param  \Illuminate\Support\Fluent  $command
+     * @return string
+     */
+    public function compileDrop(Blueprint $blueprint, Fluent $command)
+    {
+        return 'drop table '.$this->wrapTable($blueprint);
+    }
+
+    /**
+     * Compile a drop table (if exists) command.
+     *
+     * @param  \Illuminate\Database\Schema\Blueprint  $blueprint
+     * @param  \Illuminate\Support\Fluent  $command
+     * @return string
+     */
+    public function compileDropIfExists(Blueprint $blueprint, Fluent $command)
+    {
+        return 'drop table if exists '.$this->wrapTable($blueprint);
+    }
+
+    /**
+     * Compile the SQL needed to drop all tables.
+     *
+     * @return string
+     */
+    public function compileDropAllTables()
+    {
+        return "delete from sqlite_master where type in ('table', 'index', 'trigger')";
+    }
+
+    /**
+     * Compile the SQL needed to drop all views.
+     *
+     * @return string
+     */
+    public function compileDropAllViews()
+    {
+        return "delete from sqlite_master where type in ('view')";
+    }
+
+    /**
+     * Compile the SQL needed to retrieve all table names.
+     *
+     * @return string
+     */
+    public function compileGetAllTables()
+    {
+        return 'select type, name from sqlite_master where type = \'table\' and name not like \'sqlite_%\'';
+    }
+
+    /**
+     * Compile the SQL needed to retrieve all view names.
+     *
+     * @return string
+     */
+    public function compileGetAllViews()
+    {
+        return 'select type, name from sqlite_master where type = \'view\'';
+    }
+
+    /**
+     * Compile the SQL needed to rebuild the database.
+     *
+     * @return string
+     */
+    public function compileRebuild()
+    {
+        return 'vacuum';
+    }
+
+    /**
+     * Compile a drop column command.
+     *
+     * @param  \Illuminate\Database\Schema\Blueprint  $blueprint
+     * @param  \Illuminate\Support\Fluent  $command
+     * @param  \Illuminate\Database\Connection  $connection
+     * @return array
+     */
+    public function compileDropColumn(Blueprint $blueprint, Fluent $command, Connection $connection)
+    {
+        if ($connection->usingNativeSchemaOperations()) {
+            $table = $this->wrapTable($blueprint);
+
+            $columns = $this->prefixArray('drop column', $this->wrapArray($command->columns));
+
+            return collect($columns)->map(fn ($column) => 'alter table '.$table.' '.$column
+            )->all();
+        } else {
+            $tableDiff = $this->getDoctrineTableDiff(
+                $blueprint, $schema = $connection->getDoctrineSchemaManager()
+            );
+
+            foreach ($command->columns as $name) {
+                $tableDiff->removedColumns[$name] = $connection->getDoctrineColumn(
+                    $this->getTablePrefix().$blueprint->getTable(), $name
+                );
+            }
+
+            return (array) $schema->getDatabasePlatform()->getAlterTableSQL($tableDiff);
+        }
+    }
+
+    /**
+     * Compile a drop unique key command.
+     *
+     * @param  \Illuminate\Database\Schema\Blueprint  $blueprint
+     * @param  \Illuminate\Support\Fluent  $command
+     * @return string
+     */
+    public function compileDropUnique(Blueprint $blueprint, Fluent $command)
+    {
+        $index = $this->wrap($command->index);
+
+        return "drop index {$index}";
+    }
+
+    /**
+     * Compile a drop index command.
+     *
+     * @param  \Illuminate\Database\Schema\Blueprint  $blueprint
+     * @param  \Illuminate\Support\Fluent  $command
+     * @return string
+     */
+    public function compileDropIndex(Blueprint $blueprint, Fluent $command)
+    {
+        $index = $this->wrap($command->index);
+
+        return "drop index {$index}";
+    }
+
+    /**
+     * Compile a drop spatial index command.
+     *
+     * @param  \Illuminate\Database\Schema\Blueprint  $blueprint
+     * @param  \Illuminate\Support\Fluent  $command
+     * @return void
+     *
+     * @throws \RuntimeException
+     */
+    public function compileDropSpatialIndex(Blueprint $blueprint, Fluent $command)
+    {
+        throw new RuntimeException('The database driver in use does not support spatial indexes.');
+    }
+
+    /**
+     * Compile a rename table command.
+     *
+     * @param  \Illuminate\Database\Schema\Blueprint  $blueprint
+     * @param  \Illuminate\Support\Fluent  $command
+     * @return string
+     */
+    public function compileRename(Blueprint $blueprint, Fluent $command)
+    {
+        $from = $this->wrapTable($blueprint);
+
+        return "alter table {$from} rename to ".$this->wrapTable($command->to);
+    }
+
+    /**
+     * Compile a rename index command.
+     *
+     * @param  \Illuminate\Database\Schema\Blueprint  $blueprint
+     * @param  \Illuminate\Support\Fluent  $command
+     * @param  \Illuminate\Database\Connection  $connection
+     * @return array
+     *
+     * @throws \RuntimeException
+     */
+    public function compileRenameIndex(Blueprint $blueprint, Fluent $command, Connection $connection)
+    {
+        $schemaManager = $connection->getDoctrineSchemaManager();
+
+        $indexes = $schemaManager->listTableIndexes($this->getTablePrefix().$blueprint->getTable());
+
+        $index = Arr::get($indexes, $command->from);
+
+        if (! $index) {
+            throw new RuntimeException("Index [{$command->from}] does not exist.");
+        }
+
+        $newIndex = new Index(
+            $command->to, $index->getColumns(), $index->isUnique(),
+            $index->isPrimary(), $index->getFlags(), $index->getOptions()
+        );
+
+        $platform = $schemaManager->getDatabasePlatform();
+
+        return [
+            $platform->getDropIndexSQL($command->from, $this->getTablePrefix().$blueprint->getTable()),
+            $platform->getCreateIndexSQL($newIndex, $this->getTablePrefix().$blueprint->getTable()),
+        ];
+    }
+
+    /**
+     * Compile the command to enable foreign key constraints.
+     *
+     * @return string
+     */
+    public function compileEnableForeignKeyConstraints()
+    {
+        return 'PRAGMA foreign_keys = ON;';
+    }
+
+    /**
+     * Compile the command to disable foreign key constraints.
+     *
+     * @return string
+     */
+    public function compileDisableForeignKeyConstraints()
+    {
+        return 'PRAGMA foreign_keys = OFF;';
+    }
+
+    /**
+     * Compile the SQL needed to enable a writable schema.
+     *
+     * @return string
+     */
+    public function compileEnableWriteableSchema()
+    {
+        return 'PRAGMA writable_schema = 1;';
+    }
+
+    /**
+     * Compile the SQL needed to disable a writable schema.
+     *
+     * @return string
+     */
+    public function compileDisableWriteableSchema()
+    {
+        return 'PRAGMA writable_schema = 0;';
+    }
+
+    /**
+     * Create the column definition for a char type.
+     *
+     * @param  \Illuminate\Support\Fluent  $column
+     * @return string
+     */
+    protected function typeChar(Fluent $column)
+    {
+        return 'varchar';
+    }
+
+    /**
+     * Create the column definition for a string type.
+     *
+     * @param  \Illuminate\Support\Fluent  $column
+     * @return string
+     */
+    protected function typeString(Fluent $column)
+    {
+        return 'varchar';
+    }
+
+    /**
+     * Create the column definition for a tiny text type.
+     *
+     * @param  \Illuminate\Support\Fluent  $column
+     * @return string
+     */
+    protected function typeTinyText(Fluent $column)
+    {
+        return 'text';
+    }
+
+    /**
+     * Create the column definition for a text type.
+     *
+     * @param  \Illuminate\Support\Fluent  $column
+     * @return string
+     */
+    protected function typeText(Fluent $column)
+    {
+        return 'text';
+    }
+
+    /**
+     * Create the column definition for a medium text type.
+     *
+     * @param  \Illuminate\Support\Fluent  $column
+     * @return string
+     */
+    protected function typeMediumText(Fluent $column)
+    {
+        return 'text';
+    }
+
+    /**
+     * Create the column definition for a long text type.
+     *
+     * @param  \Illuminate\Support\Fluent  $column
+     * @return string
+     */
+    protected function typeLongText(Fluent $column)
+    {
+        return 'text';
+    }
+
+    /**
+     * Create the column definition for an integer type.
+     *
+     * @param  \Illuminate\Support\Fluent  $column
+     * @return string
+     */
+    protected function typeInteger(Fluent $column)
+    {
+        return 'integer';
+    }
+
+    /**
+     * Create the column definition for a big integer type.
+     *
+     * @param  \Illuminate\Support\Fluent  $column
+     * @return string
+     */
+    protected function typeBigInteger(Fluent $column)
+    {
+        return 'integer';
+    }
+
+    /**
+     * Create the column definition for a medium integer type.
+     *
+     * @param  \Illuminate\Support\Fluent  $column
+     * @return string
+     */
+    protected function typeMediumInteger(Fluent $column)
+    {
+        return 'integer';
+    }
+
+    /**
+     * Create the column definition for a tiny integer type.
+     *
+     * @param  \Illuminate\Support\Fluent  $column
+     * @return string
+     */
+    protected function typeTinyInteger(Fluent $column)
+    {
+        return 'integer';
+    }
+
+    /**
+     * Create the column definition for a small integer type.
+     *
+     * @param  \Illuminate\Support\Fluent  $column
+     * @return string
+     */
+    protected function typeSmallInteger(Fluent $column)
+    {
+        return 'integer';
+    }
+
+    /**
+     * Create the column definition for a float type.
+     *
+     * @param  \Illuminate\Support\Fluent  $column
+     * @return string
+     */
+    protected function typeFloat(Fluent $column)
+    {
+        return 'float';
+    }
+
+    /**
+     * Create the column definition for a double type.
+     *
+     * @param  \Illuminate\Support\Fluent  $column
+     * @return string
+     */
+    protected function typeDouble(Fluent $column)
+    {
+        return 'float';
+    }
+
+    /**
+     * Create the column definition for a decimal type.
+     *
+     * @param  \Illuminate\Support\Fluent  $column
+     * @return string
+     */
+    protected function typeDecimal(Fluent $column)
+    {
+        return 'numeric';
+    }
+
+    /**
+     * Create the column definition for a boolean type.
+     *
+     * @param  \Illuminate\Support\Fluent  $column
+     * @return string
+     */
+    protected function typeBoolean(Fluent $column)
+    {
+        return 'tinyint(1)';
+    }
+
+    /**
+     * Create the column definition for an enumeration type.
+     *
+     * @param  \Illuminate\Support\Fluent  $column
+     * @return string
+     */
+    protected function typeEnum(Fluent $column)
+    {
+        return sprintf(
+            'varchar check ("%s" in (%s))',
+            $column->name,
+            $this->quoteString($column->allowed)
+        );
+    }
+
+    /**
+     * Create the column definition for a json type.
+     *
+     * @param  \Illuminate\Support\Fluent  $column
+     * @return string
+     */
+    protected function typeJson(Fluent $column)
+    {
+        return 'text';
+    }
+
+    /**
+     * Create the column definition for a jsonb type.
+     *
+     * @param  \Illuminate\Support\Fluent  $column
+     * @return string
+     */
+    protected function typeJsonb(Fluent $column)
+    {
+        return 'text';
+    }
+
+    /**
+     * Create the column definition for a date type.
+     *
+     * @param  \Illuminate\Support\Fluent  $column
+     * @return string
+     */
+    protected function typeDate(Fluent $column)
+    {
+        return 'date';
+    }
+
+    /**
+     * Create the column definition for a date-time type.
+     *
+     * @param  \Illuminate\Support\Fluent  $column
+     * @return string
+     */
+    protected function typeDateTime(Fluent $column)
+    {
+        return $this->typeTimestamp($column);
+    }
+
+    /**
+     * Create the column definition for a date-time (with time zone) type.
+     *
+     * Note: "SQLite does not have a storage class set aside for storing dates and/or times."
+     *
+     * @link https://www.sqlite.org/datatype3.html
+     *
+     * @param  \Illuminate\Support\Fluent  $column
+     * @return string
+     */
+    protected function typeDateTimeTz(Fluent $column)
+    {
+        return $this->typeDateTime($column);
+    }
+
+    /**
+     * Create the column definition for a time type.
+     *
+     * @param  \Illuminate\Support\Fluent  $column
+     * @return string
+     */
+    protected function typeTime(Fluent $column)
+    {
+        return 'time';
+    }
+
+    /**
+     * Create the column definition for a time (with time zone) type.
+     *
+     * @param  \Illuminate\Support\Fluent  $column
+     * @return string
+     */
+    protected function typeTimeTz(Fluent $column)
+    {
+        return $this->typeTime($column);
+    }
+
+    /**
+     * Create the column definition for a timestamp type.
+     *
+     * @param  \Illuminate\Support\Fluent  $column
+     * @return string
+     */
+    protected function typeTimestamp(Fluent $column)
+    {
+        return $column->useCurrent ? 'datetime default CURRENT_TIMESTAMP' : 'datetime';
+    }
+
+    /**
+     * Create the column definition for a timestamp (with time zone) type.
+     *
+     * @param  \Illuminate\Support\Fluent  $column
+     * @return string
+     */
+    protected function typeTimestampTz(Fluent $column)
+    {
+        return $this->typeTimestamp($column);
+    }
+
+    /**
+     * Create the column definition for a year type.
+     *
+     * @param  \Illuminate\Support\Fluent  $column
+     * @return string
+     */
+    protected function typeYear(Fluent $column)
+    {
+        return $this->typeInteger($column);
+    }
+
+    /**
+     * Create the column definition for a binary type.
+     *
+     * @param  \Illuminate\Support\Fluent  $column
+     * @return string
+     */
+    protected function typeBinary(Fluent $column)
+    {
+        return 'blob';
+    }
+
+    /**
+     * Create the column definition for a uuid type.
+     *
+     * @param  \Illuminate\Support\Fluent  $column
+     * @return string
+     */
+    protected function typeUuid(Fluent $column)
+    {
+        return 'varchar';
+    }
+
+    /**
+     * Create the column definition for an IP address type.
+     *
+     * @param  \Illuminate\Support\Fluent  $column
+     * @return string
+     */
+    protected function typeIpAddress(Fluent $column)
+    {
+        return 'varchar';
+    }
+
+    /**
+     * Create the column definition for a MAC address type.
+     *
+     * @param  \Illuminate\Support\Fluent  $column
+     * @return string
+     */
+    protected function typeMacAddress(Fluent $column)
+    {
+        return 'varchar';
+    }
+
+    /**
+     * Create the column definition for a spatial Geometry type.
+     *
+     * @param  \Illuminate\Support\Fluent  $column
+     * @return string
+     */
+    public function typeGeometry(Fluent $column)
+    {
+        return 'geometry';
+    }
+
+    /**
+     * Create the column definition for a spatial Point type.
+     *
+     * @param  \Illuminate\Support\Fluent  $column
+     * @return string
+     */
+    public function typePoint(Fluent $column)
+    {
+        return 'point';
+    }
+
+    /**
+     * Create the column definition for a spatial LineString type.
+     *
+     * @param  \Illuminate\Support\Fluent  $column
+     * @return string
+     */
+    public function typeLineString(Fluent $column)
+    {
+        return 'linestring';
+    }
+
+    /**
+     * Create the column definition for a spatial Polygon type.
+     *
+     * @param  \Illuminate\Support\Fluent  $column
+     * @return string
+     */
+    public function typePolygon(Fluent $column)
+    {
+        return 'polygon';
+    }
+
+    /**
+     * Create the column definition for a spatial GeometryCollection type.
+     *
+     * @param  \Illuminate\Support\Fluent  $column
+     * @return string
+     */
+    public function typeGeometryCollection(Fluent $column)
+    {
+        return 'geometrycollection';
+    }
+
+    /**
+     * Create the column definition for a spatial MultiPoint type.
+     *
+     * @param  \Illuminate\Support\Fluent  $column
+     * @return string
+     */
+    public function typeMultiPoint(Fluent $column)
+    {
+        return 'multipoint';
+    }
+
+    /**
+     * Create the column definition for a spatial MultiLineString type.
+     *
+     * @param  \Illuminate\Support\Fluent  $column
+     * @return string
+     */
+    public function typeMultiLineString(Fluent $column)
+    {
+        return 'multilinestring';
+    }
+
+    /**
+     * Create the column definition for a spatial MultiPolygon type.
+     *
+     * @param  \Illuminate\Support\Fluent  $column
+     * @return string
+     */
+    public function typeMultiPolygon(Fluent $column)
+    {
+        return 'multipolygon';
+    }
+
+    /**
+     * Create the column definition for a generated, computed column type.
+     *
+     * @param  \Illuminate\Support\Fluent  $column
+     * @return void
+     *
+     * @throws \RuntimeException
+     */
+    protected function typeComputed(Fluent $column)
+    {
+        throw new RuntimeException('This database driver requires a type, see the virtualAs / storedAs modifiers.');
+    }
+
+    /**
+     * Get the SQL for a generated virtual column modifier.
+     *
+     * @param  \Illuminate\Database\Schema\Blueprint  $blueprint
+     * @param  \Illuminate\Support\Fluent  $column
+     * @return string|null
+     */
+    protected function modifyVirtualAs(Blueprint $blueprint, Fluent $column)
+    {
+        if (! is_null($virtualAs = $column->virtualAsJson)) {
+            if ($this->isJsonSelector($virtualAs)) {
+                $virtualAs = $this->wrapJsonSelector($virtualAs);
+            }
+
+            return " as ({$virtualAs})";
+        }
+
+        if (! is_null($virtualAs = $column->virtualAs)) {
+            return " as ({$virtualAs})";
+        }
+    }
+
+    /**
+     * Get the SQL for a generated stored column modifier.
+     *
+     * @param  \Illuminate\Database\Schema\Blueprint  $blueprint
+     * @param  \Illuminate\Support\Fluent  $column
+     * @return string|null
+     */
+    protected function modifyStoredAs(Blueprint $blueprint, Fluent $column)
+    {
+        if (! is_null($storedAs = $column->storedAsJson)) {
+            if ($this->isJsonSelector($storedAs)) {
+                $storedAs = $this->wrapJsonSelector($storedAs);
+            }
+
+            return " as ({$storedAs}) stored";
+        }
+
+        if (! is_null($storedAs = $column->storedAs)) {
+            return " as ({$column->storedAs}) stored";
+        }
+    }
+
+    /**
+     * Get the SQL for a nullable column modifier.
+     *
+     * @param  \Illuminate\Database\Schema\Blueprint  $blueprint
+     * @param  \Illuminate\Support\Fluent  $column
+     * @return string|null
+     */
+    protected function modifyNullable(Blueprint $blueprint, Fluent $column)
+    {
+        if (is_null($column->virtualAs) &&
+            is_null($column->virtualAsJson) &&
+            is_null($column->storedAs) &&
+            is_null($column->storedAsJson)) {
+            return $column->nullable ? '' : ' not null';
+        }
+
+        if ($column->nullable === false) {
+            return ' not null';
+        }
+    }
+
+    /**
+     * Get the SQL for a default column modifier.
+     *
+     * @param  \Illuminate\Database\Schema\Blueprint  $blueprint
+     * @param  \Illuminate\Support\Fluent  $column
+     * @return string|null
+     */
+    protected function modifyDefault(Blueprint $blueprint, Fluent $column)
+    {
+        if (! is_null($column->default) && is_null($column->virtualAs) && is_null($column->virtualAsJson) && is_null($column->storedAs)) {
+            return ' default '.$this->getDefaultValue($column->default);
+        }
+    }
+
+    /**
+     * Get the SQL for an auto-increment column modifier.
+     *
+     * @param  \Illuminate\Database\Schema\Blueprint  $blueprint
+     * @param  \Illuminate\Support\Fluent  $column
+     * @return string|null
+     */
+    protected function modifyIncrement(Blueprint $blueprint, Fluent $column)
+    {
+        if (in_array($column->type, $this->serials) && $column->autoIncrement) {
+            return ' primary key autoincrement';
+        }
+    }
+
+    /**
+     * Wrap the given JSON selector.
+     *
+     * @param  string  $value
+     * @return string
+     */
+    protected function wrapJsonSelector($value)
+    {
+        [$field, $path] = $this->wrapJsonFieldAndPath($value);
+
+        return 'json_extract('.$field.$path.')';
+    }
+}
diff --git a/vendor/illuminate/database/Schema/Grammars/SqlServerGrammar.php b/vendor/illuminate/database/Schema/Grammars/SqlServerGrammar.php
new file mode 100755
index 0000000..4d7271c
--- /dev/null
+++ b/vendor/illuminate/database/Schema/Grammars/SqlServerGrammar.php
@@ -0,0 +1,973 @@
+wrapValue($name),
+        );
+    }
+
+    /**
+     * Compile a drop database if exists command.
+     *
+     * @param  string  $name
+     * @return string
+     */
+    public function compileDropDatabaseIfExists($name)
+    {
+        return sprintf(
+            'drop database if exists %s',
+            $this->wrapValue($name)
+        );
+    }
+
+    /**
+     * Compile the query to determine if a table exists.
+     *
+     * @return string
+     */
+    public function compileTableExists()
+    {
+        return "select * from sys.sysobjects where id = object_id(?) and xtype in ('U', 'V')";
+    }
+
+    /**
+     * Compile the query to determine the list of columns.
+     *
+     * @param  string  $table
+     * @return string
+     */
+    public function compileColumnListing($table)
+    {
+        return "select name from sys.columns where object_id = object_id('$table')";
+    }
+
+    /**
+     * Compile a create table command.
+     *
+     * @param  \Illuminate\Database\Schema\Blueprint  $blueprint
+     * @param  \Illuminate\Support\Fluent  $command
+     * @return string
+     */
+    public function compileCreate(Blueprint $blueprint, Fluent $command)
+    {
+        $columns = implode(', ', $this->getColumns($blueprint));
+
+        return 'create table '.$this->wrapTable($blueprint)." ($columns)";
+    }
+
+    /**
+     * Compile a column addition table command.
+     *
+     * @param  \Illuminate\Database\Schema\Blueprint  $blueprint
+     * @param  \Illuminate\Support\Fluent  $command
+     * @return string
+     */
+    public function compileAdd(Blueprint $blueprint, Fluent $command)
+    {
+        return sprintf('alter table %s add %s',
+            $this->wrapTable($blueprint),
+            implode(', ', $this->getColumns($blueprint))
+        );
+    }
+
+    /**
+     * Compile a rename column command.
+     *
+     * @param  \Illuminate\Database\Schema\Blueprint  $blueprint
+     * @param  \Illuminate\Support\Fluent  $command
+     * @param  \Illuminate\Database\Connection  $connection
+     * @return array|string
+     */
+    public function compileRenameColumn(Blueprint $blueprint, Fluent $command, Connection $connection)
+    {
+        return $connection->usingNativeSchemaOperations()
+            ? sprintf("sp_rename '%s', %s, 'COLUMN'",
+                $this->wrap($blueprint->getTable().'.'.$command->from),
+                $this->wrap($command->to)
+            )
+            : parent::compileRenameColumn($blueprint, $command, $connection);
+    }
+
+    /**
+     * Compile a primary key command.
+     *
+     * @param  \Illuminate\Database\Schema\Blueprint  $blueprint
+     * @param  \Illuminate\Support\Fluent  $command
+     * @return string
+     */
+    public function compilePrimary(Blueprint $blueprint, Fluent $command)
+    {
+        return sprintf('alter table %s add constraint %s primary key (%s)',
+            $this->wrapTable($blueprint),
+            $this->wrap($command->index),
+            $this->columnize($command->columns)
+        );
+    }
+
+    /**
+     * Compile a unique key command.
+     *
+     * @param  \Illuminate\Database\Schema\Blueprint  $blueprint
+     * @param  \Illuminate\Support\Fluent  $command
+     * @return string
+     */
+    public function compileUnique(Blueprint $blueprint, Fluent $command)
+    {
+        return sprintf('create unique index %s on %s (%s)',
+            $this->wrap($command->index),
+            $this->wrapTable($blueprint),
+            $this->columnize($command->columns)
+        );
+    }
+
+    /**
+     * Compile a plain index key command.
+     *
+     * @param  \Illuminate\Database\Schema\Blueprint  $blueprint
+     * @param  \Illuminate\Support\Fluent  $command
+     * @return string
+     */
+    public function compileIndex(Blueprint $blueprint, Fluent $command)
+    {
+        return sprintf('create index %s on %s (%s)',
+            $this->wrap($command->index),
+            $this->wrapTable($blueprint),
+            $this->columnize($command->columns)
+        );
+    }
+
+    /**
+     * Compile a spatial index key command.
+     *
+     * @param  \Illuminate\Database\Schema\Blueprint  $blueprint
+     * @param  \Illuminate\Support\Fluent  $command
+     * @return string
+     */
+    public function compileSpatialIndex(Blueprint $blueprint, Fluent $command)
+    {
+        return sprintf('create spatial index %s on %s (%s)',
+            $this->wrap($command->index),
+            $this->wrapTable($blueprint),
+            $this->columnize($command->columns)
+        );
+    }
+
+    /**
+     * Compile a drop table command.
+     *
+     * @param  \Illuminate\Database\Schema\Blueprint  $blueprint
+     * @param  \Illuminate\Support\Fluent  $command
+     * @return string
+     */
+    public function compileDrop(Blueprint $blueprint, Fluent $command)
+    {
+        return 'drop table '.$this->wrapTable($blueprint);
+    }
+
+    /**
+     * Compile a drop table (if exists) command.
+     *
+     * @param  \Illuminate\Database\Schema\Blueprint  $blueprint
+     * @param  \Illuminate\Support\Fluent  $command
+     * @return string
+     */
+    public function compileDropIfExists(Blueprint $blueprint, Fluent $command)
+    {
+        return sprintf('if exists (select * from sys.sysobjects where id = object_id(%s, \'U\')) drop table %s',
+            "'".str_replace("'", "''", $this->getTablePrefix().$blueprint->getTable())."'",
+            $this->wrapTable($blueprint)
+        );
+    }
+
+    /**
+     * Compile the SQL needed to drop all tables.
+     *
+     * @return string
+     */
+    public function compileDropAllTables()
+    {
+        return "EXEC sp_msforeachtable 'DROP TABLE ?'";
+    }
+
+    /**
+     * Compile a drop column command.
+     *
+     * @param  \Illuminate\Database\Schema\Blueprint  $blueprint
+     * @param  \Illuminate\Support\Fluent  $command
+     * @return string
+     */
+    public function compileDropColumn(Blueprint $blueprint, Fluent $command)
+    {
+        $columns = $this->wrapArray($command->columns);
+
+        $dropExistingConstraintsSql = $this->compileDropDefaultConstraint($blueprint, $command).';';
+
+        return $dropExistingConstraintsSql.'alter table '.$this->wrapTable($blueprint).' drop column '.implode(', ', $columns);
+    }
+
+    /**
+     * Compile a drop default constraint command.
+     *
+     * @param  \Illuminate\Database\Schema\Blueprint  $blueprint
+     * @param  \Illuminate\Support\Fluent  $command
+     * @return string
+     */
+    public function compileDropDefaultConstraint(Blueprint $blueprint, Fluent $command)
+    {
+        $columns = "'".implode("','", $command->columns)."'";
+
+        $tableName = $this->getTablePrefix().$blueprint->getTable();
+
+        $sql = "DECLARE @sql NVARCHAR(MAX) = '';";
+        $sql .= "SELECT @sql += 'ALTER TABLE [dbo].[{$tableName}] DROP CONSTRAINT ' + OBJECT_NAME([default_object_id]) + ';' ";
+        $sql .= 'FROM sys.columns ';
+        $sql .= "WHERE [object_id] = OBJECT_ID('[dbo].[{$tableName}]') AND [name] in ({$columns}) AND [default_object_id] <> 0;";
+        $sql .= 'EXEC(@sql)';
+
+        return $sql;
+    }
+
+    /**
+     * Compile a drop primary key command.
+     *
+     * @param  \Illuminate\Database\Schema\Blueprint  $blueprint
+     * @param  \Illuminate\Support\Fluent  $command
+     * @return string
+     */
+    public function compileDropPrimary(Blueprint $blueprint, Fluent $command)
+    {
+        $index = $this->wrap($command->index);
+
+        return "alter table {$this->wrapTable($blueprint)} drop constraint {$index}";
+    }
+
+    /**
+     * Compile a drop unique key command.
+     *
+     * @param  \Illuminate\Database\Schema\Blueprint  $blueprint
+     * @param  \Illuminate\Support\Fluent  $command
+     * @return string
+     */
+    public function compileDropUnique(Blueprint $blueprint, Fluent $command)
+    {
+        $index = $this->wrap($command->index);
+
+        return "drop index {$index} on {$this->wrapTable($blueprint)}";
+    }
+
+    /**
+     * Compile a drop index command.
+     *
+     * @param  \Illuminate\Database\Schema\Blueprint  $blueprint
+     * @param  \Illuminate\Support\Fluent  $command
+     * @return string
+     */
+    public function compileDropIndex(Blueprint $blueprint, Fluent $command)
+    {
+        $index = $this->wrap($command->index);
+
+        return "drop index {$index} on {$this->wrapTable($blueprint)}";
+    }
+
+    /**
+     * Compile a drop spatial index command.
+     *
+     * @param  \Illuminate\Database\Schema\Blueprint  $blueprint
+     * @param  \Illuminate\Support\Fluent  $command
+     * @return string
+     */
+    public function compileDropSpatialIndex(Blueprint $blueprint, Fluent $command)
+    {
+        return $this->compileDropIndex($blueprint, $command);
+    }
+
+    /**
+     * Compile a drop foreign key command.
+     *
+     * @param  \Illuminate\Database\Schema\Blueprint  $blueprint
+     * @param  \Illuminate\Support\Fluent  $command
+     * @return string
+     */
+    public function compileDropForeign(Blueprint $blueprint, Fluent $command)
+    {
+        $index = $this->wrap($command->index);
+
+        return "alter table {$this->wrapTable($blueprint)} drop constraint {$index}";
+    }
+
+    /**
+     * Compile a rename table command.
+     *
+     * @param  \Illuminate\Database\Schema\Blueprint  $blueprint
+     * @param  \Illuminate\Support\Fluent  $command
+     * @return string
+     */
+    public function compileRename(Blueprint $blueprint, Fluent $command)
+    {
+        $from = $this->wrapTable($blueprint);
+
+        return "sp_rename {$from}, ".$this->wrapTable($command->to);
+    }
+
+    /**
+     * Compile a rename index command.
+     *
+     * @param  \Illuminate\Database\Schema\Blueprint  $blueprint
+     * @param  \Illuminate\Support\Fluent  $command
+     * @return string
+     */
+    public function compileRenameIndex(Blueprint $blueprint, Fluent $command)
+    {
+        return sprintf("sp_rename N'%s', %s, N'INDEX'",
+            $this->wrap($blueprint->getTable().'.'.$command->from),
+            $this->wrap($command->to)
+        );
+    }
+
+    /**
+     * Compile the command to enable foreign key constraints.
+     *
+     * @return string
+     */
+    public function compileEnableForeignKeyConstraints()
+    {
+        return 'EXEC sp_msforeachtable @command1="print \'?\'", @command2="ALTER TABLE ? WITH CHECK CHECK CONSTRAINT all";';
+    }
+
+    /**
+     * Compile the command to disable foreign key constraints.
+     *
+     * @return string
+     */
+    public function compileDisableForeignKeyConstraints()
+    {
+        return 'EXEC sp_msforeachtable "ALTER TABLE ? NOCHECK CONSTRAINT all";';
+    }
+
+    /**
+     * Compile the command to drop all foreign keys.
+     *
+     * @return string
+     */
+    public function compileDropAllForeignKeys()
+    {
+        return "DECLARE @sql NVARCHAR(MAX) = N'';
+            SELECT @sql += 'ALTER TABLE '
+                + QUOTENAME(OBJECT_SCHEMA_NAME(parent_object_id)) + '.' + + QUOTENAME(OBJECT_NAME(parent_object_id))
+                + ' DROP CONSTRAINT ' + QUOTENAME(name) + ';'
+            FROM sys.foreign_keys;
+
+            EXEC sp_executesql @sql;";
+    }
+
+    /**
+     * Compile the command to drop all views.
+     *
+     * @return string
+     */
+    public function compileDropAllViews()
+    {
+        return "DECLARE @sql NVARCHAR(MAX) = N'';
+            SELECT @sql += 'DROP VIEW ' + QUOTENAME(OBJECT_SCHEMA_NAME(object_id)) + '.' + QUOTENAME(name) + ';'
+            FROM sys.views;
+
+            EXEC sp_executesql @sql;";
+    }
+
+    /**
+     * Compile the SQL needed to retrieve all table names.
+     *
+     * @return string
+     */
+    public function compileGetAllTables()
+    {
+        return "select name, type from sys.tables where type = 'U'";
+    }
+
+    /**
+     * Compile the SQL needed to retrieve all view names.
+     *
+     * @return string
+     */
+    public function compileGetAllViews()
+    {
+        return "select name, type from sys.objects where type = 'V'";
+    }
+
+    /**
+     * Create the column definition for a char type.
+     *
+     * @param  \Illuminate\Support\Fluent  $column
+     * @return string
+     */
+    protected function typeChar(Fluent $column)
+    {
+        return "nchar({$column->length})";
+    }
+
+    /**
+     * Create the column definition for a string type.
+     *
+     * @param  \Illuminate\Support\Fluent  $column
+     * @return string
+     */
+    protected function typeString(Fluent $column)
+    {
+        return "nvarchar({$column->length})";
+    }
+
+    /**
+     * Create the column definition for a tiny text type.
+     *
+     * @param  \Illuminate\Support\Fluent  $column
+     * @return string
+     */
+    protected function typeTinyText(Fluent $column)
+    {
+        return 'nvarchar(255)';
+    }
+
+    /**
+     * Create the column definition for a text type.
+     *
+     * @param  \Illuminate\Support\Fluent  $column
+     * @return string
+     */
+    protected function typeText(Fluent $column)
+    {
+        return 'nvarchar(max)';
+    }
+
+    /**
+     * Create the column definition for a medium text type.
+     *
+     * @param  \Illuminate\Support\Fluent  $column
+     * @return string
+     */
+    protected function typeMediumText(Fluent $column)
+    {
+        return 'nvarchar(max)';
+    }
+
+    /**
+     * Create the column definition for a long text type.
+     *
+     * @param  \Illuminate\Support\Fluent  $column
+     * @return string
+     */
+    protected function typeLongText(Fluent $column)
+    {
+        return 'nvarchar(max)';
+    }
+
+    /**
+     * Create the column definition for an integer type.
+     *
+     * @param  \Illuminate\Support\Fluent  $column
+     * @return string
+     */
+    protected function typeInteger(Fluent $column)
+    {
+        return 'int';
+    }
+
+    /**
+     * Create the column definition for a big integer type.
+     *
+     * @param  \Illuminate\Support\Fluent  $column
+     * @return string
+     */
+    protected function typeBigInteger(Fluent $column)
+    {
+        return 'bigint';
+    }
+
+    /**
+     * Create the column definition for a medium integer type.
+     *
+     * @param  \Illuminate\Support\Fluent  $column
+     * @return string
+     */
+    protected function typeMediumInteger(Fluent $column)
+    {
+        return 'int';
+    }
+
+    /**
+     * Create the column definition for a tiny integer type.
+     *
+     * @param  \Illuminate\Support\Fluent  $column
+     * @return string
+     */
+    protected function typeTinyInteger(Fluent $column)
+    {
+        return 'tinyint';
+    }
+
+    /**
+     * Create the column definition for a small integer type.
+     *
+     * @param  \Illuminate\Support\Fluent  $column
+     * @return string
+     */
+    protected function typeSmallInteger(Fluent $column)
+    {
+        return 'smallint';
+    }
+
+    /**
+     * Create the column definition for a float type.
+     *
+     * @param  \Illuminate\Support\Fluent  $column
+     * @return string
+     */
+    protected function typeFloat(Fluent $column)
+    {
+        return 'float';
+    }
+
+    /**
+     * Create the column definition for a double type.
+     *
+     * @param  \Illuminate\Support\Fluent  $column
+     * @return string
+     */
+    protected function typeDouble(Fluent $column)
+    {
+        return 'float';
+    }
+
+    /**
+     * Create the column definition for a decimal type.
+     *
+     * @param  \Illuminate\Support\Fluent  $column
+     * @return string
+     */
+    protected function typeDecimal(Fluent $column)
+    {
+        return "decimal({$column->total}, {$column->places})";
+    }
+
+    /**
+     * Create the column definition for a boolean type.
+     *
+     * @param  \Illuminate\Support\Fluent  $column
+     * @return string
+     */
+    protected function typeBoolean(Fluent $column)
+    {
+        return 'bit';
+    }
+
+    /**
+     * Create the column definition for an enumeration type.
+     *
+     * @param  \Illuminate\Support\Fluent  $column
+     * @return string
+     */
+    protected function typeEnum(Fluent $column)
+    {
+        return sprintf(
+            'nvarchar(255) check ("%s" in (%s))',
+            $column->name,
+            $this->quoteString($column->allowed)
+        );
+    }
+
+    /**
+     * Create the column definition for a json type.
+     *
+     * @param  \Illuminate\Support\Fluent  $column
+     * @return string
+     */
+    protected function typeJson(Fluent $column)
+    {
+        return 'nvarchar(max)';
+    }
+
+    /**
+     * Create the column definition for a jsonb type.
+     *
+     * @param  \Illuminate\Support\Fluent  $column
+     * @return string
+     */
+    protected function typeJsonb(Fluent $column)
+    {
+        return 'nvarchar(max)';
+    }
+
+    /**
+     * Create the column definition for a date type.
+     *
+     * @param  \Illuminate\Support\Fluent  $column
+     * @return string
+     */
+    protected function typeDate(Fluent $column)
+    {
+        return 'date';
+    }
+
+    /**
+     * Create the column definition for a date-time type.
+     *
+     * @param  \Illuminate\Support\Fluent  $column
+     * @return string
+     */
+    protected function typeDateTime(Fluent $column)
+    {
+        return $this->typeTimestamp($column);
+    }
+
+    /**
+     * Create the column definition for a date-time (with time zone) type.
+     *
+     * @param  \Illuminate\Support\Fluent  $column
+     * @return string
+     */
+    protected function typeDateTimeTz(Fluent $column)
+    {
+        return $this->typeTimestampTz($column);
+    }
+
+    /**
+     * Create the column definition for a time type.
+     *
+     * @param  \Illuminate\Support\Fluent  $column
+     * @return string
+     */
+    protected function typeTime(Fluent $column)
+    {
+        return $column->precision ? "time($column->precision)" : 'time';
+    }
+
+    /**
+     * Create the column definition for a time (with time zone) type.
+     *
+     * @param  \Illuminate\Support\Fluent  $column
+     * @return string
+     */
+    protected function typeTimeTz(Fluent $column)
+    {
+        return $this->typeTime($column);
+    }
+
+    /**
+     * Create the column definition for a timestamp type.
+     *
+     * @param  \Illuminate\Support\Fluent  $column
+     * @return string
+     */
+    protected function typeTimestamp(Fluent $column)
+    {
+        $columnType = $column->precision ? "datetime2($column->precision)" : 'datetime';
+
+        return $column->useCurrent ? "$columnType default CURRENT_TIMESTAMP" : $columnType;
+    }
+
+    /**
+     * Create the column definition for a timestamp (with time zone) type.
+     *
+     * @link https://docs.microsoft.com/en-us/sql/t-sql/data-types/datetimeoffset-transact-sql?view=sql-server-ver15
+     *
+     * @param  \Illuminate\Support\Fluent  $column
+     * @return string
+     */
+    protected function typeTimestampTz(Fluent $column)
+    {
+        $columnType = $column->precision ? "datetimeoffset($column->precision)" : 'datetimeoffset';
+
+        return $column->useCurrent ? "$columnType default CURRENT_TIMESTAMP" : $columnType;
+    }
+
+    /**
+     * Create the column definition for a year type.
+     *
+     * @param  \Illuminate\Support\Fluent  $column
+     * @return string
+     */
+    protected function typeYear(Fluent $column)
+    {
+        return $this->typeInteger($column);
+    }
+
+    /**
+     * Create the column definition for a binary type.
+     *
+     * @param  \Illuminate\Support\Fluent  $column
+     * @return string
+     */
+    protected function typeBinary(Fluent $column)
+    {
+        return 'varbinary(max)';
+    }
+
+    /**
+     * Create the column definition for a uuid type.
+     *
+     * @param  \Illuminate\Support\Fluent  $column
+     * @return string
+     */
+    protected function typeUuid(Fluent $column)
+    {
+        return 'uniqueidentifier';
+    }
+
+    /**
+     * Create the column definition for an IP address type.
+     *
+     * @param  \Illuminate\Support\Fluent  $column
+     * @return string
+     */
+    protected function typeIpAddress(Fluent $column)
+    {
+        return 'nvarchar(45)';
+    }
+
+    /**
+     * Create the column definition for a MAC address type.
+     *
+     * @param  \Illuminate\Support\Fluent  $column
+     * @return string
+     */
+    protected function typeMacAddress(Fluent $column)
+    {
+        return 'nvarchar(17)';
+    }
+
+    /**
+     * Create the column definition for a spatial Geometry type.
+     *
+     * @param  \Illuminate\Support\Fluent  $column
+     * @return string
+     */
+    public function typeGeometry(Fluent $column)
+    {
+        return 'geography';
+    }
+
+    /**
+     * Create the column definition for a spatial Point type.
+     *
+     * @param  \Illuminate\Support\Fluent  $column
+     * @return string
+     */
+    public function typePoint(Fluent $column)
+    {
+        return 'geography';
+    }
+
+    /**
+     * Create the column definition for a spatial LineString type.
+     *
+     * @param  \Illuminate\Support\Fluent  $column
+     * @return string
+     */
+    public function typeLineString(Fluent $column)
+    {
+        return 'geography';
+    }
+
+    /**
+     * Create the column definition for a spatial Polygon type.
+     *
+     * @param  \Illuminate\Support\Fluent  $column
+     * @return string
+     */
+    public function typePolygon(Fluent $column)
+    {
+        return 'geography';
+    }
+
+    /**
+     * Create the column definition for a spatial GeometryCollection type.
+     *
+     * @param  \Illuminate\Support\Fluent  $column
+     * @return string
+     */
+    public function typeGeometryCollection(Fluent $column)
+    {
+        return 'geography';
+    }
+
+    /**
+     * Create the column definition for a spatial MultiPoint type.
+     *
+     * @param  \Illuminate\Support\Fluent  $column
+     * @return string
+     */
+    public function typeMultiPoint(Fluent $column)
+    {
+        return 'geography';
+    }
+
+    /**
+     * Create the column definition for a spatial MultiLineString type.
+     *
+     * @param  \Illuminate\Support\Fluent  $column
+     * @return string
+     */
+    public function typeMultiLineString(Fluent $column)
+    {
+        return 'geography';
+    }
+
+    /**
+     * Create the column definition for a spatial MultiPolygon type.
+     *
+     * @param  \Illuminate\Support\Fluent  $column
+     * @return string
+     */
+    public function typeMultiPolygon(Fluent $column)
+    {
+        return 'geography';
+    }
+
+    /**
+     * Create the column definition for a generated, computed column type.
+     *
+     * @param  \Illuminate\Support\Fluent  $column
+     * @return string|null
+     */
+    protected function typeComputed(Fluent $column)
+    {
+        return "as ({$column->expression})";
+    }
+
+    /**
+     * Get the SQL for a collation column modifier.
+     *
+     * @param  \Illuminate\Database\Schema\Blueprint  $blueprint
+     * @param  \Illuminate\Support\Fluent  $column
+     * @return string|null
+     */
+    protected function modifyCollate(Blueprint $blueprint, Fluent $column)
+    {
+        if (! is_null($column->collation)) {
+            return ' collate '.$column->collation;
+        }
+    }
+
+    /**
+     * Get the SQL for a nullable column modifier.
+     *
+     * @param  \Illuminate\Database\Schema\Blueprint  $blueprint
+     * @param  \Illuminate\Support\Fluent  $column
+     * @return string|null
+     */
+    protected function modifyNullable(Blueprint $blueprint, Fluent $column)
+    {
+        if ($column->type !== 'computed') {
+            return $column->nullable ? ' null' : ' not null';
+        }
+    }
+
+    /**
+     * Get the SQL for a default column modifier.
+     *
+     * @param  \Illuminate\Database\Schema\Blueprint  $blueprint
+     * @param  \Illuminate\Support\Fluent  $column
+     * @return string|null
+     */
+    protected function modifyDefault(Blueprint $blueprint, Fluent $column)
+    {
+        if (! is_null($column->default)) {
+            return ' default '.$this->getDefaultValue($column->default);
+        }
+    }
+
+    /**
+     * Get the SQL for an auto-increment column modifier.
+     *
+     * @param  \Illuminate\Database\Schema\Blueprint  $blueprint
+     * @param  \Illuminate\Support\Fluent  $column
+     * @return string|null
+     */
+    protected function modifyIncrement(Blueprint $blueprint, Fluent $column)
+    {
+        if (in_array($column->type, $this->serials) && $column->autoIncrement) {
+            return ' identity primary key';
+        }
+    }
+
+    /**
+     * Get the SQL for a generated stored column modifier.
+     *
+     * @param  \Illuminate\Database\Schema\Blueprint  $blueprint
+     * @param  \Illuminate\Support\Fluent  $column
+     * @return string|null
+     */
+    protected function modifyPersisted(Blueprint $blueprint, Fluent $column)
+    {
+        if ($column->persisted) {
+            return ' persisted';
+        }
+    }
+
+    /**
+     * Wrap a table in keyword identifiers.
+     *
+     * @param  \Illuminate\Database\Query\Expression|string  $table
+     * @return string
+     */
+    public function wrapTable($table)
+    {
+        if ($table instanceof Blueprint && $table->temporary) {
+            $this->setTablePrefix('#');
+        }
+
+        return parent::wrapTable($table);
+    }
+
+    /**
+     * Quote the given string literal.
+     *
+     * @param  string|array  $value
+     * @return string
+     */
+    public function quoteString($value)
+    {
+        if (is_array($value)) {
+            return implode(', ', array_map([$this, __FUNCTION__], $value));
+        }
+
+        return "N'$value'";
+    }
+}
diff --git a/vendor/illuminate/database/Schema/IndexDefinition.php b/vendor/illuminate/database/Schema/IndexDefinition.php
new file mode 100644
index 0000000..fc5d78e
--- /dev/null
+++ b/vendor/illuminate/database/Schema/IndexDefinition.php
@@ -0,0 +1,16 @@
+connection->statement(
+            $this->grammar->compileCreateDatabase($name, $this->connection)
+        );
+    }
+
+    /**
+     * Drop a database from the schema if the database exists.
+     *
+     * @param  string  $name
+     * @return bool
+     */
+    public function dropDatabaseIfExists($name)
+    {
+        return $this->connection->statement(
+            $this->grammar->compileDropDatabaseIfExists($name)
+        );
+    }
+
+    /**
+     * Determine if the given table exists.
+     *
+     * @param  string  $table
+     * @return bool
+     */
+    public function hasTable($table)
+    {
+        $table = $this->connection->getTablePrefix().$table;
+
+        return count($this->connection->selectFromWriteConnection(
+            $this->grammar->compileTableExists(), [$this->connection->getDatabaseName(), $table]
+        )) > 0;
+    }
+
+    /**
+     * Get the column listing for a given table.
+     *
+     * @param  string  $table
+     * @return array
+     */
+    public function getColumnListing($table)
+    {
+        $table = $this->connection->getTablePrefix().$table;
+
+        $results = $this->connection->selectFromWriteConnection(
+            $this->grammar->compileColumnListing(), [$this->connection->getDatabaseName(), $table]
+        );
+
+        return $this->connection->getPostProcessor()->processColumnListing($results);
+    }
+
+    /**
+     * Drop all tables from the database.
+     *
+     * @return void
+     */
+    public function dropAllTables()
+    {
+        $tables = [];
+
+        foreach ($this->getAllTables() as $row) {
+            $row = (array) $row;
+
+            $tables[] = reset($row);
+        }
+
+        if (empty($tables)) {
+            return;
+        }
+
+        $this->disableForeignKeyConstraints();
+
+        $this->connection->statement(
+            $this->grammar->compileDropAllTables($tables)
+        );
+
+        $this->enableForeignKeyConstraints();
+    }
+
+    /**
+     * Drop all views from the database.
+     *
+     * @return void
+     */
+    public function dropAllViews()
+    {
+        $views = [];
+
+        foreach ($this->getAllViews() as $row) {
+            $row = (array) $row;
+
+            $views[] = reset($row);
+        }
+
+        if (empty($views)) {
+            return;
+        }
+
+        $this->connection->statement(
+            $this->grammar->compileDropAllViews($views)
+        );
+    }
+
+    /**
+     * Get all of the table names for the database.
+     *
+     * @return array
+     */
+    public function getAllTables()
+    {
+        return $this->connection->select(
+            $this->grammar->compileGetAllTables()
+        );
+    }
+
+    /**
+     * Get all of the view names for the database.
+     *
+     * @return array
+     */
+    public function getAllViews()
+    {
+        return $this->connection->select(
+            $this->grammar->compileGetAllViews()
+        );
+    }
+}
diff --git a/vendor/illuminate/database/Schema/MySqlSchemaState.php b/vendor/illuminate/database/Schema/MySqlSchemaState.php
new file mode 100644
index 0000000..0cd3486
--- /dev/null
+++ b/vendor/illuminate/database/Schema/MySqlSchemaState.php
@@ -0,0 +1,170 @@
+executeDumpProcess($this->makeProcess(
+            $this->baseDumpCommand().' --routines --result-file="${:LARAVEL_LOAD_PATH}" --no-data'
+        ), $this->output, array_merge($this->baseVariables($this->connection->getConfig()), [
+            'LARAVEL_LOAD_PATH' => $path,
+        ]));
+
+        $this->removeAutoIncrementingState($path);
+
+        $this->appendMigrationData($path);
+    }
+
+    /**
+     * Remove the auto-incrementing state from the given schema dump.
+     *
+     * @param  string  $path
+     * @return void
+     */
+    protected function removeAutoIncrementingState(string $path)
+    {
+        $this->files->put($path, preg_replace(
+            '/\s+AUTO_INCREMENT=[0-9]+/iu',
+            '',
+            $this->files->get($path)
+        ));
+    }
+
+    /**
+     * Append the migration data to the schema dump.
+     *
+     * @param  string  $path
+     * @return void
+     */
+    protected function appendMigrationData(string $path)
+    {
+        $process = $this->executeDumpProcess($this->makeProcess(
+            $this->baseDumpCommand().' '.$this->migrationTable.' --no-create-info --skip-extended-insert --skip-routines --compact'
+        ), null, array_merge($this->baseVariables($this->connection->getConfig()), [
+            //
+        ]));
+
+        $this->files->append($path, $process->getOutput());
+    }
+
+    /**
+     * Load the given schema file into the database.
+     *
+     * @param  string  $path
+     * @return void
+     */
+    public function load($path)
+    {
+        $command = 'mysql '.$this->connectionString().' --database="${:LARAVEL_LOAD_DATABASE}" < "${:LARAVEL_LOAD_PATH}"';
+
+        $process = $this->makeProcess($command)->setTimeout(null);
+
+        $process->mustRun(null, array_merge($this->baseVariables($this->connection->getConfig()), [
+            'LARAVEL_LOAD_PATH' => $path,
+        ]));
+    }
+
+    /**
+     * Get the base dump command arguments for MySQL as a string.
+     *
+     * @return string
+     */
+    protected function baseDumpCommand()
+    {
+        $command = 'mysqldump '.$this->connectionString().' --no-tablespaces --skip-add-locks --skip-comments --skip-set-charset --tz-utc --column-statistics=0';
+
+        if (! $this->connection->isMaria()) {
+            $command .= ' --set-gtid-purged=OFF';
+        }
+
+        return $command.' "${:LARAVEL_LOAD_DATABASE}"';
+    }
+
+    /**
+     * Generate a basic connection string (--socket, --host, --port, --user, --password) for the database.
+     *
+     * @return string
+     */
+    protected function connectionString()
+    {
+        $value = ' --user="${:LARAVEL_LOAD_USER}" --password="${:LARAVEL_LOAD_PASSWORD}"';
+
+        $config = $this->connection->getConfig();
+
+        $value .= $config['unix_socket'] ?? false
+                        ? ' --socket="${:LARAVEL_LOAD_SOCKET}"'
+                        : ' --host="${:LARAVEL_LOAD_HOST}" --port="${:LARAVEL_LOAD_PORT}"';
+
+        if (isset($config['options'][\PDO::MYSQL_ATTR_SSL_CA])) {
+            $value .= ' --ssl-ca="${:LARAVEL_LOAD_SSL_CA}"';
+        }
+
+        return $value;
+    }
+
+    /**
+     * Get the base variables for a dump / load command.
+     *
+     * @param  array  $config
+     * @return array
+     */
+    protected function baseVariables(array $config)
+    {
+        $config['host'] ??= '';
+
+        return [
+            'LARAVEL_LOAD_SOCKET' => $config['unix_socket'] ?? '',
+            'LARAVEL_LOAD_HOST' => is_array($config['host']) ? $config['host'][0] : $config['host'],
+            'LARAVEL_LOAD_PORT' => $config['port'] ?? '',
+            'LARAVEL_LOAD_USER' => $config['username'],
+            'LARAVEL_LOAD_PASSWORD' => $config['password'] ?? '',
+            'LARAVEL_LOAD_DATABASE' => $config['database'],
+            'LARAVEL_LOAD_SSL_CA' => $config['options'][\PDO::MYSQL_ATTR_SSL_CA] ?? '',
+        ];
+    }
+
+    /**
+     * Execute the given dump process.
+     *
+     * @param  \Symfony\Component\Process\Process  $process
+     * @param  callable  $output
+     * @param  array  $variables
+     * @return \Symfony\Component\Process\Process
+     */
+    protected function executeDumpProcess(Process $process, $output, array $variables)
+    {
+        try {
+            $process->setTimeout(null)->mustRun($output, $variables);
+        } catch (Exception $e) {
+            if (Str::contains($e->getMessage(), ['column-statistics', 'column_statistics'])) {
+                return $this->executeDumpProcess(Process::fromShellCommandLine(
+                    str_replace(' --column-statistics=0', '', $process->getCommandLine())
+                ), $output, $variables);
+            }
+
+            if (str_contains($e->getMessage(), 'set-gtid-purged')) {
+                return $this->executeDumpProcess(Process::fromShellCommandLine(
+                    str_replace(' --set-gtid-purged=OFF', '', $process->getCommandLine())
+                ), $output, $variables);
+            }
+
+            throw $e;
+        }
+
+        return $process;
+    }
+}
diff --git a/vendor/illuminate/database/Schema/PostgresBuilder.php b/vendor/illuminate/database/Schema/PostgresBuilder.php
new file mode 100755
index 0000000..adfbd68
--- /dev/null
+++ b/vendor/illuminate/database/Schema/PostgresBuilder.php
@@ -0,0 +1,248 @@
+connection->statement(
+            $this->grammar->compileCreateDatabase($name, $this->connection)
+        );
+    }
+
+    /**
+     * Drop a database from the schema if the database exists.
+     *
+     * @param  string  $name
+     * @return bool
+     */
+    public function dropDatabaseIfExists($name)
+    {
+        return $this->connection->statement(
+            $this->grammar->compileDropDatabaseIfExists($name)
+        );
+    }
+
+    /**
+     * Determine if the given table exists.
+     *
+     * @param  string  $table
+     * @return bool
+     */
+    public function hasTable($table)
+    {
+        [$database, $schema, $table] = $this->parseSchemaAndTable($table);
+
+        $table = $this->connection->getTablePrefix().$table;
+
+        return count($this->connection->selectFromWriteConnection(
+            $this->grammar->compileTableExists(), [$database, $schema, $table]
+        )) > 0;
+    }
+
+    /**
+     * Drop all tables from the database.
+     *
+     * @return void
+     */
+    public function dropAllTables()
+    {
+        $tables = [];
+
+        $excludedTables = $this->grammar->escapeNames(
+            $this->connection->getConfig('dont_drop') ?? ['spatial_ref_sys']
+        );
+
+        foreach ($this->getAllTables() as $row) {
+            $row = (array) $row;
+
+            if (empty(array_intersect($this->grammar->escapeNames($row), $excludedTables))) {
+                $tables[] = $row['qualifiedname'] ?? reset($row);
+            }
+        }
+
+        if (empty($tables)) {
+            return;
+        }
+
+        $this->connection->statement(
+            $this->grammar->compileDropAllTables($tables)
+        );
+    }
+
+    /**
+     * Drop all views from the database.
+     *
+     * @return void
+     */
+    public function dropAllViews()
+    {
+        $views = [];
+
+        foreach ($this->getAllViews() as $row) {
+            $row = (array) $row;
+
+            $views[] = $row['qualifiedname'] ?? reset($row);
+        }
+
+        if (empty($views)) {
+            return;
+        }
+
+        $this->connection->statement(
+            $this->grammar->compileDropAllViews($views)
+        );
+    }
+
+    /**
+     * Drop all types from the database.
+     *
+     * @return void
+     */
+    public function dropAllTypes()
+    {
+        $types = [];
+
+        foreach ($this->getAllTypes() as $row) {
+            $row = (array) $row;
+
+            $types[] = reset($row);
+        }
+
+        if (empty($types)) {
+            return;
+        }
+
+        $this->connection->statement(
+            $this->grammar->compileDropAllTypes($types)
+        );
+    }
+
+    /**
+     * Get all of the table names for the database.
+     *
+     * @return array
+     */
+    public function getAllTables()
+    {
+        return $this->connection->select(
+            $this->grammar->compileGetAllTables(
+                $this->parseSearchPath(
+                    $this->connection->getConfig('search_path') ?: $this->connection->getConfig('schema')
+                )
+            )
+        );
+    }
+
+    /**
+     * Get all of the view names for the database.
+     *
+     * @return array
+     */
+    public function getAllViews()
+    {
+        return $this->connection->select(
+            $this->grammar->compileGetAllViews(
+                $this->parseSearchPath(
+                    $this->connection->getConfig('search_path') ?: $this->connection->getConfig('schema')
+                )
+            )
+        );
+    }
+
+    /**
+     * Get all of the type names for the database.
+     *
+     * @return array
+     */
+    public function getAllTypes()
+    {
+        return $this->connection->select(
+            $this->grammar->compileGetAllTypes()
+        );
+    }
+
+    /**
+     * Get the column listing for a given table.
+     *
+     * @param  string  $table
+     * @return array
+     */
+    public function getColumnListing($table)
+    {
+        [$database, $schema, $table] = $this->parseSchemaAndTable($table);
+
+        $table = $this->connection->getTablePrefix().$table;
+
+        $results = $this->connection->selectFromWriteConnection(
+            $this->grammar->compileColumnListing(), [$database, $schema, $table]
+        );
+
+        return $this->connection->getPostProcessor()->processColumnListing($results);
+    }
+
+    /**
+     * Parse the database object reference and extract the database, schema, and table.
+     *
+     * @param  string  $reference
+     * @return array
+     */
+    protected function parseSchemaAndTable($reference)
+    {
+        $searchPath = $this->parseSearchPath(
+            $this->connection->getConfig('search_path') ?: $this->connection->getConfig('schema') ?: 'public'
+        );
+
+        $parts = explode('.', $reference);
+
+        $database = $this->connection->getConfig('database');
+
+        // If the reference contains a database name, we will use that instead of the
+        // default database name for the connection. This allows the database name
+        // to be specified in the query instead of at the full connection level.
+        if (count($parts) === 3) {
+            $database = $parts[0];
+            array_shift($parts);
+        }
+
+        // We will use the default schema unless the schema has been specified in the
+        // query. If the schema has been specified in the query then we can use it
+        // instead of a default schema configured in the connection search path.
+        $schema = $searchPath[0];
+
+        if (count($parts) === 2) {
+            $schema = $parts[0];
+            array_shift($parts);
+        }
+
+        return [$database, $schema, $parts[0]];
+    }
+
+    /**
+     * Parse the "search_path" configuration value into an array.
+     *
+     * @param  string|array|null  $searchPath
+     * @return array
+     */
+    protected function parseSearchPath($searchPath)
+    {
+        return array_map(function ($schema) {
+            return $schema === '$user'
+                ? $this->connection->getConfig('username')
+                : $schema;
+        }, $this->baseParseSearchPath($searchPath));
+    }
+}
diff --git a/vendor/illuminate/database/Schema/PostgresSchemaState.php b/vendor/illuminate/database/Schema/PostgresSchemaState.php
new file mode 100644
index 0000000..cfb100d
--- /dev/null
+++ b/vendor/illuminate/database/Schema/PostgresSchemaState.php
@@ -0,0 +1,79 @@
+baseDumpCommand().' --schema-only > '.$path,
+            $this->baseDumpCommand().' -t '.$this->migrationTable.' --data-only >> '.$path,
+        ]);
+
+        $commands->map(function ($command, $path) {
+            $this->makeProcess($command)->mustRun($this->output, array_merge($this->baseVariables($this->connection->getConfig()), [
+                'LARAVEL_LOAD_PATH' => $path,
+            ]));
+        });
+    }
+
+    /**
+     * Load the given schema file into the database.
+     *
+     * @param  string  $path
+     * @return void
+     */
+    public function load($path)
+    {
+        $command = 'pg_restore --no-owner --no-acl --clean --if-exists --host="${:LARAVEL_LOAD_HOST}" --port="${:LARAVEL_LOAD_PORT}" --username="${:LARAVEL_LOAD_USER}" --dbname="${:LARAVEL_LOAD_DATABASE}" "${:LARAVEL_LOAD_PATH}"';
+
+        if (str_ends_with($path, '.sql')) {
+            $command = 'psql --file="${:LARAVEL_LOAD_PATH}" --host="${:LARAVEL_LOAD_HOST}" --port="${:LARAVEL_LOAD_PORT}" --username="${:LARAVEL_LOAD_USER}" --dbname="${:LARAVEL_LOAD_DATABASE}"';
+        }
+
+        $process = $this->makeProcess($command);
+
+        $process->mustRun(null, array_merge($this->baseVariables($this->connection->getConfig()), [
+            'LARAVEL_LOAD_PATH' => $path,
+        ]));
+    }
+
+    /**
+     * Get the base dump command arguments for PostgreSQL as a string.
+     *
+     * @return string
+     */
+    protected function baseDumpCommand()
+    {
+        return 'pg_dump --no-owner --no-acl --host="${:LARAVEL_LOAD_HOST}" --port="${:LARAVEL_LOAD_PORT}" --username="${:LARAVEL_LOAD_USER}" --dbname="${:LARAVEL_LOAD_DATABASE}"';
+    }
+
+    /**
+     * Get the base variables for a dump / load command.
+     *
+     * @param  array  $config
+     * @return array
+     */
+    protected function baseVariables(array $config)
+    {
+        $config['host'] ??= '';
+
+        return [
+            'LARAVEL_LOAD_HOST' => is_array($config['host']) ? $config['host'][0] : $config['host'],
+            'LARAVEL_LOAD_PORT' => $config['port'],
+            'LARAVEL_LOAD_USER' => $config['username'],
+            'PGPASSWORD' => $config['password'],
+            'LARAVEL_LOAD_DATABASE' => $config['database'],
+        ];
+    }
+}
diff --git a/vendor/illuminate/database/Schema/SQLiteBuilder.php b/vendor/illuminate/database/Schema/SQLiteBuilder.php
new file mode 100644
index 0000000..4e74f92
--- /dev/null
+++ b/vendor/illuminate/database/Schema/SQLiteBuilder.php
@@ -0,0 +1,102 @@
+connection->getDatabaseName() !== ':memory:') {
+            return $this->refreshDatabaseFile();
+        }
+
+        $this->connection->select($this->grammar->compileEnableWriteableSchema());
+
+        $this->connection->select($this->grammar->compileDropAllTables());
+
+        $this->connection->select($this->grammar->compileDisableWriteableSchema());
+
+        $this->connection->select($this->grammar->compileRebuild());
+    }
+
+    /**
+     * Drop all views from the database.
+     *
+     * @return void
+     */
+    public function dropAllViews()
+    {
+        $this->connection->select($this->grammar->compileEnableWriteableSchema());
+
+        $this->connection->select($this->grammar->compileDropAllViews());
+
+        $this->connection->select($this->grammar->compileDisableWriteableSchema());
+
+        $this->connection->select($this->grammar->compileRebuild());
+    }
+
+    /**
+     * Get all of the table names for the database.
+     *
+     * @return array
+     */
+    public function getAllTables()
+    {
+        return $this->connection->select(
+            $this->grammar->compileGetAllTables()
+        );
+    }
+
+    /**
+     * Get all of the view names for the database.
+     *
+     * @return array
+     */
+    public function getAllViews()
+    {
+        return $this->connection->select(
+            $this->grammar->compileGetAllViews()
+        );
+    }
+
+    /**
+     * Empty the database file.
+     *
+     * @return void
+     */
+    public function refreshDatabaseFile()
+    {
+        file_put_contents($this->connection->getDatabaseName(), '');
+    }
+}
diff --git a/vendor/illuminate/database/Schema/SchemaState.php b/vendor/illuminate/database/Schema/SchemaState.php
new file mode 100644
index 0000000..58d9c3a
--- /dev/null
+++ b/vendor/illuminate/database/Schema/SchemaState.php
@@ -0,0 +1,122 @@
+connection = $connection;
+
+        $this->files = $files ?: new Filesystem;
+
+        $this->processFactory = $processFactory ?: function (...$arguments) {
+            return Process::fromShellCommandline(...$arguments)->setTimeout(null);
+        };
+
+        $this->handleOutputUsing(function () {
+            //
+        });
+    }
+
+    /**
+     * Dump the database's schema into a file.
+     *
+     * @param  \Illuminate\Database\Connection  $connection
+     * @param  string  $path
+     * @return void
+     */
+    abstract public function dump(Connection $connection, $path);
+
+    /**
+     * Load the given schema file into the database.
+     *
+     * @param  string  $path
+     * @return void
+     */
+    abstract public function load($path);
+
+    /**
+     * Create a new process instance.
+     *
+     * @param  mixed  ...$arguments
+     * @return \Symfony\Component\Process\Process
+     */
+    public function makeProcess(...$arguments)
+    {
+        return call_user_func($this->processFactory, ...$arguments);
+    }
+
+    /**
+     * Specify the name of the application's migration table.
+     *
+     * @param  string  $table
+     * @return $this
+     */
+    public function withMigrationTable(string $table)
+    {
+        $this->migrationTable = $table;
+
+        return $this;
+    }
+
+    /**
+     * Specify the callback that should be used to handle process output.
+     *
+     * @param  callable  $output
+     * @return $this
+     */
+    public function handleOutputUsing(callable $output)
+    {
+        $this->output = $output;
+
+        return $this;
+    }
+}
diff --git a/vendor/illuminate/database/Schema/SqlServerBuilder.php b/vendor/illuminate/database/Schema/SqlServerBuilder.php
new file mode 100644
index 0000000..c323e12
--- /dev/null
+++ b/vendor/illuminate/database/Schema/SqlServerBuilder.php
@@ -0,0 +1,78 @@
+connection->statement(
+            $this->grammar->compileCreateDatabase($name, $this->connection)
+        );
+    }
+
+    /**
+     * Drop a database from the schema if the database exists.
+     *
+     * @param  string  $name
+     * @return bool
+     */
+    public function dropDatabaseIfExists($name)
+    {
+        return $this->connection->statement(
+            $this->grammar->compileDropDatabaseIfExists($name)
+        );
+    }
+
+    /**
+     * Drop all tables from the database.
+     *
+     * @return void
+     */
+    public function dropAllTables()
+    {
+        $this->connection->statement($this->grammar->compileDropAllForeignKeys());
+
+        $this->connection->statement($this->grammar->compileDropAllTables());
+    }
+
+    /**
+     * Drop all views from the database.
+     *
+     * @return void
+     */
+    public function dropAllViews()
+    {
+        $this->connection->statement($this->grammar->compileDropAllViews());
+    }
+
+    /**
+     * Drop all tables from the database.
+     *
+     * @return array
+     */
+    public function getAllTables()
+    {
+        return $this->connection->select(
+            $this->grammar->compileGetAllTables()
+        );
+    }
+
+    /**
+     * Get all of the view names for the database.
+     *
+     * @return array
+     */
+    public function getAllViews()
+    {
+        return $this->connection->select(
+            $this->grammar->compileGetAllViews()
+        );
+    }
+}
diff --git a/vendor/illuminate/database/Schema/SqliteSchemaState.php b/vendor/illuminate/database/Schema/SqliteSchemaState.php
new file mode 100644
index 0000000..10efc7c
--- /dev/null
+++ b/vendor/illuminate/database/Schema/SqliteSchemaState.php
@@ -0,0 +1,99 @@
+makeProcess(
+            $this->baseCommand().' .schema'
+        ))->setTimeout(null)->mustRun(null, array_merge($this->baseVariables($this->connection->getConfig()), [
+            //
+        ]));
+
+        $migrations = collect(preg_split("/\r\n|\n|\r/", $process->getOutput()))->filter(function ($line) {
+            return stripos($line, 'sqlite_sequence') === false &&
+                   strlen($line) > 0;
+        })->all();
+
+        $this->files->put($path, implode(PHP_EOL, $migrations).PHP_EOL);
+
+        $this->appendMigrationData($path);
+    }
+
+    /**
+     * Append the migration data to the schema dump.
+     *
+     * @param  string  $path
+     * @return void
+     */
+    protected function appendMigrationData(string $path)
+    {
+        with($process = $this->makeProcess(
+            $this->baseCommand().' ".dump \''.$this->migrationTable.'\'"'
+        ))->mustRun(null, array_merge($this->baseVariables($this->connection->getConfig()), [
+            //
+        ]));
+
+        $migrations = collect(preg_split("/\r\n|\n|\r/", $process->getOutput()))->filter(function ($line) {
+            return preg_match('/^\s*(--|INSERT\s)/iu', $line) === 1 &&
+                   strlen($line) > 0;
+        })->all();
+
+        $this->files->append($path, implode(PHP_EOL, $migrations).PHP_EOL);
+    }
+
+    /**
+     * Load the given schema file into the database.
+     *
+     * @param  string  $path
+     * @return void
+     */
+    public function load($path)
+    {
+        if ($this->connection->getDatabaseName() === ':memory:') {
+            $this->connection->getPdo()->exec($this->files->get($path));
+
+            return;
+        }
+
+        $process = $this->makeProcess($this->baseCommand().' < "${:LARAVEL_LOAD_PATH}"');
+
+        $process->mustRun(null, array_merge($this->baseVariables($this->connection->getConfig()), [
+            'LARAVEL_LOAD_PATH' => $path,
+        ]));
+    }
+
+    /**
+     * Get the base sqlite command arguments as a string.
+     *
+     * @return string
+     */
+    protected function baseCommand()
+    {
+        return 'sqlite3 "${:LARAVEL_LOAD_DATABASE}"';
+    }
+
+    /**
+     * Get the base variables for a dump / load command.
+     *
+     * @param  array  $config
+     * @return array
+     */
+    protected function baseVariables(array $config)
+    {
+        return [
+            'LARAVEL_LOAD_DATABASE' => $config['database'],
+        ];
+    }
+}
diff --git a/vendor/illuminate/database/Seeder.php b/vendor/illuminate/database/Seeder.php
new file mode 100755
index 0000000..ba4cd4a
--- /dev/null
+++ b/vendor/illuminate/database/Seeder.php
@@ -0,0 +1,195 @@
+resolve($class);
+
+            $name = get_class($seeder);
+
+            if ($silent === false && isset($this->command)) {
+                with(new TwoColumnDetail($this->command->getOutput()))->render(
+                    $name,
+                    'RUNNING'
+                );
+            }
+
+            $startTime = microtime(true);
+
+            $seeder->__invoke($parameters);
+
+            if ($silent === false && isset($this->command)) {
+                $runTime = number_format((microtime(true) - $startTime) * 1000, 2);
+
+                with(new TwoColumnDetail($this->command->getOutput()))->render(
+                    $name,
+                    "$runTime ms DONE"
+                );
+
+                $this->command->getOutput()->writeln('');
+            }
+
+            static::$called[] = $class;
+        }
+
+        return $this;
+    }
+
+    /**
+     * Run the given seeder class.
+     *
+     * @param  array|string  $class
+     * @param  array  $parameters
+     * @return void
+     */
+    public function callWith($class, array $parameters = [])
+    {
+        $this->call($class, false, $parameters);
+    }
+
+    /**
+     * Silently run the given seeder class.
+     *
+     * @param  array|string  $class
+     * @param  array  $parameters
+     * @return void
+     */
+    public function callSilent($class, array $parameters = [])
+    {
+        $this->call($class, true, $parameters);
+    }
+
+    /**
+     * Run the given seeder class once.
+     *
+     * @param  array|string  $class
+     * @param  bool  $silent
+     * @return void
+     */
+    public function callOnce($class, $silent = false, array $parameters = [])
+    {
+        if (in_array($class, static::$called)) {
+            return;
+        }
+
+        $this->call($class, $silent, $parameters);
+    }
+
+    /**
+     * Resolve an instance of the given seeder class.
+     *
+     * @param  string  $class
+     * @return \Illuminate\Database\Seeder
+     */
+    protected function resolve($class)
+    {
+        if (isset($this->container)) {
+            $instance = $this->container->make($class);
+
+            $instance->setContainer($this->container);
+        } else {
+            $instance = new $class;
+        }
+
+        if (isset($this->command)) {
+            $instance->setCommand($this->command);
+        }
+
+        return $instance;
+    }
+
+    /**
+     * Set the IoC container instance.
+     *
+     * @param  \Illuminate\Contracts\Container\Container  $container
+     * @return $this
+     */
+    public function setContainer(Container $container)
+    {
+        $this->container = $container;
+
+        return $this;
+    }
+
+    /**
+     * Set the console command instance.
+     *
+     * @param  \Illuminate\Console\Command  $command
+     * @return $this
+     */
+    public function setCommand(Command $command)
+    {
+        $this->command = $command;
+
+        return $this;
+    }
+
+    /**
+     * Run the database seeds.
+     *
+     * @param  array  $parameters
+     * @return mixed
+     *
+     * @throws \InvalidArgumentException
+     */
+    public function __invoke(array $parameters = [])
+    {
+        if (! method_exists($this, 'run')) {
+            throw new InvalidArgumentException('Method [run] missing from '.get_class($this));
+        }
+
+        $callback = fn () => isset($this->container)
+            ? $this->container->call([$this, 'run'], $parameters)
+            : $this->run(...$parameters);
+
+        $uses = array_flip(class_uses_recursive(static::class));
+
+        if (isset($uses[WithoutModelEvents::class])) {
+            $callback = $this->withoutModelEvents($callback);
+        }
+
+        return $callback();
+    }
+}
diff --git a/vendor/illuminate/database/SqlServerConnection.php b/vendor/illuminate/database/SqlServerConnection.php
new file mode 100755
index 0000000..feb4577
--- /dev/null
+++ b/vendor/illuminate/database/SqlServerConnection.php
@@ -0,0 +1,123 @@
+getDriverName() === 'sqlsrv') {
+                return parent::transaction($callback, $attempts);
+            }
+
+            $this->getPdo()->exec('BEGIN TRAN');
+
+            // We'll simply execute the given callback within a try / catch block
+            // and if we catch any exception we can rollback the transaction
+            // so that none of the changes are persisted to the database.
+            try {
+                $result = $callback($this);
+
+                $this->getPdo()->exec('COMMIT TRAN');
+            }
+
+            // If we catch an exception, we will rollback so nothing gets messed
+            // up in the database. Then we'll re-throw the exception so it can
+            // be handled how the developer sees fit for their applications.
+            catch (Throwable $e) {
+                $this->getPdo()->exec('ROLLBACK TRAN');
+
+                throw $e;
+            }
+
+            return $result;
+        }
+    }
+
+    /**
+     * Get the default query grammar instance.
+     *
+     * @return \Illuminate\Database\Query\Grammars\SqlServerGrammar
+     */
+    protected function getDefaultQueryGrammar()
+    {
+        return $this->withTablePrefix(new QueryGrammar);
+    }
+
+    /**
+     * Get a schema builder instance for the connection.
+     *
+     * @return \Illuminate\Database\Schema\SqlServerBuilder
+     */
+    public function getSchemaBuilder()
+    {
+        if (is_null($this->schemaGrammar)) {
+            $this->useDefaultSchemaGrammar();
+        }
+
+        return new SqlServerBuilder($this);
+    }
+
+    /**
+     * Get the default schema grammar instance.
+     *
+     * @return \Illuminate\Database\Schema\Grammars\SqlServerGrammar
+     */
+    protected function getDefaultSchemaGrammar()
+    {
+        return $this->withTablePrefix(new SchemaGrammar);
+    }
+
+    /**
+     * Get the schema state for the connection.
+     *
+     * @param  \Illuminate\Filesystem\Filesystem|null  $files
+     * @param  callable|null  $processFactory
+     *
+     * @throws \RuntimeException
+     */
+    public function getSchemaState(Filesystem $files = null, callable $processFactory = null)
+    {
+        throw new RuntimeException('Schema dumping is not supported when using SQL Server.');
+    }
+
+    /**
+     * Get the default post processor instance.
+     *
+     * @return \Illuminate\Database\Query\Processors\SqlServerProcessor
+     */
+    protected function getDefaultPostProcessor()
+    {
+        return new SqlServerProcessor;
+    }
+
+    /**
+     * Get the Doctrine DBAL driver.
+     *
+     * @return \Illuminate\Database\PDO\SqlServerDriver
+     */
+    protected function getDoctrineDriver()
+    {
+        return new SqlServerDriver;
+    }
+}
diff --git a/vendor/illuminate/database/composer.json b/vendor/illuminate/database/composer.json
new file mode 100644
index 0000000..ba2dc30
--- /dev/null
+++ b/vendor/illuminate/database/composer.json
@@ -0,0 +1,52 @@
+{
+    "name": "illuminate/database",
+    "description": "The Illuminate Database package.",
+    "license": "MIT",
+    "homepage": "https://laravel.com",
+    "support": {
+        "issues": "https://github.com/laravel/framework/issues",
+        "source": "https://github.com/laravel/framework"
+    },
+    "keywords": ["laravel", "database", "sql", "orm"],
+    "authors": [
+        {
+            "name": "Taylor Otwell",
+            "email": "taylor@laravel.com"
+        }
+    ],
+    "require": {
+        "php": "^8.0.2",
+        "ext-pdo": "*",
+        "brick/math": "^0.9.3|^0.10.2|^0.11",
+        "illuminate/collections": "^9.0",
+        "illuminate/container": "^9.0",
+        "illuminate/contracts": "^9.0",
+        "illuminate/macroable": "^9.0",
+        "illuminate/support": "^9.0",
+        "symfony/console": "^6.0.9"
+    },
+    "autoload": {
+        "psr-4": {
+            "Illuminate\\Database\\": ""
+        }
+    },
+    "extra": {
+        "branch-alias": {
+            "dev-master": "9.x-dev"
+        }
+    },
+    "suggest": {
+        "ext-filter": "Required to use the Postgres database driver.",
+        "doctrine/dbal": "Required to rename columns and drop SQLite columns (^2.13.3|^3.1.4).",
+        "fakerphp/faker": "Required to use the eloquent factory builder (^1.21).",
+        "illuminate/console": "Required to use the database commands (^9.0).",
+        "illuminate/events": "Required to use the observers with Eloquent (^9.0).",
+        "illuminate/filesystem": "Required to use the migrations (^9.0).",
+        "illuminate/pagination": "Required to paginate the result set (^9.0).",
+        "symfony/finder": "Required to use Eloquent model factories (^6.0)."
+    },
+    "config": {
+        "sort-packages": true
+    },
+    "minimum-stability": "dev"
+}
diff --git a/vendor/illuminate/pagination/AbstractCursorPaginator.php b/vendor/illuminate/pagination/AbstractCursorPaginator.php
new file mode 100644
index 0000000..e670078
--- /dev/null
+++ b/vendor/illuminate/pagination/AbstractCursorPaginator.php
@@ -0,0 +1,671 @@
+cursorName => $cursor->encode()];
+
+        if (count($this->query) > 0) {
+            $parameters = array_merge($this->query, $parameters);
+        }
+
+        return $this->path()
+            .(str_contains($this->path(), '?') ? '&' : '?')
+            .Arr::query($parameters)
+            .$this->buildFragment();
+    }
+
+    /**
+     * Get the URL for the previous page.
+     *
+     * @return string|null
+     */
+    public function previousPageUrl()
+    {
+        if (is_null($previousCursor = $this->previousCursor())) {
+            return null;
+        }
+
+        return $this->url($previousCursor);
+    }
+
+    /**
+     * The URL for the next page, or null.
+     *
+     * @return string|null
+     */
+    public function nextPageUrl()
+    {
+        if (is_null($nextCursor = $this->nextCursor())) {
+            return null;
+        }
+
+        return $this->url($nextCursor);
+    }
+
+    /**
+     * Get the "cursor" that points to the previous set of items.
+     *
+     * @return \Illuminate\Pagination\Cursor|null
+     */
+    public function previousCursor()
+    {
+        if (is_null($this->cursor) ||
+            ($this->cursor->pointsToPreviousItems() && ! $this->hasMore)) {
+            return null;
+        }
+
+        if ($this->items->isEmpty()) {
+            return null;
+        }
+
+        return $this->getCursorForItem($this->items->first(), false);
+    }
+
+    /**
+     * Get the "cursor" that points to the next set of items.
+     *
+     * @return \Illuminate\Pagination\Cursor|null
+     */
+    public function nextCursor()
+    {
+        if ((is_null($this->cursor) && ! $this->hasMore) ||
+            (! is_null($this->cursor) && $this->cursor->pointsToNextItems() && ! $this->hasMore)) {
+            return null;
+        }
+
+        if ($this->items->isEmpty()) {
+            return null;
+        }
+
+        return $this->getCursorForItem($this->items->last(), true);
+    }
+
+    /**
+     * Get a cursor instance for the given item.
+     *
+     * @param  \ArrayAccess|\stdClass  $item
+     * @param  bool  $isNext
+     * @return \Illuminate\Pagination\Cursor
+     */
+    public function getCursorForItem($item, $isNext = true)
+    {
+        return new Cursor($this->getParametersForItem($item), $isNext);
+    }
+
+    /**
+     * Get the cursor parameters for a given object.
+     *
+     * @param  \ArrayAccess|\stdClass  $item
+     * @return array
+     *
+     * @throws \Exception
+     */
+    public function getParametersForItem($item)
+    {
+        return collect($this->parameters)
+            ->flip()
+            ->map(function ($_, $parameterName) use ($item) {
+                if ($item instanceof JsonResource) {
+                    $item = $item->resource;
+                }
+
+                if ($item instanceof Model &&
+                    ! is_null($parameter = $this->getPivotParameterForItem($item, $parameterName))) {
+                    return $parameter;
+                } elseif ($item instanceof ArrayAccess || is_array($item)) {
+                    return $this->ensureParameterIsPrimitive(
+                        $item[$parameterName] ?? $item[Str::afterLast($parameterName, '.')]
+                    );
+                } elseif (is_object($item)) {
+                    return $this->ensureParameterIsPrimitive(
+                        $item->{$parameterName} ?? $item->{Str::afterLast($parameterName, '.')}
+                    );
+                }
+
+                throw new Exception('Only arrays and objects are supported when cursor paginating items.');
+            })->toArray();
+    }
+
+    /**
+     * Get the cursor parameter value from a pivot model if applicable.
+     *
+     * @param  \ArrayAccess|\stdClass  $item
+     * @param  string  $parameterName
+     * @return string|null
+     */
+    protected function getPivotParameterForItem($item, $parameterName)
+    {
+        $table = Str::beforeLast($parameterName, '.');
+
+        foreach ($item->getRelations() as $relation) {
+            if ($relation instanceof Pivot && $relation->getTable() === $table) {
+                return $this->ensureParameterIsPrimitive(
+                    $relation->getAttribute(Str::afterLast($parameterName, '.'))
+                );
+            }
+        }
+    }
+
+    /**
+     * Ensure the parameter is a primitive type.
+     *
+     * This can resolve issues that arise the developer uses a value object for an attribute.
+     *
+     * @param  mixed  $parameter
+     * @return mixed
+     */
+    protected function ensureParameterIsPrimitive($parameter)
+    {
+        return is_object($parameter) && method_exists($parameter, '__toString')
+                        ? (string) $parameter
+                        : $parameter;
+    }
+
+    /**
+     * Get / set the URL fragment to be appended to URLs.
+     *
+     * @param  string|null  $fragment
+     * @return $this|string|null
+     */
+    public function fragment($fragment = null)
+    {
+        if (is_null($fragment)) {
+            return $this->fragment;
+        }
+
+        $this->fragment = $fragment;
+
+        return $this;
+    }
+
+    /**
+     * Add a set of query string values to the paginator.
+     *
+     * @param  array|string|null  $key
+     * @param  string|null  $value
+     * @return $this
+     */
+    public function appends($key, $value = null)
+    {
+        if (is_null($key)) {
+            return $this;
+        }
+
+        if (is_array($key)) {
+            return $this->appendArray($key);
+        }
+
+        return $this->addQuery($key, $value);
+    }
+
+    /**
+     * Add an array of query string values.
+     *
+     * @param  array  $keys
+     * @return $this
+     */
+    protected function appendArray(array $keys)
+    {
+        foreach ($keys as $key => $value) {
+            $this->addQuery($key, $value);
+        }
+
+        return $this;
+    }
+
+    /**
+     * Add all current query string values to the paginator.
+     *
+     * @return $this
+     */
+    public function withQueryString()
+    {
+        if (! is_null($query = Paginator::resolveQueryString())) {
+            return $this->appends($query);
+        }
+
+        return $this;
+    }
+
+    /**
+     * Add a query string value to the paginator.
+     *
+     * @param  string  $key
+     * @param  string  $value
+     * @return $this
+     */
+    protected function addQuery($key, $value)
+    {
+        if ($key !== $this->cursorName) {
+            $this->query[$key] = $value;
+        }
+
+        return $this;
+    }
+
+    /**
+     * Build the full fragment portion of a URL.
+     *
+     * @return string
+     */
+    protected function buildFragment()
+    {
+        return $this->fragment ? '#'.$this->fragment : '';
+    }
+
+    /**
+     * Load a set of relationships onto the mixed relationship collection.
+     *
+     * @param  string  $relation
+     * @param  array  $relations
+     * @return $this
+     */
+    public function loadMorph($relation, $relations)
+    {
+        $this->getCollection()->loadMorph($relation, $relations);
+
+        return $this;
+    }
+
+    /**
+     * Load a set of relationship counts onto the mixed relationship collection.
+     *
+     * @param  string  $relation
+     * @param  array  $relations
+     * @return $this
+     */
+    public function loadMorphCount($relation, $relations)
+    {
+        $this->getCollection()->loadMorphCount($relation, $relations);
+
+        return $this;
+    }
+
+    /**
+     * Get the slice of items being paginated.
+     *
+     * @return array
+     */
+    public function items()
+    {
+        return $this->items->all();
+    }
+
+    /**
+     * Transform each item in the slice of items using a callback.
+     *
+     * @param  callable  $callback
+     * @return $this
+     */
+    public function through(callable $callback)
+    {
+        $this->items->transform($callback);
+
+        return $this;
+    }
+
+    /**
+     * Get the number of items shown per page.
+     *
+     * @return int
+     */
+    public function perPage()
+    {
+        return $this->perPage;
+    }
+
+    /**
+     * Get the current cursor being paginated.
+     *
+     * @return \Illuminate\Pagination\Cursor|null
+     */
+    public function cursor()
+    {
+        return $this->cursor;
+    }
+
+    /**
+     * Get the query string variable used to store the cursor.
+     *
+     * @return string
+     */
+    public function getCursorName()
+    {
+        return $this->cursorName;
+    }
+
+    /**
+     * Set the query string variable used to store the cursor.
+     *
+     * @param  string  $name
+     * @return $this
+     */
+    public function setCursorName($name)
+    {
+        $this->cursorName = $name;
+
+        return $this;
+    }
+
+    /**
+     * Set the base path to assign to all URLs.
+     *
+     * @param  string  $path
+     * @return $this
+     */
+    public function withPath($path)
+    {
+        return $this->setPath($path);
+    }
+
+    /**
+     * Set the base path to assign to all URLs.
+     *
+     * @param  string  $path
+     * @return $this
+     */
+    public function setPath($path)
+    {
+        $this->path = $path;
+
+        return $this;
+    }
+
+    /**
+     * Get the base path for paginator generated URLs.
+     *
+     * @return string|null
+     */
+    public function path()
+    {
+        return $this->path;
+    }
+
+    /**
+     * Resolve the current cursor or return the default value.
+     *
+     * @param  string  $cursorName
+     * @return \Illuminate\Pagination\Cursor|null
+     */
+    public static function resolveCurrentCursor($cursorName = 'cursor', $default = null)
+    {
+        if (isset(static::$currentCursorResolver)) {
+            return call_user_func(static::$currentCursorResolver, $cursorName);
+        }
+
+        return $default;
+    }
+
+    /**
+     * Set the current cursor resolver callback.
+     *
+     * @param  \Closure  $resolver
+     * @return void
+     */
+    public static function currentCursorResolver(Closure $resolver)
+    {
+        static::$currentCursorResolver = $resolver;
+    }
+
+    /**
+     * Get an instance of the view factory from the resolver.
+     *
+     * @return \Illuminate\Contracts\View\Factory
+     */
+    public static function viewFactory()
+    {
+        return Paginator::viewFactory();
+    }
+
+    /**
+     * Get an iterator for the items.
+     *
+     * @return \ArrayIterator
+     */
+    public function getIterator(): Traversable
+    {
+        return $this->items->getIterator();
+    }
+
+    /**
+     * Determine if the list of items is empty.
+     *
+     * @return bool
+     */
+    public function isEmpty()
+    {
+        return $this->items->isEmpty();
+    }
+
+    /**
+     * Determine if the list of items is not empty.
+     *
+     * @return bool
+     */
+    public function isNotEmpty()
+    {
+        return $this->items->isNotEmpty();
+    }
+
+    /**
+     * Get the number of items for the current page.
+     *
+     * @return int
+     */
+    public function count(): int
+    {
+        return $this->items->count();
+    }
+
+    /**
+     * Get the paginator's underlying collection.
+     *
+     * @return \Illuminate\Support\Collection
+     */
+    public function getCollection()
+    {
+        return $this->items;
+    }
+
+    /**
+     * Set the paginator's underlying collection.
+     *
+     * @param  \Illuminate\Support\Collection  $collection
+     * @return $this
+     */
+    public function setCollection(Collection $collection)
+    {
+        $this->items = $collection;
+
+        return $this;
+    }
+
+    /**
+     * Get the paginator options.
+     *
+     * @return array
+     */
+    public function getOptions()
+    {
+        return $this->options;
+    }
+
+    /**
+     * Determine if the given item exists.
+     *
+     * @param  mixed  $key
+     * @return bool
+     */
+    public function offsetExists($key): bool
+    {
+        return $this->items->has($key);
+    }
+
+    /**
+     * Get the item at the given offset.
+     *
+     * @param  mixed  $key
+     * @return mixed
+     */
+    public function offsetGet($key): mixed
+    {
+        return $this->items->get($key);
+    }
+
+    /**
+     * Set the item at the given offset.
+     *
+     * @param  mixed  $key
+     * @param  mixed  $value
+     * @return void
+     */
+    public function offsetSet($key, $value): void
+    {
+        $this->items->put($key, $value);
+    }
+
+    /**
+     * Unset the item at the given key.
+     *
+     * @param  mixed  $key
+     * @return void
+     */
+    public function offsetUnset($key): void
+    {
+        $this->items->forget($key);
+    }
+
+    /**
+     * Render the contents of the paginator to HTML.
+     *
+     * @return string
+     */
+    public function toHtml()
+    {
+        return (string) $this->render();
+    }
+
+    /**
+     * Make dynamic calls into the collection.
+     *
+     * @param  string  $method
+     * @param  array  $parameters
+     * @return mixed
+     */
+    public function __call($method, $parameters)
+    {
+        return $this->forwardCallTo($this->getCollection(), $method, $parameters);
+    }
+
+    /**
+     * Render the contents of the paginator when casting to a string.
+     *
+     * @return string
+     */
+    public function __toString()
+    {
+        return (string) $this->render();
+    }
+}
diff --git a/vendor/illuminate/pagination/AbstractPaginator.php b/vendor/illuminate/pagination/AbstractPaginator.php
new file mode 100644
index 0000000..a497984
--- /dev/null
+++ b/vendor/illuminate/pagination/AbstractPaginator.php
@@ -0,0 +1,797 @@
+= 1 && filter_var($page, FILTER_VALIDATE_INT) !== false;
+    }
+
+    /**
+     * Get the URL for the previous page.
+     *
+     * @return string|null
+     */
+    public function previousPageUrl()
+    {
+        if ($this->currentPage() > 1) {
+            return $this->url($this->currentPage() - 1);
+        }
+    }
+
+    /**
+     * Create a range of pagination URLs.
+     *
+     * @param  int  $start
+     * @param  int  $end
+     * @return array
+     */
+    public function getUrlRange($start, $end)
+    {
+        return collect(range($start, $end))->mapWithKeys(function ($page) {
+            return [$page => $this->url($page)];
+        })->all();
+    }
+
+    /**
+     * Get the URL for a given page number.
+     *
+     * @param  int  $page
+     * @return string
+     */
+    public function url($page)
+    {
+        if ($page <= 0) {
+            $page = 1;
+        }
+
+        // If we have any extra query string key / value pairs that need to be added
+        // onto the URL, we will put them in query string form and then attach it
+        // to the URL. This allows for extra information like sortings storage.
+        $parameters = [$this->pageName => $page];
+
+        if (count($this->query) > 0) {
+            $parameters = array_merge($this->query, $parameters);
+        }
+
+        return $this->path()
+                        .(str_contains($this->path(), '?') ? '&' : '?')
+                        .Arr::query($parameters)
+                        .$this->buildFragment();
+    }
+
+    /**
+     * Get / set the URL fragment to be appended to URLs.
+     *
+     * @param  string|null  $fragment
+     * @return $this|string|null
+     */
+    public function fragment($fragment = null)
+    {
+        if (is_null($fragment)) {
+            return $this->fragment;
+        }
+
+        $this->fragment = $fragment;
+
+        return $this;
+    }
+
+    /**
+     * Add a set of query string values to the paginator.
+     *
+     * @param  array|string|null  $key
+     * @param  string|null  $value
+     * @return $this
+     */
+    public function appends($key, $value = null)
+    {
+        if (is_null($key)) {
+            return $this;
+        }
+
+        if (is_array($key)) {
+            return $this->appendArray($key);
+        }
+
+        return $this->addQuery($key, $value);
+    }
+
+    /**
+     * Add an array of query string values.
+     *
+     * @param  array  $keys
+     * @return $this
+     */
+    protected function appendArray(array $keys)
+    {
+        foreach ($keys as $key => $value) {
+            $this->addQuery($key, $value);
+        }
+
+        return $this;
+    }
+
+    /**
+     * Add all current query string values to the paginator.
+     *
+     * @return $this
+     */
+    public function withQueryString()
+    {
+        if (isset(static::$queryStringResolver)) {
+            return $this->appends(call_user_func(static::$queryStringResolver));
+        }
+
+        return $this;
+    }
+
+    /**
+     * Add a query string value to the paginator.
+     *
+     * @param  string  $key
+     * @param  string  $value
+     * @return $this
+     */
+    protected function addQuery($key, $value)
+    {
+        if ($key !== $this->pageName) {
+            $this->query[$key] = $value;
+        }
+
+        return $this;
+    }
+
+    /**
+     * Build the full fragment portion of a URL.
+     *
+     * @return string
+     */
+    protected function buildFragment()
+    {
+        return $this->fragment ? '#'.$this->fragment : '';
+    }
+
+    /**
+     * Load a set of relationships onto the mixed relationship collection.
+     *
+     * @param  string  $relation
+     * @param  array  $relations
+     * @return $this
+     */
+    public function loadMorph($relation, $relations)
+    {
+        $this->getCollection()->loadMorph($relation, $relations);
+
+        return $this;
+    }
+
+    /**
+     * Load a set of relationship counts onto the mixed relationship collection.
+     *
+     * @param  string  $relation
+     * @param  array  $relations
+     * @return $this
+     */
+    public function loadMorphCount($relation, $relations)
+    {
+        $this->getCollection()->loadMorphCount($relation, $relations);
+
+        return $this;
+    }
+
+    /**
+     * Get the slice of items being paginated.
+     *
+     * @return array
+     */
+    public function items()
+    {
+        return $this->items->all();
+    }
+
+    /**
+     * Get the number of the first item in the slice.
+     *
+     * @return int
+     */
+    public function firstItem()
+    {
+        return count($this->items) > 0 ? ($this->currentPage - 1) * $this->perPage + 1 : null;
+    }
+
+    /**
+     * Get the number of the last item in the slice.
+     *
+     * @return int
+     */
+    public function lastItem()
+    {
+        return count($this->items) > 0 ? $this->firstItem() + $this->count() - 1 : null;
+    }
+
+    /**
+     * Transform each item in the slice of items using a callback.
+     *
+     * @param  callable  $callback
+     * @return $this
+     */
+    public function through(callable $callback)
+    {
+        $this->items->transform($callback);
+
+        return $this;
+    }
+
+    /**
+     * Get the number of items shown per page.
+     *
+     * @return int
+     */
+    public function perPage()
+    {
+        return $this->perPage;
+    }
+
+    /**
+     * Determine if there are enough items to split into multiple pages.
+     *
+     * @return bool
+     */
+    public function hasPages()
+    {
+        return $this->currentPage() != 1 || $this->hasMorePages();
+    }
+
+    /**
+     * Determine if the paginator is on the first page.
+     *
+     * @return bool
+     */
+    public function onFirstPage()
+    {
+        return $this->currentPage() <= 1;
+    }
+
+    /**
+     * Determine if the paginator is on the last page.
+     *
+     * @return bool
+     */
+    public function onLastPage()
+    {
+        return ! $this->hasMorePages();
+    }
+
+    /**
+     * Get the current page.
+     *
+     * @return int
+     */
+    public function currentPage()
+    {
+        return $this->currentPage;
+    }
+
+    /**
+     * Get the query string variable used to store the page.
+     *
+     * @return string
+     */
+    public function getPageName()
+    {
+        return $this->pageName;
+    }
+
+    /**
+     * Set the query string variable used to store the page.
+     *
+     * @param  string  $name
+     * @return $this
+     */
+    public function setPageName($name)
+    {
+        $this->pageName = $name;
+
+        return $this;
+    }
+
+    /**
+     * Set the base path to assign to all URLs.
+     *
+     * @param  string  $path
+     * @return $this
+     */
+    public function withPath($path)
+    {
+        return $this->setPath($path);
+    }
+
+    /**
+     * Set the base path to assign to all URLs.
+     *
+     * @param  string  $path
+     * @return $this
+     */
+    public function setPath($path)
+    {
+        $this->path = $path;
+
+        return $this;
+    }
+
+    /**
+     * Set the number of links to display on each side of current page link.
+     *
+     * @param  int  $count
+     * @return $this
+     */
+    public function onEachSide($count)
+    {
+        $this->onEachSide = $count;
+
+        return $this;
+    }
+
+    /**
+     * Get the base path for paginator generated URLs.
+     *
+     * @return string|null
+     */
+    public function path()
+    {
+        return $this->path;
+    }
+
+    /**
+     * Resolve the current request path or return the default value.
+     *
+     * @param  string  $default
+     * @return string
+     */
+    public static function resolveCurrentPath($default = '/')
+    {
+        if (isset(static::$currentPathResolver)) {
+            return call_user_func(static::$currentPathResolver);
+        }
+
+        return $default;
+    }
+
+    /**
+     * Set the current request path resolver callback.
+     *
+     * @param  \Closure  $resolver
+     * @return void
+     */
+    public static function currentPathResolver(Closure $resolver)
+    {
+        static::$currentPathResolver = $resolver;
+    }
+
+    /**
+     * Resolve the current page or return the default value.
+     *
+     * @param  string  $pageName
+     * @param  int  $default
+     * @return int
+     */
+    public static function resolveCurrentPage($pageName = 'page', $default = 1)
+    {
+        if (isset(static::$currentPageResolver)) {
+            return (int) call_user_func(static::$currentPageResolver, $pageName);
+        }
+
+        return $default;
+    }
+
+    /**
+     * Set the current page resolver callback.
+     *
+     * @param  \Closure  $resolver
+     * @return void
+     */
+    public static function currentPageResolver(Closure $resolver)
+    {
+        static::$currentPageResolver = $resolver;
+    }
+
+    /**
+     * Resolve the query string or return the default value.
+     *
+     * @param  string|array|null  $default
+     * @return string
+     */
+    public static function resolveQueryString($default = null)
+    {
+        if (isset(static::$queryStringResolver)) {
+            return (static::$queryStringResolver)();
+        }
+
+        return $default;
+    }
+
+    /**
+     * Set with query string resolver callback.
+     *
+     * @param  \Closure  $resolver
+     * @return void
+     */
+    public static function queryStringResolver(Closure $resolver)
+    {
+        static::$queryStringResolver = $resolver;
+    }
+
+    /**
+     * Get an instance of the view factory from the resolver.
+     *
+     * @return \Illuminate\Contracts\View\Factory
+     */
+    public static function viewFactory()
+    {
+        return call_user_func(static::$viewFactoryResolver);
+    }
+
+    /**
+     * Set the view factory resolver callback.
+     *
+     * @param  \Closure  $resolver
+     * @return void
+     */
+    public static function viewFactoryResolver(Closure $resolver)
+    {
+        static::$viewFactoryResolver = $resolver;
+    }
+
+    /**
+     * Set the default pagination view.
+     *
+     * @param  string  $view
+     * @return void
+     */
+    public static function defaultView($view)
+    {
+        static::$defaultView = $view;
+    }
+
+    /**
+     * Set the default "simple" pagination view.
+     *
+     * @param  string  $view
+     * @return void
+     */
+    public static function defaultSimpleView($view)
+    {
+        static::$defaultSimpleView = $view;
+    }
+
+    /**
+     * Indicate that Tailwind styling should be used for generated links.
+     *
+     * @return void
+     */
+    public static function useTailwind()
+    {
+        static::defaultView('pagination::tailwind');
+        static::defaultSimpleView('pagination::simple-tailwind');
+    }
+
+    /**
+     * Indicate that Bootstrap 4 styling should be used for generated links.
+     *
+     * @return void
+     */
+    public static function useBootstrap()
+    {
+        static::useBootstrapFour();
+    }
+
+    /**
+     * Indicate that Bootstrap 3 styling should be used for generated links.
+     *
+     * @return void
+     */
+    public static function useBootstrapThree()
+    {
+        static::defaultView('pagination::default');
+        static::defaultSimpleView('pagination::simple-default');
+    }
+
+    /**
+     * Indicate that Bootstrap 4 styling should be used for generated links.
+     *
+     * @return void
+     */
+    public static function useBootstrapFour()
+    {
+        static::defaultView('pagination::bootstrap-4');
+        static::defaultSimpleView('pagination::simple-bootstrap-4');
+    }
+
+    /**
+     * Indicate that Bootstrap 5 styling should be used for generated links.
+     *
+     * @return void
+     */
+    public static function useBootstrapFive()
+    {
+        static::defaultView('pagination::bootstrap-5');
+        static::defaultSimpleView('pagination::simple-bootstrap-5');
+    }
+
+    /**
+     * Get an iterator for the items.
+     *
+     * @return \ArrayIterator
+     */
+    public function getIterator(): Traversable
+    {
+        return $this->items->getIterator();
+    }
+
+    /**
+     * Determine if the list of items is empty.
+     *
+     * @return bool
+     */
+    public function isEmpty()
+    {
+        return $this->items->isEmpty();
+    }
+
+    /**
+     * Determine if the list of items is not empty.
+     *
+     * @return bool
+     */
+    public function isNotEmpty()
+    {
+        return $this->items->isNotEmpty();
+    }
+
+    /**
+     * Get the number of items for the current page.
+     *
+     * @return int
+     */
+    public function count(): int
+    {
+        return $this->items->count();
+    }
+
+    /**
+     * Get the paginator's underlying collection.
+     *
+     * @return \Illuminate\Support\Collection
+     */
+    public function getCollection()
+    {
+        return $this->items;
+    }
+
+    /**
+     * Set the paginator's underlying collection.
+     *
+     * @param  \Illuminate\Support\Collection  $collection
+     * @return $this
+     */
+    public function setCollection(Collection $collection)
+    {
+        $this->items = $collection;
+
+        return $this;
+    }
+
+    /**
+     * Get the paginator options.
+     *
+     * @return array
+     */
+    public function getOptions()
+    {
+        return $this->options;
+    }
+
+    /**
+     * Determine if the given item exists.
+     *
+     * @param  mixed  $key
+     * @return bool
+     */
+    public function offsetExists($key): bool
+    {
+        return $this->items->has($key);
+    }
+
+    /**
+     * Get the item at the given offset.
+     *
+     * @param  mixed  $key
+     * @return mixed
+     */
+    public function offsetGet($key): mixed
+    {
+        return $this->items->get($key);
+    }
+
+    /**
+     * Set the item at the given offset.
+     *
+     * @param  mixed  $key
+     * @param  mixed  $value
+     * @return void
+     */
+    public function offsetSet($key, $value): void
+    {
+        $this->items->put($key, $value);
+    }
+
+    /**
+     * Unset the item at the given key.
+     *
+     * @param  mixed  $key
+     * @return void
+     */
+    public function offsetUnset($key): void
+    {
+        $this->items->forget($key);
+    }
+
+    /**
+     * Render the contents of the paginator to HTML.
+     *
+     * @return string
+     */
+    public function toHtml()
+    {
+        return (string) $this->render();
+    }
+
+    /**
+     * Make dynamic calls into the collection.
+     *
+     * @param  string  $method
+     * @param  array  $parameters
+     * @return mixed
+     */
+    public function __call($method, $parameters)
+    {
+        return $this->forwardCallTo($this->getCollection(), $method, $parameters);
+    }
+
+    /**
+     * Render the contents of the paginator when casting to a string.
+     *
+     * @return string
+     */
+    public function __toString()
+    {
+        return (string) $this->render();
+    }
+}
diff --git a/vendor/illuminate/pagination/Cursor.php b/vendor/illuminate/pagination/Cursor.php
new file mode 100644
index 0000000..1d62280
--- /dev/null
+++ b/vendor/illuminate/pagination/Cursor.php
@@ -0,0 +1,132 @@
+parameters = $parameters;
+        $this->pointsToNextItems = $pointsToNextItems;
+    }
+
+    /**
+     * Get the given parameter from the cursor.
+     *
+     * @param  string  $parameterName
+     * @return string|null
+     *
+     * @throws \UnexpectedValueException
+     */
+    public function parameter(string $parameterName)
+    {
+        if (! array_key_exists($parameterName, $this->parameters)) {
+            throw new UnexpectedValueException("Unable to find parameter [{$parameterName}] in pagination item.");
+        }
+
+        return $this->parameters[$parameterName];
+    }
+
+    /**
+     * Get the given parameters from the cursor.
+     *
+     * @param  array  $parameterNames
+     * @return array
+     */
+    public function parameters(array $parameterNames)
+    {
+        return collect($parameterNames)->map(function ($parameterName) {
+            return $this->parameter($parameterName);
+        })->toArray();
+    }
+
+    /**
+     * Determine whether the cursor points to the next set of items.
+     *
+     * @return bool
+     */
+    public function pointsToNextItems()
+    {
+        return $this->pointsToNextItems;
+    }
+
+    /**
+     * Determine whether the cursor points to the previous set of items.
+     *
+     * @return bool
+     */
+    public function pointsToPreviousItems()
+    {
+        return ! $this->pointsToNextItems;
+    }
+
+    /**
+     * Get the array representation of the cursor.
+     *
+     * @return array
+     */
+    public function toArray()
+    {
+        return array_merge($this->parameters, [
+            '_pointsToNextItems' => $this->pointsToNextItems,
+        ]);
+    }
+
+    /**
+     * Get the encoded string representation of the cursor to construct a URL.
+     *
+     * @return string
+     */
+    public function encode()
+    {
+        return str_replace(['+', '/', '='], ['-', '_', ''], base64_encode(json_encode($this->toArray())));
+    }
+
+    /**
+     * Get a cursor instance from the encoded string representation.
+     *
+     * @param  string|null  $encodedString
+     * @return static|null
+     */
+    public static function fromEncoded($encodedString)
+    {
+        if (! is_string($encodedString)) {
+            return null;
+        }
+
+        $parameters = json_decode(base64_decode(str_replace(['-', '_'], ['+', '/'], $encodedString)), true);
+
+        if (json_last_error() !== JSON_ERROR_NONE) {
+            return null;
+        }
+
+        $pointsToNextItems = $parameters['_pointsToNextItems'];
+
+        unset($parameters['_pointsToNextItems']);
+
+        return new static($parameters, $pointsToNextItems);
+    }
+}
diff --git a/vendor/illuminate/pagination/CursorPaginator.php b/vendor/illuminate/pagination/CursorPaginator.php
new file mode 100644
index 0000000..4c0a896
--- /dev/null
+++ b/vendor/illuminate/pagination/CursorPaginator.php
@@ -0,0 +1,172 @@
+options = $options;
+
+        foreach ($options as $key => $value) {
+            $this->{$key} = $value;
+        }
+
+        $this->perPage = (int) $perPage;
+        $this->cursor = $cursor;
+        $this->path = $this->path !== '/' ? rtrim($this->path, '/') : $this->path;
+
+        $this->setItems($items);
+    }
+
+    /**
+     * Set the items for the paginator.
+     *
+     * @param  mixed  $items
+     * @return void
+     */
+    protected function setItems($items)
+    {
+        $this->items = $items instanceof Collection ? $items : Collection::make($items);
+
+        $this->hasMore = $this->items->count() > $this->perPage;
+
+        $this->items = $this->items->slice(0, $this->perPage);
+
+        if (! is_null($this->cursor) && $this->cursor->pointsToPreviousItems()) {
+            $this->items = $this->items->reverse()->values();
+        }
+    }
+
+    /**
+     * Render the paginator using the given view.
+     *
+     * @param  string|null  $view
+     * @param  array  $data
+     * @return \Illuminate\Contracts\Support\Htmlable
+     */
+    public function links($view = null, $data = [])
+    {
+        return $this->render($view, $data);
+    }
+
+    /**
+     * Render the paginator using the given view.
+     *
+     * @param  string|null  $view
+     * @param  array  $data
+     * @return \Illuminate\Contracts\Support\Htmlable
+     */
+    public function render($view = null, $data = [])
+    {
+        return static::viewFactory()->make($view ?: Paginator::$defaultSimpleView, array_merge($data, [
+            'paginator' => $this,
+        ]));
+    }
+
+    /**
+     * Determine if there are more items in the data source.
+     *
+     * @return bool
+     */
+    public function hasMorePages()
+    {
+        return (is_null($this->cursor) && $this->hasMore) ||
+            (! is_null($this->cursor) && $this->cursor->pointsToNextItems() && $this->hasMore) ||
+            (! is_null($this->cursor) && $this->cursor->pointsToPreviousItems());
+    }
+
+    /**
+     * Determine if there are enough items to split into multiple pages.
+     *
+     * @return bool
+     */
+    public function hasPages()
+    {
+        return ! $this->onFirstPage() || $this->hasMorePages();
+    }
+
+    /**
+     * Determine if the paginator is on the first page.
+     *
+     * @return bool
+     */
+    public function onFirstPage()
+    {
+        return is_null($this->cursor) || ($this->cursor->pointsToPreviousItems() && ! $this->hasMore);
+    }
+
+    /**
+     * Determine if the paginator is on the last page.
+     *
+     * @return bool
+     */
+    public function onLastPage()
+    {
+        return ! $this->hasMorePages();
+    }
+
+    /**
+     * Get the instance as an array.
+     *
+     * @return array
+     */
+    public function toArray()
+    {
+        return [
+            'data' => $this->items->toArray(),
+            'path' => $this->path(),
+            'per_page' => $this->perPage(),
+            'next_cursor' => $this->nextCursor()?->encode(),
+            'next_page_url' => $this->nextPageUrl(),
+            'prev_cursor' => $this->previousCursor()?->encode(),
+            'prev_page_url' => $this->previousPageUrl(),
+        ];
+    }
+
+    /**
+     * Convert the object into something JSON serializable.
+     *
+     * @return array
+     */
+    public function jsonSerialize(): array
+    {
+        return $this->toArray();
+    }
+
+    /**
+     * Convert the object to its JSON representation.
+     *
+     * @param  int  $options
+     * @return string
+     */
+    public function toJson($options = 0)
+    {
+        return json_encode($this->jsonSerialize(), $options);
+    }
+}
diff --git a/vendor/illuminate/pagination/LICENSE.md b/vendor/illuminate/pagination/LICENSE.md
new file mode 100644
index 0000000..79810c8
--- /dev/null
+++ b/vendor/illuminate/pagination/LICENSE.md
@@ -0,0 +1,21 @@
+The MIT License (MIT)
+
+Copyright (c) Taylor Otwell
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
diff --git a/vendor/illuminate/pagination/LengthAwarePaginator.php b/vendor/illuminate/pagination/LengthAwarePaginator.php
new file mode 100644
index 0000000..8d3e0ab
--- /dev/null
+++ b/vendor/illuminate/pagination/LengthAwarePaginator.php
@@ -0,0 +1,231 @@
+options = $options;
+
+        foreach ($options as $key => $value) {
+            $this->{$key} = $value;
+        }
+
+        $this->total = $total;
+        $this->perPage = (int) $perPage;
+        $this->lastPage = max((int) ceil($total / $perPage), 1);
+        $this->path = $this->path !== '/' ? rtrim($this->path, '/') : $this->path;
+        $this->currentPage = $this->setCurrentPage($currentPage, $this->pageName);
+        $this->items = $items instanceof Collection ? $items : Collection::make($items);
+    }
+
+    /**
+     * Get the current page for the request.
+     *
+     * @param  int  $currentPage
+     * @param  string  $pageName
+     * @return int
+     */
+    protected function setCurrentPage($currentPage, $pageName)
+    {
+        $currentPage = $currentPage ?: static::resolveCurrentPage($pageName);
+
+        return $this->isValidPageNumber($currentPage) ? (int) $currentPage : 1;
+    }
+
+    /**
+     * Render the paginator using the given view.
+     *
+     * @param  string|null  $view
+     * @param  array  $data
+     * @return \Illuminate\Contracts\Support\Htmlable
+     */
+    public function links($view = null, $data = [])
+    {
+        return $this->render($view, $data);
+    }
+
+    /**
+     * Render the paginator using the given view.
+     *
+     * @param  string|null  $view
+     * @param  array  $data
+     * @return \Illuminate\Contracts\Support\Htmlable
+     */
+    public function render($view = null, $data = [])
+    {
+        return static::viewFactory()->make($view ?: static::$defaultView, array_merge($data, [
+            'paginator' => $this,
+            'elements' => $this->elements(),
+        ]));
+    }
+
+    /**
+     * Get the paginator links as a collection (for JSON responses).
+     *
+     * @return \Illuminate\Support\Collection
+     */
+    public function linkCollection()
+    {
+        return collect($this->elements())->flatMap(function ($item) {
+            if (! is_array($item)) {
+                return [['url' => null, 'label' => '...', 'active' => false]];
+            }
+
+            return collect($item)->map(function ($url, $page) {
+                return [
+                    'url' => $url,
+                    'label' => (string) $page,
+                    'active' => $this->currentPage() === $page,
+                ];
+            });
+        })->prepend([
+            'url' => $this->previousPageUrl(),
+            'label' => function_exists('__') ? __('pagination.previous') : 'Previous',
+            'active' => false,
+        ])->push([
+            'url' => $this->nextPageUrl(),
+            'label' => function_exists('__') ? __('pagination.next') : 'Next',
+            'active' => false,
+        ]);
+    }
+
+    /**
+     * Get the array of elements to pass to the view.
+     *
+     * @return array
+     */
+    protected function elements()
+    {
+        $window = UrlWindow::make($this);
+
+        return array_filter([
+            $window['first'],
+            is_array($window['slider']) ? '...' : null,
+            $window['slider'],
+            is_array($window['last']) ? '...' : null,
+            $window['last'],
+        ]);
+    }
+
+    /**
+     * Get the total number of items being paginated.
+     *
+     * @return int
+     */
+    public function total()
+    {
+        return $this->total;
+    }
+
+    /**
+     * Determine if there are more items in the data source.
+     *
+     * @return bool
+     */
+    public function hasMorePages()
+    {
+        return $this->currentPage() < $this->lastPage();
+    }
+
+    /**
+     * Get the URL for the next page.
+     *
+     * @return string|null
+     */
+    public function nextPageUrl()
+    {
+        if ($this->hasMorePages()) {
+            return $this->url($this->currentPage() + 1);
+        }
+    }
+
+    /**
+     * Get the last page.
+     *
+     * @return int
+     */
+    public function lastPage()
+    {
+        return $this->lastPage;
+    }
+
+    /**
+     * Get the instance as an array.
+     *
+     * @return array
+     */
+    public function toArray()
+    {
+        return [
+            'current_page' => $this->currentPage(),
+            'data' => $this->items->toArray(),
+            'first_page_url' => $this->url(1),
+            'from' => $this->firstItem(),
+            'last_page' => $this->lastPage(),
+            'last_page_url' => $this->url($this->lastPage()),
+            'links' => $this->linkCollection()->toArray(),
+            'next_page_url' => $this->nextPageUrl(),
+            'path' => $this->path(),
+            'per_page' => $this->perPage(),
+            'prev_page_url' => $this->previousPageUrl(),
+            'to' => $this->lastItem(),
+            'total' => $this->total(),
+        ];
+    }
+
+    /**
+     * Convert the object into something JSON serializable.
+     *
+     * @return array
+     */
+    public function jsonSerialize(): array
+    {
+        return $this->toArray();
+    }
+
+    /**
+     * Convert the object to its JSON representation.
+     *
+     * @param  int  $options
+     * @return string
+     */
+    public function toJson($options = 0)
+    {
+        return json_encode($this->jsonSerialize(), $options);
+    }
+}
diff --git a/vendor/illuminate/pagination/PaginationServiceProvider.php b/vendor/illuminate/pagination/PaginationServiceProvider.php
new file mode 100755
index 0000000..e94cebd
--- /dev/null
+++ b/vendor/illuminate/pagination/PaginationServiceProvider.php
@@ -0,0 +1,34 @@
+loadViewsFrom(__DIR__.'/resources/views', 'pagination');
+
+        if ($this->app->runningInConsole()) {
+            $this->publishes([
+                __DIR__.'/resources/views' => $this->app->resourcePath('views/vendor/pagination'),
+            ], 'laravel-pagination');
+        }
+    }
+
+    /**
+     * Register the service provider.
+     *
+     * @return void
+     */
+    public function register()
+    {
+        PaginationState::resolveUsing($this->app);
+    }
+}
diff --git a/vendor/illuminate/pagination/PaginationState.php b/vendor/illuminate/pagination/PaginationState.php
new file mode 100644
index 0000000..347c6e2
--- /dev/null
+++ b/vendor/illuminate/pagination/PaginationState.php
@@ -0,0 +1,35 @@
+ $app['view']);
+
+        Paginator::currentPathResolver(fn () => $app['request']->url());
+
+        Paginator::currentPageResolver(function ($pageName = 'page') use ($app) {
+            $page = $app['request']->input($pageName);
+
+            if (filter_var($page, FILTER_VALIDATE_INT) !== false && (int) $page >= 1) {
+                return (int) $page;
+            }
+
+            return 1;
+        });
+
+        Paginator::queryStringResolver(fn () => $app['request']->query());
+
+        CursorPaginator::currentCursorResolver(function ($cursorName = 'cursor') use ($app) {
+            return Cursor::fromEncoded($app['request']->input($cursorName));
+        });
+    }
+}
diff --git a/vendor/illuminate/pagination/Paginator.php b/vendor/illuminate/pagination/Paginator.php
new file mode 100644
index 0000000..d307ee9
--- /dev/null
+++ b/vendor/illuminate/pagination/Paginator.php
@@ -0,0 +1,176 @@
+options = $options;
+
+        foreach ($options as $key => $value) {
+            $this->{$key} = $value;
+        }
+
+        $this->perPage = $perPage;
+        $this->currentPage = $this->setCurrentPage($currentPage);
+        $this->path = $this->path !== '/' ? rtrim($this->path, '/') : $this->path;
+
+        $this->setItems($items);
+    }
+
+    /**
+     * Get the current page for the request.
+     *
+     * @param  int  $currentPage
+     * @return int
+     */
+    protected function setCurrentPage($currentPage)
+    {
+        $currentPage = $currentPage ?: static::resolveCurrentPage();
+
+        return $this->isValidPageNumber($currentPage) ? (int) $currentPage : 1;
+    }
+
+    /**
+     * Set the items for the paginator.
+     *
+     * @param  mixed  $items
+     * @return void
+     */
+    protected function setItems($items)
+    {
+        $this->items = $items instanceof Collection ? $items : Collection::make($items);
+
+        $this->hasMore = $this->items->count() > $this->perPage;
+
+        $this->items = $this->items->slice(0, $this->perPage);
+    }
+
+    /**
+     * Get the URL for the next page.
+     *
+     * @return string|null
+     */
+    public function nextPageUrl()
+    {
+        if ($this->hasMorePages()) {
+            return $this->url($this->currentPage() + 1);
+        }
+    }
+
+    /**
+     * Render the paginator using the given view.
+     *
+     * @param  string|null  $view
+     * @param  array  $data
+     * @return string
+     */
+    public function links($view = null, $data = [])
+    {
+        return $this->render($view, $data);
+    }
+
+    /**
+     * Render the paginator using the given view.
+     *
+     * @param  string|null  $view
+     * @param  array  $data
+     * @return \Illuminate\Contracts\Support\Htmlable
+     */
+    public function render($view = null, $data = [])
+    {
+        return static::viewFactory()->make($view ?: static::$defaultSimpleView, array_merge($data, [
+            'paginator' => $this,
+        ]));
+    }
+
+    /**
+     * Manually indicate that the paginator does have more pages.
+     *
+     * @param  bool  $hasMore
+     * @return $this
+     */
+    public function hasMorePagesWhen($hasMore = true)
+    {
+        $this->hasMore = $hasMore;
+
+        return $this;
+    }
+
+    /**
+     * Determine if there are more items in the data source.
+     *
+     * @return bool
+     */
+    public function hasMorePages()
+    {
+        return $this->hasMore;
+    }
+
+    /**
+     * Get the instance as an array.
+     *
+     * @return array
+     */
+    public function toArray()
+    {
+        return [
+            'current_page' => $this->currentPage(),
+            'data' => $this->items->toArray(),
+            'first_page_url' => $this->url(1),
+            'from' => $this->firstItem(),
+            'next_page_url' => $this->nextPageUrl(),
+            'path' => $this->path(),
+            'per_page' => $this->perPage(),
+            'prev_page_url' => $this->previousPageUrl(),
+            'to' => $this->lastItem(),
+        ];
+    }
+
+    /**
+     * Convert the object into something JSON serializable.
+     *
+     * @return array
+     */
+    public function jsonSerialize(): array
+    {
+        return $this->toArray();
+    }
+
+    /**
+     * Convert the object to its JSON representation.
+     *
+     * @param  int  $options
+     * @return string
+     */
+    public function toJson($options = 0)
+    {
+        return json_encode($this->jsonSerialize(), $options);
+    }
+}
diff --git a/vendor/illuminate/pagination/UrlWindow.php b/vendor/illuminate/pagination/UrlWindow.php
new file mode 100644
index 0000000..99286f7
--- /dev/null
+++ b/vendor/illuminate/pagination/UrlWindow.php
@@ -0,0 +1,220 @@
+paginator = $paginator;
+    }
+
+    /**
+     * Create a new URL window instance.
+     *
+     * @param  \Illuminate\Contracts\Pagination\LengthAwarePaginator  $paginator
+     * @return array
+     */
+    public static function make(PaginatorContract $paginator)
+    {
+        return (new static($paginator))->get();
+    }
+
+    /**
+     * Get the window of URLs to be shown.
+     *
+     * @return array
+     */
+    public function get()
+    {
+        $onEachSide = $this->paginator->onEachSide;
+
+        if ($this->paginator->lastPage() < ($onEachSide * 2) + 8) {
+            return $this->getSmallSlider();
+        }
+
+        return $this->getUrlSlider($onEachSide);
+    }
+
+    /**
+     * Get the slider of URLs there are not enough pages to slide.
+     *
+     * @return array
+     */
+    protected function getSmallSlider()
+    {
+        return [
+            'first' => $this->paginator->getUrlRange(1, $this->lastPage()),
+            'slider' => null,
+            'last' => null,
+        ];
+    }
+
+    /**
+     * Create a URL slider links.
+     *
+     * @param  int  $onEachSide
+     * @return array
+     */
+    protected function getUrlSlider($onEachSide)
+    {
+        $window = $onEachSide + 4;
+
+        if (! $this->hasPages()) {
+            return ['first' => null, 'slider' => null, 'last' => null];
+        }
+
+        // If the current page is very close to the beginning of the page range, we will
+        // just render the beginning of the page range, followed by the last 2 of the
+        // links in this list, since we will not have room to create a full slider.
+        if ($this->currentPage() <= $window) {
+            return $this->getSliderTooCloseToBeginning($window, $onEachSide);
+        }
+
+        // If the current page is close to the ending of the page range we will just get
+        // this first couple pages, followed by a larger window of these ending pages
+        // since we're too close to the end of the list to create a full on slider.
+        elseif ($this->currentPage() > ($this->lastPage() - $window)) {
+            return $this->getSliderTooCloseToEnding($window, $onEachSide);
+        }
+
+        // If we have enough room on both sides of the current page to build a slider we
+        // will surround it with both the beginning and ending caps, with this window
+        // of pages in the middle providing a Google style sliding paginator setup.
+        return $this->getFullSlider($onEachSide);
+    }
+
+    /**
+     * Get the slider of URLs when too close to the beginning of the window.
+     *
+     * @param  int  $window
+     * @param  int  $onEachSide
+     * @return array
+     */
+    protected function getSliderTooCloseToBeginning($window, $onEachSide)
+    {
+        return [
+            'first' => $this->paginator->getUrlRange(1, $window + $onEachSide),
+            'slider' => null,
+            'last' => $this->getFinish(),
+        ];
+    }
+
+    /**
+     * Get the slider of URLs when too close to the ending of the window.
+     *
+     * @param  int  $window
+     * @param  int  $onEachSide
+     * @return array
+     */
+    protected function getSliderTooCloseToEnding($window, $onEachSide)
+    {
+        $last = $this->paginator->getUrlRange(
+            $this->lastPage() - ($window + ($onEachSide - 1)),
+            $this->lastPage()
+        );
+
+        return [
+            'first' => $this->getStart(),
+            'slider' => null,
+            'last' => $last,
+        ];
+    }
+
+    /**
+     * Get the slider of URLs when a full slider can be made.
+     *
+     * @param  int  $onEachSide
+     * @return array
+     */
+    protected function getFullSlider($onEachSide)
+    {
+        return [
+            'first' => $this->getStart(),
+            'slider' => $this->getAdjacentUrlRange($onEachSide),
+            'last' => $this->getFinish(),
+        ];
+    }
+
+    /**
+     * Get the page range for the current page window.
+     *
+     * @param  int  $onEachSide
+     * @return array
+     */
+    public function getAdjacentUrlRange($onEachSide)
+    {
+        return $this->paginator->getUrlRange(
+            $this->currentPage() - $onEachSide,
+            $this->currentPage() + $onEachSide
+        );
+    }
+
+    /**
+     * Get the starting URLs of a pagination slider.
+     *
+     * @return array
+     */
+    public function getStart()
+    {
+        return $this->paginator->getUrlRange(1, 2);
+    }
+
+    /**
+     * Get the ending URLs of a pagination slider.
+     *
+     * @return array
+     */
+    public function getFinish()
+    {
+        return $this->paginator->getUrlRange(
+            $this->lastPage() - 1,
+            $this->lastPage()
+        );
+    }
+
+    /**
+     * Determine if the underlying paginator being presented has pages to show.
+     *
+     * @return bool
+     */
+    public function hasPages()
+    {
+        return $this->paginator->lastPage() > 1;
+    }
+
+    /**
+     * Get the current page from the paginator.
+     *
+     * @return int
+     */
+    protected function currentPage()
+    {
+        return $this->paginator->currentPage();
+    }
+
+    /**
+     * Get the last page from the paginator.
+     *
+     * @return int
+     */
+    protected function lastPage()
+    {
+        return $this->paginator->lastPage();
+    }
+}
diff --git a/vendor/illuminate/pagination/composer.json b/vendor/illuminate/pagination/composer.json
new file mode 100755
index 0000000..1b054f5
--- /dev/null
+++ b/vendor/illuminate/pagination/composer.json
@@ -0,0 +1,37 @@
+{
+    "name": "illuminate/pagination",
+    "description": "The Illuminate Pagination package.",
+    "license": "MIT",
+    "homepage": "https://laravel.com",
+    "support": {
+        "issues": "https://github.com/laravel/framework/issues",
+        "source": "https://github.com/laravel/framework"
+    },
+    "authors": [
+        {
+            "name": "Taylor Otwell",
+            "email": "taylor@laravel.com"
+        }
+    ],
+    "require": {
+        "php": "^8.0.2",
+        "ext-filter": "*",
+        "illuminate/collections": "^9.0",
+        "illuminate/contracts": "^9.0",
+        "illuminate/support": "^9.0"
+    },
+    "autoload": {
+        "psr-4": {
+            "Illuminate\\Pagination\\": ""
+        }
+    },
+    "extra": {
+        "branch-alias": {
+            "dev-master": "9.x-dev"
+        }
+    },
+    "config": {
+        "sort-packages": true
+    },
+    "minimum-stability": "dev"
+}
diff --git a/vendor/illuminate/pagination/resources/views/bootstrap-4.blade.php b/vendor/illuminate/pagination/resources/views/bootstrap-4.blade.php
new file mode 100644
index 0000000..63c6f56
--- /dev/null
+++ b/vendor/illuminate/pagination/resources/views/bootstrap-4.blade.php
@@ -0,0 +1,46 @@
+@if ($paginator->hasPages())
+    
+@endif
diff --git a/vendor/illuminate/pagination/resources/views/bootstrap-5.blade.php b/vendor/illuminate/pagination/resources/views/bootstrap-5.blade.php
new file mode 100644
index 0000000..a1795a4
--- /dev/null
+++ b/vendor/illuminate/pagination/resources/views/bootstrap-5.blade.php
@@ -0,0 +1,88 @@
+@if ($paginator->hasPages())
+    
+@endif
diff --git a/vendor/illuminate/pagination/resources/views/default.blade.php b/vendor/illuminate/pagination/resources/views/default.blade.php
new file mode 100644
index 0000000..0db70b5
--- /dev/null
+++ b/vendor/illuminate/pagination/resources/views/default.blade.php
@@ -0,0 +1,46 @@
+@if ($paginator->hasPages())
+    
+@endif
diff --git a/vendor/illuminate/pagination/resources/views/semantic-ui.blade.php b/vendor/illuminate/pagination/resources/views/semantic-ui.blade.php
new file mode 100644
index 0000000..ef0dbb1
--- /dev/null
+++ b/vendor/illuminate/pagination/resources/views/semantic-ui.blade.php
@@ -0,0 +1,36 @@
+@if ($paginator->hasPages())
+    
+@endif
diff --git a/vendor/illuminate/pagination/resources/views/simple-bootstrap-4.blade.php b/vendor/illuminate/pagination/resources/views/simple-bootstrap-4.blade.php
new file mode 100644
index 0000000..4bb4917
--- /dev/null
+++ b/vendor/illuminate/pagination/resources/views/simple-bootstrap-4.blade.php
@@ -0,0 +1,27 @@
+@if ($paginator->hasPages())
+    
+@endif
diff --git a/vendor/illuminate/pagination/resources/views/simple-bootstrap-5.blade.php b/vendor/illuminate/pagination/resources/views/simple-bootstrap-5.blade.php
new file mode 100644
index 0000000..a89005e
--- /dev/null
+++ b/vendor/illuminate/pagination/resources/views/simple-bootstrap-5.blade.php
@@ -0,0 +1,29 @@
+@if ($paginator->hasPages())
+    
+@endif
diff --git a/vendor/illuminate/pagination/resources/views/simple-default.blade.php b/vendor/illuminate/pagination/resources/views/simple-default.blade.php
new file mode 100644
index 0000000..36bdbc1
--- /dev/null
+++ b/vendor/illuminate/pagination/resources/views/simple-default.blade.php
@@ -0,0 +1,19 @@
+@if ($paginator->hasPages())
+    
+@endif
diff --git a/vendor/illuminate/pagination/resources/views/simple-tailwind.blade.php b/vendor/illuminate/pagination/resources/views/simple-tailwind.blade.php
new file mode 100644
index 0000000..6872cca
--- /dev/null
+++ b/vendor/illuminate/pagination/resources/views/simple-tailwind.blade.php
@@ -0,0 +1,25 @@
+@if ($paginator->hasPages())
+    
+@endif
diff --git a/vendor/illuminate/pagination/resources/views/tailwind.blade.php b/vendor/illuminate/pagination/resources/views/tailwind.blade.php
new file mode 100644
index 0000000..5bf323b
--- /dev/null
+++ b/vendor/illuminate/pagination/resources/views/tailwind.blade.php
@@ -0,0 +1,106 @@
+@if ($paginator->hasPages())
+    
+@endif
diff --git a/vendor/maximebf/debugbar/composer.json b/vendor/maximebf/debugbar/composer.json
deleted file mode 100644
index 50793eb..0000000
--- a/vendor/maximebf/debugbar/composer.json
+++ /dev/null
@@ -1,43 +0,0 @@
-{
-    "name": "maximebf/debugbar",
-    "description": "Debug bar in the browser for php application",
-    "keywords": ["debug", "debugbar"],
-    "homepage": "https://github.com/maximebf/php-debugbar",
-    "type": "library",
-    "license": "MIT",
-    "authors": [
-        {
-            "name": "Maxime Bouroumeau-Fuseau",
-            "email": "maxime.bouroumeau@gmail.com",
-            "homepage": "http://maximebf.com"
-        },
-        {
-            "name": "Barry vd. Heuvel",
-            "email": "barryvdh@gmail.com"
-        }
-    ],
-    "require": {
-        "php": "^7.1|^8",
-        "psr/log": "^1|^2|^3",
-        "symfony/var-dumper": "^4|^5|^6"
-    },
-    "require-dev": {
-        "phpunit/phpunit": ">=7.5.20 <10.0",
-        "twig/twig": "^1.38|^2.7|^3.0"
-    },
-    "autoload": {
-        "psr-4": {
-            "DebugBar\\": "src/DebugBar/"
-        }
-    },
-    "suggest": {
-        "kriswallsmith/assetic": "The best way to manage assets",
-        "monolog/monolog": "Log using Monolog",
-        "predis/predis": "Redis storage"
-    },
-     "extra": {
-        "branch-alias": {
-            "dev-master": "1.18-dev"
-        }
-    }
-}
diff --git a/vendor/maximebf/debugbar/src/DebugBar/Bridge/CacheCacheCollector.php b/vendor/maximebf/debugbar/src/DebugBar/Bridge/CacheCacheCollector.php
deleted file mode 100644
index 7e7f46f..0000000
--- a/vendor/maximebf/debugbar/src/DebugBar/Bridge/CacheCacheCollector.php
+++ /dev/null
@@ -1,75 +0,0 @@
-
- * $debugbar->addCollector(new CacheCacheCollector(CacheManager::get('default')));
- * // or
- * $debugbar->addCollector(new CacheCacheCollector());
- * $debugbar['cache']->addCache(CacheManager::get('default'));
- * 
- */
-class CacheCacheCollector extends MonologCollector
-{
-    protected $logger;
-
-    /**
-     * CacheCacheCollector constructor.
-     * @param Cache|null $cache
-     * @param Logger|null $logger
-     * @param bool $level
-     * @param bool $bubble
-     */
-    public function __construct(Cache $cache = null, Logger $logger = null, $level = Logger::DEBUG, $bubble = true)
-    {
-        parent::__construct(null, $level, $bubble);
-
-        if ($logger === null) {
-            $logger = new Logger('Cache');
-        }
-        $this->logger = $logger;
-
-        if ($cache !== null) {
-            $this->addCache($cache);
-        }
-    }
-
-    /**
-     * @param Cache $cache
-     */
-    public function addCache(Cache $cache)
-    {
-        $backend = $cache->getBackend();
-        if (!($backend instanceof LoggingBackend)) {
-            $backend = new LoggingBackend($backend, $this->logger);
-        }
-        $cache->setBackend($backend);
-        $this->addLogger($backend->getLogger());
-    }
-
-    /**
-     * @return string
-     */
-    public function getName()
-    {
-        return 'cache';
-    }
-}
diff --git a/vendor/maximebf/debugbar/src/DebugBar/Bridge/DoctrineCollector.php b/vendor/maximebf/debugbar/src/DebugBar/Bridge/DoctrineCollector.php
deleted file mode 100644
index 7c91da9..0000000
--- a/vendor/maximebf/debugbar/src/DebugBar/Bridge/DoctrineCollector.php
+++ /dev/null
@@ -1,115 +0,0 @@
-
- * $debugStack = new Doctrine\DBAL\Logging\DebugStack();
- * $entityManager->getConnection()->getConfiguration()->setSQLLogger($debugStack);
- * $debugbar->addCollector(new DoctrineCollector($debugStack));
- * 
- */
-class DoctrineCollector extends DataCollector implements Renderable, AssetProvider
-{
-    protected $debugStack;
-
-    /**
-     * DoctrineCollector constructor.
-     * @param $debugStackOrEntityManager
-     * @throws DebugBarException
-     */
-    public function __construct($debugStackOrEntityManager)
-    {
-        if ($debugStackOrEntityManager instanceof EntityManager) {
-            $debugStackOrEntityManager = $debugStackOrEntityManager->getConnection()->getConfiguration()->getSQLLogger();
-        }
-        if (!($debugStackOrEntityManager instanceof DebugStack)) {
-            throw new DebugBarException("'DoctrineCollector' requires an 'EntityManager' or 'DebugStack' object");
-        }
-        $this->debugStack = $debugStackOrEntityManager;
-    }
-
-    /**
-     * @return array
-     */
-    public function collect()
-    {
-        $queries = array();
-        $totalExecTime = 0;
-        foreach ($this->debugStack->queries as $q) {
-            $queries[] = array(
-                'sql' => $q['sql'],
-                'params' => (object) $q['params'],
-                'duration' => $q['executionMS'],
-                'duration_str' => $this->formatDuration($q['executionMS'])
-            );
-            $totalExecTime += $q['executionMS'];
-        }
-
-        return array(
-            'nb_statements' => count($queries),
-            'accumulated_duration' => $totalExecTime,
-            'accumulated_duration_str' => $this->formatDuration($totalExecTime),
-            'statements' => $queries
-        );
-    }
-
-    /**
-     * @return string
-     */
-    public function getName()
-    {
-        return 'doctrine';
-    }
-
-    /**
-     * @return array
-     */
-    public function getWidgets()
-    {
-        return array(
-            "database" => array(
-                "icon" => "arrow-right",
-                "widget" => "PhpDebugBar.Widgets.SQLQueriesWidget",
-                "map" => "doctrine",
-                "default" => "[]"
-            ),
-            "database:badge" => array(
-                "map" => "doctrine.nb_statements",
-                "default" => 0
-            )
-        );
-    }
-
-    /**
-     * @return array
-     */
-    public function getAssets()
-    {
-        return array(
-            'css' => 'widgets/sqlqueries/widget.css',
-            'js' => 'widgets/sqlqueries/widget.js'
-        );
-    }
-}
diff --git a/vendor/maximebf/debugbar/src/DebugBar/Bridge/MonologCollector.php b/vendor/maximebf/debugbar/src/DebugBar/Bridge/MonologCollector.php
deleted file mode 100644
index 49eb37c..0000000
--- a/vendor/maximebf/debugbar/src/DebugBar/Bridge/MonologCollector.php
+++ /dev/null
@@ -1,118 +0,0 @@
-
- * $debugbar->addCollector(new MonologCollector($logger));
- * 
- */
-class MonologCollector extends AbstractProcessingHandler implements DataCollectorInterface, Renderable, MessagesAggregateInterface
-{
-    protected $name;
-
-    protected $records = array();
-
-    /**
-     * @param Logger $logger
-     * @param int $level
-     * @param boolean $bubble
-     * @param string $name
-     */
-    public function __construct(Logger $logger = null, $level = Logger::DEBUG, $bubble = true, $name = 'monolog')
-    {
-        parent::__construct($level, $bubble);
-        $this->name = $name;
-        if ($logger !== null) {
-            $this->addLogger($logger);
-        }
-    }
-
-    /**
-     * Adds logger which messages you want to log
-     *
-     * @param Logger $logger
-     */
-    public function addLogger(Logger $logger)
-    {
-        $logger->pushHandler($this);
-    }
-
-    /**
-     * @param array|\Monolog\LogRecord $record
-     */
-    protected function write($record): void
-    {
-        $this->records[] = array(
-            'message' => $record['formatted'],
-            'is_string' => true,
-            'label' => strtolower($record['level_name']),
-            'time' => $record['datetime']->format('U')
-        );
-    }
-
-    /**
-     * @return array
-     */
-    public function getMessages()
-    {
-        return $this->records;
-    }
-
-    /**
-     * @return array
-     */
-    public function collect()
-    {
-        return array(
-            'count' => count($this->records),
-            'records' => $this->records
-        );
-    }
-
-    /**
-     * @return string
-     */
-    public function getName()
-    {
-        return $this->name;
-    }
-
-    /**
-     * @return array
-     */
-    public function getWidgets()
-    {
-        $name = $this->getName();
-        return array(
-            $name => array(
-                "icon" => "suitcase",
-                "widget" => "PhpDebugBar.Widgets.MessagesWidget",
-                "map" => "$name.records",
-                "default" => "[]"
-            ),
-            "$name:badge" => array(
-                "map" => "$name.count",
-                "default" => "null"
-            )
-        );
-    }
-}
diff --git a/vendor/maximebf/debugbar/src/DebugBar/Bridge/NamespacedTwigProfileCollector.php b/vendor/maximebf/debugbar/src/DebugBar/Bridge/NamespacedTwigProfileCollector.php
deleted file mode 100644
index 02e7306..0000000
--- a/vendor/maximebf/debugbar/src/DebugBar/Bridge/NamespacedTwigProfileCollector.php
+++ /dev/null
@@ -1,204 +0,0 @@
-
- * $env = new \Twig\Environment($loader); // Or from a PSR11-container
- * $profile = new \Twig\Profiler\Profile();
- * $env->addExtension(new \Twig\Extension\ProfilerExtension($profile));
- * $debugbar->addCollector(new ModernTwigProfileCollector($profile, $env));
- * // or: $debugbar->addCollector(new ModernTwigProfileCollector($profile, $loader));
- * 
- */
-class NamespacedTwigProfileCollector extends DataCollector implements Renderable, AssetProvider
-{
-    /**
-     * @var Profile
-     */
-    private $profile;
-
-    /**
-     * @var LoaderInterface|Environment|null
-     */
-    private $loader;
-
-    /**
-     * @var int
-     */
-    private $templateCount;
-
-    /**
-     * @var int
-     */
-    private $blockCount;
-
-    /**
-     * @var int
-     */
-    private $macroCount;
-    /**
-     * @var array[] {
-     * @var string $name
-     * @var int $render_time
-     * @var string $render_time_str
-     * @var string $memory_str
-     * @var string $xdebug_link
-     * }
-     */
-    private $templates;
-
-    /**
-     * TwigProfileCollector constructor.
-     *
-     * @param Profile $profile
-     * @param LoaderInterface|Environment $loaderOrEnv
-     */
-    public function __construct(Profile $profile, $loaderOrEnv = null)
-    {
-        $this->profile = $profile;
-        if ($loaderOrEnv instanceof Environment) {
-            $loaderOrEnv = $loaderOrEnv->getLoader();
-        }
-        $this->loader = $loaderOrEnv;
-    }
-
-    /**
-     * Returns a hash where keys are control names and their values
-     * an array of options as defined in {@see \DebugBar\JavascriptRenderer::addControl()}
-     *
-     * @return array
-     */
-    public function getWidgets()
-    {
-        return [
-            'twig' => [
-                'icon' => 'leaf',
-                'widget' => 'PhpDebugBar.Widgets.TemplatesWidget',
-                'map' => 'twig',
-                'default' => json_encode(['templates' => []]),
-            ],
-            'twig:badge' => [
-                'map' => 'twig.badge',
-                'default' => 0,
-            ],
-        ];
-    }
-
-    /**
-     * @return array
-     */
-    public function getAssets()
-    {
-        return [
-            'css' => 'widgets/templates/widget.css',
-            'js' => 'widgets/templates/widget.js',
-        ];
-    }
-
-    /**
-     * Called by the DebugBar when data needs to be collected
-     *
-     * @return array Collected data
-     */
-    public function collect()
-    {
-        $this->templateCount = $this->blockCount = $this->macroCount = 0;
-        $this->templates = [];
-        $this->computeData($this->profile);
-
-        return [
-            'nb_templates' => $this->templateCount,
-            'nb_blocks' => $this->blockCount,
-            'nb_macros' => $this->macroCount,
-            'templates' => $this->templates,
-            'accumulated_render_time' => $this->profile->getDuration(),
-            'accumulated_render_time_str' => $this->getDataFormatter()->formatDuration($this->profile->getDuration()),
-            'memory_usage_str' => $this->getDataFormatter()->formatBytes($this->profile->getMemoryUsage()),
-            'callgraph' => $this->getHtmlCallGraph(),
-            'badge' => implode(
-                '/',
-                [
-                    $this->templateCount,
-                    $this->blockCount,
-                    $this->macroCount,
-                ]
-            ),
-        ];
-    }
-
-    /**
-     * Returns the unique name of the collector
-     *
-     * @return string
-     */
-    public function getName()
-    {
-        return 'twig';
-    }
-
-    public function getHtmlCallGraph()
-    {
-        $dumper = new HtmlDumper();
-        return $dumper->dump($this->profile);
-    }
-
-    /**
-     * Get an Xdebug Link to a file
-     *
-     * @return array {
-     * @var string url
-     * @var bool ajax
-     * }
-     */
-    public function getXdebugLink($template, $line = 1)
-    {
-        if (is_null($this->loader)) {
-            return null;
-        }
-        $file = $this->loader->getSourceContext($template)->getPath();
-
-        return parent::getXdebugLink($file, $line);
-    }
-
-    private function computeData(Profile $profile)
-    {
-        $this->templateCount += ($profile->isTemplate() ? 1 : 0);
-        $this->blockCount += ($profile->isBlock() ? 1 : 0);
-        $this->macroCount += ($profile->isMacro() ? 1 : 0);
-        if ($profile->isTemplate()) {
-            $this->templates[] = [
-                'name' => $profile->getName(),
-                'render_time' => $profile->getDuration(),
-                'render_time_str' => $this->getDataFormatter()->formatDuration($profile->getDuration()),
-                'memory_str' => $this->getDataFormatter()->formatBytes($profile->getMemoryUsage()),
-                'xdebug_link' => $this->getXdebugLink($profile->getTemplate()),
-            ];
-        }
-        foreach ($profile as $p) {
-            $this->computeData($p);
-        }
-    }
-}
diff --git a/vendor/maximebf/debugbar/src/DebugBar/Bridge/Propel2Collector.php b/vendor/maximebf/debugbar/src/DebugBar/Bridge/Propel2Collector.php
deleted file mode 100644
index 3df4dcc..0000000
--- a/vendor/maximebf/debugbar/src/DebugBar/Bridge/Propel2Collector.php
+++ /dev/null
@@ -1,307 +0,0 @@
-
- * $debugbar->addCollector(new \DebugBar\Bridge\Propel2Collector(\Propel\Runtime\Propel::getServiceContainer()->getReadConnection()));
- * 
- */
-class Propel2Collector extends DataCollector implements Renderable, AssetProvider
-{
-    /**
-     * @var null|TestHandler
-     */
-    protected $handler = null;
-
-    /**
-     * @var null|Logger
-     */
-    protected $logger = null;
-
-    /**
-     * @var array
-     */
-    protected $config = array();
-
-    /**
-     * @var array
-     */
-    protected $errors = array();
-
-    /**
-     * @var int
-     */
-    protected $queryCount = 0;
-
-    /**
-     * @param ConnectionInterface $connection Propel connection
-     */
-    public function __construct(
-        ConnectionInterface $connection,
-        array $logMethods = array(
-            'beginTransaction',
-            'commit',
-            'rollBack',
-            'forceRollBack',
-            'exec',
-            'query',
-            'execute'
-        )
-    ) {
-        if ($connection instanceof ProfilerConnectionWrapper) {
-            $connection->setLogMethods($logMethods);
-
-            $this->config = $connection->getProfiler()->getConfiguration();
-
-            $this->handler = new TestHandler();
-
-            if ($connection->getLogger() instanceof Logger) {
-                $this->logger = $connection->getLogger();
-                $this->logger->pushHandler($this->handler);
-            } else {
-                $this->errors[] = 'Supported only monolog logger';
-            }
-        } else {
-            $this->errors[] = 'You need set ProfilerConnectionWrapper';
-        }
-    }
-
-    /**
-     * @return TestHandler|null
-     */
-    public function getHandler()
-    {
-        return $this->handler;
-    }
-
-    /**
-     * @return array
-     */
-    public function getConfig()
-    {
-        return $this->config;
-    }
-
-    /**
-     * @return Logger|null
-     */
-    public function getLogger()
-    {
-        return $this->logger;
-    }
-
-    /**
-     * @return LoggerInterface
-     */
-    protected function getDefaultLogger()
-    {
-        return Propel::getServiceContainer()->getLogger();
-    }
-
-    /**
-     * @return int
-     */
-    protected function getQueryCount()
-    {
-        return $this->queryCount;
-    }
-
-    /**
-     * @param array $records
-     * @param array $config
-     * @return array
-     */
-    protected function getStatements($records, $config)
-    {
-        $statements = array();
-        foreach ($records as $record) {
-            $duration = null;
-            $memory = null;
-
-            $isSuccess = ( LogLevel::INFO === strtolower($record['level_name']) );
-
-            $detailsCount = count($config['details']);
-            $parameters = explode($config['outerGlue'], $record['message'], $detailsCount + 1);
-            if (count($parameters) === ($detailsCount + 1)) {
-                $parameters = array_map('trim', $parameters);
-                $_details = array();
-                foreach (array_splice($parameters, 0, $detailsCount) as $string) {
-                    list($key, $value) = array_map('trim', explode($config['innerGlue'], $string, 2));
-                    $_details[$key] = $value;
-                }
-
-                $details = array();
-                foreach ($config['details'] as $key => $detail) {
-                    if (isset($_details[$detail['name']])) {
-                        $value = $_details[$detail['name']];
-                        if ('time' === $key) {
-                            if (substr_count($value, 'ms')) {
-                                $value = (float)$value / 1000;
-                            } else {
-                                $value = (float)$value;
-                            }
-                        } else {
-                            $suffixes = array('B', 'kB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB');
-                            $suffix = substr($value, -2);
-                            $i = array_search($suffix, $suffixes, true);
-                            $i = (false === $i) ? 0 : $i;
-
-                            $value = ((float)$value) * pow(1024, $i);
-                        }
-                        $details[$key] = $value;
-                    }
-                }
-
-                if (isset($details['time'])) {
-                    $duration = $details['time'];
-                }
-                if (isset($details['memDelta'])) {
-                    $memory = $details['memDelta'];
-                }
-
-                $message = end($parameters);
-
-                if ($isSuccess) {
-                    $this->queryCount++;
-                }
-
-            } else {
-                $message = $record['message'];
-            }
-
-            $statement = array(
-                'sql' => $message,
-                'is_success' => $isSuccess,
-                'duration' => $duration,
-                'duration_str' => $this->getDataFormatter()->formatDuration($duration),
-                'memory' => $memory,
-                'memory_str' => $this->getDataFormatter()->formatBytes($memory),
-            );
-
-            if (false === $isSuccess) {
-                $statement['sql'] = '';
-                $statement['error_code'] = $record['level'];
-                $statement['error_message'] = $message;
-            }
-
-            $statements[] = $statement;
-        }
-        return $statements;
-    }
-
-    /**
-     * @return array
-     */
-    public function collect()
-    {
-        if (count($this->errors)) {
-            return array(
-                'statements' => array_map(function ($message) {
-                    return array('sql' => '', 'is_success' => false, 'error_code' => 500, 'error_message' => $message);
-                }, $this->errors),
-                'nb_statements' => 0,
-                'nb_failed_statements' => count($this->errors),
-            );
-        }
-
-        if ($this->getHandler() === null) {
-            return array();
-        }
-
-        $statements = $this->getStatements($this->getHandler()->getRecords(), $this->getConfig());
-
-        $failedStatement = count(array_filter($statements, function ($statement) {
-            return false === $statement['is_success'];
-        }));
-        $accumulatedDuration = array_reduce($statements, function ($accumulatedDuration, $statement) {
-        
-            $time = isset($statement['duration']) ? $statement['duration'] : 0;
-            return $accumulatedDuration += $time;
-        });
-        $memoryUsage = array_reduce($statements, function ($memoryUsage, $statement) {
-        
-            $time = isset($statement['memory']) ? $statement['memory'] : 0;
-            return $memoryUsage += $time;
-        });
-
-        return array(
-            'nb_statements' => $this->getQueryCount(),
-            'nb_failed_statements' => $failedStatement,
-            'accumulated_duration' => $accumulatedDuration,
-            'accumulated_duration_str' => $this->getDataFormatter()->formatDuration($accumulatedDuration),
-            'memory_usage' => $memoryUsage,
-            'memory_usage_str' => $this->getDataFormatter()->formatBytes($memoryUsage),
-            'statements' => $statements
-        );
-    }
-
-    /**
-     * @return string
-     */
-    public function getName()
-    {
-        $additionalName  = '';
-        if ($this->getLogger() !== $this->getDefaultLogger()) {
-            $additionalName = ' ('.$this->getLogger()->getName().')';
-        }
-
-        return 'propel2'.$additionalName;
-    }
-
-    /**
-     * @return array
-     */
-    public function getWidgets()
-    {
-        return array(
-            $this->getName() => array(
-                'icon' => 'bolt',
-                'widget' => 'PhpDebugBar.Widgets.SQLQueriesWidget',
-                'map' => $this->getName(),
-                'default' => '[]'
-            ),
-            $this->getName().':badge' => array(
-                'map' => $this->getName().'.nb_statements',
-                'default' => 0
-            ),
-        );
-    }
-
-    /**
-     * @return array
-     */
-    public function getAssets()
-    {
-        return array(
-            'css' => 'widgets/sqlqueries/widget.css',
-            'js' => 'widgets/sqlqueries/widget.js'
-        );
-    }
-}
diff --git a/vendor/maximebf/debugbar/src/DebugBar/Bridge/PropelCollector.php b/vendor/maximebf/debugbar/src/DebugBar/Bridge/PropelCollector.php
deleted file mode 100644
index 93ad4ff..0000000
--- a/vendor/maximebf/debugbar/src/DebugBar/Bridge/PropelCollector.php
+++ /dev/null
@@ -1,253 +0,0 @@
-
- * $debugbar->addCollector(new PropelCollector($debugbar['messages']));
- * PropelCollector::enablePropelProfiling();
- * 
- */
-class PropelCollector extends DataCollector implements BasicLogger, Renderable, AssetProvider
-{
-    protected $logger;
-
-    protected $statements = array();
-
-    protected $accumulatedTime = 0;
-
-    protected $peakMemory = 0;
-
-    /**
-     * Sets the needed configuration option in propel to enable query logging
-     *
-     * @param PropelConfiguration $config Apply profiling on a specific config
-     */
-    public static function enablePropelProfiling(PropelConfiguration $config = null)
-    {
-        if ($config === null) {
-            $config = Propel::getConfiguration(PropelConfiguration::TYPE_OBJECT);
-        }
-        $config->setParameter('debugpdo.logging.details.method.enabled', true);
-        $config->setParameter('debugpdo.logging.details.time.enabled', true);
-        $config->setParameter('debugpdo.logging.details.mem.enabled', true);
-        $allMethods = array(
-            'PropelPDO::__construct',       // logs connection opening
-            'PropelPDO::__destruct',        // logs connection close
-            'PropelPDO::exec',              // logs a query
-            'PropelPDO::query',             // logs a query
-            'PropelPDO::beginTransaction',  // logs a transaction begin
-            'PropelPDO::commit',            // logs a transaction commit
-            'PropelPDO::rollBack',          // logs a transaction rollBack (watch out for the capital 'B')
-            'DebugPDOStatement::execute',   // logs a query from a prepared statement
-        );
-        $config->setParameter('debugpdo.logging.methods', $allMethods, false);
-    }
-
-    /**
-     * @param LoggerInterface $logger A logger to forward non-query log lines to
-     * @param PropelPDO $conn Bound this collector to a connection only
-     */
-    public function __construct(LoggerInterface $logger = null, PropelPDO $conn = null)
-    {
-        if ($conn) {
-            $conn->setLogger($this);
-        } else {
-            Propel::setLogger($this);
-        }
-        $this->logger = $logger;
-        $this->logQueriesToLogger = false;
-    }
-
-    public function setLogQueriesToLogger($enable = true)
-    {
-        $this->logQueriesToLogger = $enable;
-        return $this;
-    }
-
-    public function isLogQueriesToLogger()
-    {
-        return $this->logQueriesToLogger;
-    }
-
-    public function emergency($m)
-    {
-        $this->log($m, Propel::LOG_EMERG);
-    }
-
-    public function alert($m)
-    {
-        $this->log($m, Propel::LOG_ALERT);
-    }
-
-    public function crit($m)
-    {
-        $this->log($m, Propel::LOG_CRIT);
-    }
-
-    public function err($m)
-    {
-        $this->log($m, Propel::LOG_ERR);
-    }
-
-    public function warning($m)
-    {
-        $this->log($m, Propel::LOG_WARNING);
-    }
-
-    public function notice($m)
-    {
-        $this->log($m, Propel::LOG_NOTICE);
-    }
-
-    public function info($m)
-    {
-        $this->log($m, Propel::LOG_INFO);
-    }
-
-    public function debug($m)
-    {
-        $this->log($m, Propel::LOG_DEBUG);
-    }
-
-    public function log($message, $severity = null)
-    {
-        if (strpos($message, 'DebugPDOStatement::execute') !== false) {
-            list($sql, $duration_str) = $this->parseAndLogSqlQuery($message);
-            if (!$this->logQueriesToLogger) {
-                return;
-            }
-            $message = "$sql ($duration_str)";
-        }
-
-        if ($this->logger !== null) {
-            $this->logger->log($this->convertLogLevel($severity), $message);
-        }
-    }
-
-    /**
-     * Converts Propel log levels to PSR log levels
-     *
-     * @param int $level
-     * @return string
-     */
-    protected function convertLogLevel($level)
-    {
-        $map = array(
-            Propel::LOG_EMERG => LogLevel::EMERGENCY,
-            Propel::LOG_ALERT => LogLevel::ALERT,
-            Propel::LOG_CRIT => LogLevel::CRITICAL,
-            Propel::LOG_ERR => LogLevel::ERROR,
-            Propel::LOG_WARNING => LogLevel::WARNING,
-            Propel::LOG_NOTICE => LogLevel::NOTICE,
-            Propel::LOG_DEBUG => LogLevel::DEBUG
-        );
-        return $map[$level];
-    }
-
-    /**
-     * Parse a log line to extract query information
-     *
-     * @param string $message
-     */
-    protected function parseAndLogSqlQuery($message)
-    {
-        $parts = explode('|', $message, 4);
-        $sql = trim($parts[3]);
-
-        $duration = 0;
-        if (preg_match('/([0-9]+\.[0-9]+)/', $parts[1], $matches)) {
-            $duration = (float) $matches[1];
-        }
-
-        $memory = 0;
-        if (preg_match('/([0-9]+\.[0-9]+) ([A-Z]{1,2})/', $parts[2], $matches)) {
-            $memory = (float) $matches[1];
-            if ($matches[2] == 'KB') {
-                $memory *= 1024;
-            } elseif ($matches[2] == 'MB') {
-                $memory *= 1024 * 1024;
-            }
-        }
-
-        $this->statements[] = array(
-            'sql' => $sql,
-            'is_success' => true,
-            'duration' => $duration,
-            'duration_str' => $this->formatDuration($duration),
-            'memory' => $memory,
-            'memory_str' => $this->formatBytes($memory)
-        );
-        $this->accumulatedTime += $duration;
-        $this->peakMemory = max($this->peakMemory, $memory);
-        return array($sql, $this->formatDuration($duration));
-    }
-
-    public function collect()
-    {
-        return array(
-            'nb_statements' => count($this->statements),
-            'nb_failed_statements' => 0,
-            'accumulated_duration' => $this->accumulatedTime,
-            'accumulated_duration_str' => $this->formatDuration($this->accumulatedTime),
-            'peak_memory_usage' => $this->peakMemory,
-            'peak_memory_usage_str' => $this->formatBytes($this->peakMemory),
-            'statements' => $this->statements
-        );
-    }
-
-    public function getName()
-    {
-        return 'propel';
-    }
-
-    public function getWidgets()
-    {
-        return array(
-            "propel" => array(
-                "icon" => "bolt",
-                "widget" => "PhpDebugBar.Widgets.SQLQueriesWidget",
-                "map" => "propel",
-                "default" => "[]"
-            ),
-            "propel:badge" => array(
-                "map" => "propel.nb_statements",
-                "default" => 0
-            )
-        );
-    }
-
-    public function getAssets()
-    {
-        return array(
-            'css' => 'widgets/sqlqueries/widget.css',
-            'js' => 'widgets/sqlqueries/widget.js'
-        );
-    }
-}
diff --git a/vendor/maximebf/debugbar/src/DebugBar/Bridge/SlimCollector.php b/vendor/maximebf/debugbar/src/DebugBar/Bridge/SlimCollector.php
deleted file mode 100644
index 030a3ba..0000000
--- a/vendor/maximebf/debugbar/src/DebugBar/Bridge/SlimCollector.php
+++ /dev/null
@@ -1,66 +0,0 @@
-slim = $slim;
-        if ($log = $slim->getLog()) {
-            $this->originalLogWriter = $log->getWriter();
-            $log->setWriter($this);
-            $log->setEnabled(true);
-        }
-    }
-
-    public function write($message, $level)
-    {
-        if ($this->originalLogWriter) {
-            $this->originalLogWriter->write($message, $level);
-        }
-        $this->addMessage($message, $this->getLevelName($level));
-    }
-
-    protected function getLevelName($level)
-    {
-        $map = array(
-            Log::EMERGENCY => LogLevel::EMERGENCY,
-            Log::ALERT => LogLevel::ALERT,
-            Log::CRITICAL => LogLevel::CRITICAL,
-            Log::ERROR => LogLevel::ERROR,
-            Log::WARN => LogLevel::WARNING,
-            Log::NOTICE => LogLevel::NOTICE,
-            Log::INFO => LogLevel::INFO,
-            Log::DEBUG => LogLevel::DEBUG
-        );
-        return $map[$level];
-    }
-
-    public function getName()
-    {
-        return 'slim';
-    }
-}
diff --git a/vendor/maximebf/debugbar/src/DebugBar/Bridge/SwiftMailer/SwiftLogCollector.php b/vendor/maximebf/debugbar/src/DebugBar/Bridge/SwiftMailer/SwiftLogCollector.php
deleted file mode 100644
index e8c2fcd..0000000
--- a/vendor/maximebf/debugbar/src/DebugBar/Bridge/SwiftMailer/SwiftLogCollector.php
+++ /dev/null
@@ -1,53 +0,0 @@
-registerPlugin(new Swift_Plugins_LoggerPlugin($this));
-    }
-
-    public function add($entry)
-    {
-        $this->addMessage($entry);
-    }
-
-    public function dump()
-    {
-        $dump = '';
-        foreach ($this->messages as $message) {
-            if (!$message['is_string']) {
-                continue;
-            }
-
-            $dump .= $message['message'] . PHP_EOL;
-        }
-
-        return $dump;
-    }
-
-    public function getName()
-    {
-        return 'swiftmailer_logs';
-    }
-}
diff --git a/vendor/maximebf/debugbar/src/DebugBar/Bridge/SwiftMailer/SwiftMailCollector.php b/vendor/maximebf/debugbar/src/DebugBar/Bridge/SwiftMailer/SwiftMailCollector.php
deleted file mode 100644
index 01a5e90..0000000
--- a/vendor/maximebf/debugbar/src/DebugBar/Bridge/SwiftMailer/SwiftMailCollector.php
+++ /dev/null
@@ -1,92 +0,0 @@
-messagesLogger = new Swift_Plugins_MessageLogger();
-        $mailer->registerPlugin($this->messagesLogger);
-    }
-
-    public function collect()
-    {
-        $mails = array();
-        foreach ($this->messagesLogger->getMessages() as $msg) {
-            $mails[] = array(
-                'to' => $this->formatTo($msg->getTo()),
-                'subject' => $msg->getSubject(),
-                'headers' => $msg->getHeaders()->toString()
-            );
-        }
-        return array(
-            'count' => count($mails),
-            'mails' => $mails
-        );
-    }
-
-    protected function formatTo($to)
-    {
-        if (!$to) {
-            return '';
-        }
-
-        $f = array();
-        foreach ($to as $k => $v) {
-            $f[] = (empty($v) ? '' : "$v ") . "<$k>";
-        }
-        return implode(', ', $f);
-    }
-
-    public function getName()
-    {
-        return 'swiftmailer_mails';
-    }
-
-    public function getWidgets()
-    {
-        return array(
-            'emails' => array(
-                'icon' => 'inbox',
-                'widget' => 'PhpDebugBar.Widgets.MailsWidget',
-                'map' => 'swiftmailer_mails.mails',
-                'default' => '[]',
-                'title' => 'Mails'
-            ),
-            'emails:badge' => array(
-                'map' => 'swiftmailer_mails.count',
-                'default' => 'null'
-            )
-        );
-    }
-
-    public function getAssets()
-    {
-        return array(
-            'css' => 'widgets/mails/widget.css',
-            'js' => 'widgets/mails/widget.js'
-        );
-    }
-}
diff --git a/vendor/maximebf/debugbar/src/DebugBar/Bridge/Symfony/SymfonyMailCollector.php b/vendor/maximebf/debugbar/src/DebugBar/Bridge/Symfony/SymfonyMailCollector.php
deleted file mode 100644
index 7095e8d..0000000
--- a/vendor/maximebf/debugbar/src/DebugBar/Bridge/Symfony/SymfonyMailCollector.php
+++ /dev/null
@@ -1,84 +0,0 @@
-messages[] = $message->getOriginalMessage();
-    }
-
-    public function showMessageDetail()
-    {
-        $this->showDetailed = true;
-    }
-
-    public function collect()
-    {
-        $mails = array();
-
-        foreach ($this->messages as $message) {
-            /* @var \Symfony\Component\Mime\Message $message */
-            $mails[] = array(
-                'to' => array_map(function ($address) {
-                    /* @var \Symfony\Component\Mime\Address $address */
-                    return $address->toString();
-                }, $message->getTo()),
-                'subject' => $message->getSubject(),
-                'headers' => ($this->showDetailed ? $message : $message->getHeaders())->toString(),
-            );;
-        }
-
-        return array(
-            'count' => count($mails),
-            'mails' => $mails,
-        );
-    }
-
-    public function getName()
-    {
-        return 'symfonymailer_mails';
-    }
-
-    public function getWidgets()
-    {
-        return array(
-            'emails' => array(
-                'icon' => 'inbox',
-                'widget' => 'PhpDebugBar.Widgets.MailsWidget',
-                'map' => 'symfonymailer_mails.mails',
-                'default' => '[]',
-                'title' => 'Mails'
-            ),
-            'emails:badge' => array(
-                'map' => 'symfonymailer_mails.count',
-                'default' => 'null'
-            )
-        );
-    }
-
-    public function getAssets()
-    {
-        return array(
-            'css' => 'widgets/mails/widget.css',
-            'js' => 'widgets/mails/widget.js'
-        );
-    }
-}
diff --git a/vendor/maximebf/debugbar/src/DebugBar/Bridge/Twig/TimeableTwigExtensionProfiler.php b/vendor/maximebf/debugbar/src/DebugBar/Bridge/Twig/TimeableTwigExtensionProfiler.php
deleted file mode 100644
index 30238cc..0000000
--- a/vendor/maximebf/debugbar/src/DebugBar/Bridge/Twig/TimeableTwigExtensionProfiler.php
+++ /dev/null
@@ -1,60 +0,0 @@
-timeDataCollector = $timeDataCollector;
-    }
-
-    public function __construct(\Twig_Profiler_Profile $profile, TimeDataCollector $timeDataCollector = null)
-    {
-        parent::__construct($profile);
-
-        $this->timeDataCollector = $timeDataCollector;
-    }
-
-    public function enter(Twig_Profiler_Profile $profile)
-    {
-        if ($this->timeDataCollector && $profile->isTemplate()) {
-            $this->timeDataCollector->startMeasure($profile->getName(), 'template ' . $profile->getName());
-        }
-        parent::enter($profile);
-    }
-
-    public function leave(Twig_Profiler_Profile $profile)
-    {
-        parent::leave($profile);
-        if ($this->timeDataCollector && $profile->isTemplate()) {
-            $this->timeDataCollector->stopMeasure($profile->getName());
-        }
-    }
-}
diff --git a/vendor/maximebf/debugbar/src/DebugBar/Bridge/Twig/TraceableTwigEnvironment.php b/vendor/maximebf/debugbar/src/DebugBar/Bridge/Twig/TraceableTwigEnvironment.php
deleted file mode 100644
index 9e98c19..0000000
--- a/vendor/maximebf/debugbar/src/DebugBar/Bridge/Twig/TraceableTwigEnvironment.php
+++ /dev/null
@@ -1,419 +0,0 @@
-twig = $twig;
-        $this->timeDataCollector = $timeDataCollector;
-    }
-
-    public function __call($name, $arguments)
-    {
-        return call_user_func_array(array($this->twig, $name), $arguments);
-    }
-
-    public function getRenderedTemplates()
-    {
-        return $this->renderedTemplates;
-    }
-
-    public function addRenderedTemplate(array $info)
-    {
-        $this->renderedTemplates[] = $info;
-    }
-
-    public function getTimeDataCollector()
-    {
-        return $this->timeDataCollector;
-    }
-
-    public function getBaseTemplateClass()
-    {
-        return $this->twig->getBaseTemplateClass();
-    }
-
-    public function setBaseTemplateClass($class)
-    {
-        $this->twig->setBaseTemplateClass($class);
-    }
-
-    public function enableDebug()
-    {
-        $this->twig->enableDebug();
-    }
-
-    public function disableDebug()
-    {
-        $this->twig->disableDebug();
-    }
-
-    public function isDebug()
-    {
-        return $this->twig->isDebug();
-    }
-
-    public function enableAutoReload()
-    {
-        $this->twig->enableAutoReload();
-    }
-
-    public function disableAutoReload()
-    {
-        $this->twig->disableAutoReload();
-    }
-
-    public function isAutoReload()
-    {
-        return $this->twig->isAutoReload();
-    }
-
-    public function enableStrictVariables()
-    {
-        $this->twig->enableStrictVariables();
-    }
-
-    public function disableStrictVariables()
-    {
-        $this->twig->disableStrictVariables();
-    }
-
-    public function isStrictVariables()
-    {
-        return $this->twig->isStrictVariables();
-    }
-
-    public function getCache($original = true)
-    {
-        return $this->twig->getCache($original);
-    }
-
-    public function setCache($cache)
-    {
-        $this->twig->setCache($cache);
-    }
-
-    public function getCacheFilename($name)
-    {
-        return $this->twig->getCacheFilename($name);
-    }
-
-    public function getTemplateClass($name, $index = null)
-    {
-        return $this->twig->getTemplateClass($name, $index);
-    }
-
-    public function getTemplateClassPrefix()
-    {
-        return $this->twig->getTemplateClassPrefix();
-    }
-
-    public function render($name, array $context = array())
-    {
-        return $this->loadTemplate($name)->render($context);
-    }
-
-    public function display($name, array $context = array())
-    {
-        $this->loadTemplate($name)->display($context);
-    }
-
-    public function loadTemplate($name, $index = null)
-    {
-        $cls = $this->twig->getTemplateClass($name, $index);
-
-        if (isset($this->twig->loadedTemplates[$cls])) {
-            return $this->twig->loadedTemplates[$cls];
-        }
-
-        if (!class_exists($cls, false)) {
-            if (false === $cache = $this->getCacheFilename($name)) {
-                eval('?>'.$this->compileSource($this->getLoader()->getSource($name), $name));
-            } else {
-                if (!is_file($cache) || ($this->isAutoReload() && !$this->isTemplateFresh($name, filemtime($cache)))) {
-                    $this->writeCacheFile($cache, $this->compileSource($this->getLoader()->getSource($name), $name));
-                }
-
-                require_once $cache;
-            }
-        }
-
-        if (!$this->twig->runtimeInitialized) {
-            $this->initRuntime();
-        }
-
-        return $this->twig->loadedTemplates[$cls] = new TraceableTwigTemplate($this, new $cls($this));
-    }
-
-    public function isTemplateFresh($name, $time)
-    {
-        return $this->twig->isTemplateFresh($name, $time);
-    }
-
-    public function resolveTemplate($names)
-    {
-        return $this->twig->resolveTemplate($names);
-    }
-
-    public function clearTemplateCache()
-    {
-        $this->twig->clearTemplateCache();
-    }
-
-    public function clearCacheFiles()
-    {
-        $this->twig->clearCacheFiles();
-    }
-
-    public function getLexer()
-    {
-        return $this->twig->getLexer();
-    }
-
-    public function setLexer(Twig_LexerInterface $lexer)
-    {
-        $this->twig->setLexer($lexer);
-    }
-
-    public function tokenize($source, $name = null)
-    {
-        return $this->twig->tokenize($source, $name);
-    }
-
-    public function getParser()
-    {
-        return $this->twig->getParser();
-    }
-
-    public function setParser(Twig_ParserInterface $parser)
-    {
-        $this->twig->setParser($parser);
-    }
-
-    public function parse(Twig_TokenStream $tokens)
-    {
-        return $this->twig->parse($tokens);
-    }
-
-    public function getCompiler()
-    {
-        return $this->twig->getCompiler();
-    }
-
-    public function setCompiler(Twig_CompilerInterface $compiler)
-    {
-        $this->twig->setCompiler($compiler);
-    }
-
-    public function compile(Twig_NodeInterface $node)
-    {
-        return $this->twig->compile($node);
-    }
-
-    public function compileSource($source, $name = null)
-    {
-        return $this->twig->compileSource($source, $name);
-    }
-
-    public function setLoader(Twig_LoaderInterface $loader)
-    {
-        $this->twig->setLoader($loader);
-    }
-
-    public function getLoader()
-    {
-        return $this->twig->getLoader();
-    }
-
-    public function setCharset($charset)
-    {
-        $this->twig->setCharset($charset);
-    }
-
-    public function getCharset()
-    {
-        return $this->twig->getCharset();
-    }
-
-    public function initRuntime()
-    {
-        $this->twig->initRuntime();
-    }
-
-    public function hasExtension($name)
-    {
-        return $this->twig->hasExtension($name);
-    }
-
-    public function getExtension($name)
-    {
-        return $this->twig->getExtension($name);
-    }
-
-    public function addExtension(Twig_ExtensionInterface $extension)
-    {
-        $this->twig->addExtension($extension);
-    }
-
-    public function removeExtension($name)
-    {
-        $this->twig->removeExtension($name);
-    }
-
-    public function setExtensions(array $extensions)
-    {
-        $this->twig->setExtensions($extensions);
-    }
-
-    public function getExtensions()
-    {
-        return $this->twig->getExtensions();
-    }
-
-    public function addTokenParser(Twig_TokenParserInterface $parser)
-    {
-        $this->twig->addTokenParser($parser);
-    }
-
-    public function getTokenParsers()
-    {
-        return $this->twig->getTokenParsers();
-    }
-
-    public function getTags()
-    {
-        return $this->twig->getTags();
-    }
-
-    public function addNodeVisitor(Twig_NodeVisitorInterface $visitor)
-    {
-        $this->twig->addNodeVisitor($visitor);
-    }
-
-    public function getNodeVisitors()
-    {
-        return $this->twig->getNodeVisitors();
-    }
-
-    public function addFilter($name, $filter = null)
-    {
-        $this->twig->addFilter($name, $filter);
-    }
-
-    public function getFilter($name)
-    {
-        return $this->twig->getFilter($name);
-    }
-
-    public function registerUndefinedFilterCallback($callable)
-    {
-        $this->twig->registerUndefinedFilterCallback($callable);
-    }
-
-    public function getFilters()
-    {
-        return $this->twig->getFilters();
-    }
-
-    public function addTest($name, $test = null)
-    {
-        $this->twig->addTest($name, $test);
-    }
-
-    public function getTests()
-    {
-        return $this->twig->getTests();
-    }
-
-    public function getTest($name)
-    {
-        return $this->twig->getTest($name);
-    }
-
-    public function addFunction($name, $function = null)
-    {
-        $this->twig->addFunction($name, $function);
-    }
-
-    public function getFunction($name)
-    {
-        return $this->twig->getFunction($name);
-    }
-
-    public function registerUndefinedFunctionCallback($callable)
-    {
-        $this->twig->registerUndefinedFunctionCallback($callable);
-    }
-
-    public function getFunctions()
-    {
-        return $this->twig->getFunctions();
-    }
-
-    public function addGlobal($name, $value)
-    {
-        $this->twig->addGlobal($name, $value);
-    }
-
-    public function getGlobals()
-    {
-        return $this->twig->getGlobals();
-    }
-
-    public function mergeGlobals(array $context)
-    {
-        return $this->twig->mergeGlobals($context);
-    }
-
-    public function getUnaryOperators()
-    {
-        return $this->twig->getUnaryOperators();
-    }
-
-    public function getBinaryOperators()
-    {
-        return $this->twig->getBinaryOperators();
-    }
-
-    public function computeAlternatives($name, $items)
-    {
-        return $this->twig->computeAlternatives($name, $items);
-    }
-}
diff --git a/vendor/maximebf/debugbar/src/DebugBar/Bridge/Twig/TraceableTwigTemplate.php b/vendor/maximebf/debugbar/src/DebugBar/Bridge/Twig/TraceableTwigTemplate.php
deleted file mode 100644
index 1d57d2a..0000000
--- a/vendor/maximebf/debugbar/src/DebugBar/Bridge/Twig/TraceableTwigTemplate.php
+++ /dev/null
@@ -1,138 +0,0 @@
-env = $env;
-        $this->template = $template;
-    }
-
-    public function __call($name, $arguments)
-    {
-        return call_user_func_array(array($this->template, $name), $arguments);
-    }
-
-    public function doDisplay(array $context, array $blocks = array())
-    {
-        return $this->template->doDisplay($context, $blocks);
-    }
-
-    public function getTemplateName()
-    {
-        return $this->template->getTemplateName();
-    }
-
-    public function getEnvironment()
-    {
-        return $this->template->getEnvironment();
-    }
-
-    public function getParent(array $context)
-    {
-        return $this->template->getParent($context);
-    }
-
-    public function isTraitable()
-    {
-        return $this->template->isTraitable();
-    }
-
-    public function displayParentBlock($name, array $context, array $blocks = array())
-    {
-        $this->template->displayParentBlock($name, $context, $blocks);
-    }
-
-    public function displayBlock($name, array $context, array $blocks = array(), $useBlocks = true)
-    {
-        $this->template->displayBlock($name, $context, $blocks, $useBlocks);
-    }
-
-    public function renderParentBlock($name, array $context, array $blocks = array())
-    {
-        return $this->template->renderParentBlock($name, $context, $blocks);
-    }
-
-    public function renderBlock($name, array $context, array $blocks = array(), $useBlocks = true)
-    {
-        return $this->template->renderBlock($name, $context, $blocks, $useBlocks);
-    }
-
-    public function hasBlock($name)
-    {
-        return $this->template->hasBlock($name);
-    }
-
-    public function getBlockNames()
-    {
-        return $this->template->getBlockNames();
-    }
-
-    public function getBlocks()
-    {
-        return $this->template->getBlocks();
-    }
-
-    public function display(array $context, array $blocks = array())
-    {
-        $start = microtime(true);
-        $this->template->display($context, $blocks);
-        $end = microtime(true);
-
-        if ($timeDataCollector = $this->env->getTimeDataCollector()) {
-            $name = sprintf("twig.render(%s)", $this->template->getTemplateName());
-            $timeDataCollector->addMeasure($name, $start, $end);
-        }
-
-        $this->env->addRenderedTemplate(array(
-            'name' => $this->template->getTemplateName(),
-            'render_time' => $end - $start
-        ));
-    }
-
-    public function render(array $context)
-    {
-        $level = ob_get_level();
-        ob_start();
-        try {
-            $this->display($context);
-        } catch (Exception $e) {
-            while (ob_get_level() > $level) {
-                ob_end_clean();
-            }
-
-            throw $e;
-        }
-
-        return ob_get_clean();
-    }
-
-    public static function clearCache()
-    {
-        Twig_Template::clearCache();
-    }
-}
diff --git a/vendor/maximebf/debugbar/src/DebugBar/Bridge/Twig/TwigCollector.php b/vendor/maximebf/debugbar/src/DebugBar/Bridge/Twig/TwigCollector.php
deleted file mode 100644
index bb48ab7..0000000
--- a/vendor/maximebf/debugbar/src/DebugBar/Bridge/Twig/TwigCollector.php
+++ /dev/null
@@ -1,89 +0,0 @@
-
- * $env = new TraceableTwigEnvironment(new Twig_Environment($loader));
- * $debugbar->addCollector(new TwigCollector($env));
- * 
- * 
- * @deprecated use DebugBar\Bridge\TwigProfileCollector instead
- */
-class TwigCollector extends DataCollector implements Renderable, AssetProvider
-{
-    public function __construct(TraceableTwigEnvironment $twig)
-    {
-        $this->twig = $twig;
-    }
-
-    public function collect()
-    {
-        $templates = array();
-        $accuRenderTime = 0;
-
-        foreach ($this->twig->getRenderedTemplates() as $tpl) {
-            $accuRenderTime += $tpl['render_time'];
-            $templates[] = array(
-                'name' => $tpl['name'],
-                'render_time' => $tpl['render_time'],
-                'render_time_str' => $this->formatDuration($tpl['render_time'])
-            );
-        }
-
-        return array(
-            'nb_templates' => count($templates),
-            'templates' => $templates,
-            'accumulated_render_time' => $accuRenderTime,
-            'accumulated_render_time_str' => $this->formatDuration($accuRenderTime)
-        );
-    }
-
-    public function getName()
-    {
-        return 'twig';
-    }
-
-    public function getWidgets()
-    {
-        return array(
-            'twig' => array(
-                'icon' => 'leaf',
-                'widget' => 'PhpDebugBar.Widgets.TemplatesWidget',
-                'map' => 'twig',
-                'default' => json_encode(array('templates' => array())),
-            ),
-            'twig:badge' => array(
-                'map' => 'twig.nb_templates',
-                'default' => 0
-            )
-        );
-    }
-
-    public function getAssets()
-    {
-        return array(
-            'css' => 'widgets/templates/widget.css',
-            'js' => 'widgets/templates/widget.js'
-        );
-    }
-}
diff --git a/vendor/maximebf/debugbar/src/DebugBar/Bridge/TwigProfileCollector.php b/vendor/maximebf/debugbar/src/DebugBar/Bridge/TwigProfileCollector.php
deleted file mode 100644
index ce68fcb..0000000
--- a/vendor/maximebf/debugbar/src/DebugBar/Bridge/TwigProfileCollector.php
+++ /dev/null
@@ -1,199 +0,0 @@
-
- * $env = new Twig_Environment($loader); // Or from a PSR11-container
- * $profile = new Twig_Profiler_Profile();
- * $env->addExtension(new Twig_Extension_Profile($profile));
- * $debugbar->addCollector(new TwigProfileCollector($profile, $env));
- * // or: $debugbar->addCollector(new TwigProfileCollector($profile, $loader));
- * 
- *
- * @deprecated Use `\Debugbar\Bridge\NamespacedTwigProfileCollector` instead for Twig 2.x and 3.x
- */
-class TwigProfileCollector extends DataCollector implements Renderable, AssetProvider
-{
-    /**
-     * @var \Twig_Profiler_Profile
-     */
-    private $profile;
-    /**
-     * @var \Twig_LoaderInterface
-     */
-    private $loader;
-    /** @var int */
-    private $templateCount;
-    /** @var int */
-    private $blockCount;
-    /** @var int */
-    private $macroCount;
-    /**
-     * @var array[] {
-     * @var string $name
-     * @var int    $render_time
-     * @var string $render_time_str
-     * @var string $memory_str
-     * @var string $xdebug_link
-     * }
-     */
-    private $templates;
-
-    /**
-     * TwigProfileCollector constructor.
-     *
-     * @param \Twig_Profiler_Profile $profile
-     * @param \Twig_LoaderInterface|\Twig_Environment $loaderOrEnv
-     */
-    public function __construct(\Twig_Profiler_Profile $profile, $loaderOrEnv = null)
-    {
-        $this->profile     = $profile;
-        if ($loaderOrEnv instanceof \Twig_Environment) {
-            $loaderOrEnv = $loaderOrEnv->getLoader();
-        }
-        $this->loader = $loaderOrEnv;
-    }
-
-    /**
-     * Returns a hash where keys are control names and their values
-     * an array of options as defined in {@see DebugBar\JavascriptRenderer::addControl()}
-     *
-     * @return array
-     */
-    public function getWidgets()
-    {
-        return array(
-            'twig'       => array(
-                'icon'    => 'leaf',
-                'widget'  => 'PhpDebugBar.Widgets.TemplatesWidget',
-                'map'     => 'twig',
-                'default' => json_encode(array('templates' => array())),
-            ),
-            'twig:badge' => array(
-                'map'     => 'twig.badge',
-                'default' => 0,
-            ),
-        );
-    }
-
-    /**
-     * @return array
-     */
-    public function getAssets()
-    {
-        return array(
-            'css' => 'widgets/templates/widget.css',
-            'js'  => 'widgets/templates/widget.js',
-        );
-    }
-
-    /**
-     * Called by the DebugBar when data needs to be collected
-     *
-     * @return array Collected data
-     */
-    public function collect()
-    {
-        $this->templateCount = $this->blockCount = $this->macroCount = 0;
-        $this->templates     = array();
-        $this->computeData($this->profile);
-
-        return array(
-            'nb_templates'                => $this->templateCount,
-            'nb_blocks'                   => $this->blockCount,
-            'nb_macros'                   => $this->macroCount,
-            'templates'                   => $this->templates,
-            'accumulated_render_time'     => $this->profile->getDuration(),
-            'accumulated_render_time_str' => $this->getDataFormatter()->formatDuration($this->profile->getDuration()),
-            'memory_usage_str'            => $this->getDataFormatter()->formatBytes($this->profile->getMemoryUsage()),
-            'callgraph'                   => $this->getHtmlCallGraph(),
-            'badge'                       => implode(
-                '/',
-                array(
-                    $this->templateCount,
-                    $this->blockCount,
-                    $this->macroCount,
-                )
-            ),
-        );
-    }
-
-    /**
-     * Returns the unique name of the collector
-     *
-     * @return string
-     */
-    public function getName()
-    {
-        return 'twig';
-    }
-
-    public function getHtmlCallGraph()
-    {
-        $dumper = new \Twig_Profiler_Dumper_Html();
-
-        return $dumper->dump($this->profile);
-    }
-
-    /**
-     * Get an Xdebug Link to a file
-     *
-     * @return array {
-     *  @var string url
-     *  @var bool ajax
-     * }
-     */
-    public function getXdebugLink($template, $line = 1)
-    {
-        if (is_null($this->loader)) {
-            return null;
-        }
-        $file = $this->loader->getSourceContext($template)->getPath();
-
-        return parent::getXdebugLink($file, $line);
-    }
-
-    private function computeData(\Twig_Profiler_Profile $profile)
-    {
-        $this->templateCount += ($profile->isTemplate() ? 1 : 0);
-        $this->blockCount    += ($profile->isBlock() ? 1 : 0);
-        $this->macroCount    += ($profile->isMacro() ? 1 : 0);
-        if ($profile->isTemplate()) {
-            $this->templates[] = array(
-                'name'            => $profile->getName(),
-                'render_time'     => $profile->getDuration(),
-                'render_time_str' => $this->getDataFormatter()->formatDuration($profile->getDuration()),
-                'memory_str'      => $this->getDataFormatter()->formatBytes($profile->getMemoryUsage()),
-                'xdebug_link'     => $this->getXdebugLink($profile->getTemplate()),
-            );
-        }
-        foreach ($profile as $p) {
-            $this->computeData($p);
-        }
-    }
-}
diff --git a/vendor/maximebf/debugbar/src/DebugBar/DataCollector/AggregatedCollector.php b/vendor/maximebf/debugbar/src/DebugBar/DataCollector/AggregatedCollector.php
deleted file mode 100644
index 56c9dc7..0000000
--- a/vendor/maximebf/debugbar/src/DebugBar/DataCollector/AggregatedCollector.php
+++ /dev/null
@@ -1,190 +0,0 @@
-
- * $aggcollector = new AggregateCollector('foobar');
- * $aggcollector->addCollector(new MessagesCollector('msg1'));
- * $aggcollector->addCollector(new MessagesCollector('msg2'));
- * $aggcollector['msg1']->addMessage('hello world');
- * 
- */
-class AggregatedCollector implements DataCollectorInterface, ArrayAccess
-{
-    protected $name;
-
-    protected $mergeProperty;
-
-    protected $sort;
-
-    protected $collectors = array();
-
-    /**
-     * @param string $name
-     * @param string $mergeProperty
-     * @param boolean $sort
-     */
-    public function __construct($name, $mergeProperty = null, $sort = false)
-    {
-        $this->name = $name;
-        $this->mergeProperty = $mergeProperty;
-        $this->sort = $sort;
-    }
-
-    /**
-     * @param DataCollectorInterface $collector
-     */
-    public function addCollector(DataCollectorInterface $collector) : void
-    {
-        $this->collectors[$collector->getName()] = $collector;
-    }
-
-    /**
-     * @return array
-     */
-    public function getCollectors() : array
-    {
-        return $this->collectors;
-    }
-
-    /**
-     * Merge data from one of the key/value pair of the collected data
-     *
-     * @param string $property
-     */
-    public function setMergeProperty($property) : void
-    {
-        $this->mergeProperty = $property;
-    }
-
-    /**
-     * @return string
-     */
-    public function getMergeProperty() : string
-    {
-        return $this->mergeProperty;
-    }
-
-    /**
-     * Sorts the collected data
-     *
-     * If true, sorts using sort()
-     * If it is a string, sorts the data using the value from a key/value pair of the array
-     *
-     * @param bool|string $sort
-     */
-    public function setSort($sort) : void
-    {
-        $this->sort = $sort;
-    }
-
-    /**
-     * @return bool|string
-     */
-    public function getSort()
-    {
-        return $this->sort;
-    }
-
-    /**
-     * @return array
-     */
-    public function collect() : array
-    {
-        $aggregate = array();
-        foreach ($this->collectors as $collector) {
-            $data = $collector->collect();
-            if ($this->mergeProperty !== null) {
-                $data = $data[$this->mergeProperty];
-            }
-            $aggregate = array_merge($aggregate, $data);
-        }
-
-        return $this->sort($aggregate);
-    }
-
-    /**
-     * Sorts the collected data
-     *
-     * @param array $data
-     * @return array
-     */
-    protected function sort($data) : array
-    {
-        if (is_string($this->sort)) {
-            $p = $this->sort;
-            usort($data, function ($a, $b) use ($p) {
-                if ($a[$p] == $b[$p]) {
-                    return 0;
-                }
-                return $a[$p] < $b[$p] ? -1 : 1;
-            });
-        } elseif ($this->sort === true) {
-            sort($data);
-        }
-        return $data;
-    }
-
-    /**
-     * @return string
-     */
-    public function getName() : string
-    {
-        return $this->name;
-    }
-
-    // --------------------------------------------
-    // ArrayAccess implementation
-
-    /**
-     * @param mixed $key
-     * @param mixed $value
-     * @throws DebugBarException
-     */
-    public function offsetSet($key, $value): void
-    {
-        throw new DebugBarException("AggregatedCollector[] is read-only");
-    }
-
-    /**
-     * @param mixed $key
-     * @return mixed
-     */
-    #[\ReturnTypeWillChange]
-    public function offsetGet($key)
-    {
-        return $this->collectors[$key];
-    }
-
-    /**
-     * @param mixed $key
-     * @return bool
-     */
-    public function offsetExists($key): bool
-    {
-        return isset($this->collectors[$key]);
-    }
-
-    /**
-     * @param mixed $key
-     * @throws DebugBarException
-     */
-    public function offsetUnset($key): void
-    {
-        throw new DebugBarException("AggregatedCollector[] is read-only");
-    }
-}
diff --git a/vendor/maximebf/debugbar/src/DebugBar/DataCollector/AssetProvider.php b/vendor/maximebf/debugbar/src/DebugBar/DataCollector/AssetProvider.php
deleted file mode 100644
index 58425d8..0000000
--- a/vendor/maximebf/debugbar/src/DebugBar/DataCollector/AssetProvider.php
+++ /dev/null
@@ -1,43 +0,0 @@
- tag)
-     *  - inline_js: an array map of content ID to inline JS content (not including ' . "\n", $file);
-        }
-
-        foreach ($inlineJs as $content) {
-            $html .= sprintf('' . "\n", $nonce, $content);
-        }
-
-        foreach ($inlineHead as $content) {
-            $html .= $content . "\n";
-        }
-
-        if ($this->enableJqueryNoConflict && !$this->useRequireJs) {
-            $html .= '' . "\n";
-        }
-
-        return $html;
-    }
-
-    /**
-     * Register shutdown to display the debug bar
-     *
-     * @param boolean $here Set position of HTML. True if is to current position or false for end file
-     * @param boolean $initialize Whether to render the de bug bar initialization code
-     * @param bool $renderStackedData
-     * @param bool $head
-     * @return string Return "{--DEBUGBAR_OB_START_REPLACE_ME--}" or return an empty string if $here == false
-     */
-    public function renderOnShutdown($here = true, $initialize = true, $renderStackedData = true, $head = false)
-    {
-        register_shutdown_function(array($this, "replaceTagInBuffer"), $here, $initialize, $renderStackedData, $head);
-
-        if (ob_get_level() === 0) {
-            ob_start();
-        }
-
-        return ($here) ? self::REPLACEABLE_TAG : "";
-    }
-
-    /**
-     * Same as renderOnShutdown() with $head = true
-     *
-     * @param boolean $here
-     * @param boolean $initialize
-     * @param boolean $renderStackedData
-     * @return string
-     */
-    public function renderOnShutdownWithHead($here = true, $initialize = true, $renderStackedData = true)
-    {
-        return $this->renderOnShutdown($here, $initialize, $renderStackedData, true);
-    }
-
-    /**
-     * Is callback function for register_shutdown_function(...)
-     *
-     * @param boolean $here Set position of HTML. True if is to current position or false for end file
-     * @param boolean $initialize Whether to render the de bug bar initialization code
-     * @param bool $renderStackedData
-     * @param bool $head
-     */
-    public function replaceTagInBuffer($here = true, $initialize = true, $renderStackedData = true, $head = false)
-    {
-        $render = ($head ? $this->renderHead() : "")
-                . $this->render($initialize, $renderStackedData);
-
-        $current = ($here && ob_get_level() > 0) ? ob_get_clean() : self::REPLACEABLE_TAG;
-
-        echo str_replace(self::REPLACEABLE_TAG, $render, $current, $count);
-
-        if ($count === 0) {
-            echo $render;
-        }
-    }
-
-    /**
-     * Returns the code needed to display the debug bar
-     *
-     * AJAX request should not render the initialization code.
-     *
-     * @param boolean $initialize Whether or not to render the debug bar initialization code
-     * @param boolean $renderStackedData Whether or not to render the stacked data
-     * @return string
-     */
-    public function render($initialize = true, $renderStackedData = true)
-    {
-        $js = '';
-
-        if ($initialize) {
-            $js = $this->getJsInitializationCode();
-        }
-
-        if ($renderStackedData && $this->debugBar->hasStackedData()) {
-            foreach ($this->debugBar->getStackedData() as $id => $data) {
-                $js .= $this->getAddDatasetCode($id, $data, '(stacked)');
-            }
-        }
-
-        $suffix = !$initialize ? '(ajax)' : null;
-        $js .= $this->getAddDatasetCode($this->debugBar->getCurrentRequestId(), $this->debugBar->getData(), $suffix);
-
-        $nonce = $this->getNonceAttribute();
-
-	if ($nonce != '') {
-            $js = preg_replace("/\n";
-        } else {
-            return "\n";
-        }
-
-    }
-
-    /**
-     * Returns the js code needed to initialize the debug bar
-     *
-     * @return string
-     */
-    protected function getJsInitializationCode()
-    {
-        $js = '';
-
-        if (($this->initialization & self::INITIALIZE_CONSTRUCTOR) === self::INITIALIZE_CONSTRUCTOR) {
-            $js .= sprintf("var %s = new %s();\n", $this->variableName, $this->javascriptClass);
-        }
-
-        if (($this->initialization & self::INITIALIZE_CONTROLS) === self::INITIALIZE_CONTROLS) {
-            $js .= $this->getJsControlsDefinitionCode($this->variableName);
-        }
-
-        if ($this->ajaxHandlerClass) {
-            $js .= sprintf("%s.ajaxHandler = new %s(%s, undefined, %s);\n",
-                $this->variableName,
-                $this->ajaxHandlerClass,
-                $this->variableName,
-                $this->ajaxHandlerAutoShow ? 'true' : 'false'
-            );
-            if ($this->ajaxHandlerBindToFetch) {
-                $js .= sprintf("%s.ajaxHandler.bindToFetch();\n", $this->variableName);
-            }
-            if ($this->ajaxHandlerBindToXHR) {
-                $js .= sprintf("%s.ajaxHandler.bindToXHR();\n", $this->variableName);
-            } elseif ($this->ajaxHandlerBindToJquery) {
-                $js .= sprintf("if (jQuery) %s.ajaxHandler.bindToJquery(jQuery);\n", $this->variableName);
-            }
-        }
-
-        if ($this->openHandlerUrl !== null) {
-            $js .= sprintf("%s.setOpenHandler(new %s(%s));\n", $this->variableName,
-                $this->openHandlerClass,
-                json_encode(array("url" => $this->openHandlerUrl)));
-        }
-
-        return $js;
-    }
-
-    /**
-     * Returns the js code needed to initialized the controls and data mapping of the debug bar
-     *
-     * Controls can be defined by collectors themselves or using {@see addControl()}
-     *
-     * @param string $varname Debug bar's variable name
-     * @return string
-     */
-    protected function getJsControlsDefinitionCode($varname)
-    {
-        $js = '';
-        $dataMap = array();
-        $excludedOptions = array('indicator', 'tab', 'map', 'default', 'widget', 'position');
-
-        // finds controls provided by collectors
-        $widgets = array();
-        foreach ($this->debugBar->getCollectors() as $collector) {
-            if (($collector instanceof Renderable) && !in_array($collector->getName(), $this->ignoredCollectors)) {
-                if ($w = $collector->getWidgets()) {
-                    $widgets = array_merge($widgets, $w);
-                }
-            }
-        }
-        $controls = array_merge($widgets, $this->controls);
-
-        foreach (array_filter($controls) as $name => $options) {
-            $opts = array_diff_key($options, array_flip($excludedOptions));
-
-            if (isset($options['tab']) || isset($options['widget'])) {
-                if (!isset($opts['title'])) {
-                    $opts['title'] = ucfirst(str_replace('_', ' ', $name));
-                }
-                $js .= sprintf("%s.addTab(\"%s\", new %s({%s%s}));\n",
-                    $varname,
-                    $name,
-                    isset($options['tab']) ? $options['tab'] : 'PhpDebugBar.DebugBar.Tab',
-                    substr(json_encode($opts, JSON_FORCE_OBJECT), 1, -1),
-                    isset($options['widget']) ? sprintf('%s"widget": new %s()', count($opts) ? ', ' : '', $options['widget']) : ''
-                );
-            } elseif (isset($options['indicator']) || isset($options['icon'])) {
-                $js .= sprintf("%s.addIndicator(\"%s\", new %s(%s), \"%s\");\n",
-                    $varname,
-                    $name,
-                    isset($options['indicator']) ? $options['indicator'] : 'PhpDebugBar.DebugBar.Indicator',
-                    json_encode($opts, JSON_FORCE_OBJECT),
-                    isset($options['position']) ? $options['position'] : 'right'
-                );
-            }
-
-            if (isset($options['map']) && isset($options['default'])) {
-                $dataMap[$name] = array($options['map'], $options['default']);
-            }
-        }
-
-        // creates the data mapping object
-        $mapJson = array();
-        foreach ($dataMap as $name => $values) {
-            $mapJson[] = sprintf('"%s": ["%s", %s]', $name, $values[0], $values[1]);
-        }
-        $js .= sprintf("%s.setDataMap({\n%s\n});\n", $varname, implode(",\n", $mapJson));
-
-        // activate state restoration
-        $js .= sprintf("%s.restoreState();\n", $varname);
-
-        return $js;
-    }
-
-    /**
-     * Returns the js code needed to add a dataset
-     *
-     * @param string $requestId
-     * @param array $data
-     * @param mixed $suffix
-     * @return string
-     */
-    protected function getAddDatasetCode($requestId, $data, $suffix = null)
-    {
-        $js = sprintf("%s.addDataSet(%s, \"%s\"%s);\n",
-            $this->variableName,
-            json_encode($data),
-            $requestId,
-            $suffix ? ", " . json_encode($suffix) : ''
-        );
-        return $js;
-    }
-
-    /**
-     * If a nonce it set, create the correct attribute
-     * @return string
-     */
-    protected function getNonceAttribute()
-    {
-        if ($nonce = $this->getCspNonce()) {
-            return ' nonce="' . $nonce .'"';
-        }
-
-        return '';
-    }
-}
diff --git a/vendor/maximebf/debugbar/src/DebugBar/OpenHandler.php b/vendor/maximebf/debugbar/src/DebugBar/OpenHandler.php
deleted file mode 100644
index ee4df41..0000000
--- a/vendor/maximebf/debugbar/src/DebugBar/OpenHandler.php
+++ /dev/null
@@ -1,117 +0,0 @@
-isDataPersisted()) {
-            throw new DebugBarException("DebugBar must have a storage backend to use OpenHandler");
-        }
-        $this->debugBar = $debugBar;
-    }
-
-    /**
-     * Handles the current request
-     *
-     * @param array $request Request data
-     * @param bool $echo
-     * @param bool $sendHeader
-     * @return string
-     * @throws DebugBarException
-     */
-    public function handle($request = null, $echo = true, $sendHeader = true)
-    {
-        if ($request === null) {
-            $request = $_REQUEST;
-        }
-
-        $op = 'find';
-        if (isset($request['op'])) {
-            $op = $request['op'];
-            if (!in_array($op, array('find', 'get', 'clear'))) {
-                throw new DebugBarException("Invalid operation '{$request['op']}'");
-            }
-        }
-
-        if ($sendHeader) {
-            $this->debugBar->getHttpDriver()->setHeaders(array(
-                    'Content-Type' => 'application/json'
-                ));
-        }
-
-        $response = json_encode(call_user_func(array($this, $op), $request));
-        if ($echo) {
-            echo $response;
-        }
-        return $response;
-    }
-
-    /**
-     * Find operation
-     * @param $request
-     * @return array
-     */
-    protected function find($request)
-    {
-        $max = 20;
-        if (isset($request['max'])) {
-            $max = $request['max'];
-        }
-
-        $offset = 0;
-        if (isset($request['offset'])) {
-            $offset = $request['offset'];
-        }
-
-        $filters = array();
-        foreach (array('utime', 'datetime', 'ip', 'uri', 'method') as $key) {
-            if (isset($request[$key])) {
-                $filters[$key] = $request[$key];
-            }
-        }
-
-        return $this->debugBar->getStorage()->find($filters, $max, $offset);
-    }
-
-    /**
-     * Get operation
-     * @param $request
-     * @return array
-     * @throws DebugBarException
-     */
-    protected function get($request)
-    {
-        if (!isset($request['id'])) {
-            throw new DebugBarException("Missing 'id' parameter in 'get' operation");
-        }
-        return $this->debugBar->getStorage()->get($request['id']);
-    }
-
-    /**
-     * Clear operation
-     */
-    protected function clear($request)
-    {
-        $this->debugBar->getStorage()->clear();
-        return array('success' => true);
-    }
-}
diff --git a/vendor/maximebf/debugbar/src/DebugBar/PhpHttpDriver.php b/vendor/maximebf/debugbar/src/DebugBar/PhpHttpDriver.php
deleted file mode 100644
index 36e56f8..0000000
--- a/vendor/maximebf/debugbar/src/DebugBar/PhpHttpDriver.php
+++ /dev/null
@@ -1,70 +0,0 @@
- $value) {
-            header("$name: $value");
-        }
-    }
-
-    /**
-     * @return bool
-     */
-    function isSessionStarted()
-    {
-        return isset($_SESSION);
-    }
-
-    /**
-     * @param string $name
-     * @param string $value
-     */
-    function setSessionValue($name, $value)
-    {
-        $_SESSION[$name] = $value;
-    }
-
-    /**
-     * @param string $name
-     * @return bool
-     */
-    function hasSessionValue($name)
-    {
-        return array_key_exists($name, $_SESSION);
-    }
-
-    /**
-     * @param string $name
-     * @return mixed
-     */
-    function getSessionValue($name)
-    {
-        return $_SESSION[$name];
-    }
-
-    /**
-     * @param string $name
-     */
-    function deleteSessionValue($name)
-    {
-        unset($_SESSION[$name]);
-    }
-}
diff --git a/vendor/maximebf/debugbar/src/DebugBar/RequestIdGenerator.php b/vendor/maximebf/debugbar/src/DebugBar/RequestIdGenerator.php
deleted file mode 100644
index 90c1728..0000000
--- a/vendor/maximebf/debugbar/src/DebugBar/RequestIdGenerator.php
+++ /dev/null
@@ -1,43 +0,0 @@
-= 5.3.0, but OpenSSL may not always be available
-            return 'X' . bin2hex(openssl_random_pseudo_bytes(16));
-        } else {
-            // Fall back to a rudimentary ID generator:
-            //  * $_SERVER array will make the ID unique to this request.
-            //  * spl_object_hash($this) will make the ID unique to this object instance.
-            //    (note that object hashes can be reused, but the other data here should prevent issues here).
-            //  * uniqid('', true) will use the current microtime(), plus additional random data.
-            //  * $this->index guarantees the uniqueness of IDs from the current object.
-            $this->index++;
-            $entropy = serialize($_SERVER) . uniqid('', true) . spl_object_hash($this) . $this->index;
-            return 'X' . md5($entropy);
-        }
-    }
-}
diff --git a/vendor/maximebf/debugbar/src/DebugBar/RequestIdGeneratorInterface.php b/vendor/maximebf/debugbar/src/DebugBar/RequestIdGeneratorInterface.php
deleted file mode 100644
index 3d9b4af..0000000
--- a/vendor/maximebf/debugbar/src/DebugBar/RequestIdGeneratorInterface.php
+++ /dev/null
@@ -1,25 +0,0 @@
- value maps, the returned value must be
-     * guaranteed to not be all-numeric.
-     *
-     * @return string
-     */
-    function generate();
-}
diff --git a/vendor/maximebf/debugbar/src/DebugBar/Resources/debugbar.css b/vendor/maximebf/debugbar/src/DebugBar/Resources/debugbar.css
deleted file mode 100644
index 606e51d..0000000
--- a/vendor/maximebf/debugbar/src/DebugBar/Resources/debugbar.css
+++ /dev/null
@@ -1,313 +0,0 @@
-/* Hide debugbar when printing a page */
-@media print {
-  div.phpdebugbar {
-    display: none;
-  }
-}
-
-div.phpdebugbar {
-  position: fixed;
-  bottom: 0;
-  left: 0;
-  width: 100%;
-  border-top: 0;
-  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen-Sans, Ubuntu, Cantarell, "Helvetica Neue", Helvetica, Arial, sans-serif;
-  background: #fff;
-  z-index: 10000;
-  font-size: 14px;
-  color: #000;
-  text-align: left;
-  line-height: 1;
-  letter-spacing: normal;
-  direction: ltr;
-}
-
-div.phpdebugbar a,
-div.phpdebugbar-openhandler {
-  cursor: pointer;
-}
-
-div.phpdebugbar-drag-capture {
-  position: fixed;
-  top: 0;
-  bottom: 0;
-  left: 0;
-  right: 0;
-  z-index: 10001;
-  background: none;
-  display: none;
-  cursor: ns-resize;
-}
-
-div.phpdebugbar-closed {
-    width: auto;
-}
-
-div.phpdebugbar * {
-  margin: 0;
-  padding: 0;
-  border: 0;
-  font-weight: normal;
-  text-decoration: none;
-  clear: initial;
-  width: auto;
-  -moz-box-sizing: content-box;
-       box-sizing: content-box;
-}
-
-div.phpdebugbar ol, div.phpdebugbar ul {
-  list-style: none;
-}
-
-div.phpdebugbar table {
-  border-collapse: collapse;
-  border-spacing: 0;
-}
-
-div.phpdebugbar input[type='text'], div.phpdebugbar input[type='password'] {
-  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen-Sans, Ubuntu, Cantarell, "Helvetica Neue", Helvetica, Arial, sans-serif;
-  background: #fff;
-  font-size: 14px;
-  color: #000;
-  border: 0;
-  padding: 0;
-  margin: 0;
-}
-
-div.phpdebugbar code, div.phpdebugbar pre, div.phpdebugbar samp {
-  background: none;
-  font-family: "SFMono-Regular", Consolas, "Liberation Mono", Menlo, Courier, monospace;
-  font-size: 1em;
-  border: 0;
-  padding: 0;
-  margin: 0;
-}
-
-div.phpdebugbar code, div.phpdebugbar pre {
-  color: #000;
-}
-
-div.phpdebugbar pre.sf-dump {
-  color: #a0a000;
-  outline: 0;
-}
-
-a.phpdebugbar-restore-btn {
-  float: left;
-  padding: 5px 8px;
-  font-size: 14px;
-  color: #555;
-  text-decoration: none;
-  border-right: 1px solid #ddd;
-}
-
-div.phpdebugbar-resize-handle {
-  display: none;
-  height: 4px;
-  margin-top: -4px;
-  width: 100%;
-  background: none;
-  border-bottom: 1px solid #ccc;
-  cursor: ns-resize;
-}
-
-div.phpdebugbar-closed, div.phpdebugbar-minimized{
-  border-top: 1px solid #ccc;
-}
-/* -------------------------------------- */
-
-a.phpdebugbar-restore-btn {
-    background: #efefef url(data:image/svg+xml,%3Csvg%20viewBox%3D%220%200%2020%2020%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%3E%3Ccircle%20fill%3D%22%23000%22%20cx%3D%2210%22%20cy%3D%2210%22%20r%3D%229%22%2F%3E%3Cpath%20d%3D%22M6.039%208.342c.463%200%20.772.084.927.251.154.168.191.455.11.862-.084.424-.247.727-.487.908-.241.182-.608.272-1.1.272h-.743l.456-2.293h.837zm-2.975%204.615h1.22l.29-1.457H5.62c.461%200%20.84-.047%201.139-.142.298-.095.569-.254.812-.477.205-.184.37-.387.497-.608.127-.222.217-.466.27-.734.13-.65.032-1.155-.292-1.518-.324-.362-.84-.543-1.545-.543H4.153l-1.089%205.479zM9.235%206.02h1.21l-.289%201.458h1.079c.679%200%201.147.115%201.405.347.258.231.335.607.232%201.125l-.507%202.55h-1.23l.481-2.424c.055-.276.035-.464-.06-.565-.095-.1-.298-.15-.608-.15H9.98L9.356%2011.5h-1.21l1.089-5.48M15.566%208.342c.464%200%20.773.084.928.251.154.168.19.455.11.862-.084.424-.247.727-.488.908-.24.182-.607.272-1.1.272h-.742l.456-2.293h.836zm-2.974%204.615h1.22l.29-1.457h1.046c.461%200%20.84-.047%201.139-.142.298-.095.569-.254.812-.477.205-.184.37-.387.497-.608.127-.222.217-.466.27-.734.129-.65.032-1.155-.292-1.518-.324-.362-.84-.543-1.545-.543H13.68l-1.089%205.479z%22%20fill%3D%22%23FFF%22%2F%3E%3C%2Fsvg%3E)  no-repeat 5px 4px / 20px 20px;
-}
-div.phpdebugbar-header {
-  min-height: 26px;
-  line-height: 16px;
-}
-div.phpdebugbar-header:before, div.phpdebugbar-header:after {
-  display: table;
-  line-height: 0;
-  content: "";
-}
-div.phpdebugbar-header:after {
-  clear: both;
-}
-div.phpdebugbar-header-left {
-  float: left;
-}
-div.phpdebugbar-header-right {
-  float: right;
-}
-div.phpdebugbar-header > div > * {
-  padding: 5px 5px;
-  font-size: 14px;
-  color: #555;
-  text-decoration: none;
-}
-div.phpdebugbar-header-left > * {
-  float: left;
-}
-div.phpdebugbar-header-right > * {
-  float: right;
-}
-div.phpdebugbar-header-right > select {
-  padding: 0;
-}
-
-/* -------------------------------------- */
-
-span.phpdebugbar-indicator,
-a.phpdebugbar-indicator,
-a.phpdebugbar-close-btn {
-  border-right: 1px solid #ddd;
-}
-
-a.phpdebugbar-tab.phpdebugbar-active {
-  background: #ccc;
-  color: #444;
-  background-image: linear-gradient(bottom, rgb(173,173,173) 41%, rgb(209,209,209) 71%);
-  background-image: -o-linear-gradient(bottom, rgb(173,173,173) 41%, rgb(209,209,209) 71%);
-  background-image: -moz-linear-gradient(bottom, rgb(173,173,173) 41%, rgb(209,209,209) 71%);
-  background-image: -webkit-linear-gradient(bottom, rgb(173,173,173) 41%, rgb(209,209,209) 71%);
-  background-image: -ms-linear-gradient(bottom, rgb(173,173,173) 41%, rgb(209,209,209) 71%);
-  background-image: -webkit-gradient(linear, left bottom, left top, color-stop(0.41, rgb(173,173,173)), color-stop(0.71, rgb(209,209,209)));
-}
-  a.phpdebugbar-tab span.phpdebugbar-badge {
-    display: none;
-    margin-left: 5px;
-    font-size: 11px;
-    line-height: 14px;
-    padding: 0 6px;
-    background: #ccc;
-    border-radius: 4px;
-    color: #555;
-    font-weight: normal;
-    text-shadow: none;
-    vertical-align: middle;
-  }
-  a.phpdebugbar-tab i {
-    display: none;
-    vertical-align: middle;
-  }
-  a.phpdebugbar-tab span.phpdebugbar-badge.phpdebugbar-visible {
-    display: inline;
-  }
-  a.phpdebugbar-tab span.phpdebugbar-badge.phpdebugbar-important {
-    background: #ed6868;
-    color: white;
-  }
-
-a.phpdebugbar-close-btn, a.phpdebugbar-open-btn, a.phpdebugbar-restore-btn, a.phpdebugbar-minimize-btn , a.phpdebugbar-maximize-btn {
-  width: 16px;
-  height: 16px;
-}
-
-a.phpdebugbar-minimize-btn , a.phpdebugbar-maximize-btn {
-  padding-right: 0 !important;
-}
-
-a.phpdebugbar-maximize-btn { display: none}
-
-a.phpdebugbar-minimize-btn { display: block}
-
-div.phpdebugbar-minimized a.phpdebugbar-maximize-btn { display: block}
-
-div.phpdebugbar-minimized a.phpdebugbar-minimize-btn { display: none}
-
-a.phpdebugbar-minimize-btn {
-  background:url(data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20viewBox%3D%220%200%201792%201792%22%20id%3D%22chevron-down%22%3E%3Cpath%20d%3D%22M1683%20808l-742%20741q-19%2019-45%2019t-45-19l-742-741q-19-19-19-45.5t19-45.5l166-165q19-19%2045-19t45%2019l531%20531%20531-531q19-19%2045-19t45%2019l166%20165q19%2019%2019%2045.5t-19%2045.5z%22%2F%3E%3C%2Fsvg%3E) no-repeat 6px 6px / 14px 14px;
-}
-
-a.phpdebugbar-maximize-btn {
-  background:url(data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20viewBox%3D%220%200%201792%201792%22%20id%3D%22chevron-up%22%3E%3Cpath%20d%3D%22M1683%201331l-166%20165q-19%2019-45%2019t-45-19l-531-531-531%20531q-19%2019-45%2019t-45-19l-166-165q-19-19-19-45.5t19-45.5l742-741q19-19%2045-19t45%2019l742%20741q19%2019%2019%2045.5t-19%2045.5z%22%2F%3E%3C%2Fsvg%3E) no-repeat 6px 6px / 14px 14px;
-}
-
-a.phpdebugbar-close-btn {
-  background: url(data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20viewBox%3D%220%200%201792%201792%22%20id%3D%22close%22%3E%3Cpath%20d%3D%22M1490%201322q0%2040-28%2068l-136%20136q-28%2028-68%2028t-68-28l-294-294-294%20294q-28%2028-68%2028t-68-28l-136-136q-28-28-28-68t28-68l294-294-294-294q-28-28-28-68t28-68l136-136q28-28%2068-28t68%2028l294%20294%20294-294q28-28%2068-28t68%2028l136%20136q28%2028%2028%2068t-28%2068l-294%20294%20294%20294q28%2028%2028%2068z%22%2F%3E%3C%2Fsvg%3E) no-repeat 9px 6px / 14px 14px;
-}
-
-a.phpdebugbar-open-btn {
-  background: url(data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20viewBox%3D%220%200%201792%201792%22%20id%3D%22folder-open%22%3E%3Cpath%20d%3D%22M1815%20952q0%2031-31%2066l-336%20396q-43%2051-120.5%2086.5t-143.5%2035.5h-1088q-34%200-60.5-13t-26.5-43q0-31%2031-66l336-396q43-51%20120.5-86.5t143.5-35.5h1088q34%200%2060.5%2013t26.5%2043zm-343-344v160h-832q-94%200-197%2047.5t-164%20119.5l-337%20396-5%206q0-4-.5-12.5t-.5-12.5v-960q0-92%2066-158t158-66h320q92%200%20158%2066t66%20158v32h544q92%200%20158%2066t66%20158z%22%2F%3E%3C%2Fsvg%3E) no-repeat 8px 6px / 14px 14px;
-}
-
-.phpdebugbar-indicator {
-  position: relative;
-  cursor: pointer;
-}
-  .phpdebugbar-indicator span.phpdebugbar-text {
-    margin-left: 5px;
-  }
-  .phpdebugbar-indicator span.phpdebugbar-tooltip {
-    display: none;
-    position: absolute;
-    top: -30px;
-    background: #efefef;
-    opacity: .7;
-    border: 1px solid #ccc;
-    color: #555;
-    font-size: 11px;
-    padding: 2px 3px;
-    z-index: 1000;
-    text-align: center;
-    width: 200%;
-    right: 0;
-  }
-  .phpdebugbar-indicator:hover span.phpdebugbar-tooltip:not(.phpdebugbar-disabled) {
-    display: block;
-  }
-
-select.phpdebugbar-datasets-switcher {
-  float: right;
-  display: none;
-  margin: 2px 0 0 7px;
-  max-width: 200px;
-  max-height: 23px;
-  padding: 0;
-}
-
-/* -------------------------------------- */
-
-div.phpdebugbar-body {
-  border-top: 1px solid #ccc;
-  display: none;
-  position: relative;
-  height: 300px;
-}
-
-/* -------------------------------------- */
-
-div.phpdebugbar-panel {
-  display: none;
-  height: 100%;
-  overflow: auto;
-  width: 100%;
-}
-div.phpdebugbar-panel.phpdebugbar-active {
-  display: block;
-}
-
-/* -------------------------------------- */
-
-div.phpdebugbar-mini-design a.phpdebugbar-tab {
-  position: relative;
-  border-right: 1px solid #ddd;
-}
-  div.phpdebugbar-mini-design a.phpdebugbar-tab span.phpdebugbar-text {
-    display: none;
-  }
-  div.phpdebugbar-mini-design a.phpdebugbar-tab:hover span.phpdebugbar-text {
-    display: block;
-    position: absolute;
-    top: -30px;
-    background: #efefef;
-    opacity: .7;
-    border: 1px solid #ccc;
-    color: #555;
-    font-size: 11px;
-    padding: 2px 3px;
-    z-index: 1000;
-    text-align: center;
-    right: 0;
-  }
-  div.phpdebugbar-mini-design a.phpdebugbar-tab i {
-    display:inline-block;
-  }
diff --git a/vendor/maximebf/debugbar/src/DebugBar/Resources/debugbar.js b/vendor/maximebf/debugbar/src/DebugBar/Resources/debugbar.js
deleted file mode 100644
index 66658d2..0000000
--- a/vendor/maximebf/debugbar/src/DebugBar/Resources/debugbar.js
+++ /dev/null
@@ -1,1222 +0,0 @@
-if (typeof(PhpDebugBar) == 'undefined') {
-    // namespace
-    var PhpDebugBar = {};
-    PhpDebugBar.$ = jQuery;
-}
-
-(function($) {
-
-    if (typeof(localStorage) == 'undefined') {
-        // provide mock localStorage object for dumb browsers
-        localStorage = {
-            setItem: function(key, value) {},
-            getItem: function(key) { return null; }
-        };
-    }
-
-    if (typeof(PhpDebugBar.utils) == 'undefined') {
-        PhpDebugBar.utils = {};
-    }
-
-    /**
-     * Returns the value from an object property.
-     * Using dots in the key, it is possible to retrieve nested property values
-     *
-     * @param {Object} dict
-     * @param {String} key
-     * @param {Object} default_value
-     * @return {Object}
-     */
-    var getDictValue = PhpDebugBar.utils.getDictValue = function(dict, key, default_value) {
-        var d = dict, parts = key.split('.');
-        for (var i = 0; i < parts.length; i++) {
-            if (!d[parts[i]]) {
-                return default_value;
-            }
-            d = d[parts[i]];
-        }
-        return d;
-    }
-
-    /**
-     * Counts the number of properties in an object
-     *
-     * @param {Object} obj
-     * @return {Integer}
-     */
-    var getObjectSize = PhpDebugBar.utils.getObjectSize = function(obj) {
-        if (Object.keys) {
-            return Object.keys(obj).length;
-        }
-        var count = 0;
-        for (var k in obj) {
-            if (obj.hasOwnProperty(k)) {
-                count++;
-            }
-        }
-        return count;
-    }
-
-    /**
-     * Returns a prefixed css class name
-     *
-     * @param {String} cls
-     * @return {String}
-     */
-    PhpDebugBar.utils.csscls = function(cls, prefix) {
-        if (cls.indexOf(' ') > -1) {
-            var clss = cls.split(' '), out = [];
-            for (var i = 0, c = clss.length; i < c; i++) {
-                out.push(PhpDebugBar.utils.csscls(clss[i], prefix));
-            }
-            return out.join(' ');
-        }
-        if (cls.indexOf('.') === 0) {
-            return '.' + prefix + cls.substr(1);
-        }
-        return prefix + cls;
-    };
-
-    /**
-     * Creates a partial function of csscls where the second
-     * argument is already defined
-     *
-     * @param  {string} prefix
-     * @return {Function}
-     */
-    PhpDebugBar.utils.makecsscls = function(prefix) {
-        var f = function(cls) {
-            return PhpDebugBar.utils.csscls(cls, prefix);
-        };
-        return f;
-    }
-
-    var csscls = PhpDebugBar.utils.makecsscls('phpdebugbar-');
-
-
-    // ------------------------------------------------------------------
-
-    /**
-     * Base class for all elements with a visual component
-     *
-     * @param {Object} options
-     * @constructor
-     */
-    var Widget = PhpDebugBar.Widget = function(options) {
-        this._attributes = $.extend({}, this.defaults);
-        this._boundAttributes = {};
-        this.$el = $('<' + this.tagName + ' />');
-        if (this.className) {
-            this.$el.addClass(this.className);
-        }
-        this.initialize.apply(this, [options || {}]);
-        this.render.apply(this);
-    };
-
-    $.extend(Widget.prototype, {
-
-        tagName: 'div',
-
-        className: null,
-
-        defaults: {},
-
-        /**
-         * Called after the constructor
-         *
-         * @param {Object} options
-         */
-        initialize: function(options) {
-            this.set(options);
-        },
-
-        /**
-         * Called after the constructor to render the element
-         */
-        render: function() {},
-
-        /**
-         * Sets the value of an attribute
-         *
-         * @param {String} attr Can also be an object to set multiple attributes at once
-         * @param {Object} value
-         */
-        set: function(attr, value) {
-            if (typeof(attr) != 'string') {
-                for (var k in attr) {
-                    this.set(k, attr[k]);
-                }
-                return;
-            }
-
-            this._attributes[attr] = value;
-            if (typeof(this._boundAttributes[attr]) !== 'undefined') {
-                for (var i = 0, c = this._boundAttributes[attr].length; i < c; i++) {
-                    this._boundAttributes[attr][i].apply(this, [value]);
-                }
-            }
-        },
-
-        /**
-         * Checks if an attribute exists and is not null
-         *
-         * @param {String} attr
-         * @return {[type]} [description]
-         */
-        has: function(attr) {
-            return typeof(this._attributes[attr]) !== 'undefined' && this._attributes[attr] !== null;
-        },
-
-        /**
-         * Returns the value of an attribute
-         *
-         * @param {String} attr
-         * @return {Object}
-         */
-        get: function(attr) {
-            return this._attributes[attr];
-        },
-
-        /**
-         * Registers a callback function that will be called whenever the value of the attribute changes
-         *
-         * If cb is a jQuery element, text() will be used to fill the element
-         *
-         * @param {String} attr
-         * @param {Function} cb
-         */
-        bindAttr: function(attr, cb) {
-            if ($.isArray(attr)) {
-                for (var i = 0, c = attr.length; i < c; i++) {
-                    this.bindAttr(attr[i], cb);
-                }
-                return;
-            }
-
-            if (typeof(this._boundAttributes[attr]) == 'undefined') {
-                this._boundAttributes[attr] = [];
-            }
-            if (typeof(cb) == 'object') {
-                var el = cb;
-                cb = function(value) { el.text(value || ''); };
-            }
-            this._boundAttributes[attr].push(cb);
-            if (this.has(attr)) {
-                cb.apply(this, [this._attributes[attr]]);
-            }
-        }
-
-    });
-
-
-    /**
-     * Creates a subclass
-     *
-     * Code from Backbone.js
-     *
-     * @param {Array} props Prototype properties
-     * @return {Function}
-     */
-    Widget.extend = function(props) {
-        var parent = this;
-
-        var child = function() { return parent.apply(this, arguments); };
-        $.extend(child, parent);
-
-        var Surrogate = function() { this.constructor = child; };
-        Surrogate.prototype = parent.prototype;
-        child.prototype = new Surrogate;
-        $.extend(child.prototype, props);
-
-        child.__super__ = parent.prototype;
-
-        return child;
-    };
-
-    // ------------------------------------------------------------------
-
-    /**
-     * Tab
-     *
-     * A tab is composed of a tab label which is always visible and
-     * a tab panel which is visible only when the tab is active.
-     *
-     * The panel must contain a widget. A widget is an object which has
-     * an element property containing something appendable to a jQuery object.
-     *
-     * Options:
-     *  - title
-     *  - badge
-     *  - widget
-     *  - data: forward data to widget data
-     */
-    var Tab = Widget.extend({
-
-        className: csscls('panel'),
-
-        render: function() {
-            this.$tab = $('').addClass(csscls('tab'));
-
-            this.$icon = $('').appendTo(this.$tab);
-            this.bindAttr('icon', function(icon) {
-                if (icon) {
-                    this.$icon.attr('class', 'phpdebugbar-fa phpdebugbar-fa-' + icon);
-                } else {
-                    this.$icon.attr('class', '');
-                }
-            });
-
-            this.bindAttr('title', $('').addClass(csscls('text')).appendTo(this.$tab));
-
-            this.$badge = $('').addClass(csscls('badge')).appendTo(this.$tab);
-            this.bindAttr('badge', function(value) {
-                if (value !== null) {
-                    this.$badge.text(value);
-                    this.$badge.addClass(csscls('visible'));
-                } else {
-                    this.$badge.removeClass(csscls('visible'));
-                }
-            });
-
-            this.bindAttr('widget', function(widget) {
-                this.$el.empty().append(widget.$el);
-            });
-
-            this.bindAttr('data', function(data) {
-                if (this.has('widget')) {
-                    this.get('widget').set('data', data);
-                }
-            })
-        }
-
-    });
-
-    // ------------------------------------------------------------------
-
-    /**
-     * Indicator
-     *
-     * An indicator is a text and an icon to display single value information
-     * right inside the always visible part of the debug bar
-     *
-     * Options:
-     *  - icon
-     *  - title
-     *  - tooltip
-     *  - data: alias of title
-     */
-    var Indicator = Widget.extend({
-
-        tagName: 'span',
-
-        className: csscls('indicator'),
-
-        render: function() {
-            this.$icon = $('').appendTo(this.$el);
-            this.bindAttr('icon', function(icon) {
-                if (icon) {
-                    this.$icon.attr('class', 'phpdebugbar-fa phpdebugbar-fa-' + icon);
-                } else {
-                    this.$icon.attr('class', '');
-                }
-            });
-
-            this.bindAttr(['title', 'data'], $('').addClass(csscls('text')).appendTo(this.$el));
-
-            this.$tooltip = $('').addClass(csscls('tooltip disabled')).appendTo(this.$el);
-            this.bindAttr('tooltip', function(tooltip) {
-                if (tooltip) {
-                    this.$tooltip.text(tooltip).removeClass(csscls('disabled'));
-                } else {
-                    this.$tooltip.addClass(csscls('disabled'));
-                }
-            });
-        }
-
-    });
-
-    // ------------------------------------------------------------------
-
-    /**
-     * Dataset title formater
-     *
-     * Formats the title of a dataset for the select box
-     */
-    var DatasetTitleFormater = PhpDebugBar.DatasetTitleFormater = function(debugbar) {
-        this.debugbar = debugbar;
-    };
-
-    $.extend(DatasetTitleFormater.prototype, {
-
-        /**
-         * Formats the title of a dataset
-         *
-         * @this {DatasetTitleFormater}
-         * @param {String} id
-         * @param {Object} data
-         * @param {String} suffix
-         * @return {String}
-         */
-        format: function(id, data, suffix) {
-            if (suffix) {
-                suffix = ' ' + suffix;
-            } else {
-                suffix = '';
-            }
-
-            var nb = getObjectSize(this.debugbar.datasets) + 1;
-
-            if (typeof(data['__meta']) === 'undefined') {
-                return "#" + nb + suffix;
-            }
-
-            var uri = data['__meta']['uri'], filename;
-            if (uri.length && uri.charAt(uri.length - 1) === '/') {
-                // URI ends in a trailing /: get the portion before then to avoid returning an empty string
-                filename = uri.substr(0, uri.length - 1); // strip trailing '/'
-                filename = filename.substr(filename.lastIndexOf('/') + 1); // get last path segment
-                filename += '/'; // add the trailing '/' back
-            } else {
-                filename = uri.substr(uri.lastIndexOf('/') + 1);
-            }
-
-            // truncate the filename in the label, if it's too long
-            var maxLength = 150;
-            if (filename.length > maxLength) {
-                filename = filename.substr(0, maxLength) + '...';
-            }
-
-            var label = "#" + nb + " " + filename + suffix + ' (' + data['__meta']['datetime'].split(' ')[1] + ')';
-            return label;
-        }
-
-    });
-
-    // ------------------------------------------------------------------
-
-
-    /**
-     * DebugBar
-     *
-     * Creates a bar that appends itself to the body of your page
-     * and sticks to the bottom.
-     *
-     * The bar can be customized by adding tabs and indicators.
-     * A data map is used to fill those controls with data provided
-     * from datasets.
-     */
-    var DebugBar = PhpDebugBar.DebugBar = Widget.extend({
-
-        className: "phpdebugbar " + csscls('minimized'),
-
-        options: {
-            bodyMarginBottom: true,
-            bodyMarginBottomHeight: 0
-        },
-
-        initialize: function() {
-            this.controls = {};
-            this.dataMap = {};
-            this.datasets = {};
-            this.firstTabName = null;
-            this.activePanelName = null;
-            this.datesetTitleFormater = new DatasetTitleFormater(this);
-            this.options.bodyMarginBottomHeight = parseInt($('body').css('margin-bottom'));
-            this.registerResizeHandler();
-        },
-
-        /**
-         * Register resize event, for resize debugbar with reponsive css.
-         *
-         * @this {DebugBar}
-         */
-        registerResizeHandler: function() {
-            if (typeof this.resize.bind == 'undefined') return;
-
-            var f = this.resize.bind(this);
-            this.respCSSSize = 0;
-            $(window).resize(f);
-            setTimeout(f, 20);
-        },
-
-        /**
-         * Resizes the debugbar to fit the current browser window
-         */
-        resize: function() {
-            var contentSize = this.respCSSSize;
-            if (this.respCSSSize == 0) {
-                this.$header.find("> div > *:visible").each(function () {
-                    contentSize += $(this).outerWidth();
-                });
-            }
-
-            var currentSize = this.$header.width();
-            var cssClass = "phpdebugbar-mini-design";
-            var bool = this.$header.hasClass(cssClass);
-
-            if (currentSize <= contentSize && !bool) {
-                this.respCSSSize = contentSize;
-                this.$header.addClass(cssClass);
-            } else if (contentSize < currentSize && bool) {
-                this.respCSSSize = 0;
-                this.$header.removeClass(cssClass);
-            }
-
-            // Reset height to ensure bar is still visible
-            this.setHeight(this.$body.height());
-        },
-
-        /**
-         * Initialiazes the UI
-         *
-         * @this {DebugBar}
-         */
-        render: function() {
-            var self = this;
-            this.$el.appendTo('body');
-            this.$dragCapture = $('
').addClass(csscls('drag-capture')).appendTo(this.$el); - this.$resizehdle = $('
').addClass(csscls('resize-handle')).appendTo(this.$el); - this.$header = $('
').addClass(csscls('header')).appendTo(this.$el); - this.$headerBtn = $('').addClass(csscls('restore-btn')).appendTo(this.$header); - this.$headerBtn.click(function() { - self.close(); - }); - this.$headerLeft = $('
').addClass(csscls('header-left')).appendTo(this.$header); - this.$headerRight = $('
').addClass(csscls('header-right')).appendTo(this.$header); - var $body = this.$body = $('
').addClass(csscls('body')).appendTo(this.$el); - this.recomputeBottomOffset(); - - // dragging of resize handle - var pos_y, orig_h; - this.$resizehdle.on('mousedown', function(e) { - orig_h = $body.height(), pos_y = e.pageY; - $body.parents().on('mousemove', mousemove).on('mouseup', mouseup); - self.$dragCapture.show(); - e.preventDefault(); - }); - var mousemove = function(e) { - var h = orig_h + (pos_y - e.pageY); - self.setHeight(h); - }; - var mouseup = function() { - $body.parents().off('mousemove', mousemove).off('mouseup', mouseup); - self.$dragCapture.hide(); - }; - - // close button - this.$closebtn = $('').addClass(csscls('close-btn')).appendTo(this.$headerRight); - this.$closebtn.click(function() { - self.close(); - }); - - // minimize button - this.$minimizebtn = $('').addClass(csscls('minimize-btn') ).appendTo(this.$headerRight); - this.$minimizebtn.click(function() { - self.minimize(); - }); - - // maximize button - this.$maximizebtn = $('').addClass(csscls('maximize-btn') ).appendTo(this.$headerRight); - this.$maximizebtn.click(function() { - self.restore(); - }); - - // restore button - this.$restorebtn = $('').addClass(csscls('restore-btn')).hide().appendTo(this.$el); - this.$restorebtn.click(function() { - self.restore(); - }); - - // open button - this.$openbtn = $('').addClass(csscls('open-btn')).appendTo(this.$headerRight).hide(); - this.$openbtn.click(function() { - self.openHandler.show(function(id, dataset) { - self.addDataSet(dataset, id, "(opened)"); - self.showTab(); - }); - }); - - // select box for data sets - this.$datasets = $('
') - .append('Uri:
') - .append('IP:
') - .append(searchBtn) - .appendTo(this.$actions); - }, - - handleFind: function(data) { - var self = this; - $.each(data, function(i, meta) { - var a = $('
') - .text('Load dataset') - .on('click', function(e) { - self.hide(); - self.load(meta['id'], function(data) { - self.callback(meta['id'], data); - }); - e.preventDefault(); - }); - - var method = $('') - .text(meta['method']) - .on('click', function(e) { - self.$table.empty(); - self.find({method: meta['method']}, 0, self.handleFind.bind(self)); - e.preventDefault(); - }); - - var uri = $('') - .text(meta['uri']) - .on('click', function(e) { - self.hide(); - self.load(meta['id'], function(data) { - self.callback(meta['id'], data); - }); - e.preventDefault(); - }); - - var ip = $('') - .text(meta['ip']) - .on('click', function(e) { - self.$table.empty(); - self.find({ip: meta['ip']}, 0, self.handleFind.bind(self)); - e.preventDefault(); - }); - - var search = $('') - .text('Show URL') - .on('click', function(e) { - self.$table.empty(); - self.find({uri: meta['uri']}, 0, self.handleFind.bind(self)); - e.preventDefault(); - }); - - $('') - .append('' + meta['datetime'] + '') - .append('' + meta['method'] + '') - .append($('').append(uri)) - .append($('').append(ip)) - .append($('').append(search)) - .appendTo(self.$table); - }); - if (data.length < this.get('items_per_page')) { - this.$loadmorebtn.hide(); - } - }, - - show: function(callback) { - this.callback = callback; - this.$el.show(); - this.$overlay.show(); - this.refresh(); - }, - - hide: function() { - this.$el.hide(); - this.$overlay.hide(); - }, - - find: function(filters, offset, callback) { - var data = $.extend({}, filters, {max: this.get('items_per_page'), offset: offset || 0}); - this.last_find_request = data; - this.ajax(data, callback); - }, - - load: function(id, callback) { - this.ajax({op: "get", id: id}, callback); - }, - - clear: function(callback) { - this.ajax({op: "clear"}, callback); - }, - - ajax: function(data, callback) { - $.ajax({ - dataType: 'json', - url: this.get('url'), - data: data, - success: callback, - ignoreDebugBarAjaxHandler: true - }); - } - - }); - -})(PhpDebugBar.$); diff --git a/vendor/maximebf/debugbar/src/DebugBar/Resources/vendor/font-awesome/css/font-awesome.min.css b/vendor/maximebf/debugbar/src/DebugBar/Resources/vendor/font-awesome/css/font-awesome.min.css deleted file mode 100644 index 3559d52..0000000 --- a/vendor/maximebf/debugbar/src/DebugBar/Resources/vendor/font-awesome/css/font-awesome.min.css +++ /dev/null @@ -1,4 +0,0 @@ -/*! - * Font Awesome 4.7.0 by @davegandy - http://fontawesome.io - @fontawesome - * License - http://fontawesome.io/license (Font: SIL OFL 1.1, CSS: MIT License) - */@font-face{font-family:'PhpDebugbarFontAwesome';src:url('../fonts/fontawesome-webfont.eot?v=4.7.0');src:url('../fonts/fontawesome-webfont.eot?#iefix&v=4.7.0') format('embedded-opentype'),url('../fonts/fontawesome-webfont.woff2?v=4.7.0') format('woff2'),url('../fonts/fontawesome-webfont.woff?v=4.7.0') format('woff'),url('../fonts/fontawesome-webfont.ttf?v=4.7.0') format('truetype'),url('../fonts/fontawesome-webfont.svg?v=4.7.0#fontawesomeregular') format('svg');font-weight:normal;font-style:normal}.phpdebugbar-fa{display:inline-block;font:normal normal normal 14px/1 PhpDebugbarFontAwesome;font-size:inherit;text-rendering:auto;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.phpdebugbar-fa-lg{font-size:1.33333333em;line-height:.75em;vertical-align:-15%}.phpdebugbar-fa-2x{font-size:2em}.phpdebugbar-fa-3x{font-size:3em}.phpdebugbar-fa-4x{font-size:4em}.phpdebugbar-fa-5x{font-size:5em}.phpdebugbar-fa-fw{width:1.28571429em;text-align:center}.phpdebugbar-fa-ul{padding-left:0;margin-left:2.14285714em;list-style-type:none}.phpdebugbar-fa-ul>li{position:relative}.phpdebugbar-fa-li{position:absolute;left:-2.14285714em;width:2.14285714em;top:.14285714em;text-align:center}.phpdebugbar-fa-li.phpdebugbar-fa-lg{left:-1.85714286em}.phpdebugbar-fa-border{padding:.2em .25em .15em;border:solid .08em #eee;border-radius:.1em}.phpdebugbar-fa-pull-left{float:left}.phpdebugbar-fa-pull-right{float:right}.phpdebugbar-fa.phpdebugbar-fa-pull-left{margin-right:.3em}.phpdebugbar-fa.phpdebugbar-fa-pull-right{margin-left:.3em}.pull-right{float:right}.pull-left{float:left}.phpdebugbar-fa.pull-left{margin-right:.3em}.phpdebugbar-fa.pull-right{margin-left:.3em}.phpdebugbar-fa-spin{-webkit-animation:phpdebugbar-fa-spin 2s infinite linear;animation:phpdebugbar-fa-spin 2s infinite linear}.phpdebugbar-fa-pulse{-webkit-animation:phpdebugbar-fa-spin 1s infinite steps(8);animation:phpdebugbar-fa-spin 1s infinite steps(8)}@-webkit-keyframes phpdebugbar-fa-spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes phpdebugbar-fa-spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}.phpdebugbar-fa-rotate-90{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=1)";-webkit-transform:rotate(90deg);-ms-transform:rotate(90deg);transform:rotate(90deg)}.phpdebugbar-fa-rotate-180{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=2)";-webkit-transform:rotate(180deg);-ms-transform:rotate(180deg);transform:rotate(180deg)}.phpdebugbar-fa-rotate-270{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=3)";-webkit-transform:rotate(270deg);-ms-transform:rotate(270deg);transform:rotate(270deg)}.phpdebugbar-fa-flip-horizontal{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=0, mirror=1)";-webkit-transform:scale(-1, 1);-ms-transform:scale(-1, 1);transform:scale(-1, 1)}.phpdebugbar-fa-flip-vertical{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=2, mirror=1)";-webkit-transform:scale(1, -1);-ms-transform:scale(1, -1);transform:scale(1, -1)}:root .phpdebugbar-fa-rotate-90,:root .phpdebugbar-fa-rotate-180,:root .phpdebugbar-fa-rotate-270,:root .phpdebugbar-fa-flip-horizontal,:root .phpdebugbar-fa-flip-vertical{filter:none}.phpdebugbar-fa-stack{position:relative;display:inline-block;width:2em;height:2em;line-height:2em;vertical-align:middle}.phpdebugbar-fa-stack-1x,.phpdebugbar-fa-stack-2x{position:absolute;left:0;width:100%;text-align:center}.phpdebugbar-fa-stack-1x{line-height:inherit}.phpdebugbar-fa-stack-2x{font-size:2em}.phpdebugbar-fa-inverse{color:#fff}.phpdebugbar-fa-glass:before{content:"\f000"}.phpdebugbar-fa-music:before{content:"\f001"}.phpdebugbar-fa-search:before{content:"\f002"}.phpdebugbar-fa-envelope-o:before{content:"\f003"}.phpdebugbar-fa-heart:before{content:"\f004"}.phpdebugbar-fa-star:before{content:"\f005"}.phpdebugbar-fa-star-o:before{content:"\f006"}.phpdebugbar-fa-user:before{content:"\f007"}.phpdebugbar-fa-film:before{content:"\f008"}.phpdebugbar-fa-th-large:before{content:"\f009"}.phpdebugbar-fa-th:before{content:"\f00a"}.phpdebugbar-fa-th-list:before{content:"\f00b"}.phpdebugbar-fa-check:before{content:"\f00c"}.phpdebugbar-fa-remove:before,.phpdebugbar-fa-close:before,.phpdebugbar-fa-times:before{content:"\f00d"}.phpdebugbar-fa-search-plus:before{content:"\f00e"}.phpdebugbar-fa-search-minus:before{content:"\f010"}.phpdebugbar-fa-power-off:before{content:"\f011"}.phpdebugbar-fa-signal:before{content:"\f012"}.phpdebugbar-fa-gear:before,.phpdebugbar-fa-cog:before{content:"\f013"}.phpdebugbar-fa-trash-o:before{content:"\f014"}.phpdebugbar-fa-home:before{content:"\f015"}.phpdebugbar-fa-file-o:before{content:"\f016"}.phpdebugbar-fa-clock-o:before{content:"\f017"}.phpdebugbar-fa-road:before{content:"\f018"}.phpdebugbar-fa-download:before{content:"\f019"}.phpdebugbar-fa-arrow-circle-o-down:before{content:"\f01a"}.phpdebugbar-fa-arrow-circle-o-up:before{content:"\f01b"}.phpdebugbar-fa-inbox:before{content:"\f01c"}.phpdebugbar-fa-play-circle-o:before{content:"\f01d"}.phpdebugbar-fa-rotate-right:before,.phpdebugbar-fa-repeat:before{content:"\f01e"}.phpdebugbar-fa-refresh:before{content:"\f021"}.phpdebugbar-fa-list-alt:before{content:"\f022"}.phpdebugbar-fa-lock:before{content:"\f023"}.phpdebugbar-fa-flag:before{content:"\f024"}.phpdebugbar-fa-headphones:before{content:"\f025"}.phpdebugbar-fa-volume-off:before{content:"\f026"}.phpdebugbar-fa-volume-down:before{content:"\f027"}.phpdebugbar-fa-volume-up:before{content:"\f028"}.phpdebugbar-fa-qrcode:before{content:"\f029"}.phpdebugbar-fa-barcode:before{content:"\f02a"}.phpdebugbar-fa-tag:before{content:"\f02b"}.phpdebugbar-fa-tags:before{content:"\f02c"}.phpdebugbar-fa-book:before{content:"\f02d"}.phpdebugbar-fa-bookmark:before{content:"\f02e"}.phpdebugbar-fa-print:before{content:"\f02f"}.phpdebugbar-fa-camera:before{content:"\f030"}.phpdebugbar-fa-font:before{content:"\f031"}.phpdebugbar-fa-bold:before{content:"\f032"}.phpdebugbar-fa-italic:before{content:"\f033"}.phpdebugbar-fa-text-height:before{content:"\f034"}.phpdebugbar-fa-text-width:before{content:"\f035"}.phpdebugbar-fa-align-left:before{content:"\f036"}.phpdebugbar-fa-align-center:before{content:"\f037"}.phpdebugbar-fa-align-right:before{content:"\f038"}.phpdebugbar-fa-align-justify:before{content:"\f039"}.phpdebugbar-fa-list:before{content:"\f03a"}.phpdebugbar-fa-dedent:before,.phpdebugbar-fa-outdent:before{content:"\f03b"}.phpdebugbar-fa-indent:before{content:"\f03c"}.phpdebugbar-fa-video-camera:before{content:"\f03d"}.phpdebugbar-fa-photo:before,.phpdebugbar-fa-image:before,.phpdebugbar-fa-picture-o:before{content:"\f03e"}.phpdebugbar-fa-pencil:before{content:"\f040"}.phpdebugbar-fa-map-marker:before{content:"\f041"}.phpdebugbar-fa-adjust:before{content:"\f042"}.phpdebugbar-fa-tint:before{content:"\f043"}.phpdebugbar-fa-edit:before,.phpdebugbar-fa-pencil-square-o:before{content:"\f044"}.phpdebugbar-fa-share-square-o:before{content:"\f045"}.phpdebugbar-fa-check-square-o:before{content:"\f046"}.phpdebugbar-fa-arrows:before{content:"\f047"}.phpdebugbar-fa-step-backward:before{content:"\f048"}.phpdebugbar-fa-fast-backward:before{content:"\f049"}.phpdebugbar-fa-backward:before{content:"\f04a"}.phpdebugbar-fa-play:before{content:"\f04b"}.phpdebugbar-fa-pause:before{content:"\f04c"}.phpdebugbar-fa-stop:before{content:"\f04d"}.phpdebugbar-fa-forward:before{content:"\f04e"}.phpdebugbar-fa-fast-forward:before{content:"\f050"}.phpdebugbar-fa-step-forward:before{content:"\f051"}.phpdebugbar-fa-eject:before{content:"\f052"}.phpdebugbar-fa-chevron-left:before{content:"\f053"}.phpdebugbar-fa-chevron-right:before{content:"\f054"}.phpdebugbar-fa-plus-circle:before{content:"\f055"}.phpdebugbar-fa-minus-circle:before{content:"\f056"}.phpdebugbar-fa-times-circle:before{content:"\f057"}.phpdebugbar-fa-check-circle:before{content:"\f058"}.phpdebugbar-fa-question-circle:before{content:"\f059"}.phpdebugbar-fa-info-circle:before{content:"\f05a"}.phpdebugbar-fa-crosshairs:before{content:"\f05b"}.phpdebugbar-fa-times-circle-o:before{content:"\f05c"}.phpdebugbar-fa-check-circle-o:before{content:"\f05d"}.phpdebugbar-fa-ban:before{content:"\f05e"}.phpdebugbar-fa-arrow-left:before{content:"\f060"}.phpdebugbar-fa-arrow-right:before{content:"\f061"}.phpdebugbar-fa-arrow-up:before{content:"\f062"}.phpdebugbar-fa-arrow-down:before{content:"\f063"}.phpdebugbar-fa-mail-forward:before,.phpdebugbar-fa-share:before{content:"\f064"}.phpdebugbar-fa-expand:before{content:"\f065"}.phpdebugbar-fa-compress:before{content:"\f066"}.phpdebugbar-fa-plus:before{content:"\f067"}.phpdebugbar-fa-minus:before{content:"\f068"}.phpdebugbar-fa-asterisk:before{content:"\f069"}.phpdebugbar-fa-exclamation-circle:before{content:"\f06a"}.phpdebugbar-fa-gift:before{content:"\f06b"}.phpdebugbar-fa-leaf:before{content:"\f06c"}.phpdebugbar-fa-fire:before{content:"\f06d"}.phpdebugbar-fa-eye:before{content:"\f06e"}.phpdebugbar-fa-eye-slash:before{content:"\f070"}.phpdebugbar-fa-warning:before,.phpdebugbar-fa-exclamation-triangle:before{content:"\f071"}.phpdebugbar-fa-plane:before{content:"\f072"}.phpdebugbar-fa-calendar:before{content:"\f073"}.phpdebugbar-fa-random:before{content:"\f074"}.phpdebugbar-fa-comment:before{content:"\f075"}.phpdebugbar-fa-magnet:before{content:"\f076"}.phpdebugbar-fa-chevron-up:before{content:"\f077"}.phpdebugbar-fa-chevron-down:before{content:"\f078"}.phpdebugbar-fa-retweet:before{content:"\f079"}.phpdebugbar-fa-shopping-cart:before{content:"\f07a"}.phpdebugbar-fa-folder:before{content:"\f07b"}.phpdebugbar-fa-folder-open:before{content:"\f07c"}.phpdebugbar-fa-arrows-v:before{content:"\f07d"}.phpdebugbar-fa-arrows-h:before{content:"\f07e"}.phpdebugbar-fa-bar-chart-o:before,.phpdebugbar-fa-bar-chart:before{content:"\f080"}.phpdebugbar-fa-twitter-square:before{content:"\f081"}.phpdebugbar-fa-facebook-square:before{content:"\f082"}.phpdebugbar-fa-camera-retro:before{content:"\f083"}.phpdebugbar-fa-key:before{content:"\f084"}.phpdebugbar-fa-gears:before,.phpdebugbar-fa-cogs:before{content:"\f085"}.phpdebugbar-fa-comments:before{content:"\f086"}.phpdebugbar-fa-thumbs-o-up:before{content:"\f087"}.phpdebugbar-fa-thumbs-o-down:before{content:"\f088"}.phpdebugbar-fa-star-half:before{content:"\f089"}.phpdebugbar-fa-heart-o:before{content:"\f08a"}.phpdebugbar-fa-sign-out:before{content:"\f08b"}.phpdebugbar-fa-linkedin-square:before{content:"\f08c"}.phpdebugbar-fa-thumb-tack:before{content:"\f08d"}.phpdebugbar-fa-external-link:before{content:"\f08e"}.phpdebugbar-fa-sign-in:before{content:"\f090"}.phpdebugbar-fa-trophy:before{content:"\f091"}.phpdebugbar-fa-github-square:before{content:"\f092"}.phpdebugbar-fa-upload:before{content:"\f093"}.phpdebugbar-fa-lemon-o:before{content:"\f094"}.phpdebugbar-fa-phone:before{content:"\f095"}.phpdebugbar-fa-square-o:before{content:"\f096"}.phpdebugbar-fa-bookmark-o:before{content:"\f097"}.phpdebugbar-fa-phone-square:before{content:"\f098"}.phpdebugbar-fa-twitter:before{content:"\f099"}.phpdebugbar-fa-facebook-f:before,.phpdebugbar-fa-facebook:before{content:"\f09a"}.phpdebugbar-fa-github:before{content:"\f09b"}.phpdebugbar-fa-unlock:before{content:"\f09c"}.phpdebugbar-fa-credit-card:before{content:"\f09d"}.phpdebugbar-fa-feed:before,.phpdebugbar-fa-rss:before{content:"\f09e"}.phpdebugbar-fa-hdd-o:before{content:"\f0a0"}.phpdebugbar-fa-bullhorn:before{content:"\f0a1"}.phpdebugbar-fa-bell:before{content:"\f0f3"}.phpdebugbar-fa-certificate:before{content:"\f0a3"}.phpdebugbar-fa-hand-o-right:before{content:"\f0a4"}.phpdebugbar-fa-hand-o-left:before{content:"\f0a5"}.phpdebugbar-fa-hand-o-up:before{content:"\f0a6"}.phpdebugbar-fa-hand-o-down:before{content:"\f0a7"}.phpdebugbar-fa-arrow-circle-left:before{content:"\f0a8"}.phpdebugbar-fa-arrow-circle-right:before{content:"\f0a9"}.phpdebugbar-fa-arrow-circle-up:before{content:"\f0aa"}.phpdebugbar-fa-arrow-circle-down:before{content:"\f0ab"}.phpdebugbar-fa-globe:before{content:"\f0ac"}.phpdebugbar-fa-wrench:before{content:"\f0ad"}.phpdebugbar-fa-tasks:before{content:"\f0ae"}.phpdebugbar-fa-filter:before{content:"\f0b0"}.phpdebugbar-fa-briefcase:before{content:"\f0b1"}.phpdebugbar-fa-arrows-alt:before{content:"\f0b2"}.phpdebugbar-fa-group:before,.phpdebugbar-fa-users:before{content:"\f0c0"}.phpdebugbar-fa-chain:before,.phpdebugbar-fa-link:before{content:"\f0c1"}.phpdebugbar-fa-cloud:before{content:"\f0c2"}.phpdebugbar-fa-flask:before{content:"\f0c3"}.phpdebugbar-fa-cut:before,.phpdebugbar-fa-scissors:before{content:"\f0c4"}.phpdebugbar-fa-copy:before,.phpdebugbar-fa-files-o:before{content:"\f0c5"}.phpdebugbar-fa-paperclip:before{content:"\f0c6"}.phpdebugbar-fa-save:before,.phpdebugbar-fa-floppy-o:before{content:"\f0c7"}.phpdebugbar-fa-square:before{content:"\f0c8"}.phpdebugbar-fa-navicon:before,.phpdebugbar-fa-reorder:before,.phpdebugbar-fa-bars:before{content:"\f0c9"}.phpdebugbar-fa-list-ul:before{content:"\f0ca"}.phpdebugbar-fa-list-ol:before{content:"\f0cb"}.phpdebugbar-fa-strikethrough:before{content:"\f0cc"}.phpdebugbar-fa-underline:before{content:"\f0cd"}.phpdebugbar-fa-table:before{content:"\f0ce"}.phpdebugbar-fa-magic:before{content:"\f0d0"}.phpdebugbar-fa-truck:before{content:"\f0d1"}.phpdebugbar-fa-pinterest:before{content:"\f0d2"}.phpdebugbar-fa-pinterest-square:before{content:"\f0d3"}.phpdebugbar-fa-google-plus-square:before{content:"\f0d4"}.phpdebugbar-fa-google-plus:before{content:"\f0d5"}.phpdebugbar-fa-money:before{content:"\f0d6"}.phpdebugbar-fa-caret-down:before{content:"\f0d7"}.phpdebugbar-fa-caret-up:before{content:"\f0d8"}.phpdebugbar-fa-caret-left:before{content:"\f0d9"}.phpdebugbar-fa-caret-right:before{content:"\f0da"}.phpdebugbar-fa-columns:before{content:"\f0db"}.phpdebugbar-fa-unsorted:before,.phpdebugbar-fa-sort:before{content:"\f0dc"}.phpdebugbar-fa-sort-down:before,.phpdebugbar-fa-sort-desc:before{content:"\f0dd"}.phpdebugbar-fa-sort-up:before,.phpdebugbar-fa-sort-asc:before{content:"\f0de"}.phpdebugbar-fa-envelope:before{content:"\f0e0"}.phpdebugbar-fa-linkedin:before{content:"\f0e1"}.phpdebugbar-fa-rotate-left:before,.phpdebugbar-fa-undo:before{content:"\f0e2"}.phpdebugbar-fa-legal:before,.phpdebugbar-fa-gavel:before{content:"\f0e3"}.phpdebugbar-fa-dashboard:before,.phpdebugbar-fa-tachometer:before{content:"\f0e4"}.phpdebugbar-fa-comment-o:before{content:"\f0e5"}.phpdebugbar-fa-comments-o:before{content:"\f0e6"}.phpdebugbar-fa-flash:before,.phpdebugbar-fa-bolt:before{content:"\f0e7"}.phpdebugbar-fa-sitemap:before{content:"\f0e8"}.phpdebugbar-fa-umbrella:before{content:"\f0e9"}.phpdebugbar-fa-paste:before,.phpdebugbar-fa-clipboard:before{content:"\f0ea"}.phpdebugbar-fa-lightbulb-o:before{content:"\f0eb"}.phpdebugbar-fa-exchange:before{content:"\f0ec"}.phpdebugbar-fa-cloud-download:before{content:"\f0ed"}.phpdebugbar-fa-cloud-upload:before{content:"\f0ee"}.phpdebugbar-fa-user-md:before{content:"\f0f0"}.phpdebugbar-fa-stethoscope:before{content:"\f0f1"}.phpdebugbar-fa-suitcase:before{content:"\f0f2"}.phpdebugbar-fa-bell-o:before{content:"\f0a2"}.phpdebugbar-fa-coffee:before{content:"\f0f4"}.phpdebugbar-fa-cutlery:before{content:"\f0f5"}.phpdebugbar-fa-file-text-o:before{content:"\f0f6"}.phpdebugbar-fa-building-o:before{content:"\f0f7"}.phpdebugbar-fa-hospital-o:before{content:"\f0f8"}.phpdebugbar-fa-ambulance:before{content:"\f0f9"}.phpdebugbar-fa-medkit:before{content:"\f0fa"}.phpdebugbar-fa-fighter-jet:before{content:"\f0fb"}.phpdebugbar-fa-beer:before{content:"\f0fc"}.phpdebugbar-fa-h-square:before{content:"\f0fd"}.phpdebugbar-fa-plus-square:before{content:"\f0fe"}.phpdebugbar-fa-angle-double-left:before{content:"\f100"}.phpdebugbar-fa-angle-double-right:before{content:"\f101"}.phpdebugbar-fa-angle-double-up:before{content:"\f102"}.phpdebugbar-fa-angle-double-down:before{content:"\f103"}.phpdebugbar-fa-angle-left:before{content:"\f104"}.phpdebugbar-fa-angle-right:before{content:"\f105"}.phpdebugbar-fa-angle-up:before{content:"\f106"}.phpdebugbar-fa-angle-down:before{content:"\f107"}.phpdebugbar-fa-desktop:before{content:"\f108"}.phpdebugbar-fa-laptop:before{content:"\f109"}.phpdebugbar-fa-tablet:before{content:"\f10a"}.phpdebugbar-fa-mobile-phone:before,.phpdebugbar-fa-mobile:before{content:"\f10b"}.phpdebugbar-fa-circle-o:before{content:"\f10c"}.phpdebugbar-fa-quote-left:before{content:"\f10d"}.phpdebugbar-fa-quote-right:before{content:"\f10e"}.phpdebugbar-fa-spinner:before{content:"\f110"}.phpdebugbar-fa-circle:before{content:"\f111"}.phpdebugbar-fa-mail-reply:before,.phpdebugbar-fa-reply:before{content:"\f112"}.phpdebugbar-fa-github-alt:before{content:"\f113"}.phpdebugbar-fa-folder-o:before{content:"\f114"}.phpdebugbar-fa-folder-open-o:before{content:"\f115"}.phpdebugbar-fa-smile-o:before{content:"\f118"}.phpdebugbar-fa-frown-o:before{content:"\f119"}.phpdebugbar-fa-meh-o:before{content:"\f11a"}.phpdebugbar-fa-gamepad:before{content:"\f11b"}.phpdebugbar-fa-keyboard-o:before{content:"\f11c"}.phpdebugbar-fa-flag-o:before{content:"\f11d"}.phpdebugbar-fa-flag-checkered:before{content:"\f11e"}.phpdebugbar-fa-terminal:before{content:"\f120"}.phpdebugbar-fa-code:before{content:"\f121"}.phpdebugbar-fa-mail-reply-all:before,.phpdebugbar-fa-reply-all:before{content:"\f122"}.phpdebugbar-fa-star-half-empty:before,.phpdebugbar-fa-star-half-full:before,.phpdebugbar-fa-star-half-o:before{content:"\f123"}.phpdebugbar-fa-location-arrow:before{content:"\f124"}.phpdebugbar-fa-crop:before{content:"\f125"}.phpdebugbar-fa-code-fork:before{content:"\f126"}.phpdebugbar-fa-unlink:before,.phpdebugbar-fa-chain-broken:before{content:"\f127"}.phpdebugbar-fa-question:before{content:"\f128"}.phpdebugbar-fa-info:before{content:"\f129"}.phpdebugbar-fa-exclamation:before{content:"\f12a"}.phpdebugbar-fa-superscript:before{content:"\f12b"}.phpdebugbar-fa-subscript:before{content:"\f12c"}.phpdebugbar-fa-eraser:before{content:"\f12d"}.phpdebugbar-fa-puzzle-piece:before{content:"\f12e"}.phpdebugbar-fa-microphone:before{content:"\f130"}.phpdebugbar-fa-microphone-slash:before{content:"\f131"}.phpdebugbar-fa-shield:before{content:"\f132"}.phpdebugbar-fa-calendar-o:before{content:"\f133"}.phpdebugbar-fa-fire-extinguisher:before{content:"\f134"}.phpdebugbar-fa-rocket:before{content:"\f135"}.phpdebugbar-fa-maxcdn:before{content:"\f136"}.phpdebugbar-fa-chevron-circle-left:before{content:"\f137"}.phpdebugbar-fa-chevron-circle-right:before{content:"\f138"}.phpdebugbar-fa-chevron-circle-up:before{content:"\f139"}.phpdebugbar-fa-chevron-circle-down:before{content:"\f13a"}.phpdebugbar-fa-html5:before{content:"\f13b"}.phpdebugbar-fa-css3:before{content:"\f13c"}.phpdebugbar-fa-anchor:before{content:"\f13d"}.phpdebugbar-fa-unlock-alt:before{content:"\f13e"}.phpdebugbar-fa-bullseye:before{content:"\f140"}.phpdebugbar-fa-ellipsis-h:before{content:"\f141"}.phpdebugbar-fa-ellipsis-v:before{content:"\f142"}.phpdebugbar-fa-rss-square:before{content:"\f143"}.phpdebugbar-fa-play-circle:before{content:"\f144"}.phpdebugbar-fa-ticket:before{content:"\f145"}.phpdebugbar-fa-minus-square:before{content:"\f146"}.phpdebugbar-fa-minus-square-o:before{content:"\f147"}.phpdebugbar-fa-level-up:before{content:"\f148"}.phpdebugbar-fa-level-down:before{content:"\f149"}.phpdebugbar-fa-check-square:before{content:"\f14a"}.phpdebugbar-fa-pencil-square:before{content:"\f14b"}.phpdebugbar-fa-external-link-square:before{content:"\f14c"}.phpdebugbar-fa-share-square:before{content:"\f14d"}.phpdebugbar-fa-compass:before{content:"\f14e"}.phpdebugbar-fa-toggle-down:before,.phpdebugbar-fa-caret-square-o-down:before{content:"\f150"}.phpdebugbar-fa-toggle-up:before,.phpdebugbar-fa-caret-square-o-up:before{content:"\f151"}.phpdebugbar-fa-toggle-right:before,.phpdebugbar-fa-caret-square-o-right:before{content:"\f152"}.phpdebugbar-fa-euro:before,.phpdebugbar-fa-eur:before{content:"\f153"}.phpdebugbar-fa-gbp:before{content:"\f154"}.phpdebugbar-fa-dollar:before,.phpdebugbar-fa-usd:before{content:"\f155"}.phpdebugbar-fa-rupee:before,.phpdebugbar-fa-inr:before{content:"\f156"}.phpdebugbar-fa-cny:before,.phpdebugbar-fa-rmb:before,.phpdebugbar-fa-yen:before,.phpdebugbar-fa-jpy:before{content:"\f157"}.phpdebugbar-fa-ruble:before,.phpdebugbar-fa-rouble:before,.phpdebugbar-fa-rub:before{content:"\f158"}.phpdebugbar-fa-won:before,.phpdebugbar-fa-krw:before{content:"\f159"}.phpdebugbar-fa-bitcoin:before,.phpdebugbar-fa-btc:before{content:"\f15a"}.phpdebugbar-fa-file:before{content:"\f15b"}.phpdebugbar-fa-file-text:before{content:"\f15c"}.phpdebugbar-fa-sort-alpha-asc:before{content:"\f15d"}.phpdebugbar-fa-sort-alpha-desc:before{content:"\f15e"}.phpdebugbar-fa-sort-amount-asc:before{content:"\f160"}.phpdebugbar-fa-sort-amount-desc:before{content:"\f161"}.phpdebugbar-fa-sort-numeric-asc:before{content:"\f162"}.phpdebugbar-fa-sort-numeric-desc:before{content:"\f163"}.phpdebugbar-fa-thumbs-up:before{content:"\f164"}.phpdebugbar-fa-thumbs-down:before{content:"\f165"}.phpdebugbar-fa-youtube-square:before{content:"\f166"}.phpdebugbar-fa-youtube:before{content:"\f167"}.phpdebugbar-fa-xing:before{content:"\f168"}.phpdebugbar-fa-xing-square:before{content:"\f169"}.phpdebugbar-fa-youtube-play:before{content:"\f16a"}.phpdebugbar-fa-dropbox:before{content:"\f16b"}.phpdebugbar-fa-stack-overflow:before{content:"\f16c"}.phpdebugbar-fa-instagram:before{content:"\f16d"}.phpdebugbar-fa-flickr:before{content:"\f16e"}.phpdebugbar-fa-adn:before{content:"\f170"}.phpdebugbar-fa-bitbucket:before{content:"\f171"}.phpdebugbar-fa-bitbucket-square:before{content:"\f172"}.phpdebugbar-fa-tumblr:before{content:"\f173"}.phpdebugbar-fa-tumblr-square:before{content:"\f174"}.phpdebugbar-fa-long-arrow-down:before{content:"\f175"}.phpdebugbar-fa-long-arrow-up:before{content:"\f176"}.phpdebugbar-fa-long-arrow-left:before{content:"\f177"}.phpdebugbar-fa-long-arrow-right:before{content:"\f178"}.phpdebugbar-fa-apple:before{content:"\f179"}.phpdebugbar-fa-windows:before{content:"\f17a"}.phpdebugbar-fa-android:before{content:"\f17b"}.phpdebugbar-fa-linux:before{content:"\f17c"}.phpdebugbar-fa-dribbble:before{content:"\f17d"}.phpdebugbar-fa-skype:before{content:"\f17e"}.phpdebugbar-fa-foursquare:before{content:"\f180"}.phpdebugbar-fa-trello:before{content:"\f181"}.phpdebugbar-fa-female:before{content:"\f182"}.phpdebugbar-fa-male:before{content:"\f183"}.phpdebugbar-fa-gittip:before,.phpdebugbar-fa-gratipay:before{content:"\f184"}.phpdebugbar-fa-sun-o:before{content:"\f185"}.phpdebugbar-fa-moon-o:before{content:"\f186"}.phpdebugbar-fa-archive:before{content:"\f187"}.phpdebugbar-fa-bug:before{content:"\f188"}.phpdebugbar-fa-vk:before{content:"\f189"}.phpdebugbar-fa-weibo:before{content:"\f18a"}.phpdebugbar-fa-renren:before{content:"\f18b"}.phpdebugbar-fa-pagelines:before{content:"\f18c"}.phpdebugbar-fa-stack-exchange:before{content:"\f18d"}.phpdebugbar-fa-arrow-circle-o-right:before{content:"\f18e"}.phpdebugbar-fa-arrow-circle-o-left:before{content:"\f190"}.phpdebugbar-fa-toggle-left:before,.phpdebugbar-fa-caret-square-o-left:before{content:"\f191"}.phpdebugbar-fa-dot-circle-o:before{content:"\f192"}.phpdebugbar-fa-wheelchair:before{content:"\f193"}.phpdebugbar-fa-vimeo-square:before{content:"\f194"}.phpdebugbar-fa-turkish-lira:before,.phpdebugbar-fa-try:before{content:"\f195"}.phpdebugbar-fa-plus-square-o:before{content:"\f196"}.phpdebugbar-fa-space-shuttle:before{content:"\f197"}.phpdebugbar-fa-slack:before{content:"\f198"}.phpdebugbar-fa-envelope-square:before{content:"\f199"}.phpdebugbar-fa-wordpress:before{content:"\f19a"}.phpdebugbar-fa-openid:before{content:"\f19b"}.phpdebugbar-fa-institution:before,.phpdebugbar-fa-bank:before,.phpdebugbar-fa-university:before{content:"\f19c"}.phpdebugbar-fa-mortar-board:before,.phpdebugbar-fa-graduation-cap:before{content:"\f19d"}.phpdebugbar-fa-yahoo:before{content:"\f19e"}.phpdebugbar-fa-google:before{content:"\f1a0"}.phpdebugbar-fa-reddit:before{content:"\f1a1"}.phpdebugbar-fa-reddit-square:before{content:"\f1a2"}.phpdebugbar-fa-stumbleupon-circle:before{content:"\f1a3"}.phpdebugbar-fa-stumbleupon:before{content:"\f1a4"}.phpdebugbar-fa-delicious:before{content:"\f1a5"}.phpdebugbar-fa-digg:before{content:"\f1a6"}.phpdebugbar-fa-pied-piper-pp:before{content:"\f1a7"}.phpdebugbar-fa-pied-piper-alt:before{content:"\f1a8"}.phpdebugbar-fa-drupal:before{content:"\f1a9"}.phpdebugbar-fa-joomla:before{content:"\f1aa"}.phpdebugbar-fa-language:before{content:"\f1ab"}.phpdebugbar-fa-fax:before{content:"\f1ac"}.phpdebugbar-fa-building:before{content:"\f1ad"}.phpdebugbar-fa-child:before{content:"\f1ae"}.phpdebugbar-fa-paw:before{content:"\f1b0"}.phpdebugbar-fa-spoon:before{content:"\f1b1"}.phpdebugbar-fa-cube:before{content:"\f1b2"}.phpdebugbar-fa-cubes:before{content:"\f1b3"}.phpdebugbar-fa-behance:before{content:"\f1b4"}.phpdebugbar-fa-behance-square:before{content:"\f1b5"}.phpdebugbar-fa-steam:before{content:"\f1b6"}.phpdebugbar-fa-steam-square:before{content:"\f1b7"}.phpdebugbar-fa-recycle:before{content:"\f1b8"}.phpdebugbar-fa-automobile:before,.phpdebugbar-fa-car:before{content:"\f1b9"}.phpdebugbar-fa-cab:before,.phpdebugbar-fa-taxi:before{content:"\f1ba"}.phpdebugbar-fa-tree:before{content:"\f1bb"}.phpdebugbar-fa-spotify:before{content:"\f1bc"}.phpdebugbar-fa-deviantart:before{content:"\f1bd"}.phpdebugbar-fa-soundcloud:before{content:"\f1be"}.phpdebugbar-fa-database:before{content:"\f1c0"}.phpdebugbar-fa-file-pdf-o:before{content:"\f1c1"}.phpdebugbar-fa-file-word-o:before{content:"\f1c2"}.phpdebugbar-fa-file-excel-o:before{content:"\f1c3"}.phpdebugbar-fa-file-powerpoint-o:before{content:"\f1c4"}.phpdebugbar-fa-file-photo-o:before,.phpdebugbar-fa-file-picture-o:before,.phpdebugbar-fa-file-image-o:before{content:"\f1c5"}.phpdebugbar-fa-file-zip-o:before,.phpdebugbar-fa-file-archive-o:before{content:"\f1c6"}.phpdebugbar-fa-file-sound-o:before,.phpdebugbar-fa-file-audio-o:before{content:"\f1c7"}.phpdebugbar-fa-file-movie-o:before,.phpdebugbar-fa-file-video-o:before{content:"\f1c8"}.phpdebugbar-fa-file-code-o:before{content:"\f1c9"}.phpdebugbar-fa-vine:before{content:"\f1ca"}.phpdebugbar-fa-codepen:before{content:"\f1cb"}.phpdebugbar-fa-jsfiddle:before{content:"\f1cc"}.phpdebugbar-fa-life-bouy:before,.phpdebugbar-fa-life-buoy:before,.phpdebugbar-fa-life-saver:before,.phpdebugbar-fa-support:before,.phpdebugbar-fa-life-ring:before{content:"\f1cd"}.phpdebugbar-fa-circle-o-notch:before{content:"\f1ce"}.phpdebugbar-fa-ra:before,.phpdebugbar-fa-resistance:before,.phpdebugbar-fa-rebel:before{content:"\f1d0"}.phpdebugbar-fa-ge:before,.phpdebugbar-fa-empire:before{content:"\f1d1"}.phpdebugbar-fa-git-square:before{content:"\f1d2"}.phpdebugbar-fa-git:before{content:"\f1d3"}.phpdebugbar-fa-y-combinator-square:before,.phpdebugbar-fa-yc-square:before,.phpdebugbar-fa-hacker-news:before{content:"\f1d4"}.phpdebugbar-fa-tencent-weibo:before{content:"\f1d5"}.phpdebugbar-fa-qq:before{content:"\f1d6"}.phpdebugbar-fa-wechat:before,.phpdebugbar-fa-weixin:before{content:"\f1d7"}.phpdebugbar-fa-send:before,.phpdebugbar-fa-paper-plane:before{content:"\f1d8"}.phpdebugbar-fa-send-o:before,.phpdebugbar-fa-paper-plane-o:before{content:"\f1d9"}.phpdebugbar-fa-history:before{content:"\f1da"}.phpdebugbar-fa-circle-thin:before{content:"\f1db"}.phpdebugbar-fa-header:before{content:"\f1dc"}.phpdebugbar-fa-paragraph:before{content:"\f1dd"}.phpdebugbar-fa-sliders:before{content:"\f1de"}.phpdebugbar-fa-share-alt:before{content:"\f1e0"}.phpdebugbar-fa-share-alt-square:before{content:"\f1e1"}.phpdebugbar-fa-bomb:before{content:"\f1e2"}.phpdebugbar-fa-soccer-ball-o:before,.phpdebugbar-fa-futbol-o:before{content:"\f1e3"}.phpdebugbar-fa-tty:before{content:"\f1e4"}.phpdebugbar-fa-binoculars:before{content:"\f1e5"}.phpdebugbar-fa-plug:before{content:"\f1e6"}.phpdebugbar-fa-slideshare:before{content:"\f1e7"}.phpdebugbar-fa-twitch:before{content:"\f1e8"}.phpdebugbar-fa-yelp:before{content:"\f1e9"}.phpdebugbar-fa-newspaper-o:before{content:"\f1ea"}.phpdebugbar-fa-wifi:before{content:"\f1eb"}.phpdebugbar-fa-calculator:before{content:"\f1ec"}.phpdebugbar-fa-paypal:before{content:"\f1ed"}.phpdebugbar-fa-google-wallet:before{content:"\f1ee"}.phpdebugbar-fa-cc-visa:before{content:"\f1f0"}.phpdebugbar-fa-cc-mastercard:before{content:"\f1f1"}.phpdebugbar-fa-cc-discover:before{content:"\f1f2"}.phpdebugbar-fa-cc-amex:before{content:"\f1f3"}.phpdebugbar-fa-cc-paypal:before{content:"\f1f4"}.phpdebugbar-fa-cc-stripe:before{content:"\f1f5"}.phpdebugbar-fa-bell-slash:before{content:"\f1f6"}.phpdebugbar-fa-bell-slash-o:before{content:"\f1f7"}.phpdebugbar-fa-trash:before{content:"\f1f8"}.phpdebugbar-fa-copyright:before{content:"\f1f9"}.phpdebugbar-fa-at:before{content:"\f1fa"}.phpdebugbar-fa-eyedropper:before{content:"\f1fb"}.phpdebugbar-fa-paint-brush:before{content:"\f1fc"}.phpdebugbar-fa-birthday-cake:before{content:"\f1fd"}.phpdebugbar-fa-area-chart:before{content:"\f1fe"}.phpdebugbar-fa-pie-chart:before{content:"\f200"}.phpdebugbar-fa-line-chart:before{content:"\f201"}.phpdebugbar-fa-lastfm:before{content:"\f202"}.phpdebugbar-fa-lastfm-square:before{content:"\f203"}.phpdebugbar-fa-toggle-off:before{content:"\f204"}.phpdebugbar-fa-toggle-on:before{content:"\f205"}.phpdebugbar-fa-bicycle:before{content:"\f206"}.phpdebugbar-fa-bus:before{content:"\f207"}.phpdebugbar-fa-ioxhost:before{content:"\f208"}.phpdebugbar-fa-angellist:before{content:"\f209"}.phpdebugbar-fa-cc:before{content:"\f20a"}.phpdebugbar-fa-shekel:before,.phpdebugbar-fa-sheqel:before,.phpdebugbar-fa-ils:before{content:"\f20b"}.phpdebugbar-fa-meanpath:before{content:"\f20c"}.phpdebugbar-fa-buysellads:before{content:"\f20d"}.phpdebugbar-fa-connectdevelop:before{content:"\f20e"}.phpdebugbar-fa-dashcube:before{content:"\f210"}.phpdebugbar-fa-forumbee:before{content:"\f211"}.phpdebugbar-fa-leanpub:before{content:"\f212"}.phpdebugbar-fa-sellsy:before{content:"\f213"}.phpdebugbar-fa-shirtsinbulk:before{content:"\f214"}.phpdebugbar-fa-simplybuilt:before{content:"\f215"}.phpdebugbar-fa-skyatlas:before{content:"\f216"}.phpdebugbar-fa-cart-plus:before{content:"\f217"}.phpdebugbar-fa-cart-arrow-down:before{content:"\f218"}.phpdebugbar-fa-diamond:before{content:"\f219"}.phpdebugbar-fa-ship:before{content:"\f21a"}.phpdebugbar-fa-user-secret:before{content:"\f21b"}.phpdebugbar-fa-motorcycle:before{content:"\f21c"}.phpdebugbar-fa-street-view:before{content:"\f21d"}.phpdebugbar-fa-heartbeat:before{content:"\f21e"}.phpdebugbar-fa-venus:before{content:"\f221"}.phpdebugbar-fa-mars:before{content:"\f222"}.phpdebugbar-fa-mercury:before{content:"\f223"}.phpdebugbar-fa-intersex:before,.phpdebugbar-fa-transgender:before{content:"\f224"}.phpdebugbar-fa-transgender-alt:before{content:"\f225"}.phpdebugbar-fa-venus-double:before{content:"\f226"}.phpdebugbar-fa-mars-double:before{content:"\f227"}.phpdebugbar-fa-venus-mars:before{content:"\f228"}.phpdebugbar-fa-mars-stroke:before{content:"\f229"}.phpdebugbar-fa-mars-stroke-v:before{content:"\f22a"}.phpdebugbar-fa-mars-stroke-h:before{content:"\f22b"}.phpdebugbar-fa-neuter:before{content:"\f22c"}.phpdebugbar-fa-genderless:before{content:"\f22d"}.phpdebugbar-fa-facebook-official:before{content:"\f230"}.phpdebugbar-fa-pinterest-p:before{content:"\f231"}.phpdebugbar-fa-whatsapp:before{content:"\f232"}.phpdebugbar-fa-server:before{content:"\f233"}.phpdebugbar-fa-user-plus:before{content:"\f234"}.phpdebugbar-fa-user-times:before{content:"\f235"}.phpdebugbar-fa-hotel:before,.phpdebugbar-fa-bed:before{content:"\f236"}.phpdebugbar-fa-viacoin:before{content:"\f237"}.phpdebugbar-fa-train:before{content:"\f238"}.phpdebugbar-fa-subway:before{content:"\f239"}.phpdebugbar-fa-medium:before{content:"\f23a"}.phpdebugbar-fa-yc:before,.phpdebugbar-fa-y-combinator:before{content:"\f23b"}.phpdebugbar-fa-optin-monster:before{content:"\f23c"}.phpdebugbar-fa-opencart:before{content:"\f23d"}.phpdebugbar-fa-expeditedssl:before{content:"\f23e"}.phpdebugbar-fa-battery-4:before,.phpdebugbar-fa-battery:before,.phpdebugbar-fa-battery-full:before{content:"\f240"}.phpdebugbar-fa-battery-3:before,.phpdebugbar-fa-battery-three-quarters:before{content:"\f241"}.phpdebugbar-fa-battery-2:before,.phpdebugbar-fa-battery-half:before{content:"\f242"}.phpdebugbar-fa-battery-1:before,.phpdebugbar-fa-battery-quarter:before{content:"\f243"}.phpdebugbar-fa-battery-0:before,.phpdebugbar-fa-battery-empty:before{content:"\f244"}.phpdebugbar-fa-mouse-pointer:before{content:"\f245"}.phpdebugbar-fa-i-cursor:before{content:"\f246"}.phpdebugbar-fa-object-group:before{content:"\f247"}.phpdebugbar-fa-object-ungroup:before{content:"\f248"}.phpdebugbar-fa-sticky-note:before{content:"\f249"}.phpdebugbar-fa-sticky-note-o:before{content:"\f24a"}.phpdebugbar-fa-cc-jcb:before{content:"\f24b"}.phpdebugbar-fa-cc-diners-club:before{content:"\f24c"}.phpdebugbar-fa-clone:before{content:"\f24d"}.phpdebugbar-fa-balance-scale:before{content:"\f24e"}.phpdebugbar-fa-hourglass-o:before{content:"\f250"}.phpdebugbar-fa-hourglass-1:before,.phpdebugbar-fa-hourglass-start:before{content:"\f251"}.phpdebugbar-fa-hourglass-2:before,.phpdebugbar-fa-hourglass-half:before{content:"\f252"}.phpdebugbar-fa-hourglass-3:before,.phpdebugbar-fa-hourglass-end:before{content:"\f253"}.phpdebugbar-fa-hourglass:before{content:"\f254"}.phpdebugbar-fa-hand-grab-o:before,.phpdebugbar-fa-hand-rock-o:before{content:"\f255"}.phpdebugbar-fa-hand-stop-o:before,.phpdebugbar-fa-hand-paper-o:before{content:"\f256"}.phpdebugbar-fa-hand-scissors-o:before{content:"\f257"}.phpdebugbar-fa-hand-lizard-o:before{content:"\f258"}.phpdebugbar-fa-hand-spock-o:before{content:"\f259"}.phpdebugbar-fa-hand-pointer-o:before{content:"\f25a"}.phpdebugbar-fa-hand-peace-o:before{content:"\f25b"}.phpdebugbar-fa-trademark:before{content:"\f25c"}.phpdebugbar-fa-registered:before{content:"\f25d"}.phpdebugbar-fa-creative-commons:before{content:"\f25e"}.phpdebugbar-fa-gg:before{content:"\f260"}.phpdebugbar-fa-gg-circle:before{content:"\f261"}.phpdebugbar-fa-tripadvisor:before{content:"\f262"}.phpdebugbar-fa-odnoklassniki:before{content:"\f263"}.phpdebugbar-fa-odnoklassniki-square:before{content:"\f264"}.phpdebugbar-fa-get-pocket:before{content:"\f265"}.phpdebugbar-fa-wikipedia-w:before{content:"\f266"}.phpdebugbar-fa-safari:before{content:"\f267"}.phpdebugbar-fa-chrome:before{content:"\f268"}.phpdebugbar-fa-firefox:before{content:"\f269"}.phpdebugbar-fa-opera:before{content:"\f26a"}.phpdebugbar-fa-internet-explorer:before{content:"\f26b"}.phpdebugbar-fa-tv:before,.phpdebugbar-fa-television:before{content:"\f26c"}.phpdebugbar-fa-contao:before{content:"\f26d"}.phpdebugbar-fa-500px:before{content:"\f26e"}.phpdebugbar-fa-amazon:before{content:"\f270"}.phpdebugbar-fa-calendar-plus-o:before{content:"\f271"}.phpdebugbar-fa-calendar-minus-o:before{content:"\f272"}.phpdebugbar-fa-calendar-times-o:before{content:"\f273"}.phpdebugbar-fa-calendar-check-o:before{content:"\f274"}.phpdebugbar-fa-industry:before{content:"\f275"}.phpdebugbar-fa-map-pin:before{content:"\f276"}.phpdebugbar-fa-map-signs:before{content:"\f277"}.phpdebugbar-fa-map-o:before{content:"\f278"}.phpdebugbar-fa-map:before{content:"\f279"}.phpdebugbar-fa-commenting:before{content:"\f27a"}.phpdebugbar-fa-commenting-o:before{content:"\f27b"}.phpdebugbar-fa-houzz:before{content:"\f27c"}.phpdebugbar-fa-vimeo:before{content:"\f27d"}.phpdebugbar-fa-black-tie:before{content:"\f27e"}.phpdebugbar-fa-fonticons:before{content:"\f280"}.phpdebugbar-fa-reddit-alien:before{content:"\f281"}.phpdebugbar-fa-edge:before{content:"\f282"}.phpdebugbar-fa-credit-card-alt:before{content:"\f283"}.phpdebugbar-fa-codiepie:before{content:"\f284"}.phpdebugbar-fa-modx:before{content:"\f285"}.phpdebugbar-fa-fort-awesome:before{content:"\f286"}.phpdebugbar-fa-usb:before{content:"\f287"}.phpdebugbar-fa-product-hunt:before{content:"\f288"}.phpdebugbar-fa-mixcloud:before{content:"\f289"}.phpdebugbar-fa-scribd:before{content:"\f28a"}.phpdebugbar-fa-pause-circle:before{content:"\f28b"}.phpdebugbar-fa-pause-circle-o:before{content:"\f28c"}.phpdebugbar-fa-stop-circle:before{content:"\f28d"}.phpdebugbar-fa-stop-circle-o:before{content:"\f28e"}.phpdebugbar-fa-shopping-bag:before{content:"\f290"}.phpdebugbar-fa-shopping-basket:before{content:"\f291"}.phpdebugbar-fa-hashtag:before{content:"\f292"}.phpdebugbar-fa-bluetooth:before{content:"\f293"}.phpdebugbar-fa-bluetooth-b:before{content:"\f294"}.phpdebugbar-fa-percent:before{content:"\f295"}.phpdebugbar-fa-gitlab:before{content:"\f296"}.phpdebugbar-fa-wpbeginner:before{content:"\f297"}.phpdebugbar-fa-wpforms:before{content:"\f298"}.phpdebugbar-fa-envira:before{content:"\f299"}.phpdebugbar-fa-universal-access:before{content:"\f29a"}.phpdebugbar-fa-wheelchair-alt:before{content:"\f29b"}.phpdebugbar-fa-question-circle-o:before{content:"\f29c"}.phpdebugbar-fa-blind:before{content:"\f29d"}.phpdebugbar-fa-audio-description:before{content:"\f29e"}.phpdebugbar-fa-volume-control-phone:before{content:"\f2a0"}.phpdebugbar-fa-braille:before{content:"\f2a1"}.phpdebugbar-fa-assistive-listening-systems:before{content:"\f2a2"}.phpdebugbar-fa-asl-interpreting:before,.phpdebugbar-fa-american-sign-language-interpreting:before{content:"\f2a3"}.phpdebugbar-fa-deafness:before,.phpdebugbar-fa-hard-of-hearing:before,.phpdebugbar-fa-deaf:before{content:"\f2a4"}.phpdebugbar-fa-glide:before{content:"\f2a5"}.phpdebugbar-fa-glide-g:before{content:"\f2a6"}.phpdebugbar-fa-signing:before,.phpdebugbar-fa-sign-language:before{content:"\f2a7"}.phpdebugbar-fa-low-vision:before{content:"\f2a8"}.phpdebugbar-fa-viadeo:before{content:"\f2a9"}.phpdebugbar-fa-viadeo-square:before{content:"\f2aa"}.phpdebugbar-fa-snapchat:before{content:"\f2ab"}.phpdebugbar-fa-snapchat-ghost:before{content:"\f2ac"}.phpdebugbar-fa-snapchat-square:before{content:"\f2ad"}.phpdebugbar-fa-pied-piper:before{content:"\f2ae"}.phpdebugbar-fa-first-order:before{content:"\f2b0"}.phpdebugbar-fa-yoast:before{content:"\f2b1"}.phpdebugbar-fa-themeisle:before{content:"\f2b2"}.phpdebugbar-fa-google-plus-circle:before,.phpdebugbar-fa-google-plus-official:before{content:"\f2b3"}.phpdebugbar-fa-fa:before,.phpdebugbar-fa-font-awesome:before{content:"\f2b4"}.phpdebugbar-fa-handshake-o:before{content:"\f2b5"}.phpdebugbar-fa-envelope-open:before{content:"\f2b6"}.phpdebugbar-fa-envelope-open-o:before{content:"\f2b7"}.phpdebugbar-fa-linode:before{content:"\f2b8"}.phpdebugbar-fa-address-book:before{content:"\f2b9"}.phpdebugbar-fa-address-book-o:before{content:"\f2ba"}.phpdebugbar-fa-vcard:before,.phpdebugbar-fa-address-card:before{content:"\f2bb"}.phpdebugbar-fa-vcard-o:before,.phpdebugbar-fa-address-card-o:before{content:"\f2bc"}.phpdebugbar-fa-user-circle:before{content:"\f2bd"}.phpdebugbar-fa-user-circle-o:before{content:"\f2be"}.phpdebugbar-fa-user-o:before{content:"\f2c0"}.phpdebugbar-fa-id-badge:before{content:"\f2c1"}.phpdebugbar-fa-drivers-license:before,.phpdebugbar-fa-id-card:before{content:"\f2c2"}.phpdebugbar-fa-drivers-license-o:before,.phpdebugbar-fa-id-card-o:before{content:"\f2c3"}.phpdebugbar-fa-quora:before{content:"\f2c4"}.phpdebugbar-fa-free-code-camp:before{content:"\f2c5"}.phpdebugbar-fa-telegram:before{content:"\f2c6"}.phpdebugbar-fa-thermometer-4:before,.phpdebugbar-fa-thermometer:before,.phpdebugbar-fa-thermometer-full:before{content:"\f2c7"}.phpdebugbar-fa-thermometer-3:before,.phpdebugbar-fa-thermometer-three-quarters:before{content:"\f2c8"}.phpdebugbar-fa-thermometer-2:before,.phpdebugbar-fa-thermometer-half:before{content:"\f2c9"}.phpdebugbar-fa-thermometer-1:before,.phpdebugbar-fa-thermometer-quarter:before{content:"\f2ca"}.phpdebugbar-fa-thermometer-0:before,.phpdebugbar-fa-thermometer-empty:before{content:"\f2cb"}.phpdebugbar-fa-shower:before{content:"\f2cc"}.phpdebugbar-fa-bathtub:before,.phpdebugbar-fa-s15:before,.phpdebugbar-fa-bath:before{content:"\f2cd"}.phpdebugbar-fa-podcast:before{content:"\f2ce"}.phpdebugbar-fa-window-maximize:before{content:"\f2d0"}.phpdebugbar-fa-window-minimize:before{content:"\f2d1"}.phpdebugbar-fa-window-restore:before{content:"\f2d2"}.phpdebugbar-fa-times-rectangle:before,.phpdebugbar-fa-window-close:before{content:"\f2d3"}.phpdebugbar-fa-times-rectangle-o:before,.phpdebugbar-fa-window-close-o:before{content:"\f2d4"}.phpdebugbar-fa-bandcamp:before{content:"\f2d5"}.phpdebugbar-fa-grav:before{content:"\f2d6"}.phpdebugbar-fa-etsy:before{content:"\f2d7"}.phpdebugbar-fa-imdb:before{content:"\f2d8"}.phpdebugbar-fa-ravelry:before{content:"\f2d9"}.phpdebugbar-fa-eercast:before{content:"\f2da"}.phpdebugbar-fa-microchip:before{content:"\f2db"}.phpdebugbar-fa-snowflake-o:before{content:"\f2dc"}.phpdebugbar-fa-superpowers:before{content:"\f2dd"}.phpdebugbar-fa-wpexplorer:before{content:"\f2de"}.phpdebugbar-fa-meetup:before{content:"\f2e0"}.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0, 0, 0, 0);border:0}.sr-only-focusable:active,.sr-only-focusable:focus{position:static;width:auto;height:auto;margin:0;overflow:visible;clip:auto} diff --git a/vendor/maximebf/debugbar/src/DebugBar/Resources/vendor/font-awesome/fonts/FontAwesome.otf b/vendor/maximebf/debugbar/src/DebugBar/Resources/vendor/font-awesome/fonts/FontAwesome.otf deleted file mode 100644 index 401ec0f36e4f73b8efa40bd6f604fe80d286db70..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 134808 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 diff --git a/vendor/maximebf/debugbar/src/DebugBar/Resources/vendor/font-awesome/fonts/fontawesome-webfont.eot b/vendor/maximebf/debugbar/src/DebugBar/Resources/vendor/font-awesome/fonts/fontawesome-webfont.eot deleted file mode 100644 index e9f60ca953f93e35eab4108bd414bc02ddcf3928..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 165742 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 G*yFsbY~cLNXLP73aA74Mq6M9f^&YV`isWW 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

5q!RY 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 - - - -Created by FontForge 20120731 at Mon Oct 24 17:37:40 2016 - By ,,, -Copyright Dave Gandy 2016. All rights reserved. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/vendor/maximebf/debugbar/src/DebugBar/Resources/vendor/font-awesome/fonts/fontawesome-webfont.ttf b/vendor/maximebf/debugbar/src/DebugBar/Resources/vendor/font-awesome/fonts/fontawesome-webfont.ttf deleted file mode 100644 index 35acda2fa1196aad98c2adf4378a7611dd713aa3..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 165548 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 z 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

",2===Jt.childNodes.length),ce.parseHTML=function(e,t,n){return"string"!=typeof e?[]:("boolean"==typeof t&&(n=t,t=!1),t||(le.createHTMLDocument?((r=(t=C.implementation.createHTMLDocument("")).createElement("base")).href=C.location.href,t.head.appendChild(r)):t=C),o=!n&&[],(i=w.exec(e))?[t.createElement(i[1])]:(i=Ae([e],t,o),o&&o.length&&ce(o).remove(),ce.merge([],i.childNodes)));var r,i,o},ce.fn.load=function(e,t,n){var r,i,o,a=this,s=e.indexOf(" ");return-1").append(ce.parseHTML(e)).find(r):e)}).always(n&&function(e,t){a.each(function(){n.apply(this,o||[e.responseText,t,e])})}),this},ce.expr.pseudos.animated=function(t){return ce.grep(ce.timers,function(e){return t===e.elem}).length},ce.offset={setOffset:function(e,t,n){var r,i,o,a,s,u,l=ce.css(e,"position"),c=ce(e),f={};"static"===l&&(e.style.position="relative"),s=c.offset(),o=ce.css(e,"top"),u=ce.css(e,"left"),("absolute"===l||"fixed"===l)&&-1<(o+u).indexOf("auto")?(a=(r=c.position()).top,i=r.left):(a=parseFloat(o)||0,i=parseFloat(u)||0),v(t)&&(t=t.call(e,n,ce.extend({},s))),null!=t.top&&(f.top=t.top-s.top+a),null!=t.left&&(f.left=t.left-s.left+i),"using"in t?t.using.call(e,f):c.css(f)}},ce.fn.extend({offset:function(t){if(arguments.length)return void 0===t?this:this.each(function(e){ce.offset.setOffset(this,t,e)});var e,n,r=this[0];return r?r.getClientRects().length?(e=r.getBoundingClientRect(),n=r.ownerDocument.defaultView,{top:e.top+n.pageYOffset,left:e.left+n.pageXOffset}):{top:0,left:0}:void 0},position:function(){if(this[0]){var e,t,n,r=this[0],i={top:0,left:0};if("fixed"===ce.css(r,"position"))t=r.getBoundingClientRect();else{t=this.offset(),n=r.ownerDocument,e=r.offsetParent||n.documentElement;while(e&&(e===n.body||e===n.documentElement)&&"static"===ce.css(e,"position"))e=e.parentNode;e&&e!==r&&1===e.nodeType&&((i=ce(e).offset()).top+=ce.css(e,"borderTopWidth",!0),i.left+=ce.css(e,"borderLeftWidth",!0))}return{top:t.top-i.top-ce.css(r,"marginTop",!0),left:t.left-i.left-ce.css(r,"marginLeft",!0)}}},offsetParent:function(){return this.map(function(){var e=this.offsetParent;while(e&&"static"===ce.css(e,"position"))e=e.offsetParent;return e||J})}}),ce.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},function(t,i){var o="pageYOffset"===i;ce.fn[t]=function(e){return M(this,function(e,t,n){var r;if(y(e)?r=e:9===e.nodeType&&(r=e.defaultView),void 0===n)return r?r[i]:e[t];r?r.scrollTo(o?r.pageXOffset:n,o?n:r.pageYOffset):e[t]=n},t,e,arguments.length)}}),ce.each(["top","left"],function(e,n){ce.cssHooks[n]=Ye(le.pixelPosition,function(e,t){if(t)return t=Ge(e,n),_e.test(t)?ce(e).position()[n]+"px":t})}),ce.each({Height:"height",Width:"width"},function(a,s){ce.each({padding:"inner"+a,content:s,"":"outer"+a},function(r,o){ce.fn[o]=function(e,t){var n=arguments.length&&(r||"boolean"!=typeof e),i=r||(!0===e||!0===t?"margin":"border");return M(this,function(e,t,n){var r;return y(e)?0===o.indexOf("outer")?e["inner"+a]:e.document.documentElement["client"+a]:9===e.nodeType?(r=e.documentElement,Math.max(e.body["scroll"+a],r["scroll"+a],e.body["offset"+a],r["offset"+a],r["client"+a])):void 0===n?ce.css(e,t,i):ce.style(e,t,n,i)},s,n?e:void 0,n)}})}),ce.each(["ajaxStart","ajaxStop","ajaxComplete","ajaxError","ajaxSuccess","ajaxSend"],function(e,t){ce.fn[t]=function(e){return this.on(t,e)}}),ce.fn.extend({bind:function(e,t,n){return this.on(e,null,t,n)},unbind:function(e,t){return this.off(e,null,t)},delegate:function(e,t,n,r){return this.on(t,e,n,r)},undelegate:function(e,t,n){return 1===arguments.length?this.off(e,"**"):this.off(t,e||"**",n)},hover:function(e,t){return this.on("mouseenter",e).on("mouseleave",t||e)}}),ce.each("blur focus focusin focusout resize scroll click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup contextmenu".split(" "),function(e,n){ce.fn[n]=function(e,t){return 0 - * - * @param {String} text - * @return {String} - */ - var htmlize = PhpDebugBar.Widgets.htmlize = function(text) { - return text.replace(/\n/g, '
').replace(/\s/g, " ") - }; - - /** - * Returns a string representation of value, using JSON.stringify - * if it's an object. - * - * @param {Object} value - * @param {Boolean} prettify Uses htmlize() if true - * @return {String} - */ - var renderValue = PhpDebugBar.Widgets.renderValue = function(value, prettify) { - if (typeof(value) !== 'string') { - if (prettify) { - return htmlize(JSON.stringify(value, undefined, 2)); - } - return JSON.stringify(value); - } - return value; - }; - - /** - * Highlights a block of code - * - * @param {String} code - * @param {String} lang - * @return {String} - */ - var highlight = PhpDebugBar.Widgets.highlight = function(code, lang) { - if (typeof(code) === 'string') { - if (typeof(hljs) === 'undefined') { - return htmlize(code); - } - if (lang) { - return hljs.highlight(code, {language: lang}).value; - } - return hljs.highlightAuto(code).value; - } - - if (typeof(hljs) === 'object') { - code.each(function(i, e) { hljs.highlightElement(e); }); - } - return code; - }; - - /** - * Creates a
 element with a block of code
-     *
-     * @param  {String} code
-     * @param  {String} lang
-     * @param  {Number} [firstLineNumber] If provided, shows line numbers beginning with the given value.
-     * @param  {Number} [highlightedLine] If provided, the given line number will be highlighted.
-     * @return {String}
-     */
-    var createCodeBlock = PhpDebugBar.Widgets.createCodeBlock = function(code, lang, firstLineNumber, highlightedLine) {
-        var pre = $('
').addClass(csscls('code-block'));
-        // Add a newline to prevent  element from vertically collapsing too far if the last
-        // code line was empty: that creates problems with the horizontal scrollbar being
-        // incorrectly positioned - most noticeable when line numbers are shown.
-        var codeElement = $('').text(code + '\n').appendTo(pre);
-
-        // Add a span with a special class if we are supposed to highlight a line.  highlight.js will
-        // still correctly format code even with existing markup in it.
-        if ($.isNumeric(highlightedLine)) {
-            if ($.isNumeric(firstLineNumber)) {
-                highlightedLine = highlightedLine - firstLineNumber + 1;
-            }
-            codeElement.html(function (index, html) {
-                var currentLine = 1;
-                return html.replace(/^.*$/gm, function(line) {
-                    if (currentLine++ == highlightedLine) {
-                        return '' + line + '';
-                    } else {
-                        return line;
-                    }
-                });
-            });
-        }
-
-        // Format the code
-        if (lang) {
-            pre.addClass("language-" + lang);
-        }
-        highlight(pre);
-
-        // Show line numbers in a list
-        if ($.isNumeric(firstLineNumber)) {
-            var lineCount = code.split('\n').length;
-            var $lineNumbers = $('

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 d0mRO}xo^G_%I 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 SdSQM28?+M|D(2r_;{O0|uQ74} diff --git a/vendor/maximebf/debugbar/src/DebugBar/Resources/vendor/font-awesome/fonts/fontawesome-webfont.woff2 b/vendor/maximebf/debugbar/src/DebugBar/Resources/vendor/font-awesome/fonts/fontawesome-webfont.woff2 deleted file mode 100644 index 4d13fc60404b91e398a37200c4a77b645cfd9586..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 77160 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 diff --git a/vendor/maximebf/debugbar/src/DebugBar/Resources/vendor/highlightjs/highlight.pack.js b/vendor/maximebf/debugbar/src/DebugBar/Resources/vendor/highlightjs/highlight.pack.js deleted file mode 100644 index 0fd2855..0000000 --- a/vendor/maximebf/debugbar/src/DebugBar/Resources/vendor/highlightjs/highlight.pack.js +++ /dev/null @@ -1 +0,0 @@ -var hljs=function(){"use strict";function e(n){return n instanceof Map?n.clear=n.delete=n.set=()=>{throw Error("map is read-only")}:n instanceof Set&&(n.add=n.clear=n.delete=()=>{throw Error("set is read-only")}),Object.freeze(n),Object.getOwnPropertyNames(n).forEach((t=>{const a=n[t],i=typeof a;"object"!==i&&"function"!==i||Object.isFrozen(a)||e(a)})),n}class n{constructor(e){void 0===e.data&&(e.data={}),this.data=e.data,this.isMatchIgnored=!1}ignoreMatch(){this.isMatchIgnored=!0}}function t(e){return e.replace(/&/g,"&").replace(//g,">").replace(/"/g,""").replace(/'/g,"'")}function a(e,...n){const t=Object.create(null);for(const n in e)t[n]=e[n];return n.forEach((e=>{for(const n in e)t[n]=e[n]})),t}const i=e=>!!e.scope;class r{constructor(e,n){this.buffer="",this.classPrefix=n.classPrefix,e.walk(this)}addText(e){this.buffer+=t(e)}openNode(e){if(!i(e))return;const n=((e,{prefix:n})=>{if(e.startsWith("language:"))return e.replace("language:","language-");if(e.includes(".")){const t=e.split(".");return[`${n}${t.shift()}`,...t.map(((e,n)=>`${e}${"_".repeat(n+1)}`))].join(" ")}return`${n}${e}`})(e.scope,{prefix:this.classPrefix});this.span(n)}closeNode(e){i(e)&&(this.buffer+="")}value(){return this.buffer}span(e){this.buffer+=``}}const s=(e={})=>{const n={children:[]};return Object.assign(n,e),n};class o{constructor(){this.rootNode=s(),this.stack=[this.rootNode]}get top(){return this.stack[this.stack.length-1]}get root(){return this.rootNode}add(e){this.top.children.push(e)}openNode(e){const n=s({scope:e});this.add(n),this.stack.push(n)}closeNode(){if(this.stack.length>1)return this.stack.pop()}closeAllNodes(){for(;this.closeNode(););}toJSON(){return JSON.stringify(this.rootNode,null,4)}walk(e){return this.constructor._walk(e,this.rootNode)}static _walk(e,n){return"string"==typeof n?e.addText(n):n.children&&(e.openNode(n),n.children.forEach((n=>this._walk(e,n))),e.closeNode(n)),e}static _collapse(e){"string"!=typeof e&&e.children&&(e.children.every((e=>"string"==typeof e))?e.children=[e.children.join("")]:e.children.forEach((e=>{o._collapse(e)})))}}class l extends o{constructor(e){super(),this.options=e}addText(e){""!==e&&this.add(e)}startScope(e){this.openNode(e)}endScope(){this.closeNode()}__addSublanguage(e,n){const t=e.root;n&&(t.scope="language:"+n),this.add(t)}toHTML(){return new r(this,this.options).value()}finalize(){return this.closeAllNodes(),!0}}function c(e){return e?"string"==typeof e?e:e.source:null}function d(e){return b("(?=",e,")")}function g(e){return b("(?:",e,")*")}function u(e){return b("(?:",e,")?")}function b(...e){return e.map((e=>c(e))).join("")}function m(...e){const n=(e=>{const n=e[e.length-1];return"object"==typeof n&&n.constructor===Object?(e.splice(e.length-1,1),n):{}})(e);return"("+(n.capture?"":"?:")+e.map((e=>c(e))).join("|")+")"}function p(e){return RegExp(e.toString()+"|").exec("").length-1}const _=/\[(?:[^\\\]]|\\.)*\]|\(\??|\\([1-9][0-9]*)|\\./;function h(e,{joinWith:n}){let t=0;return e.map((e=>{t+=1;const n=t;let a=c(e),i="";for(;a.length>0;){const e=_.exec(a);if(!e){i+=a;break}i+=a.substring(0,e.index),a=a.substring(e.index+e[0].length),"\\"===e[0][0]&&e[1]?i+="\\"+(Number(e[1])+n):(i+=e[0],"("===e[0]&&t++)}return i})).map((e=>`(${e})`)).join(n)}const f="[a-zA-Z]\\w*",E="[a-zA-Z_]\\w*",y="\\b\\d+(\\.\\d+)?",N="(-?)(\\b0[xX][a-fA-F0-9]+|(\\b\\d+(\\.\\d*)?|\\.\\d+)([eE][-+]?\\d+)?)",w="\\b(0b[01]+)",v={begin:"\\\\[\\s\\S]",relevance:0},O={scope:"string",begin:"'",end:"'",illegal:"\\n",contains:[v]},k={scope:"string",begin:'"',end:'"',illegal:"\\n",contains:[v]},x=(e,n,t={})=>{const i=a({scope:"comment",begin:e,end:n,contains:[]},t);i.contains.push({scope:"doctag",begin:"[ ]*(?=(TODO|FIXME|NOTE|BUG|OPTIMIZE|HACK|XXX):)",end:/(TODO|FIXME|NOTE|BUG|OPTIMIZE|HACK|XXX):/,excludeBegin:!0,relevance:0});const r=m("I","a","is","so","us","to","at","if","in","it","on",/[A-Za-z]+['](d|ve|re|ll|t|s|n)/,/[A-Za-z]+[-][a-z]+/,/[A-Za-z][a-z]{2,}/);return i.contains.push({begin:b(/[ ]+/,"(",r,/[.]?[:]?([.][ ]|[ ])/,"){3}")}),i},M=x("//","$"),S=x("/\\*","\\*/"),A=x("#","$");var C=Object.freeze({__proto__:null,MATCH_NOTHING_RE:/\b\B/,IDENT_RE:f,UNDERSCORE_IDENT_RE:E,NUMBER_RE:y,C_NUMBER_RE:N,BINARY_NUMBER_RE:w,RE_STARTERS_RE:"!|!=|!==|%|%=|&|&&|&=|\\*|\\*=|\\+|\\+=|,|-|-=|/=|/|:|;|<<|<<=|<=|<|===|==|=|>>>=|>>=|>=|>>>|>>|>|\\?|\\[|\\{|\\(|\\^|\\^=|\\||\\|=|\\|\\||~",SHEBANG:(e={})=>{const n=/^#![ ]*\//;return e.binary&&(e.begin=b(n,/.*\b/,e.binary,/\b.*/)),a({scope:"meta",begin:n,end:/$/,relevance:0,"on:begin":(e,n)=>{0!==e.index&&n.ignoreMatch()}},e)},BACKSLASH_ESCAPE:v,APOS_STRING_MODE:O,QUOTE_STRING_MODE:k,PHRASAL_WORDS_MODE:{begin:/\b(a|an|the|are|I'm|isn't|don't|doesn't|won't|but|just|should|pretty|simply|enough|gonna|going|wtf|so|such|will|you|your|they|like|more)\b/},COMMENT:x,C_LINE_COMMENT_MODE:M,C_BLOCK_COMMENT_MODE:S,HASH_COMMENT_MODE:A,NUMBER_MODE:{scope:"number",begin:y,relevance:0},C_NUMBER_MODE:{scope:"number",begin:N,relevance:0},BINARY_NUMBER_MODE:{scope:"number",begin:w,relevance:0},REGEXP_MODE:{begin:/(?=\/[^/\n]*\/)/,contains:[{scope:"regexp",begin:/\//,end:/\/[gimuy]*/,illegal:/\n/,contains:[v,{begin:/\[/,end:/\]/,relevance:0,contains:[v]}]}]},TITLE_MODE:{scope:"title",begin:f,relevance:0},UNDERSCORE_TITLE_MODE:{scope:"title",begin:E,relevance:0},METHOD_GUARD:{begin:"\\.\\s*"+E,relevance:0},END_SAME_AS_BEGIN:e=>Object.assign(e,{"on:begin":(e,n)=>{n.data._beginMatch=e[1]},"on:end":(e,n)=>{n.data._beginMatch!==e[1]&&n.ignoreMatch()}})});function T(e,n){"."===e.input[e.index-1]&&n.ignoreMatch()}function R(e,n){void 0!==e.className&&(e.scope=e.className,delete e.className)}function D(e,n){n&&e.beginKeywords&&(e.begin="\\b("+e.beginKeywords.split(" ").join("|")+")(?!\\.)(?=\\b|\\s)",e.__beforeBegin=T,e.keywords=e.keywords||e.beginKeywords,delete e.beginKeywords,void 0===e.relevance&&(e.relevance=0))}function I(e,n){Array.isArray(e.illegal)&&(e.illegal=m(...e.illegal))}function L(e,n){if(e.match){if(e.begin||e.end)throw Error("begin & end are not supported with match");e.begin=e.match,delete e.match}}function B(e,n){void 0===e.relevance&&(e.relevance=1)}const $=(e,n)=>{if(!e.beforeMatch)return;if(e.starts)throw Error("beforeMatch cannot be used with starts");const t=Object.assign({},e);Object.keys(e).forEach((n=>{delete e[n]})),e.keywords=t.keywords,e.begin=b(t.beforeMatch,d(t.begin)),e.starts={relevance:0,contains:[Object.assign(t,{endsParent:!0})]},e.relevance=0,delete t.beforeMatch},z=["of","and","for","in","not","or","if","then","parent","list","value"],F="keyword";function U(e,n,t=F){const a=Object.create(null);return"string"==typeof e?i(t,e.split(" ")):Array.isArray(e)?i(t,e):Object.keys(e).forEach((t=>{Object.assign(a,U(e[t],n,t))})),a;function i(e,t){n&&(t=t.map((e=>e.toLowerCase()))),t.forEach((n=>{const t=n.split("|");a[t[0]]=[e,j(t[0],t[1])]}))}}function j(e,n){return n?Number(n):(e=>z.includes(e.toLowerCase()))(e)?0:1}const P={},K=e=>{console.error(e)},q=(e,...n)=>{console.log("WARN: "+e,...n)},H=(e,n)=>{P[`${e}/${n}`]||(console.log(`Deprecated as of ${e}. ${n}`),P[`${e}/${n}`]=!0)},G=Error();function Z(e,n,{key:t}){let a=0;const i=e[t],r={},s={};for(let e=1;e<=n.length;e++)s[e+a]=i[e],r[e+a]=!0,a+=p(n[e-1]);e[t]=s,e[t]._emit=r,e[t]._multi=!0}function W(e){(e=>{e.scope&&"object"==typeof e.scope&&null!==e.scope&&(e.beginScope=e.scope,delete e.scope)})(e),"string"==typeof e.beginScope&&(e.beginScope={_wrap:e.beginScope}),"string"==typeof e.endScope&&(e.endScope={_wrap:e.endScope}),(e=>{if(Array.isArray(e.begin)){if(e.skip||e.excludeBegin||e.returnBegin)throw K("skip, excludeBegin, returnBegin not compatible with beginScope: {}"),G;if("object"!=typeof e.beginScope||null===e.beginScope)throw K("beginScope must be object"),G;Z(e,e.begin,{key:"beginScope"}),e.begin=h(e.begin,{joinWith:""})}})(e),(e=>{if(Array.isArray(e.end)){if(e.skip||e.excludeEnd||e.returnEnd)throw K("skip, excludeEnd, returnEnd not compatible with endScope: {}"),G;if("object"!=typeof e.endScope||null===e.endScope)throw K("endScope must be object"),G;Z(e,e.end,{key:"endScope"}),e.end=h(e.end,{joinWith:""})}})(e)}function Q(e){function n(n,t){return RegExp(c(n),"m"+(e.case_insensitive?"i":"")+(e.unicodeRegex?"u":"")+(t?"g":""))}class t{constructor(){this.matchIndexes={},this.regexes=[],this.matchAt=1,this.position=0}addRule(e,n){n.position=this.position++,this.matchIndexes[this.matchAt]=n,this.regexes.push([n,e]),this.matchAt+=p(e)+1}compile(){0===this.regexes.length&&(this.exec=()=>null);const e=this.regexes.map((e=>e[1]));this.matcherRe=n(h(e,{joinWith:"|"}),!0),this.lastIndex=0}exec(e){this.matcherRe.lastIndex=this.lastIndex;const n=this.matcherRe.exec(e);if(!n)return null;const t=n.findIndex(((e,n)=>n>0&&void 0!==e)),a=this.matchIndexes[t];return n.splice(0,t),Object.assign(n,a)}}class i{constructor(){this.rules=[],this.multiRegexes=[],this.count=0,this.lastIndex=0,this.regexIndex=0}getMatcher(e){if(this.multiRegexes[e])return this.multiRegexes[e];const n=new t;return this.rules.slice(e).forEach((([e,t])=>n.addRule(e,t))),n.compile(),this.multiRegexes[e]=n,n}resumingScanAtSamePosition(){return 0!==this.regexIndex}considerAll(){this.regexIndex=0}addRule(e,n){this.rules.push([e,n]),"begin"===n.type&&this.count++}exec(e){const n=this.getMatcher(this.regexIndex);n.lastIndex=this.lastIndex;let t=n.exec(e);if(this.resumingScanAtSamePosition())if(t&&t.index===this.lastIndex);else{const n=this.getMatcher(0);n.lastIndex=this.lastIndex+1,t=n.exec(e)}return t&&(this.regexIndex+=t.position+1,this.regexIndex===this.count&&this.considerAll()),t}}if(e.compilerExtensions||(e.compilerExtensions=[]),e.contains&&e.contains.includes("self"))throw Error("ERR: contains `self` is not supported at the top-level of a language. See documentation.");return e.classNameAliases=a(e.classNameAliases||{}),function t(r,s){const o=r;if(r.isCompiled)return o;[R,L,W,$].forEach((e=>e(r,s))),e.compilerExtensions.forEach((e=>e(r,s))),r.__beforeBegin=null,[D,I,B].forEach((e=>e(r,s))),r.isCompiled=!0;let l=null;return"object"==typeof r.keywords&&r.keywords.$pattern&&(r.keywords=Object.assign({},r.keywords),l=r.keywords.$pattern,delete r.keywords.$pattern),l=l||/\w+/,r.keywords&&(r.keywords=U(r.keywords,e.case_insensitive)),o.keywordPatternRe=n(l,!0),s&&(r.begin||(r.begin=/\B|\b/),o.beginRe=n(o.begin),r.end||r.endsWithParent||(r.end=/\B|\b/),r.end&&(o.endRe=n(o.end)),o.terminatorEnd=c(o.end)||"",r.endsWithParent&&s.terminatorEnd&&(o.terminatorEnd+=(r.end?"|":"")+s.terminatorEnd)),r.illegal&&(o.illegalRe=n(r.illegal)),r.contains||(r.contains=[]),r.contains=[].concat(...r.contains.map((e=>(e=>(e.variants&&!e.cachedVariants&&(e.cachedVariants=e.variants.map((n=>a(e,{variants:null},n)))),e.cachedVariants?e.cachedVariants:X(e)?a(e,{starts:e.starts?a(e.starts):null}):Object.isFrozen(e)?a(e):e))("self"===e?r:e)))),r.contains.forEach((e=>{t(e,o)})),r.starts&&t(r.starts,s),o.matcher=(e=>{const n=new i;return e.contains.forEach((e=>n.addRule(e.begin,{rule:e,type:"begin"}))),e.terminatorEnd&&n.addRule(e.terminatorEnd,{type:"end"}),e.illegal&&n.addRule(e.illegal,{type:"illegal"}),n})(o),o}(e)}function X(e){return!!e&&(e.endsWithParent||X(e.starts))}class V extends Error{constructor(e,n){super(e),this.name="HTMLInjectionError",this.html=n}}const J=t,Y=a,ee=Symbol("nomatch"),ne=t=>{const a=Object.create(null),i=Object.create(null),r=[];let s=!0;const o="Could not find the language '{}', did you forget to load/include a language module?",c={disableAutodetect:!0,name:"Plain text",contains:[]};let p={ignoreUnescapedHTML:!1,throwUnescapedHTML:!1,noHighlightRe:/^(no-?highlight)$/i,languageDetectRe:/\blang(?:uage)?-([\w-]+)\b/i,classPrefix:"hljs-",cssSelector:"pre code",languages:null,__emitter:l};function _(e){return p.noHighlightRe.test(e)}function h(e,n,t){let a="",i="";"object"==typeof n?(a=e,t=n.ignoreIllegals,i=n.language):(H("10.7.0","highlight(lang, code, ...args) has been deprecated."),H("10.7.0","Please use highlight(code, options) instead.\nhttps://github.com/highlightjs/highlight.js/issues/2277"),i=e,a=n),void 0===t&&(t=!0);const r={code:a,language:i};x("before:highlight",r);const s=r.result?r.result:f(r.language,r.code,t);return s.code=r.code,x("after:highlight",s),s}function f(e,t,i,r){const l=Object.create(null);function c(){if(!x.keywords)return void S.addText(A);let e=0;x.keywordPatternRe.lastIndex=0;let n=x.keywordPatternRe.exec(A),t="";for(;n;){t+=A.substring(e,n.index);const i=w.case_insensitive?n[0].toLowerCase():n[0],r=(a=i,x.keywords[a]);if(r){const[e,a]=r;if(S.addText(t),t="",l[i]=(l[i]||0)+1,l[i]<=7&&(C+=a),e.startsWith("_"))t+=n[0];else{const t=w.classNameAliases[e]||e;g(n[0],t)}}else t+=n[0];e=x.keywordPatternRe.lastIndex,n=x.keywordPatternRe.exec(A)}var a;t+=A.substring(e),S.addText(t)}function d(){null!=x.subLanguage?(()=>{if(""===A)return;let e=null;if("string"==typeof x.subLanguage){if(!a[x.subLanguage])return void S.addText(A);e=f(x.subLanguage,A,!0,M[x.subLanguage]),M[x.subLanguage]=e._top}else e=E(A,x.subLanguage.length?x.subLanguage:null);x.relevance>0&&(C+=e.relevance),S.__addSublanguage(e._emitter,e.language)})():c(),A=""}function g(e,n){""!==e&&(S.startScope(n),S.addText(e),S.endScope())}function u(e,n){let t=1;const a=n.length-1;for(;t<=a;){if(!e._emit[t]){t++;continue}const a=w.classNameAliases[e[t]]||e[t],i=n[t];a?g(i,a):(A=i,c(),A=""),t++}}function b(e,n){return e.scope&&"string"==typeof e.scope&&S.openNode(w.classNameAliases[e.scope]||e.scope),e.beginScope&&(e.beginScope._wrap?(g(A,w.classNameAliases[e.beginScope._wrap]||e.beginScope._wrap),A=""):e.beginScope._multi&&(u(e.beginScope,n),A="")),x=Object.create(e,{parent:{value:x}}),x}function m(e,t,a){let i=((e,n)=>{const t=e&&e.exec(n);return t&&0===t.index})(e.endRe,a);if(i){if(e["on:end"]){const a=new n(e);e["on:end"](t,a),a.isMatchIgnored&&(i=!1)}if(i){for(;e.endsParent&&e.parent;)e=e.parent;return e}}if(e.endsWithParent)return m(e.parent,t,a)}function _(e){return 0===x.matcher.regexIndex?(A+=e[0],1):(D=!0,0)}function h(e){const n=e[0],a=t.substring(e.index),i=m(x,e,a);if(!i)return ee;const r=x;x.endScope&&x.endScope._wrap?(d(),g(n,x.endScope._wrap)):x.endScope&&x.endScope._multi?(d(),u(x.endScope,e)):r.skip?A+=n:(r.returnEnd||r.excludeEnd||(A+=n),d(),r.excludeEnd&&(A=n));do{x.scope&&S.closeNode(),x.skip||x.subLanguage||(C+=x.relevance),x=x.parent}while(x!==i.parent);return i.starts&&b(i.starts,e),r.returnEnd?0:n.length}let y={};function N(a,r){const o=r&&r[0];if(A+=a,null==o)return d(),0;if("begin"===y.type&&"end"===r.type&&y.index===r.index&&""===o){if(A+=t.slice(r.index,r.index+1),!s){const n=Error(`0 width match regex (${e})`);throw n.languageName=e,n.badRule=y.rule,n}return 1}if(y=r,"begin"===r.type)return(e=>{const t=e[0],a=e.rule,i=new n(a),r=[a.__beforeBegin,a["on:begin"]];for(const n of r)if(n&&(n(e,i),i.isMatchIgnored))return _(t);return a.skip?A+=t:(a.excludeBegin&&(A+=t),d(),a.returnBegin||a.excludeBegin||(A=t)),b(a,e),a.returnBegin?0:t.length})(r);if("illegal"===r.type&&!i){const e=Error('Illegal lexeme "'+o+'" for mode "'+(x.scope||"")+'"');throw e.mode=x,e}if("end"===r.type){const e=h(r);if(e!==ee)return e}if("illegal"===r.type&&""===o)return 1;if(R>1e5&&R>3*r.index)throw Error("potential infinite loop, way more iterations than matches");return A+=o,o.length}const w=v(e);if(!w)throw K(o.replace("{}",e)),Error('Unknown language: "'+e+'"');const O=Q(w);let k="",x=r||O;const M={},S=new p.__emitter(p);(()=>{const e=[];for(let n=x;n!==w;n=n.parent)n.scope&&e.unshift(n.scope);e.forEach((e=>S.openNode(e)))})();let A="",C=0,T=0,R=0,D=!1;try{if(w.__emitTokens)w.__emitTokens(t,S);else{for(x.matcher.considerAll();;){R++,D?D=!1:x.matcher.considerAll(),x.matcher.lastIndex=T;const e=x.matcher.exec(t);if(!e)break;const n=N(t.substring(T,e.index),e);T=e.index+n}N(t.substring(T))}return S.finalize(),k=S.toHTML(),{language:e,value:k,relevance:C,illegal:!1,_emitter:S,_top:x}}catch(n){if(n.message&&n.message.includes("Illegal"))return{language:e,value:J(t),illegal:!0,relevance:0,_illegalBy:{message:n.message,index:T,context:t.slice(T-100,T+100),mode:n.mode,resultSoFar:k},_emitter:S};if(s)return{language:e,value:J(t),illegal:!1,relevance:0,errorRaised:n,_emitter:S,_top:x};throw n}}function E(e,n){n=n||p.languages||Object.keys(a);const t=(e=>{const n={value:J(e),illegal:!1,relevance:0,_top:c,_emitter:new p.__emitter(p)};return n._emitter.addText(e),n})(e),i=n.filter(v).filter(k).map((n=>f(n,e,!1)));i.unshift(t);const r=i.sort(((e,n)=>{if(e.relevance!==n.relevance)return n.relevance-e.relevance;if(e.language&&n.language){if(v(e.language).supersetOf===n.language)return 1;if(v(n.language).supersetOf===e.language)return-1}return 0})),[s,o]=r,l=s;return l.secondBest=o,l}function y(e){let n=null;const t=(e=>{let n=e.className+" ";n+=e.parentNode?e.parentNode.className:"";const t=p.languageDetectRe.exec(n);if(t){const n=v(t[1]);return n||(q(o.replace("{}",t[1])),q("Falling back to no-highlight mode for this block.",e)),n?t[1]:"no-highlight"}return n.split(/\s+/).find((e=>_(e)||v(e)))})(e);if(_(t))return;if(x("before:highlightElement",{el:e,language:t}),e.children.length>0&&(p.ignoreUnescapedHTML||(console.warn("One of your code blocks includes unescaped HTML. This is a potentially serious security risk."),console.warn("https://github.com/highlightjs/highlight.js/wiki/security"),console.warn("The element with unescaped HTML:"),console.warn(e)),p.throwUnescapedHTML))throw new V("One of your code blocks includes unescaped HTML.",e.innerHTML);n=e;const a=n.textContent,r=t?h(a,{language:t,ignoreIllegals:!0}):E(a);e.innerHTML=r.value,((e,n,t)=>{const a=n&&i[n]||t;e.classList.add("hljs"),e.classList.add("language-"+a)})(e,t,r.language),e.result={language:r.language,re:r.relevance,relevance:r.relevance},r.secondBest&&(e.secondBest={language:r.secondBest.language,relevance:r.secondBest.relevance}),x("after:highlightElement",{el:e,result:r,text:a})}let N=!1;function w(){"loading"!==document.readyState?document.querySelectorAll(p.cssSelector).forEach(y):N=!0}function v(e){return e=(e||"").toLowerCase(),a[e]||a[i[e]]}function O(e,{languageName:n}){"string"==typeof e&&(e=[e]),e.forEach((e=>{i[e.toLowerCase()]=n}))}function k(e){const n=v(e);return n&&!n.disableAutodetect}function x(e,n){const t=e;r.forEach((e=>{e[t]&&e[t](n)}))}"undefined"!=typeof window&&window.addEventListener&&window.addEventListener("DOMContentLoaded",(()=>{N&&w()}),!1),Object.assign(t,{highlight:h,highlightAuto:E,highlightAll:w,highlightElement:y,highlightBlock:e=>(H("10.7.0","highlightBlock will be removed entirely in v12.0"),H("10.7.0","Please use highlightElement now."),y(e)),configure:e=>{p=Y(p,e)},initHighlighting:()=>{w(),H("10.6.0","initHighlighting() deprecated. Use highlightAll() now.")},initHighlightingOnLoad:()=>{w(),H("10.6.0","initHighlightingOnLoad() deprecated. Use highlightAll() now.")},registerLanguage:(e,n)=>{let i=null;try{i=n(t)}catch(n){if(K("Language definition for '{}' could not be registered.".replace("{}",e)),!s)throw n;K(n),i=c}i.name||(i.name=e),a[e]=i,i.rawDefinition=n.bind(null,t),i.aliases&&O(i.aliases,{languageName:e})},unregisterLanguage:e=>{delete a[e];for(const n of Object.keys(i))i[n]===e&&delete i[n]},listLanguages:()=>Object.keys(a),getLanguage:v,registerAliases:O,autoDetection:k,inherit:Y,addPlugin:e=>{(e=>{e["before:highlightBlock"]&&!e["before:highlightElement"]&&(e["before:highlightElement"]=n=>{e["before:highlightBlock"](Object.assign({block:n.el},n))}),e["after:highlightBlock"]&&!e["after:highlightElement"]&&(e["after:highlightElement"]=n=>{e["after:highlightBlock"](Object.assign({block:n.el},n))})})(e),r.push(e)},removePlugin:e=>{const n=r.indexOf(e);-1!==n&&r.splice(n,1)}}),t.debugMode=()=>{s=!1},t.safeMode=()=>{s=!0},t.versionString="11.8.0",t.regex={concat:b,lookahead:d,either:m,optional:u,anyNumberOfTimes:g};for(const n in C)"object"==typeof C[n]&&e(C[n]);return Object.assign(t,C),t},te=ne({});te.newInstance=()=>ne({});var ae=te;const ie=e=>({IMPORTANT:{scope:"meta",begin:"!important"},BLOCK_COMMENT:e.C_BLOCK_COMMENT_MODE,HEXCOLOR:{scope:"number",begin:/#(([0-9a-fA-F]{3,4})|(([0-9a-fA-F]{2}){3,4}))\b/},FUNCTION_DISPATCH:{className:"built_in",begin:/[\w-]+(?=\()/},ATTRIBUTE_SELECTOR_MODE:{scope:"selector-attr",begin:/\[/,end:/\]/,illegal:"$",contains:[e.APOS_STRING_MODE,e.QUOTE_STRING_MODE]},CSS_NUMBER_MODE:{scope:"number",begin:e.NUMBER_RE+"(%|em|ex|ch|rem|vw|vh|vmin|vmax|cm|mm|in|pt|pc|px|deg|grad|rad|turn|s|ms|Hz|kHz|dpi|dpcm|dppx)?",relevance:0},CSS_VARIABLE:{className:"attr",begin:/--[A-Za-z][A-Za-z0-9_-]*/}}),re=["a","abbr","address","article","aside","audio","b","blockquote","body","button","canvas","caption","cite","code","dd","del","details","dfn","div","dl","dt","em","fieldset","figcaption","figure","footer","form","h1","h2","h3","h4","h5","h6","header","hgroup","html","i","iframe","img","input","ins","kbd","label","legend","li","main","mark","menu","nav","object","ol","p","q","quote","samp","section","span","strong","summary","sup","table","tbody","td","textarea","tfoot","th","thead","time","tr","ul","var","video"],se=["any-hover","any-pointer","aspect-ratio","color","color-gamut","color-index","device-aspect-ratio","device-height","device-width","display-mode","forced-colors","grid","height","hover","inverted-colors","monochrome","orientation","overflow-block","overflow-inline","pointer","prefers-color-scheme","prefers-contrast","prefers-reduced-motion","prefers-reduced-transparency","resolution","scan","scripting","update","width","min-width","max-width","min-height","max-height"],oe=["active","any-link","blank","checked","current","default","defined","dir","disabled","drop","empty","enabled","first","first-child","first-of-type","fullscreen","future","focus","focus-visible","focus-within","has","host","host-context","hover","indeterminate","in-range","invalid","is","lang","last-child","last-of-type","left","link","local-link","not","nth-child","nth-col","nth-last-child","nth-last-col","nth-last-of-type","nth-of-type","only-child","only-of-type","optional","out-of-range","past","placeholder-shown","read-only","read-write","required","right","root","scope","target","target-within","user-invalid","valid","visited","where"],le=["after","backdrop","before","cue","cue-region","first-letter","first-line","grammar-error","marker","part","placeholder","selection","slotted","spelling-error"],ce=["align-content","align-items","align-self","all","animation","animation-delay","animation-direction","animation-duration","animation-fill-mode","animation-iteration-count","animation-name","animation-play-state","animation-timing-function","backface-visibility","background","background-attachment","background-blend-mode","background-clip","background-color","background-image","background-origin","background-position","background-repeat","background-size","block-size","border","border-block","border-block-color","border-block-end","border-block-end-color","border-block-end-style","border-block-end-width","border-block-start","border-block-start-color","border-block-start-style","border-block-start-width","border-block-style","border-block-width","border-bottom","border-bottom-color","border-bottom-left-radius","border-bottom-right-radius","border-bottom-style","border-bottom-width","border-collapse","border-color","border-image","border-image-outset","border-image-repeat","border-image-slice","border-image-source","border-image-width","border-inline","border-inline-color","border-inline-end","border-inline-end-color","border-inline-end-style","border-inline-end-width","border-inline-start","border-inline-start-color","border-inline-start-style","border-inline-start-width","border-inline-style","border-inline-width","border-left","border-left-color","border-left-style","border-left-width","border-radius","border-right","border-right-color","border-right-style","border-right-width","border-spacing","border-style","border-top","border-top-color","border-top-left-radius","border-top-right-radius","border-top-style","border-top-width","border-width","bottom","box-decoration-break","box-shadow","box-sizing","break-after","break-before","break-inside","caption-side","caret-color","clear","clip","clip-path","clip-rule","color","column-count","column-fill","column-gap","column-rule","column-rule-color","column-rule-style","column-rule-width","column-span","column-width","columns","contain","content","content-visibility","counter-increment","counter-reset","cue","cue-after","cue-before","cursor","direction","display","empty-cells","filter","flex","flex-basis","flex-direction","flex-flow","flex-grow","flex-shrink","flex-wrap","float","flow","font","font-display","font-family","font-feature-settings","font-kerning","font-language-override","font-size","font-size-adjust","font-smoothing","font-stretch","font-style","font-synthesis","font-variant","font-variant-caps","font-variant-east-asian","font-variant-ligatures","font-variant-numeric","font-variant-position","font-variation-settings","font-weight","gap","glyph-orientation-vertical","grid","grid-area","grid-auto-columns","grid-auto-flow","grid-auto-rows","grid-column","grid-column-end","grid-column-start","grid-gap","grid-row","grid-row-end","grid-row-start","grid-template","grid-template-areas","grid-template-columns","grid-template-rows","hanging-punctuation","height","hyphens","icon","image-orientation","image-rendering","image-resolution","ime-mode","inline-size","isolation","justify-content","left","letter-spacing","line-break","line-height","list-style","list-style-image","list-style-position","list-style-type","margin","margin-block","margin-block-end","margin-block-start","margin-bottom","margin-inline","margin-inline-end","margin-inline-start","margin-left","margin-right","margin-top","marks","mask","mask-border","mask-border-mode","mask-border-outset","mask-border-repeat","mask-border-slice","mask-border-source","mask-border-width","mask-clip","mask-composite","mask-image","mask-mode","mask-origin","mask-position","mask-repeat","mask-size","mask-type","max-block-size","max-height","max-inline-size","max-width","min-block-size","min-height","min-inline-size","min-width","mix-blend-mode","nav-down","nav-index","nav-left","nav-right","nav-up","none","normal","object-fit","object-position","opacity","order","orphans","outline","outline-color","outline-offset","outline-style","outline-width","overflow","overflow-wrap","overflow-x","overflow-y","padding","padding-block","padding-block-end","padding-block-start","padding-bottom","padding-inline","padding-inline-end","padding-inline-start","padding-left","padding-right","padding-top","page-break-after","page-break-before","page-break-inside","pause","pause-after","pause-before","perspective","perspective-origin","pointer-events","position","quotes","resize","rest","rest-after","rest-before","right","row-gap","scroll-margin","scroll-margin-block","scroll-margin-block-end","scroll-margin-block-start","scroll-margin-bottom","scroll-margin-inline","scroll-margin-inline-end","scroll-margin-inline-start","scroll-margin-left","scroll-margin-right","scroll-margin-top","scroll-padding","scroll-padding-block","scroll-padding-block-end","scroll-padding-block-start","scroll-padding-bottom","scroll-padding-inline","scroll-padding-inline-end","scroll-padding-inline-start","scroll-padding-left","scroll-padding-right","scroll-padding-top","scroll-snap-align","scroll-snap-stop","scroll-snap-type","scrollbar-color","scrollbar-gutter","scrollbar-width","shape-image-threshold","shape-margin","shape-outside","speak","speak-as","src","tab-size","table-layout","text-align","text-align-all","text-align-last","text-combine-upright","text-decoration","text-decoration-color","text-decoration-line","text-decoration-style","text-emphasis","text-emphasis-color","text-emphasis-position","text-emphasis-style","text-indent","text-justify","text-orientation","text-overflow","text-rendering","text-shadow","text-transform","text-underline-position","top","transform","transform-box","transform-origin","transform-style","transition","transition-delay","transition-duration","transition-property","transition-timing-function","unicode-bidi","vertical-align","visibility","voice-balance","voice-duration","voice-family","voice-pitch","voice-range","voice-rate","voice-stress","voice-volume","white-space","widows","width","will-change","word-break","word-spacing","word-wrap","writing-mode","z-index"].reverse(),de=oe.concat(le);var ge="[0-9](_*[0-9])*",ue=`\\.(${ge})`,be="[0-9a-fA-F](_*[0-9a-fA-F])*",me={className:"number",variants:[{begin:`(\\b(${ge})((${ue})|\\.)?|(${ue}))[eE][+-]?(${ge})[fFdD]?\\b`},{begin:`\\b(${ge})((${ue})[fFdD]?\\b|\\.([fFdD]\\b)?)`},{begin:`(${ue})[fFdD]?\\b`},{begin:`\\b(${ge})[fFdD]\\b`},{begin:`\\b0[xX]((${be})\\.?|(${be})?\\.(${be}))[pP][+-]?(${ge})[fFdD]?\\b`},{begin:"\\b(0|[1-9](_*[0-9])*)[lL]?\\b"},{begin:`\\b0[xX](${be})[lL]?\\b`},{begin:"\\b0(_*[0-7])*[lL]?\\b"},{begin:"\\b0[bB][01](_*[01])*[lL]?\\b"}],relevance:0};function pe(e,n,t){return-1===t?"":e.replace(n,(a=>pe(e,n,t-1)))}const _e="[A-Za-z$_][0-9A-Za-z$_]*",he=["as","in","of","if","for","while","finally","var","new","function","do","return","void","else","break","catch","instanceof","with","throw","case","default","try","switch","continue","typeof","delete","let","yield","const","class","debugger","async","await","static","import","from","export","extends"],fe=["true","false","null","undefined","NaN","Infinity"],Ee=["Object","Function","Boolean","Symbol","Math","Date","Number","BigInt","String","RegExp","Array","Float32Array","Float64Array","Int8Array","Uint8Array","Uint8ClampedArray","Int16Array","Int32Array","Uint16Array","Uint32Array","BigInt64Array","BigUint64Array","Set","Map","WeakSet","WeakMap","ArrayBuffer","SharedArrayBuffer","Atomics","DataView","JSON","Promise","Generator","GeneratorFunction","AsyncFunction","Reflect","Proxy","Intl","WebAssembly"],ye=["Error","EvalError","InternalError","RangeError","ReferenceError","SyntaxError","TypeError","URIError"],Ne=["setInterval","setTimeout","clearInterval","clearTimeout","require","exports","eval","isFinite","isNaN","parseFloat","parseInt","decodeURI","decodeURIComponent","encodeURI","encodeURIComponent","escape","unescape"],we=["arguments","this","super","console","window","document","localStorage","sessionStorage","module","global"],ve=[].concat(Ne,Ee,ye);function Oe(e){const n=e.regex,t=_e,a={begin:/<[A-Za-z0-9\\._:-]+/,end:/\/[A-Za-z0-9\\._:-]+>|\/>/,isTrulyOpeningTag:(e,n)=>{const t=e[0].length+e.index,a=e.input[t];if("<"===a||","===a)return void n.ignoreMatch();let i;">"===a&&(((e,{after:n})=>{const t="",M={match:[/const|var|let/,/\s+/,t,/\s*/,/=\s*/,/(async\s*)?/,n.lookahead(x)],keywords:"async",className:{1:"keyword",3:"title.function"},contains:[f]};return{name:"JavaScript",aliases:["js","jsx","mjs","cjs"],keywords:i,exports:{PARAMS_CONTAINS:h,CLASS_REFERENCE:y},illegal:/#(?![$_A-z])/,contains:[e.SHEBANG({label:"shebang",binary:"node",relevance:5}),{label:"use_strict",className:"meta",relevance:10,begin:/^\s*['"]use (strict|asm)['"]/},e.APOS_STRING_MODE,e.QUOTE_STRING_MODE,d,g,u,b,m,{match:/\$\d+/},l,y,{className:"attr",begin:t+n.lookahead(":"),relevance:0},M,{begin:"("+e.RE_STARTERS_RE+"|\\b(case|return|throw)\\b)\\s*",keywords:"return throw case",relevance:0,contains:[m,e.REGEXP_MODE,{className:"function",begin:x,returnBegin:!0,end:"\\s*=>",contains:[{className:"params",variants:[{begin:e.UNDERSCORE_IDENT_RE,relevance:0},{className:null,begin:/\(\s*\)/,skip:!0},{begin:/\(/,end:/\)/,excludeBegin:!0,excludeEnd:!0,keywords:i,contains:h}]}]},{begin:/,/,relevance:0},{match:/\s+/,relevance:0},{variants:[{begin:"<>",end:""},{match:/<[A-Za-z0-9\\._:-]+\s*\/>/},{begin:a.begin,"on:begin":a.isTrulyOpeningTag,end:a.end}],subLanguage:"xml",contains:[{begin:a.begin,end:a.end,skip:!0,contains:["self"]}]}]},N,{beginKeywords:"while if switch catch for"},{begin:"\\b(?!function)"+e.UNDERSCORE_IDENT_RE+"\\([^()]*(\\([^()]*(\\([^()]*\\)[^()]*)*\\)[^()]*)*\\)\\s*\\{",returnBegin:!0,label:"func.def",contains:[f,e.inherit(e.TITLE_MODE,{begin:t,className:"title.function"})]},{match:/\.\.\./,relevance:0},O,{match:"\\$"+t,relevance:0},{match:[/\bconstructor(?=\s*\()/],className:{1:"title.function"},contains:[f]},w,{relevance:0,match:/\b[A-Z][A-Z_0-9]+\b/,className:"variable.constant"},E,k,{match:/\$[(.]/}]}}const ke=e=>b(/\b/,e,/\w$/.test(e)?/\b/:/\B/),xe=["Protocol","Type"].map(ke),Me=["init","self"].map(ke),Se=["Any","Self"],Ae=["actor","any","associatedtype","async","await",/as\?/,/as!/,"as","break","case","catch","class","continue","convenience","default","defer","deinit","didSet","distributed","do","dynamic","else","enum","extension","fallthrough",/fileprivate\(set\)/,"fileprivate","final","for","func","get","guard","if","import","indirect","infix",/init\?/,/init!/,"inout",/internal\(set\)/,"internal","in","is","isolated","nonisolated","lazy","let","mutating","nonmutating",/open\(set\)/,"open","operator","optional","override","postfix","precedencegroup","prefix",/private\(set\)/,"private","protocol",/public\(set\)/,"public","repeat","required","rethrows","return","set","some","static","struct","subscript","super","switch","throws","throw",/try\?/,/try!/,"try","typealias",/unowned\(safe\)/,/unowned\(unsafe\)/,"unowned","var","weak","where","while","willSet"],Ce=["false","nil","true"],Te=["assignment","associativity","higherThan","left","lowerThan","none","right"],Re=["#colorLiteral","#column","#dsohandle","#else","#elseif","#endif","#error","#file","#fileID","#fileLiteral","#filePath","#function","#if","#imageLiteral","#keyPath","#line","#selector","#sourceLocation","#warn_unqualified_access","#warning"],De=["abs","all","any","assert","assertionFailure","debugPrint","dump","fatalError","getVaList","isKnownUniquelyReferenced","max","min","numericCast","pointwiseMax","pointwiseMin","precondition","preconditionFailure","print","readLine","repeatElement","sequence","stride","swap","swift_unboxFromSwiftValueWithType","transcode","type","unsafeBitCast","unsafeDowncast","withExtendedLifetime","withUnsafeMutablePointer","withUnsafePointer","withVaList","withoutActuallyEscaping","zip"],Ie=m(/[/=\-+!*%<>&|^~?]/,/[\u00A1-\u00A7]/,/[\u00A9\u00AB]/,/[\u00AC\u00AE]/,/[\u00B0\u00B1]/,/[\u00B6\u00BB\u00BF\u00D7\u00F7]/,/[\u2016-\u2017]/,/[\u2020-\u2027]/,/[\u2030-\u203E]/,/[\u2041-\u2053]/,/[\u2055-\u205E]/,/[\u2190-\u23FF]/,/[\u2500-\u2775]/,/[\u2794-\u2BFF]/,/[\u2E00-\u2E7F]/,/[\u3001-\u3003]/,/[\u3008-\u3020]/,/[\u3030]/),Le=m(Ie,/[\u0300-\u036F]/,/[\u1DC0-\u1DFF]/,/[\u20D0-\u20FF]/,/[\uFE00-\uFE0F]/,/[\uFE20-\uFE2F]/),Be=b(Ie,Le,"*"),$e=m(/[a-zA-Z_]/,/[\u00A8\u00AA\u00AD\u00AF\u00B2-\u00B5\u00B7-\u00BA]/,/[\u00BC-\u00BE\u00C0-\u00D6\u00D8-\u00F6\u00F8-\u00FF]/,/[\u0100-\u02FF\u0370-\u167F\u1681-\u180D\u180F-\u1DBF]/,/[\u1E00-\u1FFF]/,/[\u200B-\u200D\u202A-\u202E\u203F-\u2040\u2054\u2060-\u206F]/,/[\u2070-\u20CF\u2100-\u218F\u2460-\u24FF\u2776-\u2793]/,/[\u2C00-\u2DFF\u2E80-\u2FFF]/,/[\u3004-\u3007\u3021-\u302F\u3031-\u303F\u3040-\uD7FF]/,/[\uF900-\uFD3D\uFD40-\uFDCF\uFDF0-\uFE1F\uFE30-\uFE44]/,/[\uFE47-\uFEFE\uFF00-\uFFFD]/),ze=m($e,/\d/,/[\u0300-\u036F\u1DC0-\u1DFF\u20D0-\u20FF\uFE20-\uFE2F]/),Fe=b($e,ze,"*"),Ue=b(/[A-Z]/,ze,"*"),je=["autoclosure",b(/convention\(/,m("swift","block","c"),/\)/),"discardableResult","dynamicCallable","dynamicMemberLookup","escaping","frozen","GKInspectable","IBAction","IBDesignable","IBInspectable","IBOutlet","IBSegueAction","inlinable","main","nonobjc","NSApplicationMain","NSCopying","NSManaged",b(/objc\(/,Fe,/\)/),"objc","objcMembers","propertyWrapper","requires_stored_property_inits","resultBuilder","testable","UIApplicationMain","unknown","usableFromInline"],Pe=["iOS","iOSApplicationExtension","macOS","macOSApplicationExtension","macCatalyst","macCatalystApplicationExtension","watchOS","watchOSApplicationExtension","tvOS","tvOSApplicationExtension","swift"];var Ke=Object.freeze({__proto__:null,grmr_bash:e=>{const n=e.regex,t={},a={begin:/\$\{/,end:/\}/,contains:["self",{begin:/:-/,contains:[t]}]};Object.assign(t,{className:"variable",variants:[{begin:n.concat(/\$[\w\d#@][\w\d_]*/,"(?![\\w\\d])(?![$])")},a]});const i={className:"subst",begin:/\$\(/,end:/\)/,contains:[e.BACKSLASH_ESCAPE]},r={begin:/<<-?\s*(?=\w+)/,starts:{contains:[e.END_SAME_AS_BEGIN({begin:/(\w+)/,end:/(\w+)/,className:"string"})]}},s={className:"string",begin:/"/,end:/"/,contains:[e.BACKSLASH_ESCAPE,t,i]};i.contains.push(s);const o={begin:/\$?\(\(/,end:/\)\)/,contains:[{begin:/\d+#[0-9a-f]+/,className:"number"},e.NUMBER_MODE,t]},l=e.SHEBANG({binary:"(fish|bash|zsh|sh|csh|ksh|tcsh|dash|scsh)",relevance:10}),c={className:"function",begin:/\w[\w\d_]*\s*\(\s*\)\s*\{/,returnBegin:!0,contains:[e.inherit(e.TITLE_MODE,{begin:/\w[\w\d_]*/})],relevance:0};return{name:"Bash",aliases:["sh"],keywords:{$pattern:/\b[a-z][a-z0-9._-]+\b/,keyword:["if","then","else","elif","fi","for","while","until","in","do","done","case","esac","function","select"],literal:["true","false"],built_in:["break","cd","continue","eval","exec","exit","export","getopts","hash","pwd","readonly","return","shift","test","times","trap","umask","unset","alias","bind","builtin","caller","command","declare","echo","enable","help","let","local","logout","mapfile","printf","read","readarray","source","type","typeset","ulimit","unalias","set","shopt","autoload","bg","bindkey","bye","cap","chdir","clone","comparguments","compcall","compctl","compdescribe","compfiles","compgroups","compquote","comptags","comptry","compvalues","dirs","disable","disown","echotc","echoti","emulate","fc","fg","float","functions","getcap","getln","history","integer","jobs","kill","limit","log","noglob","popd","print","pushd","pushln","rehash","sched","setcap","setopt","stat","suspend","ttyctl","unfunction","unhash","unlimit","unsetopt","vared","wait","whence","where","which","zcompile","zformat","zftp","zle","zmodload","zparseopts","zprof","zpty","zregexparse","zsocket","zstyle","ztcp","chcon","chgrp","chown","chmod","cp","dd","df","dir","dircolors","ln","ls","mkdir","mkfifo","mknod","mktemp","mv","realpath","rm","rmdir","shred","sync","touch","truncate","vdir","b2sum","base32","base64","cat","cksum","comm","csplit","cut","expand","fmt","fold","head","join","md5sum","nl","numfmt","od","paste","ptx","pr","sha1sum","sha224sum","sha256sum","sha384sum","sha512sum","shuf","sort","split","sum","tac","tail","tr","tsort","unexpand","uniq","wc","arch","basename","chroot","date","dirname","du","echo","env","expr","factor","groups","hostid","id","link","logname","nice","nohup","nproc","pathchk","pinky","printenv","printf","pwd","readlink","runcon","seq","sleep","stat","stdbuf","stty","tee","test","timeout","tty","uname","unlink","uptime","users","who","whoami","yes"]},contains:[l,e.SHEBANG(),c,o,e.HASH_COMMENT_MODE,r,{match:/(\/[a-z._-]+)+/},s,{className:"",begin:/\\"/},{className:"string",begin:/'/,end:/'/},t]}},grmr_c:e=>{const n=e.regex,t=e.COMMENT("//","$",{contains:[{begin:/\\\n/}]}),a="decltype\\(auto\\)",i="[a-zA-Z_]\\w*::",r="("+a+"|"+n.optional(i)+"[a-zA-Z_]\\w*"+n.optional("<[^<>]+>")+")",s={className:"type",variants:[{begin:"\\b[a-z\\d_]*_t\\b"},{match:/\batomic_[a-z]{3,6}\b/}]},o={className:"string",variants:[{begin:'(u8?|U|L)?"',end:'"',illegal:"\\n",contains:[e.BACKSLASH_ESCAPE]},{begin:"(u8?|U|L)?'(\\\\(x[0-9A-Fa-f]{2}|u[0-9A-Fa-f]{4,8}|[0-7]{3}|\\S)|.)",end:"'",illegal:"."},e.END_SAME_AS_BEGIN({begin:/(?:u8?|U|L)?R"([^()\\ ]{0,16})\(/,end:/\)([^()\\ ]{0,16})"/})]},l={className:"number",variants:[{begin:"\\b(0b[01']+)"},{begin:"(-?)\\b([\\d']+(\\.[\\d']*)?|\\.[\\d']+)((ll|LL|l|L)(u|U)?|(u|U)(ll|LL|l|L)?|f|F|b|B)"},{begin:"(-?)(\\b0[xX][a-fA-F0-9']+|(\\b[\\d']+(\\.[\\d']*)?|\\.[\\d']+)([eE][-+]?[\\d']+)?)"}],relevance:0},c={className:"meta",begin:/#\s*[a-z]+\b/,end:/$/,keywords:{keyword:"if else elif endif define undef warning error line pragma _Pragma ifdef ifndef include"},contains:[{begin:/\\\n/,relevance:0},e.inherit(o,{className:"string"}),{className:"string",begin:/<.*?>/},t,e.C_BLOCK_COMMENT_MODE]},d={className:"title",begin:n.optional(i)+e.IDENT_RE,relevance:0},g=n.optional(i)+e.IDENT_RE+"\\s*\\(",u={keyword:["asm","auto","break","case","continue","default","do","else","enum","extern","for","fortran","goto","if","inline","register","restrict","return","sizeof","struct","switch","typedef","union","volatile","while","_Alignas","_Alignof","_Atomic","_Generic","_Noreturn","_Static_assert","_Thread_local","alignas","alignof","noreturn","static_assert","thread_local","_Pragma"],type:["float","double","signed","unsigned","int","short","long","char","void","_Bool","_Complex","_Imaginary","_Decimal32","_Decimal64","_Decimal128","const","static","complex","bool","imaginary"],literal:"true false NULL",built_in:"std string wstring cin cout cerr clog stdin stdout stderr stringstream istringstream ostringstream auto_ptr deque list queue stack vector map set pair bitset multiset multimap unordered_set unordered_map unordered_multiset unordered_multimap priority_queue make_pair array shared_ptr abort terminate abs acos asin atan2 atan calloc ceil cosh cos exit exp fabs floor fmod fprintf fputs free frexp fscanf future isalnum isalpha iscntrl isdigit isgraph islower isprint ispunct isspace isupper isxdigit tolower toupper labs ldexp log10 log malloc realloc memchr memcmp memcpy memset modf pow printf putchar puts scanf sinh sin snprintf sprintf sqrt sscanf strcat strchr strcmp strcpy strcspn strlen strncat strncmp strncpy strpbrk strrchr strspn strstr tanh tan vfprintf vprintf vsprintf endl initializer_list unique_ptr"},b=[c,s,t,e.C_BLOCK_COMMENT_MODE,l,o],m={variants:[{begin:/=/,end:/;/},{begin:/\(/,end:/\)/},{beginKeywords:"new throw return else",end:/;/}],keywords:u,contains:b.concat([{begin:/\(/,end:/\)/,keywords:u,contains:b.concat(["self"]),relevance:0}]),relevance:0},p={begin:"("+r+"[\\*&\\s]+)+"+g,returnBegin:!0,end:/[{;=]/,excludeEnd:!0,keywords:u,illegal:/[^\w\s\*&:<>.]/,contains:[{begin:a,keywords:u,relevance:0},{begin:g,returnBegin:!0,contains:[e.inherit(d,{className:"title.function"})],relevance:0},{relevance:0,match:/,/},{className:"params",begin:/\(/,end:/\)/,keywords:u,relevance:0,contains:[t,e.C_BLOCK_COMMENT_MODE,o,l,s,{begin:/\(/,end:/\)/,keywords:u,relevance:0,contains:["self",t,e.C_BLOCK_COMMENT_MODE,o,l,s]}]},s,t,e.C_BLOCK_COMMENT_MODE,c]};return{name:"C",aliases:["h"],keywords:u,disableAutodetect:!0,illegal:"=]/,contains:[{beginKeywords:"final class struct"},e.TITLE_MODE]}]),exports:{preprocessor:c,strings:o,keywords:u}}},grmr_cpp:e=>{const n=e.regex,t=e.COMMENT("//","$",{contains:[{begin:/\\\n/}]}),a="decltype\\(auto\\)",i="[a-zA-Z_]\\w*::",r="(?!struct)("+a+"|"+n.optional(i)+"[a-zA-Z_]\\w*"+n.optional("<[^<>]+>")+")",s={className:"type",begin:"\\b[a-z\\d_]*_t\\b"},o={className:"string",variants:[{begin:'(u8?|U|L)?"',end:'"',illegal:"\\n",contains:[e.BACKSLASH_ESCAPE]},{begin:"(u8?|U|L)?'(\\\\(x[0-9A-Fa-f]{2}|u[0-9A-Fa-f]{4,8}|[0-7]{3}|\\S)|.)",end:"'",illegal:"."},e.END_SAME_AS_BEGIN({begin:/(?:u8?|U|L)?R"([^()\\ ]{0,16})\(/,end:/\)([^()\\ ]{0,16})"/})]},l={className:"number",variants:[{begin:"\\b(0b[01']+)"},{begin:"(-?)\\b([\\d']+(\\.[\\d']*)?|\\.[\\d']+)((ll|LL|l|L)(u|U)?|(u|U)(ll|LL|l|L)?|f|F|b|B)"},{begin:"(-?)(\\b0[xX][a-fA-F0-9']+|(\\b[\\d']+(\\.[\\d']*)?|\\.[\\d']+)([eE][-+]?[\\d']+)?)"}],relevance:0},c={className:"meta",begin:/#\s*[a-z]+\b/,end:/$/,keywords:{keyword:"if else elif endif define undef warning error line pragma _Pragma ifdef ifndef include"},contains:[{begin:/\\\n/,relevance:0},e.inherit(o,{className:"string"}),{className:"string",begin:/<.*?>/},t,e.C_BLOCK_COMMENT_MODE]},d={className:"title",begin:n.optional(i)+e.IDENT_RE,relevance:0},g=n.optional(i)+e.IDENT_RE+"\\s*\\(",u={type:["bool","char","char16_t","char32_t","char8_t","double","float","int","long","short","void","wchar_t","unsigned","signed","const","static"],keyword:["alignas","alignof","and","and_eq","asm","atomic_cancel","atomic_commit","atomic_noexcept","auto","bitand","bitor","break","case","catch","class","co_await","co_return","co_yield","compl","concept","const_cast|10","consteval","constexpr","constinit","continue","decltype","default","delete","do","dynamic_cast|10","else","enum","explicit","export","extern","false","final","for","friend","goto","if","import","inline","module","mutable","namespace","new","noexcept","not","not_eq","nullptr","operator","or","or_eq","override","private","protected","public","reflexpr","register","reinterpret_cast|10","requires","return","sizeof","static_assert","static_cast|10","struct","switch","synchronized","template","this","thread_local","throw","transaction_safe","transaction_safe_dynamic","true","try","typedef","typeid","typename","union","using","virtual","volatile","while","xor","xor_eq"],literal:["NULL","false","nullopt","nullptr","true"],built_in:["_Pragma"],_type_hints:["any","auto_ptr","barrier","binary_semaphore","bitset","complex","condition_variable","condition_variable_any","counting_semaphore","deque","false_type","future","imaginary","initializer_list","istringstream","jthread","latch","lock_guard","multimap","multiset","mutex","optional","ostringstream","packaged_task","pair","promise","priority_queue","queue","recursive_mutex","recursive_timed_mutex","scoped_lock","set","shared_future","shared_lock","shared_mutex","shared_timed_mutex","shared_ptr","stack","string_view","stringstream","timed_mutex","thread","true_type","tuple","unique_lock","unique_ptr","unordered_map","unordered_multimap","unordered_multiset","unordered_set","variant","vector","weak_ptr","wstring","wstring_view"]},b={className:"function.dispatch",relevance:0,keywords:{_hint:["abort","abs","acos","apply","as_const","asin","atan","atan2","calloc","ceil","cerr","cin","clog","cos","cosh","cout","declval","endl","exchange","exit","exp","fabs","floor","fmod","forward","fprintf","fputs","free","frexp","fscanf","future","invoke","isalnum","isalpha","iscntrl","isdigit","isgraph","islower","isprint","ispunct","isspace","isupper","isxdigit","labs","launder","ldexp","log","log10","make_pair","make_shared","make_shared_for_overwrite","make_tuple","make_unique","malloc","memchr","memcmp","memcpy","memset","modf","move","pow","printf","putchar","puts","realloc","scanf","sin","sinh","snprintf","sprintf","sqrt","sscanf","std","stderr","stdin","stdout","strcat","strchr","strcmp","strcpy","strcspn","strlen","strncat","strncmp","strncpy","strpbrk","strrchr","strspn","strstr","swap","tan","tanh","terminate","to_underlying","tolower","toupper","vfprintf","visit","vprintf","vsprintf"]},begin:n.concat(/\b/,/(?!decltype)/,/(?!if)/,/(?!for)/,/(?!switch)/,/(?!while)/,e.IDENT_RE,n.lookahead(/(<[^<>]+>|)\s*\(/))},m=[b,c,s,t,e.C_BLOCK_COMMENT_MODE,l,o],p={variants:[{begin:/=/,end:/;/},{begin:/\(/,end:/\)/},{beginKeywords:"new throw return else",end:/;/}],keywords:u,contains:m.concat([{begin:/\(/,end:/\)/,keywords:u,contains:m.concat(["self"]),relevance:0}]),relevance:0},_={className:"function",begin:"("+r+"[\\*&\\s]+)+"+g,returnBegin:!0,end:/[{;=]/,excludeEnd:!0,keywords:u,illegal:/[^\w\s\*&:<>.]/,contains:[{begin:a,keywords:u,relevance:0},{begin:g,returnBegin:!0,contains:[d],relevance:0},{begin:/::/,relevance:0},{begin:/:/,endsWithParent:!0,contains:[o,l]},{relevance:0,match:/,/},{className:"params",begin:/\(/,end:/\)/,keywords:u,relevance:0,contains:[t,e.C_BLOCK_COMMENT_MODE,o,l,s,{begin:/\(/,end:/\)/,keywords:u,relevance:0,contains:["self",t,e.C_BLOCK_COMMENT_MODE,o,l,s]}]},s,t,e.C_BLOCK_COMMENT_MODE,c]};return{name:"C++",aliases:["cc","c++","h++","hpp","hh","hxx","cxx"],keywords:u,illegal:"",keywords:u,contains:["self",s]},{begin:e.IDENT_RE+"::",keywords:u},{match:[/\b(?:enum(?:\s+(?:class|struct))?|class|struct|union)/,/\s+/,/\w+/],className:{1:"keyword",3:"title.class"}}])}},grmr_csharp:e=>{const n={keyword:["abstract","as","base","break","case","catch","class","const","continue","do","else","event","explicit","extern","finally","fixed","for","foreach","goto","if","implicit","in","interface","internal","is","lock","namespace","new","operator","out","override","params","private","protected","public","readonly","record","ref","return","scoped","sealed","sizeof","stackalloc","static","struct","switch","this","throw","try","typeof","unchecked","unsafe","using","virtual","void","volatile","while"].concat(["add","alias","and","ascending","async","await","by","descending","equals","from","get","global","group","init","into","join","let","nameof","not","notnull","on","or","orderby","partial","remove","select","set","unmanaged","value|0","var","when","where","with","yield"]),built_in:["bool","byte","char","decimal","delegate","double","dynamic","enum","float","int","long","nint","nuint","object","sbyte","short","string","ulong","uint","ushort"],literal:["default","false","null","true"]},t=e.inherit(e.TITLE_MODE,{begin:"[a-zA-Z](\\.?\\w)*"}),a={className:"number",variants:[{begin:"\\b(0b[01']+)"},{begin:"(-?)\\b([\\d']+(\\.[\\d']*)?|\\.[\\d']+)(u|U|l|L|ul|UL|f|F|b|B)"},{begin:"(-?)(\\b0[xX][a-fA-F0-9']+|(\\b[\\d']+(\\.[\\d']*)?|\\.[\\d']+)([eE][-+]?[\\d']+)?)"}],relevance:0},i={className:"string",begin:'@"',end:'"',contains:[{begin:'""'}]},r=e.inherit(i,{illegal:/\n/}),s={className:"subst",begin:/\{/,end:/\}/,keywords:n},o=e.inherit(s,{illegal:/\n/}),l={className:"string",begin:/\$"/,end:'"',illegal:/\n/,contains:[{begin:/\{\{/},{begin:/\}\}/},e.BACKSLASH_ESCAPE,o]},c={className:"string",begin:/\$@"/,end:'"',contains:[{begin:/\{\{/},{begin:/\}\}/},{begin:'""'},s]},d=e.inherit(c,{illegal:/\n/,contains:[{begin:/\{\{/},{begin:/\}\}/},{begin:'""'},o]});s.contains=[c,l,i,e.APOS_STRING_MODE,e.QUOTE_STRING_MODE,a,e.C_BLOCK_COMMENT_MODE],o.contains=[d,l,r,e.APOS_STRING_MODE,e.QUOTE_STRING_MODE,a,e.inherit(e.C_BLOCK_COMMENT_MODE,{illegal:/\n/})];const g={variants:[c,l,i,e.APOS_STRING_MODE,e.QUOTE_STRING_MODE]},u={begin:"<",end:">",contains:[{beginKeywords:"in out"},t]},b=e.IDENT_RE+"(<"+e.IDENT_RE+"(\\s*,\\s*"+e.IDENT_RE+")*>)?(\\[\\])?",m={begin:"@"+e.IDENT_RE,relevance:0};return{name:"C#",aliases:["cs","c#"],keywords:n,illegal:/::/,contains:[e.COMMENT("///","$",{returnBegin:!0,contains:[{className:"doctag",variants:[{begin:"///",relevance:0},{begin:"\x3c!--|--\x3e"},{begin:""}]}]}),e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE,{className:"meta",begin:"#",end:"$",keywords:{keyword:"if else elif endif define undef warning error line region endregion pragma checksum"}},g,a,{beginKeywords:"class interface",relevance:0,end:/[{;=]/,illegal:/[^\s:,]/,contains:[{beginKeywords:"where class"},t,u,e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE]},{beginKeywords:"namespace",relevance:0,end:/[{;=]/,illegal:/[^\s:]/,contains:[t,e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE]},{beginKeywords:"record",relevance:0,end:/[{;=]/,illegal:/[^\s:]/,contains:[t,u,e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE]},{className:"meta",begin:"^\\s*\\[(?=[\\w])",excludeBegin:!0,end:"\\]",excludeEnd:!0,contains:[{className:"string",begin:/"/,end:/"/}]},{beginKeywords:"new return throw await else",relevance:0},{className:"function",begin:"("+b+"\\s+)+"+e.IDENT_RE+"\\s*(<[^=]+>\\s*)?\\(",returnBegin:!0,end:/\s*[{;=]/,excludeEnd:!0,keywords:n,contains:[{beginKeywords:"public private protected static internal protected abstract async extern override unsafe virtual new sealed partial",relevance:0},{begin:e.IDENT_RE+"\\s*(<[^=]+>\\s*)?\\(",returnBegin:!0,contains:[e.TITLE_MODE,u],relevance:0},{match:/\(\)/},{className:"params",begin:/\(/,end:/\)/,excludeBegin:!0,excludeEnd:!0,keywords:n,relevance:0,contains:[g,a,e.C_BLOCK_COMMENT_MODE]},e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE]},m]}},grmr_css:e=>{const n=e.regex,t=ie(e),a=[e.APOS_STRING_MODE,e.QUOTE_STRING_MODE];return{name:"CSS",case_insensitive:!0,illegal:/[=|'\$]/,keywords:{keyframePosition:"from to"},classNameAliases:{keyframePosition:"selector-tag"},contains:[t.BLOCK_COMMENT,{begin:/-(webkit|moz|ms|o)-(?=[a-z])/},t.CSS_NUMBER_MODE,{className:"selector-id",begin:/#[A-Za-z0-9_-]+/,relevance:0},{className:"selector-class",begin:"\\.[a-zA-Z-][a-zA-Z0-9_-]*",relevance:0},t.ATTRIBUTE_SELECTOR_MODE,{className:"selector-pseudo",variants:[{begin:":("+oe.join("|")+")"},{begin:":(:)?("+le.join("|")+")"}]},t.CSS_VARIABLE,{className:"attribute",begin:"\\b("+ce.join("|")+")\\b"},{begin:/:/,end:/[;}{]/,contains:[t.BLOCK_COMMENT,t.HEXCOLOR,t.IMPORTANT,t.CSS_NUMBER_MODE,...a,{begin:/(url|data-uri)\(/,end:/\)/,relevance:0,keywords:{built_in:"url data-uri"},contains:[...a,{className:"string",begin:/[^)]/,endsWithParent:!0,excludeEnd:!0}]},t.FUNCTION_DISPATCH]},{begin:n.lookahead(/@/),end:"[{;]",relevance:0,illegal:/:/,contains:[{className:"keyword",begin:/@-?\w[\w]*(-\w+)*/},{begin:/\s/,endsWithParent:!0,excludeEnd:!0,relevance:0,keywords:{$pattern:/[a-z-]+/,keyword:"and or not only",attribute:se.join(" ")},contains:[{begin:/[a-z-]+(?=:)/,className:"attribute"},...a,t.CSS_NUMBER_MODE]}]},{className:"selector-tag",begin:"\\b("+re.join("|")+")\\b"}]}},grmr_diff:e=>{const n=e.regex;return{name:"Diff",aliases:["patch"],contains:[{className:"meta",relevance:10,match:n.either(/^@@ +-\d+,\d+ +\+\d+,\d+ +@@/,/^\*\*\* +\d+,\d+ +\*\*\*\*$/,/^--- +\d+,\d+ +----$/)},{className:"comment",variants:[{begin:n.either(/Index: /,/^index/,/={3,}/,/^-{3}/,/^\*{3} /,/^\+{3}/,/^diff --git/),end:/$/},{match:/^\*{15}$/}]},{className:"addition",begin:/^\+/,end:/$/},{className:"deletion",begin:/^-/,end:/$/},{className:"addition",begin:/^!/,end:/$/}]}},grmr_go:e=>{const n={keyword:["break","case","chan","const","continue","default","defer","else","fallthrough","for","func","go","goto","if","import","interface","map","package","range","return","select","struct","switch","type","var"],type:["bool","byte","complex64","complex128","error","float32","float64","int8","int16","int32","int64","string","uint8","uint16","uint32","uint64","int","uint","uintptr","rune"],literal:["true","false","iota","nil"],built_in:["append","cap","close","complex","copy","imag","len","make","new","panic","print","println","real","recover","delete"]};return{name:"Go",aliases:["golang"],keywords:n,illegal:"{const n=e.regex;return{name:"GraphQL",aliases:["gql"],case_insensitive:!0,disableAutodetect:!1,keywords:{keyword:["query","mutation","subscription","type","input","schema","directive","interface","union","scalar","fragment","enum","on"],literal:["true","false","null"]},contains:[e.HASH_COMMENT_MODE,e.QUOTE_STRING_MODE,e.NUMBER_MODE,{scope:"punctuation",match:/[.]{3}/,relevance:0},{scope:"punctuation",begin:/[\!\(\)\:\=\[\]\{\|\}]{1}/,relevance:0},{scope:"variable",begin:/\$/,end:/\W/,excludeEnd:!0,relevance:0},{scope:"meta",match:/@\w+/,excludeEnd:!0},{scope:"symbol",begin:n.concat(/[_A-Za-z][_0-9A-Za-z]*/,n.lookahead(/\s*:/)),relevance:0}],illegal:[/[;<']/,/BEGIN/]}},grmr_ini:e=>{const n=e.regex,t={className:"number",relevance:0,variants:[{begin:/([+-]+)?[\d]+_[\d_]+/},{begin:e.NUMBER_RE}]},a=e.COMMENT();a.variants=[{begin:/;/,end:/$/},{begin:/#/,end:/$/}];const i={className:"variable",variants:[{begin:/\$[\w\d"][\w\d_]*/},{begin:/\$\{(.*?)\}/}]},r={className:"literal",begin:/\bon|off|true|false|yes|no\b/},s={className:"string",contains:[e.BACKSLASH_ESCAPE],variants:[{begin:"'''",end:"'''",relevance:10},{begin:'"""',end:'"""',relevance:10},{begin:'"',end:'"'},{begin:"'",end:"'"}]},o={begin:/\[/,end:/\]/,contains:[a,r,i,s,t,"self"],relevance:0},l=n.either(/[A-Za-z0-9_-]+/,/"(\\"|[^"])*"/,/'[^']*'/);return{name:"TOML, also INI",aliases:["toml"],case_insensitive:!0,illegal:/\S/,contains:[a,{className:"section",begin:/\[+/,end:/\]+/},{begin:n.concat(l,"(\\s*\\.\\s*",l,")*",n.lookahead(/\s*=\s*[^#\s]/)),className:"attr",starts:{end:/$/,contains:[a,o,r,i,s,t]}}]}},grmr_java:e=>{const n=e.regex,t="[\xc0-\u02b8a-zA-Z_$][\xc0-\u02b8a-zA-Z_$0-9]*",a=t+pe("(?:<"+t+"~~~(?:\\s*,\\s*"+t+"~~~)*>)?",/~~~/g,2),i={keyword:["synchronized","abstract","private","var","static","if","const ","for","while","strictfp","finally","protected","import","native","final","void","enum","else","break","transient","catch","instanceof","volatile","case","assert","package","default","public","try","switch","continue","throws","protected","public","private","module","requires","exports","do","sealed","yield","permits"],literal:["false","true","null"],type:["char","boolean","long","float","int","byte","short","double"],built_in:["super","this"]},r={className:"meta",begin:"@"+t,contains:[{begin:/\(/,end:/\)/,contains:["self"]}]},s={className:"params",begin:/\(/,end:/\)/,keywords:i,relevance:0,contains:[e.C_BLOCK_COMMENT_MODE],endsParent:!0};return{name:"Java",aliases:["jsp"],keywords:i,illegal:/<\/|#/,contains:[e.COMMENT("/\\*\\*","\\*/",{relevance:0,contains:[{begin:/\w+@/,relevance:0},{className:"doctag",begin:"@[A-Za-z]+"}]}),{begin:/import java\.[a-z]+\./,keywords:"import",relevance:2},e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE,{begin:/"""/,end:/"""/,className:"string",contains:[e.BACKSLASH_ESCAPE]},e.APOS_STRING_MODE,e.QUOTE_STRING_MODE,{match:[/\b(?:class|interface|enum|extends|implements|new)/,/\s+/,t],className:{1:"keyword",3:"title.class"}},{match:/non-sealed/,scope:"keyword"},{begin:[n.concat(/(?!else)/,t),/\s+/,t,/\s+/,/=(?!=)/],className:{1:"type",3:"variable",5:"operator"}},{begin:[/record/,/\s+/,t],className:{1:"keyword",3:"title.class"},contains:[s,e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE]},{beginKeywords:"new throw return else",relevance:0},{begin:["(?:"+a+"\\s+)",e.UNDERSCORE_IDENT_RE,/\s*(?=\()/],className:{2:"title.function"},keywords:i,contains:[{className:"params",begin:/\(/,end:/\)/,keywords:i,relevance:0,contains:[r,e.APOS_STRING_MODE,e.QUOTE_STRING_MODE,me,e.C_BLOCK_COMMENT_MODE]},e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE]},me,r]}},grmr_javascript:Oe,grmr_json:e=>{const n=["true","false","null"],t={scope:"literal",beginKeywords:n.join(" ")};return{name:"JSON",keywords:{literal:n},contains:[{className:"attr",begin:/"(\\.|[^\\"\r\n])*"(?=\s*:)/,relevance:1.01},{match:/[{}[\],:]/,className:"punctuation",relevance:0},e.QUOTE_STRING_MODE,t,e.C_NUMBER_MODE,e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE],illegal:"\\S"}},grmr_kotlin:e=>{const n={keyword:"abstract as val var vararg get set class object open private protected public noinline crossinline dynamic final enum if else do while for when throw try catch finally import package is in fun override companion reified inline lateinit init interface annotation data sealed internal infix operator out by constructor super tailrec where const inner suspend typealias external expect actual",built_in:"Byte Short Char Int Long Boolean Float Double Void Unit Nothing",literal:"true false null"},t={className:"symbol",begin:e.UNDERSCORE_IDENT_RE+"@"},a={className:"subst",begin:/\$\{/,end:/\}/,contains:[e.C_NUMBER_MODE]},i={className:"variable",begin:"\\$"+e.UNDERSCORE_IDENT_RE},r={className:"string",variants:[{begin:'"""',end:'"""(?=[^"])',contains:[i,a]},{begin:"'",end:"'",illegal:/\n/,contains:[e.BACKSLASH_ESCAPE]},{begin:'"',end:'"',illegal:/\n/,contains:[e.BACKSLASH_ESCAPE,i,a]}]};a.contains.push(r);const s={className:"meta",begin:"@(?:file|property|field|get|set|receiver|param|setparam|delegate)\\s*:(?:\\s*"+e.UNDERSCORE_IDENT_RE+")?"},o={className:"meta",begin:"@"+e.UNDERSCORE_IDENT_RE,contains:[{begin:/\(/,end:/\)/,contains:[e.inherit(r,{className:"string"}),"self"]}]},l=me,c=e.COMMENT("/\\*","\\*/",{contains:[e.C_BLOCK_COMMENT_MODE]}),d={variants:[{className:"type",begin:e.UNDERSCORE_IDENT_RE},{begin:/\(/,end:/\)/,contains:[]}]},g=d;return g.variants[1].contains=[d],d.variants[1].contains=[g],{name:"Kotlin",aliases:["kt","kts"],keywords:n,contains:[e.COMMENT("/\\*\\*","\\*/",{relevance:0,contains:[{className:"doctag",begin:"@[A-Za-z]+"}]}),e.C_LINE_COMMENT_MODE,c,{className:"keyword",begin:/\b(break|continue|return|this)\b/,starts:{contains:[{className:"symbol",begin:/@\w+/}]}},t,s,o,{className:"function",beginKeywords:"fun",end:"[(]|$",returnBegin:!0,excludeEnd:!0,keywords:n,relevance:5,contains:[{begin:e.UNDERSCORE_IDENT_RE+"\\s*\\(",returnBegin:!0,relevance:0,contains:[e.UNDERSCORE_TITLE_MODE]},{className:"type",begin://,keywords:"reified",relevance:0},{className:"params",begin:/\(/,end:/\)/,endsParent:!0,keywords:n,relevance:0,contains:[{begin:/:/,end:/[=,\/]/,endsWithParent:!0,contains:[d,e.C_LINE_COMMENT_MODE,c],relevance:0},e.C_LINE_COMMENT_MODE,c,s,o,r,e.C_NUMBER_MODE]},c]},{begin:[/class|interface|trait/,/\s+/,e.UNDERSCORE_IDENT_RE],beginScope:{3:"title.class"},keywords:"class interface trait",end:/[:\{(]|$/,excludeEnd:!0,illegal:"extends implements",contains:[{beginKeywords:"public protected internal private constructor"},e.UNDERSCORE_TITLE_MODE,{className:"type",begin://,excludeBegin:!0,excludeEnd:!0,relevance:0},{className:"type",begin:/[,:]\s*/,end:/[<\(,){\s]|$/,excludeBegin:!0,returnEnd:!0},s,o]},r,{className:"meta",begin:"^#!/usr/bin/env",end:"$",illegal:"\n"},l]}},grmr_less:e=>{const n=ie(e),t=de,a="[\\w-]+",i="("+a+"|@\\{"+a+"\\})",r=[],s=[],o=e=>({className:"string",begin:"~?"+e+".*?"+e}),l=(e,n,t)=>({className:e,begin:n,relevance:t}),c={$pattern:/[a-z-]+/,keyword:"and or not only",attribute:se.join(" ")},d={begin:"\\(",end:"\\)",contains:s,keywords:c,relevance:0};s.push(e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE,o("'"),o('"'),n.CSS_NUMBER_MODE,{begin:"(url|data-uri)\\(",starts:{className:"string",end:"[\\)\\n]",excludeEnd:!0}},n.HEXCOLOR,d,l("variable","@@?"+a,10),l("variable","@\\{"+a+"\\}"),l("built_in","~?`[^`]*?`"),{className:"attribute",begin:a+"\\s*:",end:":",returnBegin:!0,excludeEnd:!0},n.IMPORTANT,{beginKeywords:"and not"},n.FUNCTION_DISPATCH);const g=s.concat({begin:/\{/,end:/\}/,contains:r}),u={beginKeywords:"when",endsWithParent:!0,contains:[{beginKeywords:"and not"}].concat(s)},b={begin:i+"\\s*:",returnBegin:!0,end:/[;}]/,relevance:0,contains:[{begin:/-(webkit|moz|ms|o)-/},n.CSS_VARIABLE,{className:"attribute",begin:"\\b("+ce.join("|")+")\\b",end:/(?=:)/,starts:{endsWithParent:!0,illegal:"[<=$]",relevance:0,contains:s}}]},m={className:"keyword",begin:"@(import|media|charset|font-face|(-[a-z]+-)?keyframes|supports|document|namespace|page|viewport|host)\\b",starts:{end:"[;{}]",keywords:c,returnEnd:!0,contains:s,relevance:0}},p={className:"variable",variants:[{begin:"@"+a+"\\s*:",relevance:15},{begin:"@"+a}],starts:{end:"[;}]",returnEnd:!0,contains:g}},_={variants:[{begin:"[\\.#:&\\[>]",end:"[;{}]"},{begin:i,end:/\{/}],returnBegin:!0,returnEnd:!0,illegal:"[<='$\"]",relevance:0,contains:[e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE,u,l("keyword","all\\b"),l("variable","@\\{"+a+"\\}"),{begin:"\\b("+re.join("|")+")\\b",className:"selector-tag"},n.CSS_NUMBER_MODE,l("selector-tag",i,0),l("selector-id","#"+i),l("selector-class","\\."+i,0),l("selector-tag","&",0),n.ATTRIBUTE_SELECTOR_MODE,{className:"selector-pseudo",begin:":("+oe.join("|")+")"},{className:"selector-pseudo",begin:":(:)?("+le.join("|")+")"},{begin:/\(/,end:/\)/,relevance:0,contains:g},{begin:"!important"},n.FUNCTION_DISPATCH]},h={begin:a+":(:)?"+`(${t.join("|")})`,returnBegin:!0,contains:[_]};return r.push(e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE,m,p,h,b,_,u,n.FUNCTION_DISPATCH),{name:"Less",case_insensitive:!0,illegal:"[=>'/<($\"]",contains:r}},grmr_lua:e=>{const n="\\[=*\\[",t="\\]=*\\]",a={begin:n,end:t,contains:["self"]},i=[e.COMMENT("--(?!"+n+")","$"),e.COMMENT("--"+n,t,{contains:[a],relevance:10})];return{name:"Lua",keywords:{$pattern:e.UNDERSCORE_IDENT_RE,literal:"true false nil",keyword:"and break do else elseif end for goto if in local not or repeat return then until while",built_in:"_G _ENV _VERSION __index __newindex __mode __call __metatable __tostring __len __gc __add __sub __mul __div __mod __pow __concat __unm __eq __lt __le assert collectgarbage dofile error getfenv getmetatable ipairs load loadfile loadstring module next pairs pcall print rawequal rawget rawset require select setfenv setmetatable tonumber tostring type unpack xpcall arg self coroutine resume yield status wrap create running debug getupvalue debug sethook getmetatable gethook setmetatable setlocal traceback setfenv getinfo setupvalue getlocal getregistry getfenv io lines write close flush open output type read stderr stdin input stdout popen tmpfile math log max acos huge ldexp pi cos tanh pow deg tan cosh sinh random randomseed frexp ceil floor rad abs sqrt modf asin min mod fmod log10 atan2 exp sin atan os exit setlocale date getenv difftime remove time clock tmpname rename execute package preload loadlib loaded loaders cpath config path seeall string sub upper len gfind rep find match char dump gmatch reverse byte format gsub lower table setn insert getn foreachi maxn foreach concat sort remove"},contains:i.concat([{className:"function",beginKeywords:"function",end:"\\)",contains:[e.inherit(e.TITLE_MODE,{begin:"([_a-zA-Z]\\w*\\.)*([_a-zA-Z]\\w*:)?[_a-zA-Z]\\w*"}),{className:"params",begin:"\\(",endsWithParent:!0,contains:i}].concat(i)},e.C_NUMBER_MODE,e.APOS_STRING_MODE,e.QUOTE_STRING_MODE,{className:"string",begin:n,end:t,contains:[a],relevance:5}])}},grmr_makefile:e=>{const n={className:"variable",variants:[{begin:"\\$\\("+e.UNDERSCORE_IDENT_RE+"\\)",contains:[e.BACKSLASH_ESCAPE]},{begin:/\$[@%{const n=e.regex,t=n.concat(/[\p{L}_]/u,n.optional(/[\p{L}0-9_.-]*:/u),/[\p{L}0-9_.-]*/u),a={className:"symbol",begin:/&[a-z]+;|&#[0-9]+;|&#x[a-f0-9]+;/},i={begin:/\s/,contains:[{className:"keyword",begin:/#?[a-z_][a-z1-9_-]+/,illegal:/\n/}]},r=e.inherit(i,{begin:/\(/,end:/\)/}),s=e.inherit(e.APOS_STRING_MODE,{className:"string"}),o=e.inherit(e.QUOTE_STRING_MODE,{className:"string"}),l={endsWithParent:!0,illegal:/`]+/}]}]}]};return{name:"HTML, XML",aliases:["html","xhtml","rss","atom","xjb","xsd","xsl","plist","wsf","svg"],case_insensitive:!0,unicodeRegex:!0,contains:[{className:"meta",begin://,relevance:10,contains:[i,o,s,r,{begin:/\[/,end:/\]/,contains:[{className:"meta",begin://,contains:[i,r,o,s]}]}]},e.COMMENT(//,{relevance:10}),{begin://,relevance:10},a,{className:"meta",end:/\?>/,variants:[{begin:/<\?xml/,relevance:10,contains:[o]},{begin:/<\?[a-z][a-z0-9]+/}]},{className:"tag",begin:/)/,end:/>/,keywords:{name:"style"},contains:[l],starts:{end:/<\/style>/,returnEnd:!0,subLanguage:["css","xml"]}},{className:"tag",begin:/)/,end:/>/,keywords:{name:"script"},contains:[l],starts:{end:/<\/script>/,returnEnd:!0,subLanguage:["javascript","handlebars","xml"]}},{className:"tag",begin:/<>|<\/>/},{className:"tag",begin:n.concat(//,/>/,/\s/)))),end:/\/?>/,contains:[{className:"name",begin:t,relevance:0,starts:l}]},{className:"tag",begin:n.concat(/<\//,n.lookahead(n.concat(t,/>/))),contains:[{className:"name",begin:t,relevance:0},{begin:/>/,relevance:0,endsParent:!0}]}]}},grmr_markdown:e=>{const n={begin:/<\/?[A-Za-z_]/,end:">",subLanguage:"xml",relevance:0},t={variants:[{begin:/\[.+?\]\[.*?\]/,relevance:0},{begin:/\[.+?\]\(((data|javascript|mailto):|(?:http|ftp)s?:\/\/).*?\)/,relevance:2},{begin:e.regex.concat(/\[.+?\]\(/,/[A-Za-z][A-Za-z0-9+.-]*/,/:\/\/.*?\)/),relevance:2},{begin:/\[.+?\]\([./?&#].*?\)/,relevance:1},{begin:/\[.*?\]\(.*?\)/,relevance:0}],returnBegin:!0,contains:[{match:/\[(?=\])/},{className:"string",relevance:0,begin:"\\[",end:"\\]",excludeBegin:!0,returnEnd:!0},{className:"link",relevance:0,begin:"\\]\\(",end:"\\)",excludeBegin:!0,excludeEnd:!0},{className:"symbol",relevance:0,begin:"\\]\\[",end:"\\]",excludeBegin:!0,excludeEnd:!0}]},a={className:"strong",contains:[],variants:[{begin:/_{2}(?!\s)/,end:/_{2}/},{begin:/\*{2}(?!\s)/,end:/\*{2}/}]},i={className:"emphasis",contains:[],variants:[{begin:/\*(?![*\s])/,end:/\*/},{begin:/_(?![_\s])/,end:/_/,relevance:0}]},r=e.inherit(a,{contains:[]}),s=e.inherit(i,{contains:[]});a.contains.push(s),i.contains.push(r);let o=[n,t];return[a,i,r,s].forEach((e=>{e.contains=e.contains.concat(o)})),o=o.concat(a,i),{name:"Markdown",aliases:["md","mkdown","mkd"],contains:[{className:"section",variants:[{begin:"^#{1,6}",end:"$",contains:o},{begin:"(?=^.+?\\n[=-]{2,}$)",contains:[{begin:"^[=-]*$"},{begin:"^",end:"\\n",contains:o}]}]},n,{className:"bullet",begin:"^[ \t]*([*+-]|(\\d+\\.))(?=\\s+)",end:"\\s+",excludeEnd:!0},a,i,{className:"quote",begin:"^>\\s+",contains:o,end:"$"},{className:"code",variants:[{begin:"(`{3,})[^`](.|\\n)*?\\1`*[ ]*"},{begin:"(~{3,})[^~](.|\\n)*?\\1~*[ ]*"},{begin:"```",end:"```+[ ]*$"},{begin:"~~~",end:"~~~+[ ]*$"},{begin:"`.+?`"},{begin:"(?=^( {4}|\\t))",contains:[{begin:"^( {4}|\\t)",end:"(\\n)$"}],relevance:0}]},{begin:"^[-\\*]{3,}",end:"$"},t,{begin:/^\[[^\n]+\]:/,returnBegin:!0,contains:[{className:"symbol",begin:/\[/,end:/\]/,excludeBegin:!0,excludeEnd:!0},{className:"link",begin:/:\s*/,end:/$/,excludeBegin:!0}]}]}},grmr_objectivec:e=>{const n=/[a-zA-Z@][a-zA-Z0-9_]*/,t={$pattern:n,keyword:["@interface","@class","@protocol","@implementation"]};return{name:"Objective-C",aliases:["mm","objc","obj-c","obj-c++","objective-c++"],keywords:{"variable.language":["this","super"],$pattern:n,keyword:["while","export","sizeof","typedef","const","struct","for","union","volatile","static","mutable","if","do","return","goto","enum","else","break","extern","asm","case","default","register","explicit","typename","switch","continue","inline","readonly","assign","readwrite","self","@synchronized","id","typeof","nonatomic","IBOutlet","IBAction","strong","weak","copy","in","out","inout","bycopy","byref","oneway","__strong","__weak","__block","__autoreleasing","@private","@protected","@public","@try","@property","@end","@throw","@catch","@finally","@autoreleasepool","@synthesize","@dynamic","@selector","@optional","@required","@encode","@package","@import","@defs","@compatibility_alias","__bridge","__bridge_transfer","__bridge_retained","__bridge_retain","__covariant","__contravariant","__kindof","_Nonnull","_Nullable","_Null_unspecified","__FUNCTION__","__PRETTY_FUNCTION__","__attribute__","getter","setter","retain","unsafe_unretained","nonnull","nullable","null_unspecified","null_resettable","class","instancetype","NS_DESIGNATED_INITIALIZER","NS_UNAVAILABLE","NS_REQUIRES_SUPER","NS_RETURNS_INNER_POINTER","NS_INLINE","NS_AVAILABLE","NS_DEPRECATED","NS_ENUM","NS_OPTIONS","NS_SWIFT_UNAVAILABLE","NS_ASSUME_NONNULL_BEGIN","NS_ASSUME_NONNULL_END","NS_REFINED_FOR_SWIFT","NS_SWIFT_NAME","NS_SWIFT_NOTHROW","NS_DURING","NS_HANDLER","NS_ENDHANDLER","NS_VALUERETURN","NS_VOIDRETURN"],literal:["false","true","FALSE","TRUE","nil","YES","NO","NULL"],built_in:["dispatch_once_t","dispatch_queue_t","dispatch_sync","dispatch_async","dispatch_once"],type:["int","float","char","unsigned","signed","short","long","double","wchar_t","unichar","void","bool","BOOL","id|0","_Bool"]},illegal:"/,end:/$/,illegal:"\\n"},e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE]},{className:"class",begin:"("+t.keyword.join("|")+")\\b",end:/(\{|$)/,excludeEnd:!0,keywords:t,contains:[e.UNDERSCORE_TITLE_MODE]},{begin:"\\."+e.UNDERSCORE_IDENT_RE,relevance:0}]}},grmr_perl:e=>{const n=e.regex,t=/[dualxmsipngr]{0,12}/,a={$pattern:/[\w.]+/,keyword:"abs accept alarm and atan2 bind binmode bless break caller chdir chmod chomp chop chown chr chroot close closedir connect continue cos crypt dbmclose dbmopen defined delete die do dump each else elsif endgrent endhostent endnetent endprotoent endpwent endservent eof eval exec exists exit exp fcntl fileno flock for foreach fork format formline getc getgrent getgrgid getgrnam gethostbyaddr gethostbyname gethostent getlogin getnetbyaddr getnetbyname getnetent getpeername getpgrp getpriority getprotobyname getprotobynumber getprotoent getpwent getpwnam getpwuid getservbyname getservbyport getservent getsockname getsockopt given glob gmtime goto grep gt hex if index int ioctl join keys kill last lc lcfirst length link listen local localtime log lstat lt ma map mkdir msgctl msgget msgrcv msgsnd my ne next no not oct open opendir or ord our pack package pipe pop pos print printf prototype push q|0 qq quotemeta qw qx rand read readdir readline readlink readpipe recv redo ref rename require reset return reverse rewinddir rindex rmdir say scalar seek seekdir select semctl semget semop send setgrent sethostent setnetent setpgrp setpriority setprotoent setpwent setservent setsockopt shift shmctl shmget shmread shmwrite shutdown sin sleep socket socketpair sort splice split sprintf sqrt srand stat state study sub substr symlink syscall sysopen sysread sysseek system syswrite tell telldir tie tied time times tr truncate uc ucfirst umask undef unless unlink unpack unshift untie until use utime values vec wait waitpid wantarray warn when while write x|0 xor y|0"},i={className:"subst",begin:"[$@]\\{",end:"\\}",keywords:a},r={begin:/->\{/,end:/\}/},s={variants:[{begin:/\$\d/},{begin:n.concat(/[$%@](\^\w\b|#\w+(::\w+)*|\{\w+\}|\w+(::\w*)*)/,"(?![A-Za-z])(?![@$%])")},{begin:/[$%@][^\s\w{]/,relevance:0}]},o=[e.BACKSLASH_ESCAPE,i,s],l=[/!/,/\//,/\|/,/\?/,/'/,/"/,/#/],c=(e,a,i="\\1")=>{const r="\\1"===i?i:n.concat(i,a);return n.concat(n.concat("(?:",e,")"),a,/(?:\\.|[^\\\/])*?/,r,/(?:\\.|[^\\\/])*?/,i,t)},d=(e,a,i)=>n.concat(n.concat("(?:",e,")"),a,/(?:\\.|[^\\\/])*?/,i,t),g=[s,e.HASH_COMMENT_MODE,e.COMMENT(/^=\w/,/=cut/,{endsWithParent:!0}),r,{className:"string",contains:o,variants:[{begin:"q[qwxr]?\\s*\\(",end:"\\)",relevance:5},{begin:"q[qwxr]?\\s*\\[",end:"\\]",relevance:5},{begin:"q[qwxr]?\\s*\\{",end:"\\}",relevance:5},{begin:"q[qwxr]?\\s*\\|",end:"\\|",relevance:5},{begin:"q[qwxr]?\\s*<",end:">",relevance:5},{begin:"qw\\s+q",end:"q",relevance:5},{begin:"'",end:"'",contains:[e.BACKSLASH_ESCAPE]},{begin:'"',end:'"'},{begin:"`",end:"`",contains:[e.BACKSLASH_ESCAPE]},{begin:/\{\w+\}/,relevance:0},{begin:"-?\\w+\\s*=>",relevance:0}]},{className:"number",begin:"(\\b0[0-7_]+)|(\\b0x[0-9a-fA-F_]+)|(\\b[1-9][0-9_]*(\\.[0-9_]+)?)|[0_]\\b",relevance:0},{begin:"(\\/\\/|"+e.RE_STARTERS_RE+"|\\b(split|return|print|reverse|grep)\\b)\\s*",keywords:"split return print reverse grep",relevance:0,contains:[e.HASH_COMMENT_MODE,{className:"regexp",variants:[{begin:c("s|tr|y",n.either(...l,{capture:!0}))},{begin:c("s|tr|y","\\(","\\)")},{begin:c("s|tr|y","\\[","\\]")},{begin:c("s|tr|y","\\{","\\}")}],relevance:2},{className:"regexp",variants:[{begin:/(m|qr)\/\//,relevance:0},{begin:d("(?:m|qr)?",/\//,/\//)},{begin:d("m|qr",n.either(...l,{capture:!0}),/\1/)},{begin:d("m|qr",/\(/,/\)/)},{begin:d("m|qr",/\[/,/\]/)},{begin:d("m|qr",/\{/,/\}/)}]}]},{className:"function",beginKeywords:"sub",end:"(\\s*\\(.*?\\))?[;{]",excludeEnd:!0,relevance:5,contains:[e.TITLE_MODE]},{begin:"-\\w\\b",relevance:0},{begin:"^__DATA__$",end:"^__END__$",subLanguage:"mojolicious",contains:[{begin:"^@@.*",end:"$",className:"comment"}]}];return i.contains=g,r.contains=g,{name:"Perl",aliases:["pl","pm"],keywords:a,contains:g}},grmr_php:e=>{const n=e.regex,t=/(?![A-Za-z0-9])(?![$])/,a=n.concat(/[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*/,t),i=n.concat(/(\\?[A-Z][a-z0-9_\x7f-\xff]+|\\?[A-Z]+(?=[A-Z][a-z0-9_\x7f-\xff])){1,}/,t),r={scope:"variable",match:"\\$+"+a},s={scope:"subst",variants:[{begin:/\$\w+/},{begin:/\{\$/,end:/\}/}]},o=e.inherit(e.APOS_STRING_MODE,{illegal:null}),l="[ \t\n]",c={scope:"string",variants:[e.inherit(e.QUOTE_STRING_MODE,{illegal:null,contains:e.QUOTE_STRING_MODE.contains.concat(s)}),o,{begin:/<<<[ \t]*(?:(\w+)|"(\w+)")\n/,end:/[ \t]*(\w+)\b/,contains:e.QUOTE_STRING_MODE.contains.concat(s),"on:begin":(e,n)=>{n.data._beginMatch=e[1]||e[2]},"on:end":(e,n)=>{n.data._beginMatch!==e[1]&&n.ignoreMatch()}},e.END_SAME_AS_BEGIN({begin:/<<<[ \t]*'(\w+)'\n/,end:/[ \t]*(\w+)\b/})]},d={scope:"number",variants:[{begin:"\\b0[bB][01]+(?:_[01]+)*\\b"},{begin:"\\b0[oO][0-7]+(?:_[0-7]+)*\\b"},{begin:"\\b0[xX][\\da-fA-F]+(?:_[\\da-fA-F]+)*\\b"},{begin:"(?:\\b\\d+(?:_\\d+)*(\\.(?:\\d+(?:_\\d+)*))?|\\B\\.\\d+)(?:[eE][+-]?\\d+)?"}],relevance:0},g=["false","null","true"],u=["__CLASS__","__DIR__","__FILE__","__FUNCTION__","__COMPILER_HALT_OFFSET__","__LINE__","__METHOD__","__NAMESPACE__","__TRAIT__","die","echo","exit","include","include_once","print","require","require_once","array","abstract","and","as","binary","bool","boolean","break","callable","case","catch","class","clone","const","continue","declare","default","do","double","else","elseif","empty","enddeclare","endfor","endforeach","endif","endswitch","endwhile","enum","eval","extends","final","finally","float","for","foreach","from","global","goto","if","implements","instanceof","insteadof","int","integer","interface","isset","iterable","list","match|0","mixed","new","never","object","or","private","protected","public","readonly","real","return","string","switch","throw","trait","try","unset","use","var","void","while","xor","yield"],b=["Error|0","AppendIterator","ArgumentCountError","ArithmeticError","ArrayIterator","ArrayObject","AssertionError","BadFunctionCallException","BadMethodCallException","CachingIterator","CallbackFilterIterator","CompileError","Countable","DirectoryIterator","DivisionByZeroError","DomainException","EmptyIterator","ErrorException","Exception","FilesystemIterator","FilterIterator","GlobIterator","InfiniteIterator","InvalidArgumentException","IteratorIterator","LengthException","LimitIterator","LogicException","MultipleIterator","NoRewindIterator","OutOfBoundsException","OutOfRangeException","OuterIterator","OverflowException","ParentIterator","ParseError","RangeException","RecursiveArrayIterator","RecursiveCachingIterator","RecursiveCallbackFilterIterator","RecursiveDirectoryIterator","RecursiveFilterIterator","RecursiveIterator","RecursiveIteratorIterator","RecursiveRegexIterator","RecursiveTreeIterator","RegexIterator","RuntimeException","SeekableIterator","SplDoublyLinkedList","SplFileInfo","SplFileObject","SplFixedArray","SplHeap","SplMaxHeap","SplMinHeap","SplObjectStorage","SplObserver","SplPriorityQueue","SplQueue","SplStack","SplSubject","SplTempFileObject","TypeError","UnderflowException","UnexpectedValueException","UnhandledMatchError","ArrayAccess","BackedEnum","Closure","Fiber","Generator","Iterator","IteratorAggregate","Serializable","Stringable","Throwable","Traversable","UnitEnum","WeakReference","WeakMap","Directory","__PHP_Incomplete_Class","parent","php_user_filter","self","static","stdClass"],m={keyword:u,literal:(e=>{const n=[];return e.forEach((e=>{n.push(e),e.toLowerCase()===e?n.push(e.toUpperCase()):n.push(e.toLowerCase())})),n})(g),built_in:b},p=e=>e.map((e=>e.replace(/\|\d+$/,""))),_={variants:[{match:[/new/,n.concat(l,"+"),n.concat("(?!",p(b).join("\\b|"),"\\b)"),i],scope:{1:"keyword",4:"title.class"}}]},h=n.concat(a,"\\b(?!\\()"),f={variants:[{match:[n.concat(/::/,n.lookahead(/(?!class\b)/)),h],scope:{2:"variable.constant"}},{match:[/::/,/class/],scope:{2:"variable.language"}},{match:[i,n.concat(/::/,n.lookahead(/(?!class\b)/)),h],scope:{1:"title.class",3:"variable.constant"}},{match:[i,n.concat("::",n.lookahead(/(?!class\b)/))],scope:{1:"title.class"}},{match:[i,/::/,/class/],scope:{1:"title.class",3:"variable.language"}}]},E={scope:"attr",match:n.concat(a,n.lookahead(":"),n.lookahead(/(?!::)/))},y={relevance:0,begin:/\(/,end:/\)/,keywords:m,contains:[E,r,f,e.C_BLOCK_COMMENT_MODE,c,d,_]},N={relevance:0,match:[/\b/,n.concat("(?!fn\\b|function\\b|",p(u).join("\\b|"),"|",p(b).join("\\b|"),"\\b)"),a,n.concat(l,"*"),n.lookahead(/(?=\()/)],scope:{3:"title.function.invoke"},contains:[y]};y.contains.push(N);const w=[E,f,e.C_BLOCK_COMMENT_MODE,c,d,_];return{case_insensitive:!1,keywords:m,contains:[{begin:n.concat(/#\[\s*/,i),beginScope:"meta",end:/]/,endScope:"meta",keywords:{literal:g,keyword:["new","array"]},contains:[{begin:/\[/,end:/]/,keywords:{literal:g,keyword:["new","array"]},contains:["self",...w]},...w,{scope:"meta",match:i}]},e.HASH_COMMENT_MODE,e.COMMENT("//","$"),e.COMMENT("/\\*","\\*/",{contains:[{scope:"doctag",match:"@[A-Za-z]+"}]}),{match:/__halt_compiler\(\);/,keywords:"__halt_compiler",starts:{scope:"comment",end:e.MATCH_NOTHING_RE,contains:[{match:/\?>/,scope:"meta",endsParent:!0}]}},{scope:"meta",variants:[{begin:/<\?php/,relevance:10},{begin:/<\?=/},{begin:/<\?/,relevance:.1},{begin:/\?>/}]},{scope:"variable.language",match:/\$this\b/},r,N,f,{match:[/const/,/\s/,a],scope:{1:"keyword",3:"variable.constant"}},_,{scope:"function",relevance:0,beginKeywords:"fn function",end:/[;{]/,excludeEnd:!0,illegal:"[$%\\[]",contains:[{beginKeywords:"use"},e.UNDERSCORE_TITLE_MODE,{begin:"=>",endsParent:!0},{scope:"params",begin:"\\(",end:"\\)",excludeBegin:!0,excludeEnd:!0,keywords:m,contains:["self",r,f,e.C_BLOCK_COMMENT_MODE,c,d]}]},{scope:"class",variants:[{beginKeywords:"enum",illegal:/[($"]/},{beginKeywords:"class interface trait",illegal:/[:($"]/}],relevance:0,end:/\{/,excludeEnd:!0,contains:[{beginKeywords:"extends implements"},e.UNDERSCORE_TITLE_MODE]},{beginKeywords:"namespace",relevance:0,end:";",illegal:/[.']/,contains:[e.inherit(e.UNDERSCORE_TITLE_MODE,{scope:"title.class"})]},{beginKeywords:"use",relevance:0,end:";",contains:[{match:/\b(as|const|function)\b/,scope:"keyword"},e.UNDERSCORE_TITLE_MODE]},c,d]}},grmr_php_template:e=>({name:"PHP template",subLanguage:"xml",contains:[{begin:/<\?(php|=)?/,end:/\?>/,subLanguage:"php",contains:[{begin:"/\\*",end:"\\*/",skip:!0},{begin:'b"',end:'"',skip:!0},{begin:"b'",end:"'",skip:!0},e.inherit(e.APOS_STRING_MODE,{illegal:null,className:null,contains:null,skip:!0}),e.inherit(e.QUOTE_STRING_MODE,{illegal:null,className:null,contains:null,skip:!0})]}]}),grmr_plaintext:e=>({name:"Plain text",aliases:["text","txt"],disableAutodetect:!0}),grmr_python:e=>{const n=e.regex,t=/[\p{XID_Start}_]\p{XID_Continue}*/u,a=["and","as","assert","async","await","break","case","class","continue","def","del","elif","else","except","finally","for","from","global","if","import","in","is","lambda","match","nonlocal|10","not","or","pass","raise","return","try","while","with","yield"],i={$pattern:/[A-Za-z]\w+|__\w+__/,keyword:a,built_in:["__import__","abs","all","any","ascii","bin","bool","breakpoint","bytearray","bytes","callable","chr","classmethod","compile","complex","delattr","dict","dir","divmod","enumerate","eval","exec","filter","float","format","frozenset","getattr","globals","hasattr","hash","help","hex","id","input","int","isinstance","issubclass","iter","len","list","locals","map","max","memoryview","min","next","object","oct","open","ord","pow","print","property","range","repr","reversed","round","set","setattr","slice","sorted","staticmethod","str","sum","super","tuple","type","vars","zip"],literal:["__debug__","Ellipsis","False","None","NotImplemented","True"],type:["Any","Callable","Coroutine","Dict","List","Literal","Generic","Optional","Sequence","Set","Tuple","Type","Union"]},r={className:"meta",begin:/^(>>>|\.\.\.) /},s={className:"subst",begin:/\{/,end:/\}/,keywords:i,illegal:/#/},o={begin:/\{\{/,relevance:0},l={className:"string",contains:[e.BACKSLASH_ESCAPE],variants:[{begin:/([uU]|[bB]|[rR]|[bB][rR]|[rR][bB])?'''/,end:/'''/,contains:[e.BACKSLASH_ESCAPE,r],relevance:10},{begin:/([uU]|[bB]|[rR]|[bB][rR]|[rR][bB])?"""/,end:/"""/,contains:[e.BACKSLASH_ESCAPE,r],relevance:10},{begin:/([fF][rR]|[rR][fF]|[fF])'''/,end:/'''/,contains:[e.BACKSLASH_ESCAPE,r,o,s]},{begin:/([fF][rR]|[rR][fF]|[fF])"""/,end:/"""/,contains:[e.BACKSLASH_ESCAPE,r,o,s]},{begin:/([uU]|[rR])'/,end:/'/,relevance:10},{begin:/([uU]|[rR])"/,end:/"/,relevance:10},{begin:/([bB]|[bB][rR]|[rR][bB])'/,end:/'/},{begin:/([bB]|[bB][rR]|[rR][bB])"/,end:/"/},{begin:/([fF][rR]|[rR][fF]|[fF])'/,end:/'/,contains:[e.BACKSLASH_ESCAPE,o,s]},{begin:/([fF][rR]|[rR][fF]|[fF])"/,end:/"/,contains:[e.BACKSLASH_ESCAPE,o,s]},e.APOS_STRING_MODE,e.QUOTE_STRING_MODE]},c="[0-9](_?[0-9])*",d=`(\\b(${c}))?\\.(${c})|\\b(${c})\\.`,g="\\b|"+a.join("|"),u={className:"number",relevance:0,variants:[{begin:`(\\b(${c})|(${d}))[eE][+-]?(${c})[jJ]?(?=${g})`},{begin:`(${d})[jJ]?`},{begin:`\\b([1-9](_?[0-9])*|0+(_?0)*)[lLjJ]?(?=${g})`},{begin:`\\b0[bB](_?[01])+[lL]?(?=${g})`},{begin:`\\b0[oO](_?[0-7])+[lL]?(?=${g})`},{begin:`\\b0[xX](_?[0-9a-fA-F])+[lL]?(?=${g})`},{begin:`\\b(${c})[jJ](?=${g})`}]},b={className:"comment",begin:n.lookahead(/# type:/),end:/$/,keywords:i,contains:[{begin:/# type:/},{begin:/#/,end:/\b\B/,endsWithParent:!0}]},m={className:"params",variants:[{className:"",begin:/\(\s*\)/,skip:!0},{begin:/\(/,end:/\)/,excludeBegin:!0,excludeEnd:!0,keywords:i,contains:["self",r,u,l,e.HASH_COMMENT_MODE]}]};return s.contains=[l,u,r],{name:"Python",aliases:["py","gyp","ipython"],unicodeRegex:!0,keywords:i,illegal:/(<\/|\?)|=>/,contains:[r,u,{begin:/\bself\b/},{beginKeywords:"if",relevance:0},l,b,e.HASH_COMMENT_MODE,{match:[/\bdef/,/\s+/,t],scope:{1:"keyword",3:"title.function"},contains:[m]},{variants:[{match:[/\bclass/,/\s+/,t,/\s*/,/\(\s*/,t,/\s*\)/]},{match:[/\bclass/,/\s+/,t]}],scope:{1:"keyword",3:"title.class",6:"title.class.inherited"}},{className:"meta",begin:/^[\t ]*@/,end:/(?=#)|$/,contains:[u,m,l]}]}},grmr_python_repl:e=>({aliases:["pycon"],contains:[{className:"meta.prompt",starts:{end:/ |$/,starts:{end:"$",subLanguage:"python"}},variants:[{begin:/^>>>(?=[ ]|$)/},{begin:/^\.\.\.(?=[ ]|$)/}]}]}),grmr_r:e=>{const n=e.regex,t=/(?:(?:[a-zA-Z]|\.[._a-zA-Z])[._a-zA-Z0-9]*)|\.(?!\d)/,a=n.either(/0[xX][0-9a-fA-F]+\.[0-9a-fA-F]*[pP][+-]?\d+i?/,/0[xX][0-9a-fA-F]+(?:[pP][+-]?\d+)?[Li]?/,/(?:\d+(?:\.\d*)?|\.\d+)(?:[eE][+-]?\d+)?[Li]?/),i=/[=!<>:]=|\|\||&&|:::?|<-|<<-|->>|->|\|>|[-+*\/?!$&|:<=>@^~]|\*\*/,r=n.either(/[()]/,/[{}]/,/\[\[/,/[[\]]/,/\\/,/,/);return{name:"R",keywords:{$pattern:t,keyword:"function if in break next repeat else for while",literal:"NULL NA TRUE FALSE Inf NaN NA_integer_|10 NA_real_|10 NA_character_|10 NA_complex_|10",built_in:"LETTERS letters month.abb month.name pi T F abs acos acosh all any anyNA Arg as.call as.character as.complex as.double as.environment as.integer as.logical as.null.default as.numeric as.raw asin asinh atan atanh attr attributes baseenv browser c call ceiling class Conj cos cosh cospi cummax cummin cumprod cumsum digamma dim dimnames emptyenv exp expression floor forceAndCall gamma gc.time globalenv Im interactive invisible is.array is.atomic is.call is.character is.complex is.double is.environment is.expression is.finite is.function is.infinite is.integer is.language is.list is.logical is.matrix is.na is.name is.nan is.null is.numeric is.object is.pairlist is.raw is.recursive is.single is.symbol lazyLoadDBfetch length lgamma list log max min missing Mod names nargs nzchar oldClass on.exit pos.to.env proc.time prod quote range Re rep retracemem return round seq_along seq_len seq.int sign signif sin sinh sinpi sqrt standardGeneric substitute sum switch tan tanh tanpi tracemem trigamma trunc unclass untracemem UseMethod xtfrm"},contains:[e.COMMENT(/#'/,/$/,{contains:[{scope:"doctag",match:/@examples/,starts:{end:n.lookahead(n.either(/\n^#'\s*(?=@[a-zA-Z]+)/,/\n^(?!#')/)),endsParent:!0}},{scope:"doctag",begin:"@param",end:/$/,contains:[{scope:"variable",variants:[{match:t},{match:/`(?:\\.|[^`\\])+`/}],endsParent:!0}]},{scope:"doctag",match:/@[a-zA-Z]+/},{scope:"keyword",match:/\\[a-zA-Z]+/}]}),e.HASH_COMMENT_MODE,{scope:"string",contains:[e.BACKSLASH_ESCAPE],variants:[e.END_SAME_AS_BEGIN({begin:/[rR]"(-*)\(/,end:/\)(-*)"/}),e.END_SAME_AS_BEGIN({begin:/[rR]"(-*)\{/,end:/\}(-*)"/}),e.END_SAME_AS_BEGIN({begin:/[rR]"(-*)\[/,end:/\](-*)"/}),e.END_SAME_AS_BEGIN({begin:/[rR]'(-*)\(/,end:/\)(-*)'/}),e.END_SAME_AS_BEGIN({begin:/[rR]'(-*)\{/,end:/\}(-*)'/}),e.END_SAME_AS_BEGIN({begin:/[rR]'(-*)\[/,end:/\](-*)'/}),{begin:'"',end:'"',relevance:0},{begin:"'",end:"'",relevance:0}]},{relevance:0,variants:[{scope:{1:"operator",2:"number"},match:[i,a]},{scope:{1:"operator",2:"number"},match:[/%[^%]*%/,a]},{scope:{1:"punctuation",2:"number"},match:[r,a]},{scope:{2:"number"},match:[/[^a-zA-Z0-9._]|^/,a]}]},{scope:{3:"operator"},match:[t,/\s+/,/<-/,/\s+/]},{scope:"operator",relevance:0,variants:[{match:i},{match:/%[^%]*%/}]},{scope:"punctuation",relevance:0,match:r},{begin:"`",end:"`",contains:[{begin:/\\./}]}]}},grmr_ruby:e=>{const n=e.regex,t="([a-zA-Z_]\\w*[!?=]?|[-+~]@|<<|>>|=~|===?|<=>|[<>]=?|\\*\\*|[-/+%^&*~`|]|\\[\\]=?)",a=n.either(/\b([A-Z]+[a-z0-9]+)+/,/\b([A-Z]+[a-z0-9]+)+[A-Z]+/),i=n.concat(a,/(::\w+)*/),r={"variable.constant":["__FILE__","__LINE__","__ENCODING__"],"variable.language":["self","super"],keyword:["alias","and","begin","BEGIN","break","case","class","defined","do","else","elsif","end","END","ensure","for","if","in","module","next","not","or","redo","require","rescue","retry","return","then","undef","unless","until","when","while","yield","include","extend","prepend","public","private","protected","raise","throw"],built_in:["proc","lambda","attr_accessor","attr_reader","attr_writer","define_method","private_constant","module_function"],literal:["true","false","nil"]},s={className:"doctag",begin:"@[A-Za-z]+"},o={begin:"#<",end:">"},l=[e.COMMENT("#","$",{contains:[s]}),e.COMMENT("^=begin","^=end",{contains:[s],relevance:10}),e.COMMENT("^__END__",e.MATCH_NOTHING_RE)],c={className:"subst",begin:/#\{/,end:/\}/,keywords:r},d={className:"string",contains:[e.BACKSLASH_ESCAPE,c],variants:[{begin:/'/,end:/'/},{begin:/"/,end:/"/},{begin:/`/,end:/`/},{begin:/%[qQwWx]?\(/,end:/\)/},{begin:/%[qQwWx]?\[/,end:/\]/},{begin:/%[qQwWx]?\{/,end:/\}/},{begin:/%[qQwWx]?/},{begin:/%[qQwWx]?\//,end:/\//},{begin:/%[qQwWx]?%/,end:/%/},{begin:/%[qQwWx]?-/,end:/-/},{begin:/%[qQwWx]?\|/,end:/\|/},{begin:/\B\?(\\\d{1,3})/},{begin:/\B\?(\\x[A-Fa-f0-9]{1,2})/},{begin:/\B\?(\\u\{?[A-Fa-f0-9]{1,6}\}?)/},{begin:/\B\?(\\M-\\C-|\\M-\\c|\\c\\M-|\\M-|\\C-\\M-)[\x20-\x7e]/},{begin:/\B\?\\(c|C-)[\x20-\x7e]/},{begin:/\B\?\\?\S/},{begin:n.concat(/<<[-~]?'?/,n.lookahead(/(\w+)(?=\W)[^\n]*\n(?:[^\n]*\n)*?\s*\1\b/)),contains:[e.END_SAME_AS_BEGIN({begin:/(\w+)/,end:/(\w+)/,contains:[e.BACKSLASH_ESCAPE,c]})]}]},g="[0-9](_?[0-9])*",u={className:"number",relevance:0,variants:[{begin:`\\b([1-9](_?[0-9])*|0)(\\.(${g}))?([eE][+-]?(${g})|r)?i?\\b`},{begin:"\\b0[dD][0-9](_?[0-9])*r?i?\\b"},{begin:"\\b0[bB][0-1](_?[0-1])*r?i?\\b"},{begin:"\\b0[oO][0-7](_?[0-7])*r?i?\\b"},{begin:"\\b0[xX][0-9a-fA-F](_?[0-9a-fA-F])*r?i?\\b"},{begin:"\\b0(_?[0-7])+r?i?\\b"}]},b={variants:[{match:/\(\)/},{className:"params",begin:/\(/,end:/(?=\))/,excludeBegin:!0,endsParent:!0,keywords:r}]},m=[d,{variants:[{match:[/class\s+/,i,/\s+<\s+/,i]},{match:[/\b(class|module)\s+/,i]}],scope:{2:"title.class",4:"title.class.inherited"},keywords:r},{match:[/(include|extend)\s+/,i],scope:{2:"title.class"},keywords:r},{relevance:0,match:[i,/\.new[. (]/],scope:{1:"title.class"}},{relevance:0,match:/\b[A-Z][A-Z_0-9]+\b/,className:"variable.constant"},{relevance:0,match:a,scope:"title.class"},{match:[/def/,/\s+/,t],scope:{1:"keyword",3:"title.function"},contains:[b]},{begin:e.IDENT_RE+"::"},{className:"symbol",begin:e.UNDERSCORE_IDENT_RE+"(!|\\?)?:",relevance:0},{className:"symbol",begin:":(?!\\s)",contains:[d,{begin:t}],relevance:0},u,{className:"variable",begin:"(\\$\\W)|((\\$|@@?)(\\w+))(?=[^@$?])(?![A-Za-z])(?![@$?'])"},{className:"params",begin:/\|/,end:/\|/,excludeBegin:!0,excludeEnd:!0,relevance:0,keywords:r},{begin:"("+e.RE_STARTERS_RE+"|unless)\\s*",keywords:"unless",contains:[{className:"regexp",contains:[e.BACKSLASH_ESCAPE,c],illegal:/\n/,variants:[{begin:"/",end:"/[a-z]*"},{begin:/%r\{/,end:/\}[a-z]*/},{begin:"%r\\(",end:"\\)[a-z]*"},{begin:"%r!",end:"![a-z]*"},{begin:"%r\\[",end:"\\][a-z]*"}]}].concat(o,l),relevance:0}].concat(o,l);c.contains=m,b.contains=m;const p=[{begin:/^\s*=>/,starts:{end:"$",contains:m}},{className:"meta.prompt",begin:"^([>?]>|[\\w#]+\\(\\w+\\):\\d+:\\d+[>*]|(\\w+-)?\\d+\\.\\d+\\.\\d+(p\\d+)?[^\\d][^>]+>)(?=[ ])",starts:{end:"$",keywords:r,contains:m}}];return l.unshift(o),{name:"Ruby",aliases:["rb","gemspec","podspec","thor","irb"],keywords:r,illegal:/\/\*/,contains:[e.SHEBANG({binary:"ruby"})].concat(p).concat(l).concat(m)}},grmr_rust:e=>{const n=e.regex,t={className:"title.function.invoke",relevance:0,begin:n.concat(/\b/,/(?!let\b)/,e.IDENT_RE,n.lookahead(/\s*\(/))},a="([ui](8|16|32|64|128|size)|f(32|64))?",i=["drop ","Copy","Send","Sized","Sync","Drop","Fn","FnMut","FnOnce","ToOwned","Clone","Debug","PartialEq","PartialOrd","Eq","Ord","AsRef","AsMut","Into","From","Default","Iterator","Extend","IntoIterator","DoubleEndedIterator","ExactSizeIterator","SliceConcatExt","ToString","assert!","assert_eq!","bitflags!","bytes!","cfg!","col!","concat!","concat_idents!","debug_assert!","debug_assert_eq!","env!","panic!","file!","format!","format_args!","include_bytes!","include_str!","line!","local_data_key!","module_path!","option_env!","print!","println!","select!","stringify!","try!","unimplemented!","unreachable!","vec!","write!","writeln!","macro_rules!","assert_ne!","debug_assert_ne!"],r=["i8","i16","i32","i64","i128","isize","u8","u16","u32","u64","u128","usize","f32","f64","str","char","bool","Box","Option","Result","String","Vec"];return{name:"Rust",aliases:["rs"],keywords:{$pattern:e.IDENT_RE+"!?",type:r,keyword:["abstract","as","async","await","become","box","break","const","continue","crate","do","dyn","else","enum","extern","false","final","fn","for","if","impl","in","let","loop","macro","match","mod","move","mut","override","priv","pub","ref","return","self","Self","static","struct","super","trait","true","try","type","typeof","unsafe","unsized","use","virtual","where","while","yield"],literal:["true","false","Some","None","Ok","Err"],built_in:i},illegal:""},t]}},grmr_scss:e=>{const n=ie(e),t=le,a=oe,i="@[a-z-]+",r={className:"variable",begin:"(\\$[a-zA-Z-][a-zA-Z0-9_-]*)\\b",relevance:0};return{name:"SCSS",case_insensitive:!0,illegal:"[=/|']",contains:[e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE,n.CSS_NUMBER_MODE,{className:"selector-id",begin:"#[A-Za-z0-9_-]+",relevance:0},{className:"selector-class",begin:"\\.[A-Za-z0-9_-]+",relevance:0},n.ATTRIBUTE_SELECTOR_MODE,{className:"selector-tag",begin:"\\b("+re.join("|")+")\\b",relevance:0},{className:"selector-pseudo",begin:":("+a.join("|")+")"},{className:"selector-pseudo",begin:":(:)?("+t.join("|")+")"},r,{begin:/\(/,end:/\)/,contains:[n.CSS_NUMBER_MODE]},n.CSS_VARIABLE,{className:"attribute",begin:"\\b("+ce.join("|")+")\\b"},{begin:"\\b(whitespace|wait|w-resize|visible|vertical-text|vertical-ideographic|uppercase|upper-roman|upper-alpha|underline|transparent|top|thin|thick|text|text-top|text-bottom|tb-rl|table-header-group|table-footer-group|sw-resize|super|strict|static|square|solid|small-caps|separate|se-resize|scroll|s-resize|rtl|row-resize|ridge|right|repeat|repeat-y|repeat-x|relative|progress|pointer|overline|outside|outset|oblique|nowrap|not-allowed|normal|none|nw-resize|no-repeat|no-drop|newspaper|ne-resize|n-resize|move|middle|medium|ltr|lr-tb|lowercase|lower-roman|lower-alpha|loose|list-item|line|line-through|line-edge|lighter|left|keep-all|justify|italic|inter-word|inter-ideograph|inside|inset|inline|inline-block|inherit|inactive|ideograph-space|ideograph-parenthesis|ideograph-numeric|ideograph-alpha|horizontal|hidden|help|hand|groove|fixed|ellipsis|e-resize|double|dotted|distribute|distribute-space|distribute-letter|distribute-all-lines|disc|disabled|default|decimal|dashed|crosshair|collapse|col-resize|circle|char|center|capitalize|break-word|break-all|bottom|both|bolder|bold|block|bidi-override|below|baseline|auto|always|all-scroll|absolute|table|table-cell)\\b"},{begin:/:/,end:/[;}{]/,relevance:0,contains:[n.BLOCK_COMMENT,r,n.HEXCOLOR,n.CSS_NUMBER_MODE,e.QUOTE_STRING_MODE,e.APOS_STRING_MODE,n.IMPORTANT,n.FUNCTION_DISPATCH]},{begin:"@(page|font-face)",keywords:{$pattern:i,keyword:"@page @font-face"}},{begin:"@",end:"[{;]",returnBegin:!0,keywords:{$pattern:/[a-z-]+/,keyword:"and or not only",attribute:se.join(" ")},contains:[{begin:i,className:"keyword"},{begin:/[a-z-]+(?=:)/,className:"attribute"},r,e.QUOTE_STRING_MODE,e.APOS_STRING_MODE,n.HEXCOLOR,n.CSS_NUMBER_MODE]},n.FUNCTION_DISPATCH]}},grmr_shell:e=>({name:"Shell Session",aliases:["console","shellsession"],contains:[{className:"meta.prompt",begin:/^\s{0,3}[/~\w\d[\]()@-]*[>%$#][ ]?/,starts:{end:/[^\\](?=\s*$)/,subLanguage:"bash"}}]}),grmr_sql:e=>{const n=e.regex,t=e.COMMENT("--","$"),a=["true","false","unknown"],i=["bigint","binary","blob","boolean","char","character","clob","date","dec","decfloat","decimal","float","int","integer","interval","nchar","nclob","national","numeric","real","row","smallint","time","timestamp","varchar","varying","varbinary"],r=["abs","acos","array_agg","asin","atan","avg","cast","ceil","ceiling","coalesce","corr","cos","cosh","count","covar_pop","covar_samp","cume_dist","dense_rank","deref","element","exp","extract","first_value","floor","json_array","json_arrayagg","json_exists","json_object","json_objectagg","json_query","json_table","json_table_primitive","json_value","lag","last_value","lead","listagg","ln","log","log10","lower","max","min","mod","nth_value","ntile","nullif","percent_rank","percentile_cont","percentile_disc","position","position_regex","power","rank","regr_avgx","regr_avgy","regr_count","regr_intercept","regr_r2","regr_slope","regr_sxx","regr_sxy","regr_syy","row_number","sin","sinh","sqrt","stddev_pop","stddev_samp","substring","substring_regex","sum","tan","tanh","translate","translate_regex","treat","trim","trim_array","unnest","upper","value_of","var_pop","var_samp","width_bucket"],s=["create table","insert into","primary key","foreign key","not null","alter table","add constraint","grouping sets","on overflow","character set","respect nulls","ignore nulls","nulls first","nulls last","depth first","breadth first"],o=r,l=["abs","acos","all","allocate","alter","and","any","are","array","array_agg","array_max_cardinality","as","asensitive","asin","asymmetric","at","atan","atomic","authorization","avg","begin","begin_frame","begin_partition","between","bigint","binary","blob","boolean","both","by","call","called","cardinality","cascaded","case","cast","ceil","ceiling","char","char_length","character","character_length","check","classifier","clob","close","coalesce","collate","collect","column","commit","condition","connect","constraint","contains","convert","copy","corr","corresponding","cos","cosh","count","covar_pop","covar_samp","create","cross","cube","cume_dist","current","current_catalog","current_date","current_default_transform_group","current_path","current_role","current_row","current_schema","current_time","current_timestamp","current_path","current_role","current_transform_group_for_type","current_user","cursor","cycle","date","day","deallocate","dec","decimal","decfloat","declare","default","define","delete","dense_rank","deref","describe","deterministic","disconnect","distinct","double","drop","dynamic","each","element","else","empty","end","end_frame","end_partition","end-exec","equals","escape","every","except","exec","execute","exists","exp","external","extract","false","fetch","filter","first_value","float","floor","for","foreign","frame_row","free","from","full","function","fusion","get","global","grant","group","grouping","groups","having","hold","hour","identity","in","indicator","initial","inner","inout","insensitive","insert","int","integer","intersect","intersection","interval","into","is","join","json_array","json_arrayagg","json_exists","json_object","json_objectagg","json_query","json_table","json_table_primitive","json_value","lag","language","large","last_value","lateral","lead","leading","left","like","like_regex","listagg","ln","local","localtime","localtimestamp","log","log10","lower","match","match_number","match_recognize","matches","max","member","merge","method","min","minute","mod","modifies","module","month","multiset","national","natural","nchar","nclob","new","no","none","normalize","not","nth_value","ntile","null","nullif","numeric","octet_length","occurrences_regex","of","offset","old","omit","on","one","only","open","or","order","out","outer","over","overlaps","overlay","parameter","partition","pattern","per","percent","percent_rank","percentile_cont","percentile_disc","period","portion","position","position_regex","power","precedes","precision","prepare","primary","procedure","ptf","range","rank","reads","real","recursive","ref","references","referencing","regr_avgx","regr_avgy","regr_count","regr_intercept","regr_r2","regr_slope","regr_sxx","regr_sxy","regr_syy","release","result","return","returns","revoke","right","rollback","rollup","row","row_number","rows","running","savepoint","scope","scroll","search","second","seek","select","sensitive","session_user","set","show","similar","sin","sinh","skip","smallint","some","specific","specifictype","sql","sqlexception","sqlstate","sqlwarning","sqrt","start","static","stddev_pop","stddev_samp","submultiset","subset","substring","substring_regex","succeeds","sum","symmetric","system","system_time","system_user","table","tablesample","tan","tanh","then","time","timestamp","timezone_hour","timezone_minute","to","trailing","translate","translate_regex","translation","treat","trigger","trim","trim_array","true","truncate","uescape","union","unique","unknown","unnest","update","upper","user","using","value","values","value_of","var_pop","var_samp","varbinary","varchar","varying","versioning","when","whenever","where","width_bucket","window","with","within","without","year","add","asc","collation","desc","final","first","last","view"].filter((e=>!r.includes(e))),c={begin:n.concat(/\b/,n.either(...o),/\s*\(/),relevance:0,keywords:{built_in:o}};return{name:"SQL",case_insensitive:!0,illegal:/[{}]|<\//,keywords:{$pattern:/\b[\w\.]+/,keyword:((e,{exceptions:n,when:t}={})=>{const a=t;return n=n||[],e.map((e=>e.match(/\|\d+$/)||n.includes(e)?e:a(e)?e+"|0":e))})(l,{when:e=>e.length<3}),literal:a,type:i,built_in:["current_catalog","current_date","current_default_transform_group","current_path","current_role","current_schema","current_transform_group_for_type","current_user","session_user","system_time","system_user","current_time","localtime","current_timestamp","localtimestamp"]},contains:[{begin:n.either(...s),relevance:0,keywords:{$pattern:/[\w\.]+/,keyword:l.concat(s),literal:a,type:i}},{className:"type",begin:n.either("double precision","large object","with timezone","without timezone")},c,{className:"variable",begin:/@[a-z0-9][a-z0-9_]*/},{className:"string",variants:[{begin:/'/,end:/'/,contains:[{begin:/''/}]}]},{begin:/"/,end:/"/,contains:[{begin:/""/}]},e.C_NUMBER_MODE,e.C_BLOCK_COMMENT_MODE,t,{className:"operator",begin:/[-+*/=%^~]|&&?|\|\|?|!=?|<(?:=>?|<|>)?|>[>=]?/,relevance:0}]}},grmr_swift:e=>{const n={match:/\s+/,relevance:0},t=e.COMMENT("/\\*","\\*/",{contains:["self"]}),a=[e.C_LINE_COMMENT_MODE,t],i={match:[/\./,m(...xe,...Me)],className:{2:"keyword"}},r={match:b(/\./,m(...Ae)),relevance:0},s=Ae.filter((e=>"string"==typeof e)).concat(["_|0"]),o={variants:[{className:"keyword",match:m(...Ae.filter((e=>"string"!=typeof e)).concat(Se).map(ke),...Me)}]},l={$pattern:m(/\b\w+/,/#\w+/),keyword:s.concat(Re),literal:Ce},c=[i,r,o],g=[{match:b(/\./,m(...De)),relevance:0},{className:"built_in",match:b(/\b/,m(...De),/(?=\()/)}],u={match:/->/,relevance:0},p=[u,{className:"operator",relevance:0,variants:[{match:Be},{match:`\\.(\\.|${Le})+`}]}],_="([0-9]_*)+",h="([0-9a-fA-F]_*)+",f={className:"number",relevance:0,variants:[{match:`\\b(${_})(\\.(${_}))?([eE][+-]?(${_}))?\\b`},{match:`\\b0x(${h})(\\.(${h}))?([pP][+-]?(${_}))?\\b`},{match:/\b0o([0-7]_*)+\b/},{match:/\b0b([01]_*)+\b/}]},E=(e="")=>({className:"subst",variants:[{match:b(/\\/,e,/[0\\tnr"']/)},{match:b(/\\/,e,/u\{[0-9a-fA-F]{1,8}\}/)}]}),y=(e="")=>({className:"subst",match:b(/\\/,e,/[\t ]*(?:[\r\n]|\r\n)/)}),N=(e="")=>({className:"subst",label:"interpol",begin:b(/\\/,e,/\(/),end:/\)/}),w=(e="")=>({begin:b(e,/"""/),end:b(/"""/,e),contains:[E(e),y(e),N(e)]}),v=(e="")=>({begin:b(e,/"/),end:b(/"/,e),contains:[E(e),N(e)]}),O={className:"string",variants:[w(),w("#"),w("##"),w("###"),v(),v("#"),v("##"),v("###")]},k={match:b(/`/,Fe,/`/)},x=[k,{className:"variable",match:/\$\d+/},{className:"variable",match:`\\$${ze}+`}],M=[{match:/(@|#(un)?)available/,className:"keyword",starts:{contains:[{begin:/\(/,end:/\)/,keywords:Pe,contains:[...p,f,O]}]}},{className:"keyword",match:b(/@/,m(...je))},{className:"meta",match:b(/@/,Fe)}],S={match:d(/\b[A-Z]/),relevance:0,contains:[{className:"type",match:b(/(AV|CA|CF|CG|CI|CL|CM|CN|CT|MK|MP|MTK|MTL|NS|SCN|SK|UI|WK|XC)/,ze,"+")},{className:"type",match:Ue,relevance:0},{match:/[?!]+/,relevance:0},{match:/\.\.\./,relevance:0},{match:b(/\s+&\s+/,d(Ue)),relevance:0}]},A={begin://,keywords:l,contains:[...a,...c,...M,u,S]};S.contains.push(A);const C={begin:/\(/,end:/\)/,relevance:0,keywords:l,contains:["self",{match:b(Fe,/\s*:/),keywords:"_|0",relevance:0},...a,...c,...g,...p,f,O,...x,...M,S]},T={begin://,contains:[...a,S]},R={begin:/\(/,end:/\)/,keywords:l,contains:[{begin:m(d(b(Fe,/\s*:/)),d(b(Fe,/\s+/,Fe,/\s*:/))),end:/:/,relevance:0,contains:[{className:"keyword",match:/\b_\b/},{className:"params",match:Fe}]},...a,...c,...p,f,O,...M,S,C],endsParent:!0,illegal:/["']/},D={match:[/func/,/\s+/,m(k.match,Fe,Be)],className:{1:"keyword",3:"title.function"},contains:[T,R,n],illegal:[/\[/,/%/]},I={match:[/\b(?:subscript|init[?!]?)/,/\s*(?=[<(])/],className:{1:"keyword"},contains:[T,R,n],illegal:/\[|%/},L={match:[/operator/,/\s+/,Be],className:{1:"keyword",3:"title"}},B={begin:[/precedencegroup/,/\s+/,Ue],className:{1:"keyword",3:"title"},contains:[S],keywords:[...Te,...Ce],end:/}/};for(const e of O.variants){const n=e.contains.find((e=>"interpol"===e.label));n.keywords=l;const t=[...c,...g,...p,f,O,...x];n.contains=[...t,{begin:/\(/,end:/\)/,contains:["self",...t]}]}return{name:"Swift",keywords:l,contains:[...a,D,I,{beginKeywords:"struct protocol class extension enum actor",end:"\\{",excludeEnd:!0,keywords:l,contains:[e.inherit(e.TITLE_MODE,{className:"title.class",begin:/[A-Za-z$_][\u00C0-\u02B80-9A-Za-z$_]*/}),...c]},L,B,{beginKeywords:"import",end:/$/,contains:[...a],relevance:0},...c,...g,...p,f,O,...x,...M,S,C]}},grmr_typescript:e=>{const n=Oe(e),t=_e,a=["any","void","number","boolean","string","object","never","symbol","bigint","unknown"],i={beginKeywords:"namespace",end:/\{/,excludeEnd:!0,contains:[n.exports.CLASS_REFERENCE]},r={beginKeywords:"interface",end:/\{/,excludeEnd:!0,keywords:{keyword:"interface extends",built_in:a},contains:[n.exports.CLASS_REFERENCE]},s={$pattern:_e,keyword:he.concat(["type","namespace","interface","public","private","protected","implements","declare","abstract","readonly","enum","override"]),literal:fe,built_in:ve.concat(a),"variable.language":we},o={className:"meta",begin:"@"+t},l=(e,n,t)=>{const a=e.contains.findIndex((e=>e.label===n));if(-1===a)throw Error("can not find mode to replace");e.contains.splice(a,1,t)};return Object.assign(n.keywords,s),n.exports.PARAMS_CONTAINS.push(o),n.contains=n.contains.concat([o,i,r]),l(n,"shebang",e.SHEBANG()),l(n,"use_strict",{className:"meta",relevance:10,begin:/^\s*['"]use strict['"]/}),n.contains.find((e=>"func.def"===e.label)).relevance=0,Object.assign(n,{name:"TypeScript",aliases:["ts","tsx","mts","cts"]}),n},grmr_vbnet:e=>{const n=e.regex,t=/\d{1,2}\/\d{1,2}\/\d{4}/,a=/\d{4}-\d{1,2}-\d{1,2}/,i=/(\d|1[012])(:\d+){0,2} *(AM|PM)/,r=/\d{1,2}(:\d{1,2}){1,2}/,s={className:"literal",variants:[{begin:n.concat(/# */,n.either(a,t),/ *#/)},{begin:n.concat(/# */,r,/ *#/)},{begin:n.concat(/# */,i,/ *#/)},{begin:n.concat(/# */,n.either(a,t),/ +/,n.either(i,r),/ *#/)}]},o=e.COMMENT(/'''/,/$/,{contains:[{className:"doctag",begin:/<\/?/,end:/>/}]}),l=e.COMMENT(null,/$/,{variants:[{begin:/'/},{begin:/([\t ]|^)REM(?=\s)/}]});return{name:"Visual Basic .NET",aliases:["vb"],case_insensitive:!0,classNameAliases:{label:"symbol"},keywords:{keyword:"addhandler alias aggregate ansi as async assembly auto binary by byref byval call case catch class compare const continue custom declare default delegate dim distinct do each equals else elseif end enum erase error event exit explicit finally for friend from function get global goto group handles if implements imports in inherits interface into iterator join key let lib loop me mid module mustinherit mustoverride mybase myclass namespace narrowing new next notinheritable notoverridable of off on operator option optional order overloads overridable overrides paramarray partial preserve private property protected public raiseevent readonly redim removehandler resume return select set shadows shared skip static step stop structure strict sub synclock take text then throw to try unicode until using when where while widening with withevents writeonly yield",built_in:"addressof and andalso await directcast gettype getxmlnamespace is isfalse isnot istrue like mod nameof new not or orelse trycast typeof xor cbool cbyte cchar cdate cdbl cdec cint clng cobj csbyte cshort csng cstr cuint culng cushort",type:"boolean byte char date decimal double integer long object sbyte short single string uinteger ulong ushort",literal:"true false nothing"},illegal:"//|\\{|\\}|endif|gosub|variant|wend|^\\$ ",contains:[{className:"string",begin:/"(""|[^/n])"C\b/},{className:"string",begin:/"/,end:/"/,illegal:/\n/,contains:[{begin:/""/}]},s,{className:"number",relevance:0,variants:[{begin:/\b\d[\d_]*((\.[\d_]+(E[+-]?[\d_]+)?)|(E[+-]?[\d_]+))[RFD@!#]?/},{begin:/\b\d[\d_]*((U?[SIL])|[%&])?/},{begin:/&H[\dA-F_]+((U?[SIL])|[%&])?/},{begin:/&O[0-7_]+((U?[SIL])|[%&])?/},{begin:/&B[01_]+((U?[SIL])|[%&])?/}]},{className:"label",begin:/^\w+:/},o,l,{className:"meta",begin:/[\t ]*#(const|disable|else|elseif|enable|end|externalsource|if|region)\b/,end:/$/,keywords:{keyword:"const disable else elseif enable end externalsource if region then"},contains:[l]}]}},grmr_wasm:e=>{e.regex;const n=e.COMMENT(/\(;/,/;\)/);return n.contains.push("self"),{name:"WebAssembly",keywords:{$pattern:/[\w.]+/,keyword:["anyfunc","block","br","br_if","br_table","call","call_indirect","data","drop","elem","else","end","export","func","global.get","global.set","local.get","local.set","local.tee","get_global","get_local","global","if","import","local","loop","memory","memory.grow","memory.size","module","mut","nop","offset","param","result","return","select","set_global","set_local","start","table","tee_local","then","type","unreachable"]},contains:[e.COMMENT(/;;/,/$/),n,{match:[/(?:offset|align)/,/\s*/,/=/],className:{1:"keyword",3:"operator"}},{className:"variable",begin:/\$[\w_]+/},{match:/(\((?!;)|\))+/,className:"punctuation",relevance:0},{begin:[/(?:func|call|call_indirect)/,/\s+/,/\$[^\s)]+/],className:{1:"keyword",3:"title.function"}},e.QUOTE_STRING_MODE,{match:/(i32|i64|f32|f64)(?!\.)/,className:"type"},{className:"keyword",match:/\b(f32|f64|i32|i64)(?:\.(?:abs|add|and|ceil|clz|const|convert_[su]\/i(?:32|64)|copysign|ctz|demote\/f64|div(?:_[su])?|eqz?|extend_[su]\/i32|floor|ge(?:_[su])?|gt(?:_[su])?|le(?:_[su])?|load(?:(?:8|16|32)_[su])?|lt(?:_[su])?|max|min|mul|nearest|neg?|or|popcnt|promote\/f32|reinterpret\/[fi](?:32|64)|rem_[su]|rot[lr]|shl|shr_[su]|store(?:8|16|32)?|sqrt|sub|trunc(?:_[su]\/f(?:32|64))?|wrap\/i64|xor))\b/},{className:"number",relevance:0,match:/[+-]?\b(?:\d(?:_?\d)*(?:\.\d(?:_?\d)*)?(?:[eE][+-]?\d(?:_?\d)*)?|0x[\da-fA-F](?:_?[\da-fA-F])*(?:\.[\da-fA-F](?:_?[\da-fA-D])*)?(?:[pP][+-]?\d(?:_?\d)*)?)\b|\binf\b|\bnan(?::0x[\da-fA-F](?:_?[\da-fA-D])*)?\b/}]}},grmr_yaml:e=>{const n="true false yes no null",t="[\\w#;/?:@&=+$,.~*'()[\\]]+",a={className:"string",relevance:0,variants:[{begin:/'/,end:/'/},{begin:/"/,end:/"/},{begin:/\S+/}],contains:[e.BACKSLASH_ESCAPE,{className:"template-variable",variants:[{begin:/\{\{/,end:/\}\}/},{begin:/%\{/,end:/\}/}]}]},i=e.inherit(a,{variants:[{begin:/'/,end:/'/},{begin:/"/,end:/"/},{begin:/[^\s,{}[\]]+/}]}),r={end:",",endsWithParent:!0,excludeEnd:!0,keywords:n,relevance:0},s={begin:/\{/,end:/\}/,contains:[r],illegal:"\\n",relevance:0},o={begin:"\\[",end:"\\]",contains:[r],illegal:"\\n",relevance:0},l=[{className:"attr",variants:[{begin:"\\w[\\w :\\/.-]*:(?=[ \t]|$)"},{begin:'"\\w[\\w :\\/.-]*":(?=[ \t]|$)'},{begin:"'\\w[\\w :\\/.-]*':(?=[ \t]|$)"}]},{className:"meta",begin:"^---\\s*$",relevance:10},{className:"string",begin:"[\\|>]([1-9]?[+-])?[ ]*\\n( +)[^ ][^\\n]*\\n(\\2[^\\n]+\\n?)*"},{begin:"<%[%=-]?",end:"[%-]?%>",subLanguage:"ruby",excludeBegin:!0,excludeEnd:!0,relevance:0},{className:"type",begin:"!\\w+!"+t},{className:"type",begin:"!<"+t+">"},{className:"type",begin:"!"+t},{className:"type",begin:"!!"+t},{className:"meta",begin:"&"+e.UNDERSCORE_IDENT_RE+"$"},{className:"meta",begin:"\\*"+e.UNDERSCORE_IDENT_RE+"$"},{className:"bullet",begin:"-(?=[ ]|$)",relevance:0},e.HASH_COMMENT_MODE,{beginKeywords:n,keywords:{literal:n}},{className:"number",begin:"\\b[0-9]{4}(-[0-9][0-9]){0,2}([Tt \\t][0-9][0-9]?(:[0-9][0-9]){2})?(\\.[0-9]*)?([ \\t])*(Z|[-+][0-9][0-9]?(:[0-9][0-9])?)?\\b"},{className:"number",begin:e.C_NUMBER_RE+"\\b",relevance:0},s,o,a],c=[...l];return c.pop(),c.push(i),r.contains=c,{name:"YAML",case_insensitive:!0,aliases:["yml"],contains:l}}});const qe=ae;for(const e of Object.keys(Ke)){const n=e.replace("grmr_","").replace("_","-");qe.registerLanguage(n,Ke[e])}return qe}();"object"==typeof exports&&"undefined"!=typeof module&&(module.exports=hljs); \ No newline at end of file diff --git a/vendor/maximebf/debugbar/src/DebugBar/Resources/vendor/highlightjs/styles/github.css b/vendor/maximebf/debugbar/src/DebugBar/Resources/vendor/highlightjs/styles/github.css deleted file mode 100644 index f5202fd..0000000 --- a/vendor/maximebf/debugbar/src/DebugBar/Resources/vendor/highlightjs/styles/github.css +++ /dev/null @@ -1,82 +0,0 @@ -/* - -github.com style (c) Vasily Polovnyov - -*/ -div.phpdebugbar pre code.hljs { - display: block; - overflow-x: auto; - padding: 1em; -} -div.phpdebugbar code.hljs { - padding: 3px 5px; -} -div.phpdebugbar .hljs { - background: #f3f3f3; - color: #444; -} -div.phpdebugbar .hljs-comment { - color: #697070; -} -div.phpdebugbar .hljs-punctuation, -div.phpdebugbar .hljs-tag { - color: #444a; -} -div.phpdebugbar .hljs-tag .hljs-attr, -div.phpdebugbar .hljs-tag .hljs-name { - color: #444; -} -div.phpdebugbar .hljs-attribute, -div.phpdebugbar .hljs-doctag, -div.phpdebugbar .hljs-keyword, -div.phpdebugbar .hljs-meta .hljs-keyword, -div.phpdebugbar .hljs-name, -div.phpdebugbar .hljs-selector-tag { - font-weight: 700; -} -div.phpdebugbar .hljs-deletion, -div.phpdebugbar .hljs-number, -div.phpdebugbar .hljs-quote, -div.phpdebugbar .hljs-selector-class, -div.phpdebugbar .hljs-selector-id, -div.phpdebugbar .hljs-string, -div.phpdebugbar .hljs-template-tag, -div.phpdebugbar .hljs-type { - color: #800; -} -div.phpdebugbar .hljs-section, -div.phpdebugbar .hljs-title { - color: #800; - font-weight: 700; -} -div.phpdebugbar .hljs-link, -div.phpdebugbar .hljs-operator, -div.phpdebugbar .hljs-regexp, -div.phpdebugbar .hljs-selector-attr, -div.phpdebugbar .hljs-selector-pseudo, -div.phpdebugbar .hljs-symbol, -div.phpdebugbar .hljs-template-variable, -div.phpdebugbar .hljs-variable { - color: #ab5656; -} -div.phpdebugbar .hljs-literal { - color: #695; -} -div.phpdebugbar .hljs-addition, -div.phpdebugbar .hljs-built_in, -div.phpdebugbar .hljs-bullet, -div.phpdebugbar .hljs-code { - color: #397300; -} -div.phpdebugbar .hljs-meta { - color: #1f7199; -} -div.phpdebugbar .hljs-meta .hljs-string { - color: #38a; -} -div.phpdebugbar .hljs-emphasis { - font-style: italic; -} -div.phpdebugbar .hljs-strong { - font-weight: 700; -} diff --git a/vendor/maximebf/debugbar/src/DebugBar/Resources/vendor/jquery/dist/jquery.min.js b/vendor/maximebf/debugbar/src/DebugBar/Resources/vendor/jquery/dist/jquery.min.js deleted file mode 100644 index e9f6710..0000000 --- a/vendor/maximebf/debugbar/src/DebugBar/Resources/vendor/jquery/dist/jquery.min.js +++ /dev/null @@ -1,2 +0,0 @@ -/*! jQuery v3.7.1 | (c) OpenJS Foundation and other contributors | jquery.org/license */ -!function(e,t){"use strict";"object"==typeof module&&"object"==typeof module.exports?module.exports=e.document?t(e,!0):function(e){if(!e.document)throw new Error("jQuery requires a window with a document");return t(e)}:t(e)}("undefined"!=typeof window?window:this,function(ie,e){"use strict";var oe=[],r=Object.getPrototypeOf,ae=oe.slice,g=oe.flat?function(e){return oe.flat.call(e)}:function(e){return oe.concat.apply([],e)},s=oe.push,se=oe.indexOf,n={},i=n.toString,ue=n.hasOwnProperty,o=ue.toString,a=o.call(Object),le={},v=function(e){return"function"==typeof e&&"number"!=typeof e.nodeType&&"function"!=typeof e.item},y=function(e){return null!=e&&e===e.window},C=ie.document,u={type:!0,src:!0,nonce:!0,noModule:!0};function m(e,t,n){var r,i,o=(n=n||C).createElement("script");if(o.text=e,t)for(r in u)(i=t[r]||t.getAttribute&&t.getAttribute(r))&&o.setAttribute(r,i);n.head.appendChild(o).parentNode.removeChild(o)}function x(e){return null==e?e+"":"object"==typeof e||"function"==typeof e?n[i.call(e)]||"object":typeof e}var t="3.7.1-pre",l=/HTML$/i,ce=function(e,t){return new ce.fn.init(e,t)};function c(e){var t=!!e&&"length"in e&&e.length,n=x(e);return!v(e)&&!y(e)&&("array"===n||0===t||"number"==typeof t&&0+~]|"+ge+")"+ge+"*"),x=new RegExp(ge+"|>"),j=new RegExp(g),A=new RegExp("^"+t+"$"),D={ID:new RegExp("^#("+t+")"),CLASS:new RegExp("^\\.("+t+")"),TAG:new RegExp("^("+t+"|[*])"),ATTR:new RegExp("^"+p),PSEUDO:new RegExp("^"+g),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+ge+"*(even|odd|(([+-]|)(\\d*)n|)"+ge+"*(?:([+-]|)"+ge+"*(\\d+)|))"+ge+"*\\)|)","i"),bool:new RegExp("^(?:"+f+")$","i"),needsContext:new RegExp("^"+ge+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+ge+"*((?:-\\d)?\\d*)"+ge+"*\\)|)(?=[^-]|$)","i")},N=/^(?:input|select|textarea|button)$/i,q=/^h\d$/i,L=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,H=/[+~]/,O=new RegExp("\\\\[\\da-fA-F]{1,6}"+ge+"?|\\\\([^\\r\\n\\f])","g"),P=function(e,t){var n="0x"+e.slice(1)-65536;return t||(n<0?String.fromCharCode(n+65536):String.fromCharCode(n>>10|55296,1023&n|56320))},M=function(){V()},R=J(function(e){return!0===e.disabled&&fe(e,"fieldset")},{dir:"parentNode",next:"legend"});try{k.apply(oe=ae.call(ye.childNodes),ye.childNodes),oe[ye.childNodes.length].nodeType}catch(e){k={apply:function(e,t){me.apply(e,ae.call(t))},call:function(e){me.apply(e,ae.call(arguments,1))}}}function I(t,e,n,r){var i,o,a,s,u,l,c,f=e&&e.ownerDocument,p=e?e.nodeType:9;if(n=n||[],"string"!=typeof t||!t||1!==p&&9!==p&&11!==p)return n;if(!r&&(V(e),e=e||T,C)){if(11!==p&&(u=L.exec(t)))if(i=u[1]){if(9===p){if(!(a=e.getElementById(i)))return n;if(a.id===i)return k.call(n,a),n}else if(f&&(a=f.getElementById(i))&&I.contains(e,a)&&a.id===i)return k.call(n,a),n}else{if(u[2])return k.apply(n,e.getElementsByTagName(t)),n;if((i=u[3])&&e.getElementsByClassName)return k.apply(n,e.getElementsByClassName(i)),n}if(!(h[t+" "]||d&&d.test(t))){if(c=t,f=e,1===p&&(x.test(t)||m.test(t))){(f=H.test(t)&&U(e.parentNode)||e)==e&&le.scope||((s=e.getAttribute("id"))?s=ce.escapeSelector(s):e.setAttribute("id",s=S)),o=(l=Y(t)).length;while(o--)l[o]=(s?"#"+s:":scope")+" "+Q(l[o]);c=l.join(",")}try{return k.apply(n,f.querySelectorAll(c)),n}catch(e){h(t,!0)}finally{s===S&&e.removeAttribute("id")}}}return re(t.replace(ve,"$1"),e,n,r)}function W(){var r=[];return function e(t,n){return r.push(t+" ")>b.cacheLength&&delete e[r.shift()],e[t+" "]=n}}function F(e){return e[S]=!0,e}function $(e){var t=T.createElement("fieldset");try{return!!e(t)}catch(e){return!1}finally{t.parentNode&&t.parentNode.removeChild(t),t=null}}function B(t){return function(e){return fe(e,"input")&&e.type===t}}function _(t){return function(e){return(fe(e,"input")||fe(e,"button"))&&e.type===t}}function z(t){return function(e){return"form"in e?e.parentNode&&!1===e.disabled?"label"in e?"label"in e.parentNode?e.parentNode.disabled===t:e.disabled===t:e.isDisabled===t||e.isDisabled!==!t&&R(e)===t:e.disabled===t:"label"in e&&e.disabled===t}}function X(a){return F(function(o){return o=+o,F(function(e,t){var n,r=a([],e.length,o),i=r.length;while(i--)e[n=r[i]]&&(e[n]=!(t[n]=e[n]))})})}function U(e){return e&&"undefined"!=typeof e.getElementsByTagName&&e}function V(e){var t,n=e?e.ownerDocument||e:ye;return n!=T&&9===n.nodeType&&n.documentElement&&(r=(T=n).documentElement,C=!ce.isXMLDoc(T),i=r.matches||r.webkitMatchesSelector||r.msMatchesSelector,r.msMatchesSelector&&ye!=T&&(t=T.defaultView)&&t.top!==t&&t.addEventListener("unload",M),le.getById=$(function(e){return r.appendChild(e).id=ce.expando,!T.getElementsByName||!T.getElementsByName(ce.expando).length}),le.disconnectedMatch=$(function(e){return i.call(e,"*")}),le.scope=$(function(){return T.querySelectorAll(":scope")}),le.cssHas=$(function(){try{return T.querySelector(":has(*,:jqfake)"),!1}catch(e){return!0}}),le.getById?(b.filter.ID=function(e){var t=e.replace(O,P);return function(e){return e.getAttribute("id")===t}},b.find.ID=function(e,t){if("undefined"!=typeof t.getElementById&&C){var n=t.getElementById(e);return n?[n]:[]}}):(b.filter.ID=function(e){var n=e.replace(O,P);return function(e){var t="undefined"!=typeof e.getAttributeNode&&e.getAttributeNode("id");return t&&t.value===n}},b.find.ID=function(e,t){if("undefined"!=typeof t.getElementById&&C){var n,r,i,o=t.getElementById(e);if(o){if((n=o.getAttributeNode("id"))&&n.value===e)return[o];i=t.getElementsByName(e),r=0;while(o=i[r++])if((n=o.getAttributeNode("id"))&&n.value===e)return[o]}return[]}}),b.find.TAG=function(e,t){return"undefined"!=typeof t.getElementsByTagName?t.getElementsByTagName(e):t.querySelectorAll(e)},b.find.CLASS=function(e,t){if("undefined"!=typeof t.getElementsByClassName&&C)return t.getElementsByClassName(e)},d=[],$(function(e){var t;r.appendChild(e).innerHTML="",e.querySelectorAll("[selected]").length||d.push("\\["+ge+"*(?:value|"+f+")"),e.querySelectorAll("[id~="+S+"-]").length||d.push("~="),e.querySelectorAll("a#"+S+"+*").length||d.push(".#.+[+~]"),e.querySelectorAll(":checked").length||d.push(":checked"),(t=T.createElement("input")).setAttribute("type","hidden"),e.appendChild(t).setAttribute("name","D"),r.appendChild(e).disabled=!0,2!==e.querySelectorAll(":disabled").length&&d.push(":enabled",":disabled"),(t=T.createElement("input")).setAttribute("name",""),e.appendChild(t),e.querySelectorAll("[name='']").length||d.push("\\["+ge+"*name"+ge+"*="+ge+"*(?:''|\"\")")}),le.cssHas||d.push(":has"),d=d.length&&new RegExp(d.join("|")),l=function(e,t){if(e===t)return a=!0,0;var n=!e.compareDocumentPosition-!t.compareDocumentPosition;return n||(1&(n=(e.ownerDocument||e)==(t.ownerDocument||t)?e.compareDocumentPosition(t):1)||!le.sortDetached&&t.compareDocumentPosition(e)===n?e===T||e.ownerDocument==ye&&I.contains(ye,e)?-1:t===T||t.ownerDocument==ye&&I.contains(ye,t)?1:o?se.call(o,e)-se.call(o,t):0:4&n?-1:1)}),T}for(e in I.matches=function(e,t){return I(e,null,null,t)},I.matchesSelector=function(e,t){if(V(e),C&&!h[t+" "]&&(!d||!d.test(t)))try{var n=i.call(e,t);if(n||le.disconnectedMatch||e.document&&11!==e.document.nodeType)return n}catch(e){h(t,!0)}return 0":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(e){return e[1]=e[1].replace(O,P),e[3]=(e[3]||e[4]||e[5]||"").replace(O,P),"~="===e[2]&&(e[3]=" "+e[3]+" "),e.slice(0,4)},CHILD:function(e){return e[1]=e[1].toLowerCase(),"nth"===e[1].slice(0,3)?(e[3]||I.error(e[0]),e[4]=+(e[4]?e[5]+(e[6]||1):2*("even"===e[3]||"odd"===e[3])),e[5]=+(e[7]+e[8]||"odd"===e[3])):e[3]&&I.error(e[0]),e},PSEUDO:function(e){var t,n=!e[6]&&e[2];return D.CHILD.test(e[0])?null:(e[3]?e[2]=e[4]||e[5]||"":n&&j.test(n)&&(t=Y(n,!0))&&(t=n.indexOf(")",n.length-t)-n.length)&&(e[0]=e[0].slice(0,t),e[2]=n.slice(0,t)),e.slice(0,3))}},filter:{TAG:function(e){var t=e.replace(O,P).toLowerCase();return"*"===e?function(){return!0}:function(e){return fe(e,t)}},CLASS:function(e){var t=s[e+" "];return t||(t=new RegExp("(^|"+ge+")"+e+"("+ge+"|$)"))&&s(e,function(e){return t.test("string"==typeof e.className&&e.className||"undefined"!=typeof e.getAttribute&&e.getAttribute("class")||"")})},ATTR:function(n,r,i){return function(e){var t=I.attr(e,n);return null==t?"!="===r:!r||(t+="","="===r?t===i:"!="===r?t!==i:"^="===r?i&&0===t.indexOf(i):"*="===r?i&&-1:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i;function T(e,n,r){return v(n)?ce.grep(e,function(e,t){return!!n.call(e,t,e)!==r}):n.nodeType?ce.grep(e,function(e){return e===n!==r}):"string"!=typeof n?ce.grep(e,function(e){return-1)[^>]*|#([\w-]+))$/;(ce.fn.init=function(e,t,n){var r,i;if(!e)return this;if(n=n||k,"string"==typeof e){if(!(r="<"===e[0]&&">"===e[e.length-1]&&3<=e.length?[null,e,null]:S.exec(e))||!r[1]&&t)return!t||t.jquery?(t||n).find(e):this.constructor(t).find(e);if(r[1]){if(t=t instanceof ce?t[0]:t,ce.merge(this,ce.parseHTML(r[1],t&&t.nodeType?t.ownerDocument||t:C,!0)),w.test(r[1])&&ce.isPlainObject(t))for(r in t)v(this[r])?this[r](t[r]):this.attr(r,t[r]);return this}return(i=C.getElementById(r[2]))&&(this[0]=i,this.length=1),this}return e.nodeType?(this[0]=e,this.length=1,this):v(e)?void 0!==n.ready?n.ready(e):e(ce):ce.makeArray(e,this)}).prototype=ce.fn,k=ce(C);var E=/^(?:parents|prev(?:Until|All))/,j={children:!0,contents:!0,next:!0,prev:!0};function A(e,t){while((e=e[t])&&1!==e.nodeType);return e}ce.fn.extend({has:function(e){var t=ce(e,this),n=t.length;return this.filter(function(){for(var e=0;e\x20\t\r\n\f]*)/i,Ce=/^$|^module$|\/(?:java|ecma)script/i;xe=C.createDocumentFragment().appendChild(C.createElement("div")),(be=C.createElement("input")).setAttribute("type","radio"),be.setAttribute("checked","checked"),be.setAttribute("name","t"),xe.appendChild(be),le.checkClone=xe.cloneNode(!0).cloneNode(!0).lastChild.checked,xe.innerHTML="",le.noCloneChecked=!!xe.cloneNode(!0).lastChild.defaultValue,xe.innerHTML="",le.option=!!xe.lastChild;var ke={thead:[1,"","
"],col:[2,"","
"],tr:[2,"","
"],td:[3,"","
"],_default:[0,"",""]};function Se(e,t){var n;return n="undefined"!=typeof e.getElementsByTagName?e.getElementsByTagName(t||"*"):"undefined"!=typeof e.querySelectorAll?e.querySelectorAll(t||"*"):[],void 0===t||t&&fe(e,t)?ce.merge([e],n):n}function Ee(e,t){for(var n=0,r=e.length;n",""]);var je=/<|&#?\w+;/;function Ae(e,t,n,r,i){for(var o,a,s,u,l,c,f=t.createDocumentFragment(),p=[],d=0,h=e.length;d\s*$/g;function Re(e,t){return fe(e,"table")&&fe(11!==t.nodeType?t:t.firstChild,"tr")&&ce(e).children("tbody")[0]||e}function Ie(e){return e.type=(null!==e.getAttribute("type"))+"/"+e.type,e}function We(e){return"true/"===(e.type||"").slice(0,5)?e.type=e.type.slice(5):e.removeAttribute("type"),e}function Fe(e,t){var n,r,i,o,a,s;if(1===t.nodeType){if(_.hasData(e)&&(s=_.get(e).events))for(i in _.remove(t,"handle events"),s)for(n=0,r=s[i].length;n").attr(n.scriptAttrs||{}).prop({charset:n.scriptCharset,src:n.url}).on("load error",i=function(e){r.remove(),i=null,e&&t("error"===e.type?404:200,e.type)}),C.head.appendChild(r[0])},abort:function(){i&&i()}}});var Jt,Kt=[],Zt=/(=)\?(?=&|$)|\?\?/;ce.ajaxSetup({jsonp:"callback",jsonpCallback:function(){var e=Kt.pop()||ce.expando+"_"+jt.guid++;return this[e]=!0,e}}),ce.ajaxPrefilter("json jsonp",function(e,t,n){var r,i,o,a=!1!==e.jsonp&&(Zt.test(e.url)?"url":"string"==typeof e.data&&0===(e.contentType||"").indexOf("application/x-www-form-urlencoded")&&Zt.test(e.data)&&"data");if(a||"jsonp"===e.dataTypes[0])return r=e.jsonpCallback=v(e.jsonpCallback)?e.jsonpCallback():e.jsonpCallback,a?e[a]=e[a].replace(Zt,"$1"+r):!1!==e.jsonp&&(e.url+=(At.test(e.url)?"&":"?")+e.jsonp+"="+r),e.converters["script json"]=function(){return o||ce.error(r+" was not called"),o[0]},e.dataTypes[0]="json",i=ie[r],ie[r]=function(){o=arguments},n.always(function(){void 0===i?ce(ie).removeProp(r):ie[r]=i,e[r]&&(e.jsonpCallback=t.jsonpCallback,Kt.push(r)),o&&v(i)&&i(o[0]),o=i=void 0}),"script"}),le.createHTMLDocument=((Jt=C.implementation.createHTMLDocument("").body).innerHTML="